Nguyên tắc khi chuyển đổi VBA sang DLL

tuhocvba

Administrator
Thành viên BQT
Chúng ta đã có một topic về tạo , và topic tạo (sẽ được công khai vào ngày 28/10/2021), thì tôi có một số kinh nghiệm chia sẻ cho mọi người.
1. Về mức độ bảo mật
Như một số anh em đã thảo luận thì DLL VB6 khả năng bị dịch ngược là gần như không thể, trong khi đó DLL của VB.NET thì dễ bị bẻ hơn.
2. Về chuyển đổi.
-Các logic toán học thông thường, như xử lý với mảng, ...
Các logic này dễ chuyển đổi nhất. Đối với các biến không phải là object, việc xử lý trên VBA ra sao thì trên VB.NET hay VB6 cũng làm tương tự. Đối với VB.NET thì có khác một chút xíu, đặc biệt với mảng. Tuy nhiên thông qua các topic đang có trên diễn đàn, thì việc xử lý này cũng .
Còn nếu trên VB6 thì có thể nói, VBA xử lý ra sao thì bê y nguyên code như vậy lên VB6.

Có một số lưu ý khi mọi người chuyển đổi.
Cấu trúc chương trình nên tuân thủ theo cấu trúc sau:
Bạn cần đăng nhập để thấy đính kèm

Tức là các thủ tục hay hàm chuyển đổi, không nên có sự xuất hiện của msgbox. Ở hình ảnh minh họa phía trên, các chữ màu đỏ (hàm hay thủ tục con) là các đơn vị sẽ được chuyển thành DLL. Nội dung bên trong chúng nên tránh sử dụng msgbox.

Nguyên tắc 1: Các hàm và thủ tục con không chứa hàm msgbox.


Ngoài ra có một số biến được khai báo public.
Nếu trên VBA, các biến này xuất hiện ở trong bất cứ hàm hay thủ tục con nào đều được. Nhưng khi đã chuyển sang DLL, thì các biến public nên được khai báo trong thông số đấu vào củ hàm hay thủ tục con.
Bạn cần đăng nhập để thấy đính kèm

Nếu để như hình trên thì ở bên DLL, chương trình sẽ không hiểu p1 là gì, p2 là gì.
Do đó phải chuyển đổi như sau:
Bạn cần đăng nhập để thấy đính kèm


Nguyên tắc 2: Biến public phải được khai báo là biến đầu vào cho các hàm hay thủ tục có sử dụng tới chúng mà chúng ta muốn chuyển các hàm hay thủ tục này sang DLL.

-Một vấn đề anh em hơi lăn tăn và ngại ngùng là làm việc với Word hay Excel thì sao?
Trước tiên nói về Word (có lẽ Excel cũng tương tự).
Bạn cần đăng nhập để thấy đính kèm

Thay vì viết tràn lan, ở cái đoạn ... đó, tôi sẽ ngắt nó ra làm thủ tục con và đưa thủ tục này vào DLL.
Như vậy trên code VBA nếu các bạn có thói quen ngắt tách thủ tục con ngay sau khi khai báo xong các Object, thì việc chuyển sang DLL cũng sẽ bớt đi được công sức.
Nguyên tắc 3 : Làm việc với các đối tượng, thì các đối tượng này làm biến đầu vào cho hàm hay thủ tục con khi chuyển sang DLL, đơn giản ta chỉ cần khai báo chúng là Object. Bên trong chương trình, tên các phương thức và các thuộc tính trước nay như thế nào thì vẫn như vậy. Chú ý, các hằng số nên viết giá trị là số.
Chẳng hạn trên VBA bạn có thể viết là :
Mã:
unit:=wdStory
Nhưng bên DLL sẽ không hiểu wdStory là gì, việc google tra cứu cũng đơn giản thôi, khi chuyển đổi sang DLL thì bạn nên viết thẳng giá trị, ví dụ là:
Mã:
unit:=6 'wdStory
Với nguyên tắc số 3, nếu tuân thủ, bạn sẽ không còn phải băn khoăn, để làm việc với Word hay Excel trên VB6 hay VB.NET thì ta phải làm gì. Code trên VBA như nào thì cứ bê sang như vậy thôi. Có lẽ máy tính đã tự hiểu được Object mà nó nhận được chính là Word (hay Excel) rồi.
Chú ý, khi chuyển đổi sang VB.NET, do không khai báo Word, mà tôi đơn thuần làm theo cách trên, thì cấu trúc With~End With không thấy hoạt động.
Tôi đành phải viết:
Mã:
obj.phuongthuca
obj.thuoctinhA.thuoctinhA1.... =
obj.thuoctinhB.thuoctihB2...=
Hơi vất vả xíu nhưng code cũng đã chạy. Còn với VB6 thì mọi việc thuận lợi hơn nhiều, như đã nói, VBA như thế nào thì cứ mang sang VB6 như vậy, miễn là bạn tuân thủ nguyên tắc số 3.

Topic sẽ tiếp tục được cập nhật thêm. Nếu bạn có kiến thức gì, thì cứ tùy ý trao đổi trong này.
 

phuonghong1997

Yêu THVBA như điếu đổ
Nguyên tắc 2: Biến public phải được khai báo là biến đầu vào cho các hàm hay thủ tục có sử dụng tới chúng mà chúng ta muốn chuyển các hàm hay thủ tục này sang DLL.
Đúng vậy.
Nếu trên VBA có :
Mã:
thutuccon(byval rng as range) 'Phần xử lý liên quan tới rng
thì trên DLL chỉ cần khai báo rng là object. Trên DLL :
Mã:
thutuccon(Byval rng as object)
...'Phần xử lý thông tin liên quan tới rng, chả hạn nạp giá trị rng vô mảng
Đối với hàm msgbox thì mình ít dùng, nhưng với hàm thông báo trên VBA:
Mã:
Application.Assistant.DoAlert...
Khi chuyển sang DLL ở trên VBA cần làm như sau:
Mã:
Dim obj as object
Set obj = Application
...
Trên DLL sẽ lấy obj làm đầu vào :
Mã:
thutuccon(byval obj as object)
obj.Assistant.DoAlert...
Sheet hay Application hay workbook cứ gán cho một biến object rồi bên DLL lấy đầu vào là Object.
 
D

Deleted member 293

Guest
Nguyên tắc số 3 quá hay.
Nguyên tắc 3 : Làm việc với các đối tượng, thì các đối tượng này làm biến đầu vào cho hàm hay thủ tục con khi chuyển sang DLL, đơn giản ta chỉ cần khai báo chúng là Object.
Em đã thử áp dụng và được luôn.
Code gốc VBA:
Mã:
Sub vidu()
    ThisWorkbook.Sheets(1).Cells(1, 1) = 1
End Sub
Trước khi chuyển sang DLL em kiểm tra coi xem trên VBA có hoạt động được không?
VBA:
Sub vidu()
    Dim obj As Object
    Set obj = ThisWorkbook
    Call xyz(obj)
End Sub
DLL VB6:
Sub xyz(ByVal obj As Object)
    obj.Sheets(1).Cells(1, 1) = 1
End Sub
Thấy VBA vẫn hoạt động, như vậy thủ tục xyz có thể cho vào DLL được.
 
T

thuthuy2000

Guest
Đúng rồi bạn, cái gì không biết khai báo ra sao (Workbook, Worksheet,...) thì khai báo là Object. Bên VB6 không phải khai báo thêm thư viện gì luôn.
 

tuhocvba

Administrator
Thành viên BQT
Để thành thục, chúng ta sẽ làm bài luyện tập.
Bài tập 1: Chuyển đổi code VBA sau sang DLL VB6
VBA:
Function Rankgiamdan(arr As Variant, j As Long) As Long
    'Tim vi tri cua mot phan tu trong mang la vi tri thu may
    Dim i As Long

    For i = 1 To UBound(arr)
        'Tim theo vi tri giam dan
        If arr(j) = WorksheetFunction.Large(arr, i) Then
            Rankgiamdan = i
            Exit For
        End If
    Next

End Function
Khi chuyển đổi sang DLL, tức là viết code trên VB6, nó sẽ không hiểu WorksheetFunction là gì.
Chú ý lệnh này nếu viết đầy đủ sẽ là Application.WorksheetFunction .
Do đó ta nên thêm tham số đầu vào cho hàm Rankgiamdan một biến obj trong đó obj = Application.
Tóm lại trên DLL sẽ viết là:
DLL:
Function Rankgiamdan(obj As Object, arr As Variant, j As Long) As Long
    'Tim vi tri cua mot phan tu trong mang la vi tri thu may
    Dim i As Long
    For i = 1 To UBound(arr)
        'Tim theo vi tri giam dan
        If arr(j) = obj.WorksheetFunction.Large(arr, i) Then
            Rankgiamdan = i
            Exit For
        End If
    Next
End Function
Ở trên VBA khi gọi hàm Rankgiamdan từ DLL ta viết như sau :
VBA:
i = Rankgiamdan(Application, arr, j)
 

Euler

Administrator
Thành viên BQT
Bài tập 2: Chuyển code VBA sau sang DLL VB6
Mã:
ThisWorkbook.Sheets("DATA").Cells(1, 1).Value = "Tuhocvba.net"
Bước 1:
Mở VB6 quyền admin. Tạo Project ActiveX DLL.
Trên đó viết code như sau:
DLL:
Sub ghigiatri(ByVal obj As Object)
    'obj = workbook
    obj.Sheets("DATA").Cells(1, 1).Value = "Tuhocvba.net"
End Sub
Thông tin :
Class1XXX
Project1XXX
Tạo ra file DLL : Project1XXX.dll
Bước 2:
Tạo project Active Exe
Thông tin :
Class1AAA
Project1AAA
Module1
Class1AAA:
Public Function Newinstance(ProgID As String) As Object
  Set CreateInstance = CreateObject(ProgID)
End Function
Sub ghigiatri(ByVal obj As Object)
    If xx Is Nothing Then
        Set xx = CreateObject("Project1XXX.Class1XXX")
    End If
    Call xx.ghigiatri(obj)
End Sub
Module1:
Public xx As Object
Tạo ra file Exe : Project1AAA.exe

Bước 3: Tiến hành đăng ký file Exe và DLL
Bước 4: Viết code VBA trên Excel như sau:
Mã:
Sub vidu()
    Dim x As Object
    Dim obj As Object
    
    Set x = CreateObject("Project1AAA.Class1AAA")
    Set obj = ThisWorkbook
    Call x.ghigiatri(obj)
End Sub
Trên đây ta đã coi objworkbook và thấy rằng khi viết code trên VB6 thì gần giống với VBA. Chỗ nào là workbook thì thay bằng obj là được.
Bằng cách này trên VB6 ta cũng không phải khai báo thư viện Excel Application gì nữa.
 
Bài tập 3: Chuyển code VBA sau sang DLL VB6
VBA:
ThisWorkbook.Sheets(1).Cells(2,2).Value = 1
DLL:
 obj.Cells(1, 1).Value = 1
VBA:
    Dim x As Object
    Dim obj As Object
   
    Set x = CreateObject("Project1AAA.Class1AAA")
    Set obj = ThisWorkbook.Sheets(1)
    Call x.ghigiatri2(obj)
Ở bài tập này, obj đóng vai trò là sheet.
 
Top