VBA - 封裝我們的VBA代碼

        Visual Basic for Applications(簡稱VBA)是新一代標準宏語言,是基於Visual Basic for Windows 發展而來的。VBA 提供了面向對象的程序設計方法,提供了相當完整的程序設計語言。VBA 易於學習掌握,用戶可以容易地將日常工作轉換爲VBA程序代碼,使工作自動化。
        但是VBA在代碼的保護上卻存在着缺陷。如果不對VBA工程設置密碼保護,代碼很容易被人瀏覽乃至竊取。而且即使設置了密碼保護,也很容易被人破解。筆者就曾用破解工具officekey輕鬆地破解了他人設置的密碼保護,不費吹灰之力便瀏覽了其中的代碼,而且從中發現了文檔保護密碼。可見,要想保護自己的VBA代碼,僅僅設置密碼保護是不夠的。
        我們知道,Visual C++、Visual Basic和C++ Builder以及Delphi等編譯器所編譯出來的程序不容易被人破解(相對來說),這是因爲代碼被編譯成了可執行文件或者動態鏈接庫文件。那麼,我們是否可以將VBA代碼封裝到動態鏈接庫文件中,然後用Word調用呢?回答是肯定的。而且這樣做還有一個好處,即可以加快代碼的運行速度。
        一、將VBA代碼封裝成動態鏈接庫
        假如我們已經寫好了一個VBA工程,而且運行無誤。
         1.建立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建立的對象來調用此方法(具體怎麼調用,我們將後面介紹)。當然,我們可以繼續向工程裏添加代碼。
        2.修改代碼
       雖然VBA源於VB,但是兩者畢竟存在着一些差異。因此,需要對轉移到VB中的VBA代碼做一些必要的修改。
       (1)修改VBA代碼中所特有類型的對象。
       如果我們所添加的代碼裏有VBA所特有類型——如Document、Rang、BookMark等所建立的對象,編譯時會提示錯誤,因爲VB不能夠識別這些對象。此時修改的方法是,將這些對象作爲過程或函數的參數進行傳遞。需要注意的是,這些參數的類型都一律設爲Object。
       例如,我們在過程Test中要訪問對象ThisDocument,但是VB無法識別ThisDocument,於是我們就爲過程test添加一個參數Doc來傳遞ThisDocument,即Test可定義爲Test(Doc As Object)。
       (2)修改VBA所特有一般變量。
       VB也無法識別VBA特有的一般變量,如ProtectType,同樣,我們也將其作爲過程後函數的參數進行傳遞,不過其類型名都一律設爲Variant。
       (3)修改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,問題到此就迎刃而解了。
        3.封裝用戶窗體
       我們也可以將用戶窗體封裝到動態鏈接庫文件裏。首先打開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工程設置密碼保護,別人也將很難窺視到我們的代碼。  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章