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

  • Thread starter vothanhthu
  • Ngày gửi
V

vothanhthu

Guest
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....!
 
V

vothanhthu

Guest
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....
 
V

vothanhthu

Guest
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 bởi điều hành viên:
V

vothanhthu

Guest
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
 
Sửa lần cuối bởi điều hành viên:
V

vothanhthu

Guest
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 bởi điều hành viên:
V

vothanhthu

Guest
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
 

giaiphapvba

Administrator
Thành viên BQT
Có lẽ topic này đã trình bày xong nên cho phép mình viết mấy lời bà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
Chỉ riêng điều này đã đi ngược lại cách nghĩ của diễn đàn: Làm sao để bất cứ ai cũng sử dụng được.
Sẽ thế nào nếu sản phẩm mang tới cho người A mà họ lại không dùng được.

Cách nghĩ làm sao để bất cứ ai cũng sử dụng-có ảnh hưởng rất lớn tới các hoạt động trên diễn đàn. Ví dụ cho tới nay chúng ta không có một bài dịch nào về TreeView, ListView,...

Bảo mật code là không cần thiết đối với VBA. Vì quan điểm của diễn đàn: Mọi thứ nên mở, ít nhất trong VBA, mọi kiến thức kinh nghiệm sẽ là chia sẻ cởi mở.
Hàng loạt các bài dịch trên diễn đàn mà mọi người coi là hữu ích, dễ hiểu-chúng đều là các bài viết công khai trên các trang nước ngoài. Chúng ta kiến thức thì còn ít nhưng lại luôn suy nghĩ đóng kín.

Có lẽ vì mục đích khác nhau, một bên muốn thương mại hóa sản phẩm, cho nên rất quan tâm bảo mật code. Một bên coi VBA là công cụ phục vụ công việc cho nên rất mở. Diễn đàn đi theo hướng thứ hai, VBA là công cụ phục vụ công việc.
Nếu các bạn muốn thương mại hóa sản phẩm:

1. Hãy lấy giá cao, phù hợp với công sức bạn bỏ ra cho người có nhu cầu. Người ta sau đó công khai sản phẩm hay không, đó là quyền của người ta.
Ví dụ, , người yêu cầu đã phải bỏ ra hơn 15 triệu để nhận sản phẩm. Công sức bỏ ra của những người code là nhiều. Hai bên đều thỏa mãn.
Sản phẩm thuộc về sở hữu của người yêu cầu code. Diễn đàn không công khai code. Đó cũng là cách bảo mật tốt nhất. Một khi nó không được chia sẻ thì không ai biết.

2. Tool VBA nếu có ứng dụng rộng rãi mà công sức bỏ ra không nhiều, hãy chia sẻ cho cộng đồng. Mọi người đều làm như vậy, diễn đàn có tài liệu để dịch kiến thức cho các bạn đọc cũng vì nó được công khai, chia sẻ. Chúng tôi mong muốn điều này được thúc đẩy ở VN nhiều hơn nữa.

Topic này cho phép mình khóa ở đây.
 

tuhocvba

Administrator
Thành viên BQT
Hừm, giờ vác sách vở đi học bảo mật. Từ trước giờ chả bao giờ quan tâm tới mảng này, mà qua tới giờ anh em vất vả quá.
@Ngày Mới
Sao Make DLL bị lỗi này hả Smod?
(Win 10 64bit, Office 2016-64bit)
Bạn cần đăng nhập để thấy đính kèm
 

tuhocvba

Administrator
Thành viên BQT
Chạy với quyền Admin thì Make DLL ok.
Nhưng sau đó chạy macro trên Excel thì lỗi:
Bạn cần đăng nhập để thấy đính kèm

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

Nó báo Class chưa được đăng ký.

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

NhanSu

SMod
Thành viên BQT
VB6 chỉ hỗ trợ 32 bit nên chỉ hỗ trợ excel 32 bit. Để tạo dll64 đơn giản nhất là dùng .net
 
D

Deleted member 1294

Guest
@NhanSu đúng là vb6 chỉ hỗ trợ office 32 nhưng có người đã làm nó chạy được trên office 64 bít.
 
D

Deleted member 1294

Guest
@thuhocvba thật ra mình chưa thử ! Hiiiiii vì không xài vb6 !
 
Top