Dùng VBA để viết VBA

  • Thread starter Thread starter OverAC
  • Ngày gửi Ngày gửi
Liên hệ QC

OverAC

Đỗ Nguyên Bình
Thành viên BQT
Administrator
Tham gia
30/5/06
Bài viết
2,693
Được thích
15,089
Hôm nay nghĩ ra chuyện này, có thể nào dùng VBA để viết VBA hay không?
Google một phát và nhận thấy rằng câu trả lời là được.

Thử xem một đoạn code này, dùng VBA để tạo ra các nút lệnh và gán code cho các nút lệnh đó.
Đây chỉ là một dạng ý tưởng, tôi tin rằng tôi sắp có một đống các ý tưởng khác từ ý tưởng này.

Sưu tầm từ MrExcel

Đọc code này chú ý vào phần cCode nhé.

PHP:
Sub AddComm_button()

Dim myButton As New OLEObject
Dim sCode As String
Dim iX As Integer
Dim CurSheet As Worksheet

Set CurSheet = Worksheets("Sheet1")

For iX = 1 To 2
Set myButton = ActiveSheet.OLEObjects.Add(ClassType:="Forms.CommandButton.1")
myButton.Left = 126 * iX
myButton.Top = 96
myButton.Width = 126.75
myButton.Height = 25.5

Set myButton = Nothing
Next iX

For iX = 1 To 2
'Code for button
sCode = ""
sCode = "Sub CommandButton" & iX & "_Click()" & vbCrLf
sCode = sCode & " Sheets(""Sheet" & iX & """).Activate" & vbCrLf
sCode = sCode & "End Sub"

'Write code for button
ThisWorkbook.VBProject.VBComponents(CurSheet.Name).Activate

With ThisWorkbook.VBProject.VBComponents(CurSheet.Name).CodeModule
.AddFromString (sCode)
End With

sCode = vbNullString
Next iX

End Sub
 
Đây chỉ là ý tưởng thôi hả Anh! không biết có ứng dụng trong VBA nhiều không nữa.
 
Upvote 0
Có lẽ ý nghĩa thực của đoạn code trên là: Dùng lệnh VBA để viết (tạo ra) các object, các thủ tục, hàm. Các object lấy từ thư viện VBA và các thủ tục hàm này cũng bằng ngôn ngữ VBA.

Chứ nếu nói rằng dùng VBA để viết VBA nhỡ hiểu nhầm rằng viết ra ngôn ngữ VBAtạo object cho VBA thì ....
 
Upvote 0
Cái này cũng có nói nhiều rồi chắc chú Bình nhà ta chưa tìm hiểu thôi. Thường dùng cái này để tạo các object trên Userform, cái này có đợt tôi đưa ra ý tưởng tạo một form nhập liệu chứng từ phiếu thu chi gồm nhiều textbox đó nhưng vẫn chưa thấy các cao thủ đưa ra ý kiến.
 
Upvote 0
Có lẽ ý nghĩa thực của đoạn code trên là: Dùng lệnh VBA để viết (tạo ra) các object, các thủ tục, hàm. Các object lấy từ thư viện VBA và các thủ tục hàm này cũng bằng ngôn ngữ VBA.

Chứ nếu nói rằng dùng VBA để viết VBA nhỡ hiểu nhầm rằng viết ra ngôn ngữ VBAtạo object cho VBA thì ....

Tôi nghĩ nếu được như vậy cũng tốt lắm rồi.
Và tôi hình dung như mình đang ở trên ghế mà cố nhấc cái ghế lên, nghĩ vậy thôi, không biết có giống không.
Các thành viên của thung lũng Silicon cũng thường có những ý tưởng "điên rồ" như vậy mà đã làm thay đổi cả thế giới!
 
Upvote 0
Tôi nghĩ nếu được như vậy cũng tốt lắm rồi.
Và tôi hình dung như mình đang ở trên ghế mà cố nhấc cái ghế lên, nghĩ vậy thôi, không biết có giống không.
Các thành viên của thung lũng Silicon cũng thường có những ý tưởng "điên rồ" như vậy mà đã làm thay đổi cả thế giới!

Không phải đang ở trên ghế mà cố nhấc cái ghế lên.
Ứng dụng của cái này là viết 1 ứng dụng Excel không form, không object, không sự kiện, không hàm, không thủ tục con. Tất cả chỉ là những module điều khiển.

Bạn hãy tưởng tượng như 1 phần mềm chỉ toàn exe và dll, không có form, không có report.

Và hãy tưởng tượng 1 file excel mà trong project trống trơn không có object nào hết, nhưng khi mở lên (và chạy code điều khiển) thì hiện ra nào form, nào nút nhấn, nào combobox, nào list, option button, ... với đầy đủ chức năng.

Rồi khi đóng file, tất cả lại biến mất.
 
Upvote 0
Nếu thật vậy thì đem lại lợi ích gì? vì mọi thứ đã có sẵn. Ngoài chuyện thỏa mãn sự khám phá?
 
Upvote 0
Nhân bản đối tượng

Để tạo đối tượng và cho chạy mã sự kiện trong đối tượng vừa sinh ra tôi đã viết lên diễn đàn ngày 16/11/2007 tại bài Class module - Kỹ thuật Tạo và Wrap đối lượng. Mọi người đọc bài #3 - clsCommandButton .

Không ngờ một kiến thức quan trọng trong lập trình Class Module đã có từ lâu mà anh em GPE không biết khai thác.
 
Upvote 0
Nếu thật vậy thì đem lại lợi ích gì? vì mọi thứ đã có sẵn. Ngoài chuyện thỏa mãn sự khám phá?

Tất nhiên là có những cái lợi:

- File excel ứng dụng sẽ nhẹ đi. Nếu kết hợp với VB để tạo xll, dll, ... thậm chí lưu module điều khiển dạng txt thì lại càng nhẹ.
- Tốc độ có lẽ cũng nhanh hơn và không chiếm dụng bộ nhớ lâu: tạo form để sử dụng, sử dụng xong thì xoá đi, khác với load form có sẵn, sử dụng xong thì unload.
- ...

Và đương nhiên cũng sẽ có những cái bất lợi:

- Chỉnh sửa form bằng code thì khó khăn hơn chỉnh sửa 1 cái form hiển thị trực quan.
- Nếu không khéo tổ chức các module điều khiển (sơ đồ khối lập trình), thì khi cần chỉnh sửa sẽ khó khăn và dắt dây: thí dụ sửa cách hiển thị của 1 form thì phải biết là form đó tạo ra từ module điều khiển nào, và module đó có liên kết với module nào khác không, ... để kiểm tra.
- Nếu quá nhiều các module phụ thuộc lẫn nhau thì việc sửa chữa lại càng khó khăn.

Tuy nhiên những khó khăn này thuộc về người viết, không phải thuộc về người dùng. Điều này phải chấp nhận vì ưu tiên thuộc về người dùng (coi như khách hàng).
 
Upvote 0
Hôm nay nghĩ ra chuyện này, có thể nào dùng VBA để viết VBA hay không?
Google một phát và nhận thấy rằng câu trả lời là được.

Thử xem một đoạn code này, dùng VBA để tạo ra các nút lệnh và gán code cho các nút lệnh đó.
Đây chỉ là một dạng ý tưởng, tôi tin rằng tôi sắp có một đống các ý tưởng khác từ ý tưởng này.

Sưu tầm từ MrExcel
Cái này có lâu rồi Bình ơi!
Xem món mình làm tại đây nhé
http://www.giaiphapexcel.com/forum/showthread.php?34190-L%C3%A0m-sao-%C4%91%E1%BB%83-ch%E1%BA%A1y-1-l%E1%BB%87nh-t%E1%BB%AB-1-chu%E1%BB%95i-%28c%C3%B3-c%C3%BA-ph%C3%A1p-c%E1%BB%A7a-1-l%E1%BB%87nh%29
Mấu chốt nằm ở chổ: Biến chuổi thành code
 
Lần chỉnh sửa cuối:
Upvote 0
Để tạo đối tượng và cho chạy mã sự kiện trong đối tượng vừa sinh ra tôi đã viết lên diễn đàn ngày 16/11/2007 tại bài Class module - Kỹ thuật Tạo và Wrap đối lượng. Mọi người đọc bài #3 - clsCommandButton .

Không ngờ một kiến thức quan trọng trong lập trình Class Module đã có từ lâu mà anh em GPE không biết khai thác.

@ anh Tuân: Em chưa học được các vấn đề về class-modules, đành hẹn gặp lại cái này khi nào đó. Việc tạo ra các nút lệnh và gán code sẳn cho nó em đã làm được. Nhưng viết ra các code thì chưa.

@ mọi người: sự thật là tiện ích trong vấn đề này theo em là không ít. sắp tới em sẽ có một số ứng dụng trong vấn đề này.
1. Nhân bản file. Ví dụ: Em có một file điều khiển tổng em sẽ lần lượt tác động đến hàng loạt file khác để tạo ra những sự khác biệt cần thiết.

2. Nhân bản các điều khiển khác, tạo sự khác biệt khi khai báo các khai báo khác nhau.
 
Upvote 0
@ anh Tuân: Em chưa học được các vấn đề về class-modules, đành hẹn gặp lại cái này khi nào đó. Việc tạo ra các nút lệnh và gán code sẳn cho nó em đã làm được. Nhưng viết ra các code thì chưa.

@ mọi người: sự thật là tiện ích trong vấn đề này theo em là không ít. sắp tới em sẽ có một số ứng dụng trong vấn đề này.
1. Nhân bản file. Ví dụ: Em có một file điều khiển tổng em sẽ lần lượt tác động đến hàng loạt file khác để tạo ra những sự khác biệt cần thiết.

2. Nhân bản các điều khiển khác, tạo sự khác biệt khi khai báo các khai báo khác nhau.

Về code tạo đối tượng(controls: Button, TextBox,...) nằm ở đâu đó trong Userform hay trong bảng tính thì code tạo trong Class hay Module là như nhau. Nhưng nếu nhân bản thì nên dùng Class Module - Đây là phương pháp lập trình chuẩn của mọi ngôn ngữ lập trình.

Viết code để tạo ra thủ tục hoặc function rồi gán vào trong module để chạy các đối tượng cũng được nhưng thực sự gặp nhiều khó khăn lắm, còn nhiều tình huống xảy ra trong quá trình vận hành. Thời gian tìm giải pháp hoàn thiện cho việc "Nhân bản" kiểu này có lẽ còn lâu hơn nhiều với việc học tạo một Class!

Có các vấn đề khi lạp trình và sử dụng đối tượng nhân bản kiểu viết code như ý tưởng của Bình:
+ Không debug trong chuỗi code (chuỗi được tạo ra cho đối tượng)
+ Quá trình vận hành có thể sử dụng những biến toàn cục (biến khai báo ngoài thủ tục, hàm, mudule)
+ Khi file VBA được protect VBA Project thì không đưa code vào được
+...

Đó là kinh nghiệm lập trình của mình nên nêu ra các vấn đề như vậy. Bình cũng nên cân nhắc để chọn giải pháp phù hợp.
 
Upvote 0
+ Khi file VBA được protect VBA Project thì không đưa code vào được
Phát biểu này hình như chưa chính xác nha!
Mình có thể chèn 1 đoạn code (từ 1 chuổi cho trước) vào ActiveWorkbook, bất kể nó có được Protect VBA hay không... Nghe có vẽ vô lý nhưng Macro 4 làm được điều này, thậm chí rất dễ dàng
Ví dụ:
PHP:
Sub Test()
  Workbooks.Open("D:\Excel\SourceFile.xls").Activate
  ExecuteExcel4Macro ("VBA.INSERT.FILE(""C:\SourceCode.txt"")")
End Sub
- Code này sẽ mở file SourceFile.xls từ đường dẫn D:\Excel\ (SourceFile.xls đã được Protect VBA)
- Active Workbook này
- Lấy code từ file text SourceCode.txt rồi chèn vào SourceFile.xls
 
Upvote 0
Phát biểu này hình như chưa chính xác nha!
Mình có thể chèn 1 đoạn code (từ 1 chuổi cho trước) vào ActiveWorkbook, bất kể nó có được Protect VBA hay không... Nghe có vẽ vô lý nhưng Macro 4 làm được điều này, thậm chí rất dễ dàng
Ví dụ:
PHP:
Sub Test()
  Workbooks.Open("D:\Excel\SourceFile.xls").Activate
  ExecuteExcel4Macro ("VBA.INSERT.FILE(""C:\SourceCode.txt"")")
End Sub
- Code này sẽ mở file SourceFile.xls từ đường dẫn D:\Excel\ (SourceFile.xls đã được Protect VBA)
- Active Workbook này
- Lấy code từ file text SourceCode.txt rồi chèn vào SourceFile.xls

Việc chèn đoạn văn bản của anh vào với mục đích làm gì?

Anh thử chèn đoạn code vào sheet1 để chạy sự chiện SheetChange hoặc sự kiện khác trong sheet này xem được không?
Anh thử chèn đoạn code để chạy một nút lệnh trên một sheet nào đó được không?

Nếu những việc trên mà làm được thì cơ chế bảo mật code của VBA là không tác dụng rồi.
 
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom