Kỹ thuật lập trình DLL cho VBA - Bảo vệ code VBA tốt nhất hiện nay

vothanhthu

Võ Thành Thứ
1. Tại sao cần lập trình DLL cho VBA
Hiện nay, nếu nói về các phương pháp bảo mật code VBA trên thế giới chúng ta sẽ có: khóa VBAProject, khóa Unviewable (biến hóa nhiều kiểu), ẩn Module, mã hóa code, nạp DLL... và có thể còn nhiều phương pháp Thứ chưa biết. Trong số tất cả các phương pháp đó, sử dụng phương pháp nạp DLL vào Excel là an toàn nhất tính đến thời điểm hiện tại. Bằng cách này, ta sẽ viết code VBA trong file DLL thông qua một ngôn ngữ khác, lấy đó làm thư viện, dùng Excel trích các thư viện trong DLL ra dùng. Về nguyên tác, Code vẫn sẽ nằm trong file DLL, Excel chỉ lấy ra mà dùng, việc bảo mật sẽ phụ thuộc hoàn toàn vào file DLL. Chắc các bạn cũng biết, khả năng bảo mật của DLL là cực kì tốt, hơn rất nhiều lần VBA.

Trong bài viết này, Thứ sẽ hướng dẫn các bạn các bước cơ bản để viết được ngôn ngữ VBA trong file DLL, nạp vào Excel để xử dụng. Thứ sẽ sử dụng ngôn ngữ VB6, ngôn ngữ gần với VBA nhất cho các bạn dễ hiểu.
2. Làm thế nào để viết code được trong file DLL
Việc đầu tiên bạn cần làm là phải có ngôn ngữ VB6, Thứ sử dụng chương trình Visual Studio 6.0. Các bạn có thể tải tại hoặc bất cứ đâu từ Internet
Thứ lưu ý, chúng ta cần phân biệt rõ ràng các ngôn ngữ VB để tranh có lỗi không cần thiết khi lập trình, các bạn có thể tham khảo tại
Khi mở phần mềm, chúng ta sẽ tạo một dự án mới dạng ActiveX DLL
Bạn cần đăng nhập để thấy đính kèm

Bên cửa sổ chúng ta sẽ đổi tên Project1 Class1 lại, việc này quan trọng vì sẽ quyết định đến khả năng gọi ngược khi nạp vào Excel. Chúng ta cần tập thói quen đổi tên Module, Class phù hợp với code. Ở đây Thứ sẽ đổi Project1 thành TuhocVBA, và Class1 thành Test
Bạn cần đăng nhập để thấy đính kèm

Ví dụ, Thứ có một đoạn code đơn giản như thế này trong VB6
Mã:
Public sub Goi_Msg
    Msgbox "Hello TuhocVBA", vbInformation, "Thong bao"
End sub
Thứ sẽ Save lại thành file DLL bằng File > Make TuhocVBA.dll...
Bạn cần đăng nhập để thấy đính kèm

3. Làm sao để nạp DLL vào Excel và chạy chúng
Mở File Excel cần chạy code. Vào cửa sổ lập trình VBA (Ctrl + F11). Chọn Tool > References > Browser > Chọn địa chỉ TuhocVBA.dll > OK
Bạn cần đăng nhập để thấy đính kèm

Và Thứ sẽ viết code khai báo lấy code DLL trong VBA như sau
Mã:
Public Sub Goi_DLL
    Dim ShowMsg as TuhocVBA.Test 'Khai báo biến đối tượng
    Set ShowMsg = New TuhocVBA.Test 'Set ShowMsg đến Class Test
    ShowMsg.Goi_Msg 'Gọi thủ tục Goi_Msg
End sub
Và đây là kết quả
Bạn cần đăng nhập để thấy đính kèm

4. Làm thế nào để lấy dữ liệu Excel vào VB6
Còn nữa....!
 

vothanhthu

Võ Thành Thứ
4. Làm thế nào để lấy dữ liệu Excel vào VB6
Tương tự như khai báo DLL trong VBA. Trong VB6, để sử dụng được các đối tượng trong Excel chúng ta cần nạp thư viện đó vào VB6.
Trong VB6, Vào Project > References > Tích chọn Microsoft Excel 15.0 Object Library (Tùy bản Excel bạn đang dùng mà số 15.0 sẽ không giống nhau, có thể là 11.0 hoặc 13.0)
Bạn cần đăng nhập để thấy đính kèm

Thứ sẽ viết code trong VB6 như sau
Mã:
Option Explicit
Private ExApp As Excel.Application 'Khai báo ExApp sẽ là ứng dụng Excel
Public Property Set ExcelApp(ByRef EApp As Excel.Application) 'Ðặt thuộc tính tham chiếu
    Set ExApp = EApp
End Property

'===================================================
Public Sub Goi_Msg()
MsgBox "Hello TuhocVBA", vbInformation 'Hiện msgbox
End Sub

Public Sub Viet_TuhocVBA()
ExApp.ActiveCell.Value = "TuhocVBA" 'Đặt giá trị tại trỏ chuột là TuhocVBA
End Sub

Public Sub Hien_Value()
MsgBox ExApp.ActiveCell.Value 'Hiện Msgbox giá trị tại ô trỏ chuột
End Sub

Public Function Dientich(Dai As Long, Rong As Long) 'Hàm tính diện tích
Dientich = Dai * Rong
End Function
Thứ sẽ Save code này lại thành file TuhocVBA.dll và nạp lại vào Excel tương tự như các thao tác trên
Sau đó thứ sẽ viết lại code trong VBA như sau, Thứ sẽ gôm các code gọi DLL lại thành 1 thủ tục, chỉ cần gọi 1 lần để sử dụng. Để dễ dàng bạn có thể gọi thủ tục này tại sự kiện Workbook_Open.
Lưu ý: Khi có thay đổi thêm sửa code nhớ chạy lại thủ tục GoiDll
Mã:
Public ExApp As TuhocVBA.Test
Sub GoiDll()
Set ExApp = New TuhocVBA.Test
Set ExApp.ExcelApp = Application
End Sub

Public Sub Viet_TuhocVBA()
ExApp.Viet_TuhocVBA
End Sub

Public Sub DienTich()
MsgBox ExApp.DienTich(2, 3)
End Sub

Public Sub Hien_Value()
ExApp.Hien_Value
End Sub

Public Sub Goi_Msg()
ExApp.Goi_Msg
End Sub
Và đây là kết quả
Bạn cần đăng nhập để thấy đính kèm

Bạn cần đăng nhập để thấy đính kèm

Bạn cần đăng nhập để thấy đính kèm

5. Làm thế nào để chèn UserForm từ VB6 vào VBA
Còn nữa....
 

vothanhthu

Võ Thành Thứ
5. Làm thế nào để chèn UserForm từ VB6 vào VBA
Để tạo mới một UserForm trong VB6 các bạn vào Project > Add Form
Thứ sẽ tạo một UserForm đặt tên là Form1 gồm 1 Label và 1 Button
Bạn cần đăng nhập để thấy đính kèm

Code trong nút Button là khi nhấn sẽ đóng Userform này lại, Code trong nút Button
Mã:
Private Sub Command1_Click()
    Me.Hide
End Sub
Để tạo được sự liên kết từ UserForm trong VB6 đến Excel, Thứ sẽ tạo một Class Module đặt tên là Test
Mã:
Option Explicit
Private Const GWL_HWNDPARENT As Long = -8 'Khai báo SetWindowLongA API
Private ExlApp As Excel.Application 'Khai báo biến để gọi Excel
Private mlXLhWnd As Long
'Khai báo các hàm API
Private Declare Function FindWindowA Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowLongA Lib "user32" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Property Set ExcelApp(ByRef ExApp As Excel.Application) 'Đặt thuộc tính ExcelApp
    Set ExlApp = ExApp
    mlXLhWnd = FindWindowA(vbNullString, ExlApp.Caption) 'Lây handle cửa sổ Excel
End Property
'========================================================
Public Sub ShowVB6Form()
Dim frmThV As From1
Set frmThV = New From1
Load frmThV
SetWindowLongA frmThV.hWnd, GWL_HWNDPARENT, mlXLhWnd
frmThV.Show vbModal
Unload frmThV
End Sub
Tương tự như các bước trên, Thứ Make TuhocVBA.dll... và chèn vào Excel. Và giờ là đơn giản rồi, chúng ta chỉ cần khai báo và chạy thủ tục trong DLL bằng VBA nữa là xong.
Mã:
Public Sub ShowFormVB6()
Dim ExlApp As TuhocVBA.Test
Set ExlApp = New TuhocVBA.Test
Set ExlApp.ExcelApp = Application
ExlApp.ShowVB6Form
Set ExlApp = Nothing
End Sub
Và đây là kết quả
Bạn cần đăng nhập để thấy đính kèm

Nguồn: Duy Tuân (2014)
Chỉnh sửa dễ hiểu: Thứ
6. Tạo file .exe với giao diện UserForm VB6, dữ liệu được xuất ra Excel
Còn nữa...
 
Sửa lần cuối:

vothanhthu

Võ Thành Thứ
6. Tạo file .exe với giao diện UserForm VB6, dữ liệu được xuất ra Excel
Để tạo ra một Standard EXE từ VB6 ta tạo dự án mới dạng Standard EXE và đổi tên thành TuhocVBA

Thứ tạo một UserForm mới đặt tên là Form1 gồm
- 1 Label: tên Label1
- 1 Textbox: tên Text1
- 1 Button: tên Command1
Bạn cần đăng nhập để thấy đính kèm

Thứ đặt code trong nút Button như sau:
Mã:
Private Sub Command1_Click()
Dim ExcelApp As Excel.Application
Dim NewEx As Workbook, rng As Range

On Error Resume Next 'Bỏ qua lỗi nếu có
Set ExcelApp = GetObject(, "Excel.Application")  'Khi Excel đang mở

If Err Then 'Lỗi khi Excel chưa mở > Mở
    Err.Clear
    Set ExcelApp = CreateObject("Excel.Application")
End If

Set NewEx = ExcelApp.Workbooks.Add 'Thêm WB mới

If Me.Text1 = vbNullString Then Exit Sub 'Nếu Text rỗng thì thoát sub

Set rng = NewEx.Sheets(1).Range("A1") 'rng là ô A1
rng.Value = Me.Text1 'Điền giá trị

Unload Me 'Thoát Form
ExcelApp.Visible = True 'Hiện Excel lên
End Sub
Sau đó thứ Save vẫn chọn File > Make TuhocVBA.exe...
Và kết quả

Bạn cần đăng nhập để thấy đính kèm
 

vothanhthu

Võ Thành Thứ
7. Một vài điểm lưu ý khi lập trình trong VB6
VB6 hiện là ngôn ngữ lập có thể tạo được DLL, EXE... giống với VBA nhất, các bạn nào đã hiểu và biết VBA thì chắc chắn sẽ nắm được VB6 rất nhanh.
Bạn nào đang và có ý định bảo mật code VBA bằng DLL thì nên thử qua ngôn ngữ này một lần vì chúng rất gần VBA, dễ học, hiểu được lập trình DLL nạp vào Excel là như thế nào. Từ đó làm nền, lập trình trên các ngôn ngữ phát triển hơn.

Nhược điểm rất lớn của VB6 là chỉ hỗ trợ Office 32bit nên sẽ không chạy dc trên Office 64bit. Đối với các bạn làm VBA muốn chia sẽ nhiều máy tính thì lập trình trên VB6 là không nên. Phiên bản cập nhật mới nhất của VB6 là vào năm 1998, có thể nói Bác Bill đã ngừng phát triển VB6 để chuyển sang VB.Net.

Nhưng gì cũng cần có nền móng của nó. Các bạn nên thử qua VB6 một lần để nắm những yếu tố cốt lỗi như Thứ đã đề cập ở trên trước khi tiến xa hơn với các ngôn ngữ khác với cấp độ bảo mật cao hơn nữa như VB.Net, C+ hoặc Delphi.

Chúc các bạn có được nhiều kiến thức bổ ích từ kỹ thuật lập trình DLL cho VBA trên VB6!
 
Sửa lần cuối:

vothanhthu

Võ Thành Thứ
8. Làm thế nào để người dùng chỉ mở file là sài, không cần thao tác thêm DLL
Trong thực tế sử dụng, các bảo mật DLL thường được sử dụng cho mục đích chia sẽ file cho mọi người. Vì lý do đó, người sử dụng chỉ muốn mở file lên là sử dụng, người code không thể kêu họ vào VBE > Tool.... Như vậy, ta cần một chuỗi code để tự động hóa việc thêm DLL và chạy gọi DLL này.

Đầu tiên, Thứ cần tự động thêm Extensibility 5.3. Ta có đoạn code như sau, Thứ lấy ở
Mã:
Sub AddExtensibility()
    On Error Resume Next
    ThisWorkbook.VBProject.References.AddFromGuid "{0002E157-0000-0000-C000-000000000046}", 2, 0 'Dang ki Extensibility 5.0
End Sub
Sau đó, Thứ thêm đoạn code này vào để nạp TuhocVBA2.dll. Lưu ý để file DLL nằm cùng thư mục file Excel
Mã:
Public Sub AddReference()
    Dim VBAEditor As VBIDE.VBE
    Dim vbProj As VBIDE.VBProject
    Dim chkRef As VBIDE.Reference

    Set VBAEditor = Application.VBE
    Set vbProj = ActiveWorkbook.VBProject

    For Each chkRef In vbProj.References
        If chkRef.Name = "TuhocVBA2" Then Exit Sub '~~> Check if "TuhocVBA2.dll" is already added
    Next

    vbProj.References.AddFromFile ThisWorkbook.Path & "\TuhocVBA2.dll"
End Sub
Thứ tạo thêm sự kiện Workbook_Open để chạy 2 đoạn mã này tự động khi mở file
Mã:
Public Sub Workbook_Open()
Call AddExtensibility
Call AddReference
End Sub
Và tương tự, Thứ có đoạn code như các bài trên để trích lấy dữ liệu trong DLL ra
Mã:
Public ExApp As TuhocVBA2.test
Sub CallDll()
Set ExApp = New TuhocVBA2.test
Set ExApp.ExcelApp = Application
End Sub
Public Sub Viet_TuhocVBA()
CallDll
ExApp.Viet_TuhocVBA
End Sub

Public Sub DienTich()
CallDll
MsgBox ExApp.DienTich(2, 3)
End Sub

Public Sub Hien_Value()
CallDll
ExApp.Hien_Value
End Sub

Public Sub Goi_Msg()
CallDll
ExApp.Goi_Msg
End Sub
Và kết quả
Bạn cần đăng nhập để thấy đính kèm
 
Top