VBA中启动其它程序
前言
在程序处理流程中,经常需要调用其它程序,比如需要先将文件解压缩后再解析解压缩后的文件。
方法很多,最常用的是用VBA自带的Shell方法。或者用WshShell 对象的exec方法或是Run 方法也可以。
两者各有优缺点。Shell方法可以取得程序句柄,而如果想取得命令行程序执行结果,则需要用WshShell对象的exec()方法。
VBA自带的Shell方法
这是最简单的方法,尤其适用于打开GUI程序。打开后,后续操作由其它的代码控制(比如RPA)
语法
Shell(pathname, [ windowstyle ])
参见微软官方文档
示例
Sub Test4()
Dim dblHandle As Double
dblHandle = Shell("python", vbNormalFocus)
Debug.Print dblHandle
End Sub
参数
参数1:要打开的程序路径及名称。如果已经在系统Path参数里设置过了,也可以不带路径,只放程序名,甚至扩展名也可以不用写
参数2:打开程序的窗口样式
返回值
返回一个Double 类型的数值,代表打开程序的句柄,也就是在任务管理器中的PID.
如果是做RPA程序,那么取得PID是非常重要的。
Shell()是异步的,打开程序后,即可执行后续代码。
WshShell对象
请参见本人的另一篇文章 关于WshShell对象
WshShell对象的Run()方法
语法:
objWshShell.Run strCommand, [intWindowStyle], [bWaitOnReturn]
示例:
Sub test2()
Dim objWshShell As New WshShell
Dim lngReturn As Long
lngReturn = objWshShell.Run("notepad.exe c:\temp\test.txt ", 1, False)
objWshShell.Popup lngReturn, 5, "Information", vbOKOnly
Set objWshShell = Nothing
End Sub
参数:
参数1:命令行语句
参数2: 打开的窗口类型
参数3:是否等到用户关闭该程序再返回。如果是True, 程序会一直等待直到打开的application被关闭。如果是False, 则打开程序后会立即继续执行。
注意:
如果命令行语句中要打开的程序名称错误,并不是返回一个错误代码,而是VBA程序本身提示错误,所以一定要确保程序名称正确。
返回值:
返回值是一个long 类型数值。正常情况返回0
WshShell对象的exec()方法
语法:
objWshShell.Exec strCmd
示例:
Sub TEST3()
Dim objWshShell As New WshShell
Dim objExec As WshExec
Dim intChoice As Integer
Dim strMsg As String
'用7Zip 解压软件的命令行程序解压缩
Set objExec = objWshShell.Exec("7z e c:\temp\test.zip -aoa -o c:\temp\Test\)
strMsg = objExec.StdErr.ReadAll
objWshShell.Popup strMsg, 5, "Error", vbOKOnly
Set objWshShell = Nothing
Set objExec = Nothing
End Sub
参数
只有一个参数,命令行语句。
同Run()方法一样,如果命令行语句中要打开的程序名称错误,并不是返回一个错误代码,而是VBA程序本身提示错误,所以一定要确保程序名称正确。
返回值
返回一个WshExec对象。可以通过该对象的StdErr对象取得错误信息。
与Run() 方法不同, Exec()方法并没有同步或异步的选择。打开程序后,代码会立即继续执行。但是,如果要读取WshExec对象,则必须等到程序被关闭才行。
Run()方法与Exec()方法的差异
参见文章Differences between Run and Exec (VBScript)
对于文章中Exec()可以打开GUI程序的观点,不赞同。实践证明,Run()方法和Exec()方法都可以打开GUI程序。
如果Excel()方法需要同步执行,则需要通过cmd来实现。
Sub TEST3()
Dim objWshShell As New WshShell
Dim objExec As WshExec
Dim intChoice As Integer
Dim strMsg As String
Dim comspec As String
comspec = objWshShell.ExpandEnvironmentStrings("%comspec%") '取得cmd命令的完全路径名
Set objExec = objWshShell.Exec(comspec & " /c F:\SysPrograms\WeChat\WeChat.exe")
Do
Debug.Print objExec.StdOut.ReadLine()
Loop While Not objExec.StdOut.AtEndOfStream
Set objWshShell = Nothing
Set objExec = Nothing
End Sub