文章目录

  • VBA的Shell函数
  • 函数参数介绍
  • 过程等待
  • 案例-执行Windows的bat文件
  • 案例-mysql查询
  • 案例-执行python脚本
  • 案例-指定应用程序打开文件
  • AppActivate语句
  • EXCEL表格函数打开应用程序
  • ShellExecute函数
  • 函数介绍
  • 函数API声明
  • 案例:打开网页、图片、文本、EXCEL


VBA的Shell函数

函数参数介绍

Shell(PathName[,WindowStyle])

  • PathName :要执行的程序名,包括目录或文件夹
  • WindowStyle :程序运行时窗口的样式

Shell函数返回在第一个参数中指定的应用程序的任务标识。可以使用这个数字在稍后激活该任务;
Shell函数启动的应用正在运行时,VBA进程不会终止(类似于加入了进程等待)。
Shell函数异步运行应用程序,执行Shell函数后,还有其他过程,会与Shell函数内容同时执行;
Shell函数第二个参数WindowStyle的值:

常量


说明

vbHide

0

窗口将隐藏,并且焦点将传递给隐藏窗口。

vbNormalFocus

1

窗口具有焦点且还原为其原始大小和位置。

vbMinimizedFocus

2

窗口将显示为具有焦点的图标。

vbMaximizedFocus

3

使用焦点最大化窗口。

vbNormalNoFocus

4

窗口将还原为其最新的大小和位置。 当前活动窗口仍保持活动状态。

vbMinimizedNoFocus

6

窗口将显示为图标。 当前活动窗口仍保持活动状态。

示例:

Function shell_func(Program As String)
' Program:应用名称
Dim TaskId As Double
On Error Resume Next
TaskId = Shell(Program, 1)      ' 任务标识,参数1代表窗口具有焦点且还原为其原始大小和位置
If Err <> 0 Then     ' 不等于0,表示报错
    MsgBox "无法打开应用:" & Program, vbCritical, "Error"
End If
End Function

过程等待

Shell在运行完之后会关闭小黑窗,处理快点几乎看不见,可以通过在命令行前加入cmd /k,小黑窗不会关闭;
Shell "cmd /k ipconfig/all" VBA等待shell执行完再执行后面进程,可以定义这么一个函数

Function ShellAndWait(cmd As String) As String 
    Dim oShell As Object, oExec As Object
    Set oShell = CreateObject("WScript.Shell")
    Set oExec = oShell.exec(cmd)        ' 执行cmd命令
    result = oExec.StdOut.ReadAll    ' 读取命令行返回的内容,读完后再进行vba后面的逻辑处理;
    Set oShell = Nothing
    Set oExec = Nothing
End Function

案例-执行Windows的bat文件

Shell "c:/bat_file.bat"


案例-mysql查询

Sub sql_to_txt()
Dim this_path,cmd As String

this_path = ThisWorkbook.Path    ' 当前工作簿的路径
ChDrive "F"   '切换磁盘渠道到F盘
ChDir this_path     ' 切换路径,这样my_ndim_table文件就写入到工作簿所在目录下了
'-u账号 -p密码 库名mydb -e执行 "要执行的sql",> 查询结果重定向到txt文件
cmd = "cmd /k mysql -uroot -p123456 mydb -e ""select * from d_mg_game_ndim limit 20"" > my_ndim_table.txt"
shell cmd, 1    
End Sub

案例-执行python脚本

' 打开jupyter notebook
Shell "jupyter notebook"

' 执行python脚本
shell "python d:/python.py"

案例-指定应用程序打开文件

这里使用的是notepad++打开命名为my_ndim_table.txt的文本文件

ChDrive "c"
ChDir "C:\Program Files (x86)\Notepad++"
cmd_str = ".\notepad++.exe F:\桌面\my_ndim_table.txt"
Debug.Print cmd_str

Shell cmd_str, 1

AppActivate语句

如果一个程序已经在运行,使用shell函数会启动另一个实例,大多情况下,只需要激活正在运行的实例,而并非启动另一个实例。可以通过AppActivate语句激活实例;

Sub StartCalculate()
Dim Program As String
Dim TaskId As Double

Program = "calc.exe"   ' 计算器
On Error Resume Next   '遇到错误,继续执行下面语句
AppActivate "计算器"    ' 这里是应用程序面板的标题titile
If Err <> 0 Then   ' 如果没有捕捉到‘计算器’程序,则err不等于0
    Err = 0
    TaskId = shell(Program, 1)    ' 打开计算器
    If Err <> 0 Then MsgBox "无法打开计算器"
End If
End Sub

vba 通过shell函数 执行python程序 vba调用shell打开的程序_VBA


EXCEL表格函数打开应用程序

如果是在工作表里,我们可以使用该函数:

=HYPERLINK("C:\Windows\System32\calc.exe","打开计算器")

vba 通过shell函数 执行python程序 vba调用shell打开的程序_Shell_02


ShellExecute函数

函数介绍

使用API函数ShellExecute能打开任何文件(包括桌面和URL快捷方式)。ShellExecute解析系统注册表HKEY_CLASSES_ROOT中所有的内容,判断启动哪一个执行程序,并且启动一个新的实例或使用DDE将文件名连到一打开的实例。然后,ShellExecute返回打开文件的应用的实例句柄。
ShellExecute函数可以简单地打开磁盘文件和Internet文件。如果将第二个参数“OPEN”改为“PRINT”或者“EXPLORE”,则ShellExecute能打印文件或打开文件夹。

该函数只能启用已知文件名的应用程序(文件类型在Windows注册)


函数API声明

在模块中的声明部分输入如下声明语句

vba 通过shell函数 执行python程序 vba调用shell打开的程序_VBA_03

Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hWnd As Long, _
    ByVal ipOperation As String, ByVal lpFile As String, _
    ByVal lpParameters As String, ByVal lpDirectory As String, _
    ByVal nShowCmd As Long) As Long

声明关键词:

  • Declare关键字:在模块级别中声明对动态链接库(DLL)中外部过程的引用。
  • Function关键字:紧随Function的函数名是从VBA中调用该函数时要使用的名称。该名称可以与API函数本身的名称相同,也可以使用Declare语句中的Alias关键字,表示要在VBA中使用不同的名称(“别名”)调用该函数。
  • Lib关键字:指明包含所声明过程或函数的动态链接库。它说明的是函数或过程从何而来的问题。例如在上例中,SetFocus Lib"user32"说明函数SetFocus来自“user32.dll”文件。
  • Alias关键字:用于指定API函数的别名,如果调用的API函数要使用字符串(参数中包含String类型),则Alias关键字是必需的。这是因为在ANSI和Unicode字符集中同一API函数的名称可能是不一样的。为了保证不出现声明错误的情况,必须使用Alias关键字指出API函数的别名。

案例:打开网页、图片、文本、EXCEL

Sub open_url()
' 打开百度链接
res = ShellExecute(0&, vbNullString, "http://www.baidu.com", vbNullString, vbNullString, 1)

' 打开图片
res = ShellExecute(0&, vbNullString, "F:\桌面\111.png", vbNullString, vbNullString, 1)

' 打开txt文件
res = ShellExecute(0&, vbNullString, "my_ndim_table.txt", vbNullString, vbNullString, 1)

' 打开excel表格
res = ShellExecute(0&, vbNullString, "F:\excel_file.xlsx", vbNullString, vbNullString, 1)
End Sub