張金沙 陳建勇 鄭家翔 雷輝 劉惠蓮



摘要:為保護VBA代碼,把VBA主要程序按VB格式修改,然后利用VB6進行編譯,形成以二進制形式存在的DLL文件,在需要時調用。DLL文件很難破解,因而有效地保護了VBA的核心代碼,大大提高了程序的安全性。
關鍵詞:Excel;VBA;封裝;DLL
中圖分類號:TP311? ? ? 文獻標識碼:A
文章編號:1009-3044(2021)33-0065-03
開放科學(資源服務)標識碼(OSID):
1 背景
Excel VBA(Visual Basic for Applications)是內嵌于微軟Office軟件Excel中的程序開發語言,在Excel中可直接運行VBA程序,從而完成較復雜的工作[1-2],例如一次運行就能完成試卷質量的全部分析、操控網頁實現學生成績的批量上傳[3]、實現復雜的統計工作等等,真正實現高效辦公。
雖然Excel提供了對VBA代碼的保護,即在Excel的VBE(Visual Basic Edirtor)界面下,找到“工具”的“VBAProject屬性”,在“保護”頁面進行密碼設置,但是保護作用有限,只要具備一定VBA常識的人就能利用網絡上的破解工具解密,且用VBA編寫的程序代碼不能在VBE環境下編譯,而是“寄生”在宿主應用程序Excel中運行,解密后能直接編輯,給居心叵測之人有可乘之機,給程序帶來嚴重安全隱患。
2 技術要點
鑒于VBA的優勢,“試卷質量量化評測系統的開發與應用”課題組選用VBA為開發語言。為提高軟件的安全性,利用Microsoft Visual Basic 6.0(以下簡稱VB6),將VBA的主要程序代碼封裝為很難破解的DLL(Dynamic Link Library)文件,在需要的地方進行調用。
為避免閱讀長篇程序而分散注意力,下面用一個簡單且完整的演示程序,分析將VBA封裝為DLL文件并進行調用的技術要點。
演示程序功能使用一般VBA代碼、VB與VBA通用代碼和把代碼封裝后調用等三種不同方式,完成在C3單元格顯示A3與B3單元格的積、在D3單元格顯示實現方式,目的是清晰展示VBA代碼按VB格式修改的關鍵步驟,見圖1。
2.1 DLL 文件的創建
DLL 文件是動態鏈接文件,它存放的是各類程序的函數或子過程,當程序需要時可進行調用。一般軟件使用DLL技術的主要目的是為了節省系統資源,提高程序的運行效率,但在本文是利用DLL文件的二進制屬性、很難破解的特點,提高VBA代碼的安全性[4-5]。
2.1.1 編寫VBA代碼
啟動Excel,命名工作簿為“VBA封裝調用”并保存。按Alt+F11進入VBE,點“插入”,選“模塊”,在新增的“模塊1”中輸入下面程序。
Sub VBAcheng()? '用一般VBA代碼實現
Range("C3") = Cells(3, 1) * Cells(3, 2)
Range("d3") = "VBA"
End Sub
2.1.2 將VBA代碼修改為VB所能識別的形式
在“模塊1”中繼續錄入下面程序:
Sub VBcheng() '用 VB與VBA通用代碼實現
Dim exlapp As Object? ? ?'定義變量exlapp為object
Set exlapp = GetObject(, "Excel.Application")? ? '使exlapp表示為EXCEL對象
exlapp.Range("C3") = exlapp.Cells(3, 1) * exlapp.Cells(3, 2)
exlapp.Range("d3") = "VB與VBA通用"
End Sub
說明:1)在制作DLL時要用VB6進行編譯,必須將VBA代碼修改為VB所能識別的形式,這是成功的關鍵。2)VB不能識別Excel的對象,故在程序中應先定義exlapp為EXCEL對象,然后在所有EXCEL對象前面均加上exlapp,例如sheet→exlapp.sheet,cells→exlapp.cells, range→exlapp.range,workbook→exlapp.workbook等等。3)如VBA程序中有Application.等代碼,也要加上exlapp. 例如Application.quit要修改為exlapp.Application.quit、Application.ScreenUpdating要修改為exlapp.Application.ScreenUpdating等等。4)修改后的代碼既能在Excel中直接運行,也可在VB中成功編譯。5)為防止制作DLL后調試困難,根據經驗,最好把要制作DLL文件的代碼先在VBE中進行修改并調試無誤后,再轉入VB6中編譯。
2.1.3 制作DLL文件
第一步:啟動VB6,新建“ActiveX DLL”。修改工程名和類名分別為EncapDLL和MyClas,見圖2。
第二步:建立引用。點擊“工程”→“引用”→“Microsoft Office X Object Library”。其中X為版本號,與Excel的版本相關,一般在11.0以上。
第三步:編寫代碼。把上述VBE中經過修改、調試的代碼(即VBcheng()過程)復制在代碼窗。
Sub VBDcheng() '在名字中間加一個“D”,以示和VBcheng()過程區別
Dim exlapp As Object
Set exlapp = GetObject(, "Excel.Application")
exlapp.Range("C3") = exlapp.Cells(3, 1) * exlapp.Cells(3, 2)
exlapp.Range("d3") = "封裝調用" '僅把顯示內容修改
End Sub
第四步:生成DLL。為方便今后升級和修改程序,必須保存工程;生成DLL前,還要點菜單“運行”→“啟動”,進一步檢查修改后有無錯誤;最后點菜單“文件”→“生成EncapDLL.dll”。
2.2 DLL 的調用
2.2.1 注冊DLL
手工注冊較方便,方法是打開“VBA封裝調用”工作簿,進入VBE,在菜單中點擊“引用”→“瀏覽”→找到“EncapDLL.dll”所在文件夾并選中此文件。
2.2.2 引用DLL
進入VBE后,在左窗“工程”中,找到并雙擊ThisWorkbook,在彈出的窗口中添加如下代碼:
Private Sub Workbook_BeforeClose(Cancel As Boolean) '關閉工作簿之前卸載EncapDLL文件
Shell "Regsvr32 /s /u " & Chr(34) & ThisWorkbook.Path & "\ EncapDLL.dll" & Chr(34)
End Sub
Private Sub Workbook_Open()'打開工作簿時加載EncapDLL文件
Shell "Regsvr32 /s " & Chr(34) & ThisWorkbook.Path & "\ EncapDLL.dll" & Chr(34)
End Sub
經過上述引用后,EncapDLL.dll與“VBA封裝調用”工作簿必須如影隨形地保存于同一文件夾內,否則會出錯。
2.2.3 調用DLL
繼續在VBE中,在“模塊1”下添加如下代碼:
Sub VBDLLcheng()
Dim ABC As New MyClas? '定義ABC為新類,即為DLL文件中的類模塊MyClas
ABC.VBDcheng? ?'調用EncapDLL中提供的過程VBDcheng(),完成積的運算功能,而原VBA代碼被隱藏
Set ABC = Nothing? '釋放類資源
End Sub
2.3 演示程序界面設計
2.3.1 界面設計
在表單中添加按鈕的方法:點菜單“視圖”→“工具欄”→“控件工具箱”→找到按鈕即可添加按鈕。其他設計參考圖1。
2.3.2 按鈕與過程關聯
進入VBE后,在左窗“工程”中,找到并雙擊Sheets1,在彈出的窗口中添加如下代碼,將按鈕與對應過程關聯:
Private Sub CommandButton1_Click()
Call VBAcheng? '調用VBA代碼編寫的過程
End Sub
Private Sub CommandButton2_Click()
Call VBcheng? ?'調用VB與VBA通用代碼的過程)
End Sub
Private Sub CommandButton3_Click()
Call VBDLLcheng '調用封裝后的過程
End Sub
Private Sub CommandButton4_Click()? '清除運算結果
Range("C3") = ""
Range("d3") = ""
End Sub
至此演示程序完成。
實際運用時,在提供給用戶的版本中,可將VBA的源代碼(本例中的VBAcheng()過程和VBcheng()過程 )刪除,只需保留能完成相功能的封裝代碼過程(本例中VBDLLcheng()過程)即可。
3 結束語
把VBA代碼進行封裝并調用的過程可總結如圖3,其關鍵步驟是將VBA代碼修改為VB可識別的形式。
制作DLL文件的主要目的是保護VBA代碼。實踐證明,把VBA程序代碼經過簡單修改,利用VB6進行編譯,形成很難破解的以二進制形式存在的DLL文件,有效地保護了VBA的核心代碼,大大提高了軟件的安全性。
參考文獻:
[1] 孟兵,劉瓊.Excel VBA應用與技巧大全[M].北京:機械工業出版社,2021.
[2] 馬致明,陳興,林雨萌.巧用Excel VBA開發體溫檢測統計報表軟件[J].電腦知識與技術,2020,16(33):209-211.
[3] 張金沙,金笛,石劭紅.基于VBA成績自動上傳系統的開發[J].電腦知識與技術,2016,12(32):80-82.
[4] 周維京.VBA封裝技術分析[J].電腦與電信,2008(4):34-35.
[5] 百度經驗.封裝ExcelVBA代碼[EB/OL].[2020-12-20].
https://jingyan.baidu.com/article/f71d603756c55a1ab641d1fb.html.
【通聯編輯:謝媛媛】