|
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件 ★ 免费下载 ★ ★ 使用帮助★
本帖最后由 ivrdachen 于 2024-1-28 12:43 编辑
dll封装只支持32位,且注册还需要管理员权限,以及遇到各种未知问题,兼容性实在太差了,果断放弃了,研究了exe封装,发现exe几乎可以兼容目前大多数平台,而且不需要注册即可使用。
exe封装实际上是通过shell命令执行VB6生成的exe文件,但这里需要解决两个问题,如何传递参数和获取返回值,而且VBA里面用shell命令执行不如dll类模块调用方便,最后想了一个方法,利用数组方式,数组值作为shell执行函数的参数值,这样基本接近函数调用习惯了,例如下面的执行hanshu1, 只需要shellfunction("hanshu1", Array(3, 2))即可,hanshu1是函数名称,3, 2就是传递的参数,这样至少形式上像一个函数吧,关于读取shell命令的返回值,也是搞了好久才弄明白,原来执行的exe默认并不会将结果输出给shell窗口,而需要先将函数的输出转换成能读取到的标准输出,至此基本解决了VBA封装和兼容性问题。
执行速度上,相比于dll确实慢了很多,至少降低了50%,但是反正自动化,慢点就慢点了,兼容性好就行,测试了office2007到2016 32位系统和64位系统上都是可以正常运行的,另外exe文件可能会被杀毒软件误报,添加到信任即可。
将以下代码放到VB6模块中:
Private Declare Function GetStdHandle Lib "kernel32" _
(ByVal nStdHandle As Long) As Long
Private Declare Function WriteFile Lib "kernel32" _
(ByVal hFile As Long, ByVal lpBuffer As String, _
ByVal nNumberOfBytesToWrite As Long, _
lpNumberOfBytesWritten As Long, _
ByVal lpOverlapped As Long) As Long
Private Const STD_OUTPUT_HANDLE = -11&
Sub Main()
scmd = Command()
If scmd = "" Then
MsgBox "欢迎使用本测试软件" & Now
End If
If InStr(scmd, "hanshu1" & "|") Then
canshu = Split(scmd, "|")
res = hanshu1(canshu(1), canshu(2))
End If
If InStr(scmd, "hanshu2" & "|") Then
canshu = Split(scmd, "|")
res = hanshu2(canshu(1), canshu(2), canshu(3))
End If
WriteToStdOut CStr(res)
End Sub
Private Sub WriteToStdOut(ByVal sText As String)
Dim hStdOut As Long
Dim iWritten As Long
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
WriteFile hStdOut, ByVal sText, Len(sText), iWritten, 0&
End Sub
Function hanshu1(x, y)
hanshu1 = x * y
End Function
Function hanshu2(x, y, z)
hanshu2 = x * y + z
End Function
VBA中代码:
Sub test()
MsgBox shellfunction("hanshu1", Array(3, 2))
MsgBox shellfunction("hanshu2", Array(1, 2, 3))
End Sub
Function shellfunction(mingcheng, canshu)
Set objShell = CreateObject("WScript.Shell")
strCommand = ThisWorkbook.Path & "\excel_exe.exe " & mingcheng & "|"
For cs_num = 0 To UBound(canshu)
strCommand = strCommand & canshu(cs_num) & "|"
Next
Set objExec = objShell.exec(strCommand)
Dim output As String
output = ""
Do While Not objExec.StdOut.AtEndOfStream
output = output & objExec.StdOut.ReadLine() & vbNewLine
Loop
Set objShell = Nothing
shellfunction = output
End Function
|
评分
-
5
查看全部评分
-
|