Giáo trình Phát triển AutoCAD bằng ActiveX & VBA - Chương 13: Thiết kế đường đi dạo trong vườn - Một ví dụ về ActiveX/VBA
Trong chương này 13
Kiểm tra môi trường làm
việc
Xác định mục đích
Viết đoạn chương trình
đầu tiên
Nhập số liệu
Vẽ đường đi dạo
Vẽ lớp gạch lát
Tổng hợp lại
Duyệt mã lệnh
Thực thi Macro
Thêm giao diện hộp thoại
Bạn đang xem tài liệu "Giáo trình Phát triển AutoCAD bằng ActiveX & VBA - Chương 13: Thiết kế đường đi dạo trong vườn - Một ví dụ về ActiveX/VBA", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Giáo trình Phát triển AutoCAD bằng ActiveX & VBA - Chương 13: Thiết kế đường đi dạo trong vườn - Một ví dụ về ActiveX/VBA
Phát triển ứng dụng ActiveX và VBA | 295 THIẾT KẾ ĐƯỜNG ĐI DẠO TRONG VƯỜN - MỘT VÍ DỤ VỀ ActiveX/VBA 13 Trong chương này Kiểm tra môi trường làm việc Xác định mục đích Viết đoạn chương trình đầu tiên Nhập số liệu Vẽ đường đi dạo Vẽ lớp gạch lát Tổng hợp lại Duyệt mã lệnh Thực thi Macro Thêm giao diện hộp thoại Đây là phần hướng dẫn người đọc cách thêm một Macro mới vào trong AutoCAD, giải thích sự làm việc của ActiveX và VBA, và cách sử dụng các công nghệ này hiệu quả nhất. Ví dụ này hướng theo kiến trúc cảnh quan nhưng những khái niệm mà người đọc có thể học được vẫn có thể vận dụng vào các lĩnh vực ứng dụng khác. Phần ví dụ này được soạn với đối tượng là những người sử dụng AutoCAD thành thạo nhưng mới học lập trình với VBA. 296 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA 1. Kiểm tra môi trường làm việc Để thực hiện các thao tác cần thiết trong ví dụ này, trước hết cần cài đặt môi trường VBA trong AutoCAD. Khi cài AutoCAD với tuỳ chọn Full hoặc Standard thì môi trường VBA được tự động cài đặt, nếu chọn Custom thì có thể VBA sẽ không được cài đặt. Kiểm tra việc cài đặt VBA: 1 Khởi động AutoCAD. 2 Tại dòng nhập lệnh, gõ VBAIDE. 3 Nếu môi trường lập trình VBA mở ra thì VBA đã được cài đặt. Nếu xuất hiện thông báo “AutoCAD VBA is not currently installed” thì VBA chưa được cài đặt. Cài đặt môi trường VBA: 1 Thoát khỏi chương trình AutoCAD. 2 Chạy chương trình cài đặt AutoCAD setup.exe. 3 Chọn Add để thêm một thành phần vào bản cài đặt hiện tại. 4 Chọn VBA Support. 5 Chọn Next để tiếp tục cài đặt 6 Khẳng định các cài đặt bằng cách chọn Next một lần nữa. 7 Khi đã hoàn thành việc cài đặt thì khởi động lại chương trình AutoCAD. 8 Tại dòng nhập lệnh, nhập VBAIDE. Môi trường lập trình VBA sẽ được mở ra và môi trường làm việc để thực hiện ví dụ trong chương này đã sẵn sàng. 2. Xác định mục đích Mục tiêu trong ví dụ này là lập một Marco mới cho AutoCAD để vẽ một đường đi trong vườn và được lát bởi các viên bêtông tròn. Marco mới sẽ có các dòng nhắc theo trình tự như sau: Command: gardenpath Start point of path: Người dùng sẽ chỉ ra điểm đầu của tuyến đường Endpoint of path: Người dùng sẽ chỉ ra điểm kết thúc của tuyến đường Half width of path: Người dùng nhập vào giá trị của một nửa bề rộng Radius of tiles: Người dùng nhập vào giá trị bán kính của gạch lát Spacing between tiles: Người dùng nhập vào khoảng cách giữa hai viên gạch Khi thực hiện, Macro sẽ nhắc người dùng nhập vào điểm bắt đầu và kết thúc của tim đường đi dạo thiết kế. Tiếp đó, macro nhắc người dùng nhập bề rộng nửa đường (vẽ bề rộng nửa từ đường tim sẽ giúp dễ hình dung hơn là cả bề rộng đường) và bán kính của những viên gạch lát hình tròn. Cuối cùng, người dùng được yêu cầu nhập khoảng cách giữa các viên gạch lát. Phát triển AutoCAD bằng ActiveX và VBA | 297 3. Viết đoạn chương trình đầu tiên Macro sẽ được xây dựng dựa trên một loạt các hàm và thủ tục. Một số thủ tục làm việc với các góc vì lý do đơn vị của góc trong ActiveX là radians nhưng hầu hết người dùng thường quen làm việc với góc tính theo độ. Do đó, trước hết cần xây dựng hàm chuyển đổi từ độ sang radians. Nếu chưa mở VBA IDE thì khởi động nó từ bằng lệnh VBAIDE. Trong VBA IDE, mở cửa sổ Code như sau: trong menu View Code; hoặc dùng phím F7. Hàm chuyển đổi từ độ sang radians Gõ đoạn mã sau vào cửa sổ Code sau dòng Option Explicit: Const pi = 3.14159 ’ Chuyển đổi từ độ sang radians Function dtr(a As Double) As Double dtr = (a / 180) * pi End Function Ngay khi xuống dòng để kết thúc dòng lệnh Function dtr(a As Double) As Double, VBA sẽ tự động thêm dòng lệnh End Function. Môi trường lập trình VBA luôn thực hiện như vậy để đảm bảo rằng tất cả các chương trình con đều có lệnh kết thúc tương ứng. Ở dòng đầu tiên, hằng số pi được gán giá trị là 3.14159. Điều này cho phép thay thế việc gõ lại số 3.14159 mỗi khi cần dùng bằng cách nhập pi. Dòng tiếp theo để định nghĩa một hàm có tên là dtr (Degrees To Radians). Hàm số này cần một đối số a là góc theo đơn vị độ. Kết quả tính bằng cách chia góc a cho 180 và nhân với pi. Dòng bắt đầu bằng dấu nháy đơn là câu chú thích. VBA sẽ bỏ qua tất cả những dòng bắt đầu bằng ký tự này. Hàm này đã có thể được sử dụng trong các chương trình con khác trong dự án. Sau đó lưu dự án với tên tuỳ chọn theo trình tự chọn: menu File Save, tuy nhiên để tiện dùng, trong ví dụ này đặt tên cho dự án là gardenpath.dvb Tính khoảng cách giữa hai điểm Tiếp theo thêm một hàm tính khoảng cách giữa hai điểm. Nhập đoạn mã sau đây tiếp theo hàm dtr: ’Tính khoảng cách giữa hai điểm Function distance(sp As Variant, ep As Variant)As Double Dim x As Double Dim y As Double Dim z As Double x = sp(0) - ep(0) y = sp(1) - ep(1) z = sp(2) - ep(2) distance = Sqr((Sqr((x ^ 2) + (y ^ 2)) ^ 2) + (z ^ 2)) End Function Lưu kết quả đã thực hiện. 298 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA 4. Nhập số liệu Macro sẽ nhắc nhở người dùng nhập vị trí để vẽ đường đi, bề rộng của đường, và khoảng cách giữa các viên gạch lát. Cho nên tiếp theo sẽ định nghĩa một thủ tục để yêu cầu người dùng nhập vào các thông tin yêu cầu ở trên và sau đó thực hiện tính toán. Trong thủ tục này, sử dụng các phương thức nhập số liệu của đối tượng Utility. 4.1. Khai báo biến Thủ tục tiếp theo sẽ sử dụng một số biến toàn cục. Tất cả các biến toàn cục cần được khai báo trước khi các thủ tục có thể sử dụng chúng. Khai báo biến toàn cục Trong VBA IDE, nhập đoạn mã lệnh sau trong cửa sổ Code ngay dưới dòng lệnh Const pi = 3.14159: ’ Các biến để lưu các thông số của đường trong vườn Private sp(0 To 2) As Double Private ep(0 To 2) As Double Private hwidth As Double Private trad As Double Private tspac As Double Private pangle As Double Private plength As Double Private totalwidth As Double Private angp90 As Double Private angm90 As Double Hai hộp danh sách dạng thả xuống ở phía trên của cửa sổ Code được gọi tương ứng là Object Box (hộp chứa danh sách các đối tượng) và Procedure/Event Box (hộp danh sách chứa các thủ tục và sự kiện). Hiện tại, giá trị trong hai hộp danh sách này lần lượt là General và Declarations. Hai hộp danh sách sẽ cho biết phần dự án mà con trỏ dừng lại là phần nào: cụ thể là đối tượng nào và thủ tục hay sự kiện nào của đối tượng đó. Phần Declarations sẽ tương ứng với phần khai báo các biến sẽ sử dụng trong nhiều chương trình con. Để chuyển sang làm việc với đối tượng khác hoặc sự kiện khác của đối tượng, có thể thực hiện nhanh chóng bằng cách lựa chọn tên tương ứng trong hai hộp danh sách này. Chú ý đến dòng Option Explicit nằm trên cùng của phần Declaration. Khi dòng này xuất hiện trong một mô-đun tức là các biến phải khai báo rõ ràng bằng các lệnh Dim, Private, Public, ReDim, hoặc Static. Các trường hợp sử dụng biến chưa được khai báo thì sẽ phát sinh thông báo lỗi. Nếu không sử dụng dòng lệnh Option Explicit, tất cả các biến mà chưa được khai báo sẽ mang kiểu Variant. Người lập trình nên sử dụng dòng lệnh này để tránh những lỗi cú pháp khi nhập tên của các biến đã có hoặc tránh nhầm lẫn khi phạm vi của các biến không được khai báo rõ ràng. 4.2. Tạo chương trình con gpuser Chương trình con gpuser sẽ nhắc người dùng nhập tất cả các thông tin cần thiết để vẽ đường đi dạo trong vườn. Phát triển AutoCAD bằng ActiveX và VBA | 299 Nhắc người dùng nhập số liệu: Viết đoạn mã sau ngay dưới hàm distance: ’ Thông tin cần thiết về đường đi bộ Private Sub gpuser() Dim varRet As Variant varRet = ThisDrawing.Utility.GetPoint( ,_ "Start point of path: ") sp(0) = varRet(0) sp(1) = varRet(1) sp(2) = varRet(2) varRet = ThisDrawing.Utility.GetPoint( ,_ "Endpoint of path: ") ep(0) = varRet(0) ep(1) = varRet(1) ep(2) = varRet(2) hwidth = ThisDrawing.Utility.GetDistance(sp, _ "Half width of path: ") trad = ThisDrawing.Utility.GetDistance(sp, _ "Radius of tiles: ") tspac = ThisDrawing.Utility.GetDistance(sp, _ "Spacing between tiles: ") pangle = ThisDrawing.Utility.AngleFromXAxis(sp, ep) totalwidth = 2 * hwidth plength = distance(sp, ep) angp90 = pangle + dtr(90) angm90 = pangle - dtr(90) End Sub Đoạn mã lệnh này định nghĩa một chương trình con có tên là gpuser. Chương trình con này không có tham số và sẽ yêu cầu người dùng nhập tất cả các thông tin cần thiết. Dòng lệnh Dim varRet As Variant thực hiện khai báo biến varRet. Vì biến này chỉ sử dụng trong phạm vi của chương trình con này nên chỉ cần khai báo cục bộ trong phạm vi của nó thay vì khai báo trong phần Declarations. Dòng lệnh tiếp theo varRet = ThisDrawing.Utility.GetPoint( , "Start point of path: ") thực hiện gọi phương thức GetPoint. Dấu gạch ngang để nối dòng lệnh với dòng ngay dưới nó, khi đó VBA sẽ đọc hai dòng như một dòng lệnh. Dấu gạch này không bắt buộc phải có nên có thể nối liền hai dòng lại nhưng nếu sử dụng để ngắt dòng lệnh dài thì sẽ giúp đọc dễ dàng hơn. Để truy cập phương thức GetPoint, cần thông qua đối tượng đại diện cho bản vẽ hiện hành là ThisDrawing. Khi nhập ThisDrawing và tiếp theo là dấu chấm (.) có nghĩa là sẽ thực hiện truy cập vào một thứ gì đó chứa trong đối tượng ThisDrawing. Sau dấu chấm gõ Utility và dấu chấm tiếp theo, tức là sẽ truy cập vào bên trong của đối tượng Utility. Cuối cùng nhập GetPoint là tên của phương thức đang cần gọi. Phương thức GetPoint yêu cầu 2 tham số. Tham số thứ nhất không bắt buộc và sẽ không sử dụng trong chương trình con này bằng cách để trống tham số đó đặt dấu phẩy (,) để phân biệt nó. Tham số thứ hai là lời nhắc nên cũng không bắt buộc. Với tham số này, nhập một chuỗi để nhắc người dùng nhập điểm đầu. Điểm người dùng 300 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA nhập được gán cho biến varRet. Ba dòng lệnh tiếp theo sẽ gán toạ độ của điểm người dùng vừa nhập cho mảng sp. Điểm cuối cũng được lấy theo cách tương tự như điểm đầu. Phương thức GetDistance để nhập bề rộng nửa của đường đi bộ (hwidth), bán kính của gạch lát (trad) và khoảng cách giữa các viên gạch (tspac). Phương thức này cần hai tham số, thứ nhất là điểm cơ sở, thứ hai là một lời nhắc: yêu cầu một chuỗi hướng dẫn người dùng nhập giá trị phù hợp. Phương thức GetDistance có thể trả về giá trị khoảng cách được nhập từ dòng lệnh và cả khoảng cách giữa điểm được chọn trong AutoCAD và điểm cơ sở. Chương trình con sẽ tính toán các biến khác mà được sử dụng tiếp theo trong Macro. Biến pangle được gán cho góc giữa đường thẳng tạo bởi điểm đầu điểm cuối và chiều dương của trục x bằng phương thức AngleFromXAxis. Bề rộng của đường đi bộ được tính bằng 2 lần của giá trị nửa bề rộng nhập vào từ người dùng. Biến plength được gán giá trị là chiều dài của đường đi bộ được xác định ở trên trong phương thức GetDistance. Cuối cùng các biến angp90 và angm90 được tính và lưu bằng cách cộng và trừ giá trị góc của đường đi bộ với 900. Lưu kết quả đã thực hiện. Hình vẽ dưới biểu diễn cách các biến được tính trong chương trình con để xác định các kích thước của đường đi bộ. Chi tiết bố trí gạch lát 5. Vẽ đường đi dạo Khi đã có đủ các thông số định vị và bề rộng thì có thể bắt đầu thực hiện vẽ đường đi dạo. Vẽ đường đi dạo trong vườn: Thêm đoạn mã dưới đây ngay dưới chương trình con gpuser: Phát triển AutoCAD bằng ActiveX và VBA | 301 ’ Vẽ đường đi dạo Private Sub drawout() Dim points(0 To 9) As Double Dim pline As AcadLWPolyline Dim varRet As Variant varRet = ThisDrawing.Utility.PolarPoint(sp, angm90, hwidth) points(0) = varRet(0) points(1) = varRet(1) points(8) = varRet(0) points(9) = varRet(1) varRet = ThisDrawing.Utility.PolarPoint( _ varRet, pangle, plength) points(2) = varRet(0) points(3) = varRet(1) varRet = ThisDrawing.Utility.PolarPoint( _ varRet, angp90, totalwidth) points(4) = varRet(0) points(5) = varRet(1) varRet = ThisDrawing.Utility.PolarPoint( _ varRet, pangle + dtr(180), plength) points(6) = varRet(0) points(7) = varRet(1) Set pline = ThisDrawing.ModelSpace. _ AddLightWeightPolyline(points) End Sub Thủ tục này sẽ vẽ đường đi dạo sử dụng phương thức AddLightweightPolyline. Phương thức này cần một tham số là mảng của các điểm tạo thành đường đa tuyến. Để vẽ đa tuyến cần tìm tất cả các điểm tạo thành đường đa tuyến đó và xếp chúng vào mảng toạ độ. Với đường đi dạo thì các điểm cần thiết chính là các góc của nó. Tìm các góc của đường đi dạo bằng cách sử dụng phương thức PolarPoint. Phương thức này sẽ tìm điểm khi biết góc và khoảng cách của điểm đó so với điểm cơ sở. Từ điểm đầu (sp) có thể tìm được góc thứ nhất của đường theo chiều kim đồng hồ, đỉnh này cách sp một khoảng bằng nửa bề rộng đường (hwidth) và tạo góc (-900) so với tim đường. Để vẽ đường khép kín bao quanh phạm vi đường thì điểm này sẽ là điểm bắt đầu và cũng là điểm kết thúc của mảng toạ độ các điểm. Vì thế toạ độ X và Y được trả về từ phương thức PolarPoint sẽ được gán cho cả điểm đầu và điểm cuối của mảng. Các góc còn lại sẽ được tính theo cách tương tự sử dụng chiều dài, bề rộng của đường đi dạo (plength và width) và góc của đường đi dạo tạo với chiều dương của trục x. Mỗi khi phương thức PolarPoint được gọi thì toạ độ của các điểm nhận được (biến varRet) sẽ được chép vào mảng toạ độ các điểm. Khi tất cả các góc đã được xác định trong mảng toạ độ các điểm thì thực hiện phương thức AddLightweightPolyline, chú ý là phương thức này được gọi từ đối tượng ModelSpace. Nếu thực hiện chương trình con này, cần chú ý rằng đường đa tuyến chưa hiển thị trên AutoCAD cho đến khi bản vẽ được cập nhật lại (sẽ thực hiện ở phần sau). 302 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA 6. Vẽ lớp gạch lát Sau khi tạo thủ tục nhập số liệu từ người dùng cùng với thủ tục vẽ đường đi dạo, tiếp theo sẽ bố trí gạch lát hình tròn cho đường đi dạo. Thao tác này yêu cầu một số yếu tố về hình học bố trí gạch lát hình tròn trong đường đi dạo Trong VBAIDE, nhập dòng mã lệnh sau trong cửa sổ Code ngay dưới thủ tục drawout: ’ Đặt một hàng gạch dọc theo chiều dài của đường đi dạo ’ và các khoảng bù thích hợp Private Sub drow(pd As Double, offset As Double) Dim pfirst(0 To 2) As Double Dim pctile(0 To 2) As Double Dim pltile(0 To 2) As Double Dim cir As AcadCircle Dim varRet As Variant varRet = ThisDrawing.Utility.PolarPoint( _ sp, pangle, pd) pfirst(0) = varRet(0) pfirst(1) = varRet(1) pfirst(2) = varRet(2) varRet = ThisDrawing.Utility.PolarPoint( _ pfirst, angp90, offset) pctile(0) = varRet(0) pctile(1) = varRet(1) pctile(2) = varRet(2) pltile(0) = pctile(0) pltile(1) = pctile(1) pltile(2) = pctile(2) Do While distance(pfirst, pltile) < (hwidth - trad) Set cir = ThisDrawing.ModelSpace.AddCircle( _ pltile, trad) varRet = ThisDrawing.Utility.PolarPoint( _ pltile, angp90, (tspac + trad + trad)) pl ... mới được đánh dấu. Bởi vì phương thức GetPoint đang chờ nhập vào một điểm từ AutoCAD. Chuyển về cửa sổ của chương trình AutoCAD, và ở dòng command sẽ xuất hiện dòng nhắc nhập điểm của phương thức GetPoint, chọn một điểm nào đó trên màn hình. Trở lại môi trường VBA IDE, và để ý rằng dòng lệnh tiếp theo lời gọi phương thức GetPoint được đánh dấu. Tiếp tục thực hiện qua từng dòng lệnh bằng cách chọn phím F8 và chú ý chuyển sang cửa sổ AutoCAD khi cần nhập thông tin. 9. Thực thi Macro Khi thực hiện Macro không cần thiết phải chạy qua từng dòng lệnh như các thao tác ở phần trên. Để chạy một Macro, chọn menu Tools Macro Run Macro, trong hộp thoại xuất hiện chọn nút Run. Khi đó chương trình sẽ được thực hiện như khi người dùng sử dụng. Chạy macro từ AutoCAD và theo các giá trị nhập vào như sau: Tools Macro Run Macro: ThisDrawing.gardenpath Start point of the path: 2, 2 Endpoint of the path: 9, 8 Half width of the path: .2 Radius of tiles: .2 Spacing between tiles: .1 Với các số đầu vào này thì đường đi dạo sẽ được vẽ ra như sau: Có thể nhập các bộ giá trị khác nhau, sử dụng chuột và bàn phím để thử nghiệm Macro này. 306 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA 10. Thêm giao diện hộp thoại Các hộp thoại giao diện cho macro của VBA được tạo ra trong VBA IDE. Macro gardenpath nhận các thông số đầu vào từ dòng lệnh và có thể dễ dàng thêm hộp thoại giao diện cho nó. Các hộp thoại này tạo cho người dùng có các lựa chọn khác nhau trong nhiều lựa chọn. Macro hiện tại có ít lựa chọn và cần được bổ sung thêm một số chi tiết. Các chi tiết này sẽ cho phép người dùng chỉ ra hình dạng của gạch lát trên đường. Có thể bắt đầu bằng cách sao chép lại phần mã lệnh của gardenpath.dvb thành một tệp khác lấy tên là gpdialog.dvb. Sao chép dự án 1 Lưu dự án hiện tại trong VBA IDE 2 Dùng lệnh SaveAs trong VBA IDE và lưu dự án dưới tên là gpdialog.dvb. 10.1. Tạo hộp thoại Hộp thoại được tạo trong VBA IDE thông qua đối tượng Form. Hộp thoại tạo ra sẽ gồm 2 tuỳ chọn để khi chọn mục này thì mục kia sẽ bị xoá đi, một để chọn gạch hình tròn và một để chọn gạch hình đa giác. Trên hộp thoại sẽ gồm 3 hộp ký tự để nhập các giá trị: bán kính của gạch, khoảng cách giữa các viên gạch và số cạnh của viên gạch (chỉ có khi chọn hình dạng gạch là đa giác) Tạo hộp thoại từ VBA IDE 1 Mở một Form mới theo thao tác sau: menu Insert User Form. Sau đó sẽ xuất hiện hai cửa sổ, cửa sổ thứ nhất là hộp công cụ chứa các điều khiển để tạo hộp thoại, cửa sổ thứ hai là một Form trống để bố trí các điều khiển theo ý người lập trình. 2 Lựa chọn từng điều khiển từ hộp công cụ và đặt vào Form. Trên Form sẽ có 2 nút tùy chọn ( ), 3 nhãn ( ), 3 hộp ký tự ( ), 2 nút lệnh ( ) như mô tả ở hình dưới. 3 Đóng hộp công cụ. Phát triển AutoCAD bằng ActiveX và VBA | 307 Gán thuộc tính cho các nút tuỳ chọn 1 Trên Form, chọn điều khiển OptionButton1. Trong cửa sổ Properties, thay đổi các thuộc tính dưới đây cho điều khiển đó (nếu cửa sổ Properties chưa mở thì thực hiện theo trình tự sau đây để mở: Menu View\Properties Window): (Name) = gp_poly Caption = Polygon ControlTipText = Polygon Tile Shape Accelerator = P 2 Thực hiện như bước 1 đối với OptionButton2: (Name) = gp_circ Caption = Circle ControlTipText = Circle Tile Shape Accelerator = I Gán thuộc tính cho các nhãn 1 Trên Form, chọn điều khiển Label1. Trong cửa sổ Properties, thay đổi các thuộc tính dưới đây cho các điều khiển đó: (Name) = label_trad Caption = Radius of tiles TabStop = True 2 Thực hiện như bước 1 đối với Label2: (Name) = label_tspac Caption = Space between tiles TabStop = True 3 Thực hiện như bước 1 đối với Label3: (Name) = label_tsides Caption = Number of sides TabStop = True Gán thuộc tính cho các hộp ký tự 1 Trên Form, chọn điều khiển TextBox1. Trong cửa sổ Properties, thay đổi các thuộc tính dưới đây cho điều khiển TextBox1: (Name) = gp_trad 2 Thực hiện như bước 1 đối với TextBox2: (Name) = gp_tspac 3 Thực hiện như bước 1 đối với TextBox3: (Name) = gp_tsides Gán thuộc tính cho các nút lệnh và Form 1 Trên Form, chọn điều khiển CommandButton1. Trong cửa sổ Properties, thay đổi các thuộc tính dưới đây cho điều khiển CommandButton1 (Name) = accept Caption = OK ControlTipText = Accept the options Accelerator = O Default = True 308 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA 2 Thực hiện như bước 1 đối với CommandButton2: (Name) = cancel Caption = Cancel ControlTipText = Cancel the operation Accelerator = C 3 Chọn Form bằng cách bấm chuột lên nền của nó tại vị trí không đặt điều khiển. Trong cửa sổ Properties, thay đổi thuộc tính của các thuộc tính sau: (Name) = gpDialog Caption = Garden Path Form thiết kế sẽ có dạng như sau: 4 Lưu kết quả 10.2. Dùng cửa sổ Project để quản lý dự án Trong cửa sổ Project của VBA IDE ta sẽ thấy tên và vị trí của dự án, một thư mục có tên là AutoCAD Objects và một thư mục có tên là Forms. Khi mở thư mục AutoCAD Objects (nó có thể đã được mở sẵn từ trước) ta sẽ thấy biểu tượng bản vẽ của AutoCAD có tên là ThisDrawing. Khi mở thư mục Forms (nó có thể đã được mở sẵn từ trước) ta sẽ thấy biểu tượng của Form và có tên là gpDialog. Đây là Form vừa được tạo ra. Để xem phần mã lệnh của Form, chọn gpdialog trong cửa sổ Project, nhấn nút View Code ( ) hoặc phím F7. Phát triển AutoCAD bằng ActiveX và VBA | 309 Cửa sổ Code xuất hiện nhưng hầu như chưa có gì vì chưa nhập mã lệnh nào cho Form cả. Để trở lại Form, nhấn nút View Form trên cửa sổ Project hoặc nhấn tổ hợp phím SHIFT+F7. Chọn ThisDrawing trong cửa sổ Project và xem phần mã lệnh bằng cách nhấn nút ViewCode, khi đó toàn bộ phần mã lệnh vừa nhập xuất hiện trong cửa sổ này. Sử dụng cửa sổ Project để xác định vị trí mã lệnh và giúp người lập trình biết mình đang làm việc ở đâu một cách dễ dàng. 10.3. Cập nhật mã lệnh hiện có Sau khi tạo hộp thoại với các điều khiển được sắp xếp theo ý người lập trình, bước tiếp theo sẽ viết mã lệnh mới để cho hộp thoại có thể làm việc. Trước hết là sửa đổi mã lệnh đã có cho phù hợp. Bắt đầu từ mã lệnh cho ThisDrawing: Cập nhật các biến toàn cục để sử dụng với hộp thoại Cập nhật các dòng sau ở trong phần Declarations: Public trad As Double ’ cập nhật lại Public tspac As Double ’ cập nhật lại Public tsides As Integer ’ thêm mới Public tshape As String ’ thêm mới Các biến trad và tspace được cập nhật lại phạm vi là Public thay vì Private. Các biến Private chỉ sử dụng được trong phạm vi mô-đun mà chúng được khai báo. Tuy nhiên ở phần này, Form cũng sẽ sử dụng hai biến đó nên chúng cần phải chuyển thành dạng Public. Bên cạnh đó, thêm hai biến mới là tside và tshape, tương ứng để chứa số cạnh của gạch hình đa giác và hình dạng của gạch lát do người dùng lựa chọn là hình tròn hay đa giác. Cập nhật chương trình con gpuser để sử dụng với hộp thoại Chuyển đến phần mã lệnh của chương trình con gpuser, xoá phần nhập bán kính gạch lát và khoảng cách giữa các viên gạch vì hai thông số này sẽ được nhập vào từ Form. Xoá các dòng lệnh sau: trad = ThisDrawing.Utility. _ GetDistance(sp, "Radius of tiles: ") tspac = ThisDrawing.Utility. _ GetDistance(sp, "Spacing between tiles: ") Thêm các dòng lệnh để tải và hiển thị Form dưới đây thay vào vị trí của các dòng mã lệnh bị xoá ở trên: Load gpDialog gpDialog.Show Sau khi sửa, chương trình con gpuser mới sẽ như sau: ’ Thông tin cần thiết cho đường đi dạo Private Sub gpuser() Dim varRet As Variant varRet = ThisDrawing.Utility.GetPoint( _ , "Start point of path: ") sp(0) = varRet(0) 310 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA sp(1) = varRet(1) sp(2) = varRet(2) varRet = ThisDrawing.Utility.GetPoint( _ , "Endpoint of path: ") ep(0) = varRet(0) ep(1) = varRet(1) ep(2) = varRet(2) hwidth = ThisDrawing.Utility. _ GetDistance(sp, "Half width of path: ") Load GPDialog GPDialog.Show pangle = ThisDrawing.Utility.AngleFromXAxis( _ sp, ep) totalwidth = 2 * hwidth plength = distance(sp, ep) angp90 = pangle + dtr(90) angm90 = pangle - dtr(90) End Sub Vẽ gạch lát là hình tròn hay đa giác Tiếp theo cần thêm thủ tục để vẽ gạch lát hình tròn hay đa giác. Thêm vào đoạn mã lệnh sau vào cuối chương trình: ’Vẽ gạch lát với hình dạng theo thiết kế Sub DrawShape(pltile) Dim angleSegment As Double Dim currentAngle As Double Dim angleInRadians As Double Dim currentSide As Integer Dim varRet As Variant Dim aCircle As AcadCircle Dim aPolygon As AcadLWPolyline ReDim points(1 To tsides * 2) As Double ’Vẽ phụ thuộc vào kiểu hình dạng Select Case tshape Case "Circle" Set aCircle = ThisDrawing.ModelSpace. _ AddCircle(pltile, trad) Case "Polygon" angleSegment = 360 / tsides currentAngle = 0 For currentSide = 0 To (tsides - 1) angleInRadians = dtr(currentAngle) varRet = ThisDrawing.Utility.PolarPoint(pltile, _ angleInRadians, trad) points((currentSide * 2) + 1) = varRet(0) points((currentSide * 2) + 2) = varRet(1) currentAngle = currentAngle + angleSegment Next currentSide Set aPolygon = ThisDrawing.ModelSpace. _ AddLightWeightPolyline(points) aPolygon.Closed = True End Select End Sub Thủ tục trên sử dụng lệnh Select Case để điều khiển rẽ nhánh cho chương trình dựa vào kiểu hình dạng của viên gạch được xác định bởi biến tshape. Phát triển AutoCAD bằng ActiveX và VBA | 311 Cập nhật thủ tục drow để vẽ gạch lát phù hợp Tiếp theo, chuyển tới thủ tục drow, tìm dòng lệnh dưới đây: Set cir = ThisDrawing.ModelSpace.AddCircle(pltile, trad) và thay bằng dòng lệnh sau: DrawShape (pltile) 10.4. Thêm mã lệnh cho hộp thoại Các việc cần làm bây giờ là xoá các phần mã lệnh vẽ gạch lát hình tròn và thay bằng lời gọi thủ tục DrawShape để vẽ gạch có hình dạng theo lựa chọn của người dùng. Thêm xử lý sự kiện cho các nút tuỳ chọn Mở cửa sổ Code của gpDialog và nhập đoạn mã lệnh sau dưới câu lệnh Option Explicit: Private Sub gp_poly_Click() gp_tsides.Enabled = True ThisDrawing.tshape = "Polygon" End Sub Private Sub gp_circ_Click() gp_tsides.Enabled = False ThisDrawing.tshape = "Circle" End Sub Các thủ tục gp_poly_Click() và gp_circ_Click() được đặt tên theo hai điều khiển lựa chọn đã tạo trên Form trong phần trên kết hợp với từ “_Click”. Chúng là những thủ tục được tự động thực hiện khi người dùng bấm chuột vào điều khiển. Lần lượt mở các hộp Object và Procedure/Event ở phía trên của cửa sổ Code, ta sẽ thấy danh sách bao gồm tên của tất cả các điều khiển đã chèn vào Form và được sắp xếp theo tên. Tiếp theo, đặt con trỏ tại vị trí dòng Private Sub gp_poly_Click() và mở hộp Procedure/Event sẽ thấy một danh sách các sự kiện của điều khiển lựa chọn gp_poly. Hai thủ tục đã được tạo ra để xử lý sự kiện Click. Ta cũng có thể thêm 312 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA mã lệnh để xử lý sự kiện DblClick để chương trình tự động thực hiện khi người dùng bấm đúp chuột trên điều khiển. Ta có thể thêm mã lệnh cho bất cứ sự kiện nào của điều khiển được liệt kê trong danh sách. Các kiểu thủ tục như vậy được gọi là xử lý sự kiện. Xét mã lệnh của hai thủ tục xử lý sự kiện vừa tạo ra. Thủ tục xử lý sự kiện đầu tiên phản ứng với sự kiện Click của điều khiển gp_poly, dòng mã lệnh đầu tiên là để hộp ký tự chứa số cạnh của đa giác hoạt động. Hộp ký tự này chỉ làm việc khi hình dạng gạch lựa chọn là đa giác. Dòng lệnh tiếp theo là gán giá trị Polygon cho biến tshape. Thủ tục xử lý sự kiện thứ hai để phản ứng với sự kiện Click của điều khiển gp_circ. Thủ tục này sẽ làm mất hiệu lực của hộp ký tự chứa số cạnh của đa giác và gán biến tshape theo giá trị của Circle. Thêm xử lý sự kiện cho nút OK Thêm đoạn mã lệnh sau để xử lý sự kiện của nút OK: Private Sub accept_Click() If ThisDrawing.tshape = "Polygon" Then ThisDrawing.tsides = CInt(gp_tsides.text) If (ThisDrawing.tsides < 3#) Or _ (ThisDrawing.tsides > 1024#) Then MsgBox "Enter a value between 3 and " & _ "1024 for the number of sides." Exit Sub End If End If ThisDrawing.trad = CDbl(gp_trad.text) ThisDrawing.tspac = CDbl(gp_tspac.text) If ThisDrawing.trad < 0# Then MsgBox "Enter a positive value for the radius." Exit Sub End If If (ThisDrawing.tspac < 0#) Then MsgBox "Enter a positive value for the spacing." Exit Sub End If GPDialog.Hide End Sub Đến đây, các công việc cần thiết cho Form đã hoàn thiện. Xử lý sự kiện này, trước hết sẽ kiểm tra xem lựa chọn cuối cùng có phải là đa giác không. Nếu lựa chọn là đa giác thì nó sẽ nhận giá trị số cạnh của đa giác từ điều khiển gp_tsides. Giá trị người dùng nhập vào được lưu trong thuộc tính Text và là kiểu chuỗi, nên cần chuyển sang kiểu số nguyên bằng cách sử dụng hàm Cint của Visual Basic. Sau đó, xử lý sự kiện sẽ kiểm tra giá trị có nằm trong phạm vi hợp lệ là từ 3÷1024 không. Nếu không thì sẽ xuất hiện một hộp thông báo và xử lý sự kiện sẽ kết thúc. Khi đó người dùng sẽ có cơ hội để thay đổi giá trị nhập vào. Nhấn nút OK một lần nữa thì xử lý sự kiện sẽ được bắt đầu và kiểm tra lại giá trị nhập vào. Phát triển AutoCAD bằng ActiveX và VBA | 313 Giá trị bán kính và khoảng cách giữa các viên gạch cũng được nhận theo cách tương tự trên ngoại trừ kiểu giá trị của chúng là double chứ không phải là integer, hàm sử dụng là Cdbl. Chúng cũng được kiểm tra để đảm bảo mang giá trị dương. Khi các giá trị đã được nhập vào và kiểm tra thì lệnh gpDialog.Hide sẽ làm ẩn Form, do vậy cần thông qua các điều khiển để trở lại thủ tục đầu tiên gọi Form. Thêm xử lý sự kiện cho nút Cancel Thêm đoạn mã lệnh sau cho xử lý sự kiện của nút Cancel: Private Sub cancel_Click() Unload Me End End Sub Đây là một đoạn xử lý sự kiện đơn giản để dỡ bỏ Form và kết thúc Macro. Và còn một sự kiện nữa chưa xử lý là tạo các giá trị khởi tạo cho Form. Đó là sự kiện Initialize của Form. Sự kiện này được thi hành khi Form được tải lần đầu tiên. Thêm xử lý cho sự kiện khởi tạo của Form Thêm đoạn mã xử lý sự kiện dưới đây cho sự kiện Initialize của Form: Private Sub UserForm_Initialize() gp_circ.Value = True gp_trad.Text = ".2" gp_tspac.Text = ".1" gp_tsides.Text = "5" gp_tsides.Enabled = False ThisDrawing.tsides = 5 End Sub Đoạn mã lệnh này sẽ gán các giá trị ban đầu cho Form và cho biến tsides, biến này phải nhận giá trị dương và lớn hơn 3 ngay cả trong trường hợp chọn một đường tròn. Để hiểu lý do, tham khảo thủ tục DrawShape ở phần trên. Biến point được định nghĩa thông qua số cạnh của đa giác, biến này sẽ được cấp phát bộ nhớ mặc dù không chọn hình dạng gạch lát là đa giác. Do đó, biến tside phải được xác định trong một phạm vi hợp lý. Người dùng được tự do thay đổi các giá trị trong khi Macro thực hiện. Bây giờ Macro này đã sẵn sàng hoạt động. 314 | Chương 13: Thiết kế đường đi dạo trong vườn – Một ví dụ về ActiveX/VBA
File đính kèm:
- giao_trinh_phat_trien_autocad_bang_activex_vba_chuong_13_thi.pdf