萬盛學電腦網

 萬盛學電腦網 >> WORD教程 >> WORD使用技巧 >> 將VBA代碼編譯封裝成為DLL動態鏈接庫的方法

將VBA代碼編譯封裝成為DLL動態鏈接庫的方法

   一、為什麼要編譯成為DLL

  我們知道,Visual C++、Visual Basic和C++ Builder以及Delphi等編譯器所編譯出來的程序不容易被人破解(相對來說),這是因為代碼被編譯成了可執行文件或者動態鏈接庫文件。那麼,我們是否可以將VBA代碼封裝到動態鏈接庫文件中,然後用Word調用呢?回答是肯定的。而且這樣做還有一個好處,即可以加快代碼的運行速度。

  二、將VBA代碼封裝成動態鏈接庫

  假如我們已經寫好了一個VBA工程,而且運行無誤。

  ①建立VB工程及一般性操作

  首先,我們需要兩種工具,其中當然包括Microsoft Word,另外一種是Microsoft Basic 6.0。

  打開Microsoft Basic 6.0,在“新建工程”中選取“ActiveX DLL”,新建一個工程。在屬性窗口中將工程名改為VBAPrj,類模塊名改為VBACls。然後在“工程”菜單下打開“引用”,選取“Microsoft Office 11.0 Object Library”——這一步很是關鍵,切不可遺漏,然後保存工程。下面我們所做的是向工程內添加代碼。

  將VBA工程中的一個名為Test過程的代碼選定後復制,然後切換到VB編輯器,選中VB的工程管理器中的類模塊VBACls,將代碼粘貼至代碼編輯窗口中,於是這段代碼便成了類模塊VBACls一個方法,然後將工程編譯生成dll文件(如果編譯成功的話)。在Word中,我們就可以通過類模塊VBACls建立的對象來調用此方法(具體怎麼調用,我們將後面介紹)。當然,我們可以繼續向工程裡添加代碼。

  ②修改代碼

  雖然VBA源於VB,但是兩者畢竟存在著一些差異。因此,需要對轉移到VB中的VBA代碼做一些必要的修改。

  A、修改VBA代碼中所特有類型的對象

  如果我們所添加的代碼裡有VBA所特有類型——如Document、Rang、BookMark等所建立的對象,編譯時會提示錯誤,因為VB不能夠識別這些對象。此時修改的方法是,將這些對象作為過程或函數的參數進行傳遞。需要注意的是,這些參數的類型都一律設為Object。

  例如,我們在過程Test中要訪問對象ThisDocument,但是VB無法識別ThisDocument,於是我們就為過程test添加一個參數Doc來傳遞ThisDocument,即Test可定義為Test(Doc As Object)。

  B、修改VBA所特有一般變量

  VB也無法識別VBA特有的一般變量,如ProtectType,同樣,我們也將其作為過程後函數的參數進行傳遞,不過其類型名都一律設為Variant。

  C、修改VBA所特有常量

  如果在VBA代碼中出現了這樣的語句:

  ProtectionType = wdNoProtection

  很明顯,wdNoProtection是Word所獨有的常量,不為VB所能識別,因而無法通過編譯。怎樣解決這個問題呢?當然,我們可以用修改變量的方法予以修改。但是聰明的讀者會想到:如果我們知道了wdNoProtection的值,就可以直接將值賦給ProtectionType。但是接下來的一個問題是:我們怎樣才能獲得wdNoProtection的值呢?方法很簡單,就是讓Word“開口”告訴我們。

  在Word一個事件中添加以下語句:

  MsgBox CStr (wdNoProtection)

  其中CStr是類型轉換函數,返回參數相應的字符串。只要在Word中觸發此事件,會彈出一個對話窗,顯示“-1”,這就是Word所告訴我們的:wdNoProtection 的值是-1。於是我們就可以將語句 ProtectionType = wdNoProtection 改為 ProtectionType = -1,問題到此就迎刃而解了。

  三、封裝用戶窗體

  我們也可以將用戶窗體封裝到動態鏈接庫文件裡。首先打開Word的VBA編輯器,選中工程資源管理器中的用戶窗體,點擊右鍵,選擇“導出文件”,選定路徑後,將窗體文件保存。然後切換到VB編輯器,在“工程”菜單中選擇“添加文件”命令,添加保存的窗體文件。添加結束後,我們會發現VB編輯器中的工程資源管理器中的設計器出現了剛添加的窗體名,選中後雙擊,在窗體編輯器中就會顯現所添加的用戶窗體。

  到了這裡,讀者會問:窗體還有代碼呢,怎麼辦?先別急,試一試下面的操作,你就會明白,問題早已不再是問題了。選中工程資源管理器中的用戶窗體,點擊右鍵,選擇“查看代碼”,你就會高興發現,在代碼編輯框中出現了窗體所對應的代碼。原來,在我們導入窗體文件的同時也導入了窗體的代碼!當然高興之余,不要忘了還要對這些代碼按照我們上述的方法進行必要修改,以保證代碼順利地通過編譯。這樣Word就可以通過類模塊VBACls間接地調用窗體。

  四、在Word中引用動態鏈接庫

  假如經過我們編譯已生成了一個動態鏈接庫文件VBAPrj.dll,其中有一類模塊VBACls,此類模塊有一個方法Test(Doc As Object)。

  接下來我們所要做的是用Word調用Test,有三種方法可供選擇:

  1.打開Word的VBA編輯器中ThisDocument代碼窗口,點"工具"菜單下的"引用"命令,在引用對話框中引用該動態鏈接庫。

  調用代碼如下:

  Dim VBACls As New VBAPrj.VBACls

  VBACls.Test(ThisDocument)

  2.如果知道該動態鏈接庫文件的位置,可以在ThisDocument代碼窗口以代碼形式引用, 代碼如下:

  Private Sub Document_Open()

  On Error Resume Next

  Me.VBProject.References.AddFromFile "D:VBAPrj.dll"

  End Sub

  3.將動態鏈接庫文件拷貝到Word文檔同一目錄下,可在ThisDocument代碼窗口中建立如下引用函數:

  Private Function GetProjectDoc() As Object

  On Error Resume Next

  Dim VBACls As Object

  Set VBACls = CreateObject("VBAPrj.VBACls")

  If VBACls Is Nothing Then

  MsgBox "VBAPrj.dll必須和文檔在同一目錄下!"

  Exit Function

  End If

  Set GetProjectDoc = VBACls

  End Function

  然後以以下代碼形式調用Test:

  Dim objPrjDoc As Object

  Set objPrjDoc = GetProjectDoc

  Call objPrjDoc.Test(ThisDocument)

  Set objPrjDoc = Nothing

  推薦您使用第三種方法,雖然這種方法相對麻煩,但是只要動態鏈接庫與Word文檔處於同一目錄下,可保證程序的可移植性。

  到目前為止,我們已完成了我們所要達的目的。此時,即便我們不對VBA工程設置密碼保護,別人也將很難窺視到我們的代碼。

copyright © 萬盛學電腦網 all rights reserved