Mục tiêuSau bài này bạn có thể:
• Trình bày được nguyên tắc quản lý thời gian bằng VBA.
• Vận dụng tạo đồng hồ, thiết lập thời gian cho bài học.
Giới thiệu Trong quá trình thiết kế bài học, bài kiểm tra bằng Powerpoint, đôi khi muốn giới hạn thời gian thực hiện cho một hoạt động nào đó, lúc này ta phải tự xây dựng cho mình một đồng hồ thời gian để làm điều này. Mặc định, VBA không cung cấp đối tượng nào để quản lý thời gian. Trong Visual Basic có đối tượng Timer tự động thực hiện sau một khoảng thời gian (interval), nhưng trong VBA thì không.
Trong khi người dùng đang thực hiện những hoạt động khác, đồng hồ vẫn phải chạy. Vì vậy ý tưởng ở đây là, ta sẽ kích hoạt đồng hồ mỗi giây 1 lần, trong thời gian mỗi giây đó ta trả quyền quản lý về cho hệ thống bằng lệnh DoEvents.
Nguyên tắc quản lý thời gian bằng VBA Để xây dựng được bài trình chiếu có tính đến yếu tố thời gian dùng VBA cần tuân theo các nguyên tắc sau:
• Phải xác định điểm dừng: ví dụ đồng hồ (thời gian làm bài) sẽ dừng sau 60 phút, 10 phút, 60 giây..vv
• Viết sự kiện để bắt đầu tính thời gian: ví dụ phải có nút bắt đầu.
• Viết sự kiện để kết thúc việc tính thời gian trước khoảng thời gian quy định: ví dụ người học muốn kết thúc trước khi hết giờ làm bài.
• Chọn sự kiện hoặc khoảng thời gian để cập nhật lại đồng hồ: ví dụ cứ sau 1 giây sẽ cập nhật lại đồng hồ.
• Không bấm nút ESC để thoát khỏi slide khi đồng hồ đang chạy mà phải gọi sự kiện kết thúc trước khi bấm nút ESC.
Xây dựng đồng hồ
Ta có lệnh DoEvents sẽ trả quyền kiểm soát về cho hệ thống. Khi ta gọi câu lệnh này thì hệ thống có quyền sử dụng CPU cho bất kỳ tiến trình nào khác. Ví dụ khi ta thực hiện một vòng lặp từ 1 đến 1 tỉ sẽ mất 1 một khoảng thời gian. Trong khoảng thời gian đó hầu như ta không còn làm được việc gì khác nữa, vì hệ thống đang thực hiện vòng lặp. Tuy nhiên nếu trong mỗi vòng lặp ta gọi DoEvents thì cứ mỗi vòng lặp hệ thống có một khoản thời gian để thực hiện công việc khác chính vì vậy ta không có cảm giác vòng lặp đang chạy.
Chính đặc điểm này ta có thể sử dụng DoEvents để người dùng có thể làm những hoạt động khác trong khi đồng hồ vẫn đang chạy.
Dim PauseTime, Start, Finish
'Gán thoi gian cho la 1 giay
PauseTime = 1
'Lay thoi diem hien tai
Start = Timer
'Tao vong lap trong khi chua het thoi gian cho
DoWhile Timer < Start + PauseTime
' Chuyen quyen quan ly cho he thong trong khi lap
DoEvents
Loop
Biến nhận khoảng thời gian chờ tính theo giây, biến lấy thời gian hiện tại bằng hàm Timer, Ta thực hiện vòng lặp trong cho đến khi hết thời gian chờ. Trong mỗi lần lặp ta trả quyền kiểm soát cho hệ thống để thực hiện các tác vụ khác.
Ví dụ 4.1: Giả sử thời gian làm mỗi câu ở ví dụ 3.3 là 30 giây, viết thêm chức năng hiển thị đồng hồ, đếm lùi thời gian để người dùng có thể canh thời gian làm bài của mình.
Ý tưởng: Khi người dùng click “Bắt đầu” ta thực hiện việc gán cho Text Box đếm ngược bằng thời
Text Box này đi 1 cho đến khi giá trị của nó về 0, đồng thời cập nhật lại Label hiển thị đồng hồ. Trong khi chờ ta chuyển quyền quản lý về cho hệ thống.
Hướng dẫn chi tiết:
Bước 1: Sử dụng lại kết quả ở ví dụ 3.3. Tạo thêm Text Box txtSecond để hiển thị số giây đếm ngược, Label lblClock để hiển thị đồng hồ. Thêm Button cmdKetThuc làm nút kết thúc.
Bước 2: Khi người dùng bấm “Bắt đầu” (tương đương với nút làm lại cũ) ta thực hiện gán thời gian làm bài là 30*10 (30 giây mỗi câu, ta có 10 câu). Đồng thời bỏ chọn các Option box như ở ví dụ 3.3
PrivateSub btnReset_Click() Opt1.Value = False Opt2.Value = False Opt3.Value = False Opt4.Value = False spn.Value = 1 lblFB.Caption = "" txtSecond.Value = 30 * 10 EndSub
Bước 3: Mỗi khi txtSecond thay đổi ta chờ 1 giây, sau đó cập nhật lại đồng hồ và trừ bớt giá trị của TextBox đi 1. Trong thời gian chờ nhớ trả quyền quản lý cho hệ thống. Lưu ý để lấy thời gian hiện tại ta dùng hàm Now kết hợp với hàm Format với chuỗi định dạng là tttttt.
PrivateSub txtSecond_Change() If txtSecond.Value > 0 Then Dim PauseTime, Start, Finish
' Gán thoi gian cho la 1 giay
PauseTime = 1
'Lay thoi diem hien tai
Start = Timer
'Tao vong lap trong khi chua het thoi gian cho
DoWhile Timer < Start + PauseTime
DoEvents Loop If txtSecond.Value > 0 Then lblClock.Caption = Format(Now, "tttttt") txtSecond.Value = txtSecond.Value - 1 EndIf EndIf EndSub
Như vậy mỗi khi Text Box thay đổi nó lại gọi sự kiện của chính nó cho đến khi giá trị về đến 0. Điểm dừng của ta ở đây là khi Text Box về 0. Điểm bắt đầu là khi người dùng bấm vào “Bắt đầu”.
Bước 4: Khi người dùng không muốn làm nữa có thể click nút kết thúc.
PrivateSub cmdKetThuc_Click() txtSecond.Value = 0
EndSub
---
BÀI 5. SLIDE & SHAPE
Mục tiêu
Sau bài này bạn có thể:
• Đặt tên cho slide & shape.
• Truy xuất được đến slide & shape.
• Viết Macro cho shape.
Giới thiệu
Thành phần cơ bản trên một bài trình chiếu là Slide. Trên Slide chúng ta thường chèn TextBox, hình ảnh, shape. Ở đây ta gọi chung các đối tượng này là Shape.
Slide & Shape cũng có tên duy nhất để chúng ta có thể truy xuất đến. Tuy nhiên Powerpoint không cung cấp một chức năng nào để chúng ta có thể xem tên hoặc gán tên cho Slide/Shape. Chúng ta có thể đổi tên cho Shape/Slide bằng code, tuy nhiên nếu chúng ta thường xuyên làm việc trên Shape thì điều này rõ rang không thuận tiện, chính vì vậy tôi đã tạo ra 1 Plugin sử dụng cho PowerPoint 2007 giúp bạn thực hiện điều này. Có thể truy cập http://vn.myblog.yahoo.com/onceclick để download Plugin này.
Sau khi cài đặt PowerPoint 2007 sẽ có thêm tab VBA Support trên Ribbon. Trên này cung cấp các chức năng như lấy tên slide/shape đưa vào clipboard, đặt tên cho slide/shape, lấy đường dẫn truy xuất đến slide/shape, một số đoạn code điều hướng trên slide.
Hình 5.1: Giao diện của VBA Support
Nếu sử dụng công cụ này chúng ta không cần phải đọc phần đổi tên cho Slide/Shape nữa. Nếu bạn vẫn đang sài Powerpoint 2003 có thể đổi tên cho Slide/Shape như sau.
Đọc/đổi tên Shape/Slide
Bước 1: Chọn Slide hoặc Shape muốn đổi tên.
Bước 2: Bấm ALT+F11 để mở cửa sổ Visual Basic. Sau đó bấm Ctrl + G hoặc chọn Menu
View/Immediate Window để mở ngăn Immediate. Ngăn này cho phép người dùng gõ và chạy code thử nghiệm. Ta sẽ sử dụng ngăn này để đọc hoặc đổi tên Slide/Shape. Mỗi lệnh trong ngăn này nằm trên 1 dòng, khi nhấn Enter sẽ thực hiện lệnh đó. Ví dụ gõ vào msgbox "Hello" sau khi Enter sẽ xuất hiện thông báo với chuỗi “Hello”.
Bước 3: Gõ vào một trong các lệnh sau để thực hiện nhiệm vụ tương ứng.
Nhiệm vụ Code
Đọc tên Slide debug.printActiveWindow.View.Slide.Name
Đổi tên Slide ActiveWindow.View.Slide.Name = "Hello"
Đổi tên Shape ActiveWindow.Selection.ShapeRange.Name = "TenShape"
Bảng 5.1: Đọc/đổi tên Slide/Shape
Truy xuất đến Slide/Shape
Giả sử một Shape có tên là “Title 1” và nằm trên Slide tên “Hello” ta sẽ truy xuất đến Slide/Shape thông qua đoạn code sau:
Loại Code
Slide ActivePresentation.Slides("Hello")
Shape ActivePresentation.Slides("Hello").Shapes("Title 1")
Bảng 5.2: Truy xuất đến Slide/Shape
Muốn thay đổi hay gọi các thuộc tính/phương thức của Slide/Shape chỉ cần truy xất đến Slide/Shape sau đó thêm dấu chấm VBA sẽ hiện hộp thoại cho bạn chọn.
Ví dụ 5.1: Xem tọa độ bên trái của Shape:
debug.print ActivePresentation.Slides("Hello").Shapes("Title 1").Left Ví dụ 5.2: Quay Shape 45 độ:
ActivePresentation.Slides("Hello").Shapes("Title 1").IncrementRotation 45
Ví dụ 5.3: Lật shape theo chiều dọc
ActivePresentation.Slides("Hello").Shapes("Title 1").Flip msoFlipVertical
Viết Macro cho Shape
Macro thật ra là một đoạn code nhằm thực hiện công việc nào đó. Để tạo Macro cho Shape ta thực hiện như sau:
Bước 1: Nhấn ATL + F11 để mở cửa sổ Visual Basic, Từ Menu Insert, chọn Insert Module. Module mặc định được tạo ra là module1, có thể tạo bao nhiêu module tùy ý tuy nhiên thường chỉ cần viết trên 1 module là đủ. Code viết trên Module có thể được gọi từ bất kỳ đâu, trên bất kỳ slide nào.
Bước 2: Từ Menu Insert chọn Procedure, đặt tên cho thủ tục và nhấn OK để chèn một thủ tục mới. Thủ tục này được gọi là Macro. Sau đó viết code cho macro.
Bước 3: Quay về cửa sổ thiết kế:
Đối với PowerPoint 2003: Click phải vào Shape muốn gán Macro, chọn Action Settings, chọn Run Macro và chọn tên Macro cần thực hiện.
Đối với PowerPoint 2007: Chọn Shape cần gán Macro, click vào nút Action trong ngăn Insert, chọn
Run Macro và chọn tên Macro cần thực hiện.
Điều hướng Slide Thông thường nếu chỉ muốn di chuyển giữa các Slide, ta chỉ cần chèn Shape sau đó mở hộp thoại Action Settings như ở phần trên, trong phần Hyperlink To chọn Slide muốn chuyển tới khi click vào Shape.
Tuy nhiên đôi chúng ta muốn tùy thuộc vào điều kiện nào đó mà sẽ chuyển đến Slide thích hợp (người dùng trả lời đúng/sai), hoặc thực hiện công việc nào đó trước khi chuyển tới Slide khác (cộng dồn điểm, khởi tạo giá trị…) khi đó chúng ta phải viết Macro để chuyển Slide. Dưới đây là một số mã lệnh để chuyển Slide.
Di chuyển Code
Chuyển đến slide thứ i ActivePresentation.SlideShowWindow.View.GotoSlide(i)
Slide đầu tiên ActivePresentation.SlideShowWindow.View.First
Slide cuối ActivePresentation.SlideShowWindow.View.Last
Slide liền trước ActivePresentation.SlideShowWindow.View.Previous
Slide liền sau ActivePresentation.SlideShowWindow.View.Next
Kết thúc trình chiếu ActivePresentation.SlideShowWindow.View.Exit
Bảng 5.3: Điều hướng Slide
Thay đổi nội dung Text bên trong Shape
Cấu trúc chung:
.TextFrame.TextRange.Text ="Hello"
Ví dụ 5.4: Thay đổi giá trị cho Shape “hoten” trên slide “user” giá trị bằng “Nguyen Van A” ActivePresentation.Slides("user").Shapes("hoten").TextFrame.TextRange.Text ="Nguyen Van A"
Các ứng dụng thực tiễn của shape
Ví dụ 5.5: Xây dựng đồng hồ bằng Shape. Kết quả của ví dụ này là một đồng hồ Analog, cho phép người dùng chạy hoặc dừng.
Hình 5.2: Đồng hồ bằng Shape
Ý tưởng: Đối tượng Shape có thuộc tính Rotation, thuộc tính này mang giá trị từ (0-360), cho phép Shape quay xung quanh điểm giữa của Shape. Nhờ đặc điểm này ta dùng để thực hiện bài tập này.
Hướng dẫn chi tiết:
Bước 1: Vẽ 1 hình tròn làm khung đồng hồ.
Bước 2: Tạo kim đồng hồ. Vì Shape chỉ quay quanh tâm của nó nhưng kim đồng hồ lại không quay quanh tâm. Chính vì vậy ý tưởng đơn giản nhất là group kim đồng hồ với một hình tròn có kích thước bằng hình tròn ở bước 1. Cần chú ý bỏ đường viền và cho hình tròn này trong suốt trước khi group. Lần lượt tạo ra kim giờ, kim phút và kim giây. (Chú ý nên làm kim đứng thẳng xem như đang ở 0 độ).
Bước 3: Lần lượt đặt tên cho các group là KimGio, KimPhut, KimGiay. Đặt tên cho Slide là clock. Tạo Button đặt tên là btnStart để bật/tắt đồng hồ.
Bước 4: Cần lưu ý 1 phút tương đương với 6 độ, 1 giây tương đương với 6 độ, 1 giờ tương ứng với 30 độ (vì vậy phải sử dụng hàm làm tròn). Chính vì vậy nếu có được giây hiện tại ta cho KimGiay quanh 1 góc (SoGiay*6), tương tự cho kim phút, riêng kim giờ ngoài việc quay 1 góc (giờ*30) còn phải cộng thêm một góc do phút tạo ra (SoPhut/2) (vì 1 giờ tương đương 30 độ, cũng có nghĩa 60 phút tương đương 30 độ vì vậy mới có kết quả là SoPhut/2).
Bước 5: Khi người dùng bật đồng hồ, cứ mỗi giây ta cập nhật lại góc quay của các kim. Ở đây có sử dụng vòng lặp dạng While <điều kiện> {các lệnh} Wend. Có nghĩa là trong khi <điều kiện> đúng sẽ thực hiện các lệnh.
Vì việc cập nhật giờ bao gồm nhiều lệnh trong đó nên ta viết riêng một thủ tục CapNhatGio để cập nhật lại góc của các kim đồng hồ.
Sub CapNhatGio()
Dim gio, phut, giay As Integer gio = Hour(Now) Mod 12 phut = Minute(Now) giay = Second(Now)
'1 giay tuong duong voi 6 do
ActivePresentation.Slides("user").Shapes("KimGiay").Rotation = giay * 6
'1 phut tuong duong voi 6 do
ActivePresentation.Slides("user").Shapes("KimPhut").Rotation= phut * 6
'1h tuong duong voi 30 do
ActivePresentation.Slides("user").Shapes("KimGio").Rotation=gio*30+Round(phut/2)
EndSub
PrivateSub btnStart_Click()
If (btnStart.Caption = "Run Clock") Then btnStart.Caption = "Stop Clock"
Else
btnStart.Caption = "Run Clock" End If
While (btnStart.Caption = "Stop Clock") CapNhatGio
Dim PauseTime, Start, Finish
' Gán thoi gian cho la 1 giay
PauseTime = 1
'Lay thoi diem hien tai
Start = Timer
Do While Timer < Start + PauseTime
' Chuyen quyen quan ly cho he thong trong khi lap
DoEvents Loop
Wend
EndSub
Ví dụ 5.6: Xây dựng Slide thu thập ý kiến bằng Shape. Kết quả của ví dụ này là slide cho phép người dùng nhập ý kiến vào Text Box, khi bấm nút Add sẽ thêm nội dung vào Shape ở trên. Bấm Reset sẽ thu thập ý kiến từ đầu.
Hình 5.3: Slide thu thập ý kiến
Ý tưởng: Dùng thuộc tính .TextFrame.TextRange.Text của Shape.
Hướng dẫn chi tiết:
Bước 1: Chèn một Text Shape có dạng như hình 5.3 đặt tên là YKien, Slide có tên là ThuThap, 2 button và 1 text box lần lượt có tên là btnAdd, btnReset và txtAdd.
Bước 2: Khi người dùng bấm nút Add ta đưa nội dung từ txtAdd lên YKien bằng cách nối chuỗi (&) đồng thời làm rỗng txtAdd, khi người dung bấm Reset ta làm rỗng cả txtAdd và YKien. Điểm lưu ý ở đây là ký tự xuống dòng chr$(13). Ở đây có sử dụng cấu trúc With ..End With , cấu trúc này cho phép phần code bên trong không cần viết lại đối tượng ở trên mà chỉ cần dùng dấu “.” để gọi thuộc tính của đối tượng đó.
PrivateSub btnAdd_Click()
With ActivePresentation.Slides("ThuThap").Shapes("YKien")
.TextFrame.TextRange.Text = .TextFrame.TextRange.Text & txtAdd.Text & Chr$(13) txtAdd.Text = ""
EndWith EndSub
PrivateSub btnReset_Click()
ActivePresentation.Slides("ThuThap").Shapes("YKien").TextFrame.TextRange.Text = "" txtAdd.Text = ""