从 Powershell 调用具有不同参数计数的 VBA 函数
Calling VBA functions with varying parameter counts from Powershell
我正在尝试制作一个可以调用任何 Excel 宏的 Powershell 脚本。这行得通,只要我事先知道参数的数量。如果我尝试通过使用所有 30 个 Microsoft.Office.Interop.Excel.Application.Run 方法参数来使其通用,我 运行 进入以下错误消息: Exception calling "Run" with "31" argument (s): "Number of parameters specified does not match the expected number."
到目前为止,这是我的尝试,从 .ps1 文件的内容开始:
param (
[Parameter()][ValidateNotNullOrEmpty()][string]$excel_file_location,
[Parameter()][ValidateNotNullOrEmpty()][string]$macro_name,
[Parameter()][object[]]$macro_parameters
)
$par = (,$null) * 30
if($macro_parameters) {
for ($i = 0; $i -lt $macro_parameters.Count -and $i -lt $par.Count; $i++) {
$par[$i] = $macro_parameters[$i]
}
}
$excel_app = New-Object -ComObject Excel.Application
$excel_app.Workbooks.Open($excel_file_location)
$excel_app.Run($macro_name, $par[0], $par[1], $par[2], $par[3], $par[4], $par[5], $par[6], $par[7], $par[8], $par[9], $par[10], $par[11], $par[12], $par[13], $par[14], $par[15], $par[16], $par[17], $par[18], $par[19], $par[20], $par[21], $par[22], $par[23], $par[24], $par[25], $par[26], $par[27], $par[28], $par[29])
$excel_app.Quit()
用于测试目的的 Excel VBA 文件是空白 Excel 2016 .xlsm 文件,其中包含此宏:
Sub DoTheThing(x As String)
Cells.Select
Selection.Style = "Good"
Range("A1").Select
ActiveCell.FormulaR1C1 = x
ActiveWorkbook.SaveAs Filename:="C:\Temp\macrotest2.xlsm", _
FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
End Sub
导致错误的命令(其中ExecuteExcelVBA.ps1和macrotest.xlsm是上面描述的文件):
ExecuteExcelVBA.ps1 macrotest.xlsm DoTheThing (,"A1 value")
如果我更改 $excel_app.Run 行以删除 $par[0]
之后的所有参数,它会起作用。
我可以将我的 $par 数组值更改为某些默认值,这样 Excel 将忽略这些参数吗?
也欢迎对低效问题发表评论。
您可以结合使用 -Replace
和 -Join
运算符,使用 [=14= 的元素创建 comma-space (,
) 分隔字符串] 大批。生成的字符串可以与 .Run()
方法调用命令连接。可以使用 Invoke-Expression
调用最终字符串 ($macro_run
)。请注意在 $macro_run
赋值期间使用单引号对以防止变量被扩展。
param (
[Parameter()][ValidateNotNullOrEmpty()][string]$excel_file_location,
[Parameter()][ValidateNotNullOrEmpty()][string]$macro_name,
[Parameter()][object[]]$macro_parameters
)
$par = $macro_parameters -replace ".*",'''$&' -join ", "
$excel_app = New-Object -ComObject Excel.Application
$excel_app.Workbooks.Open($excel_file_location)
$macro_run = '$excel_app.Run($macro_name, ' + $par + ')'
Invoke-Expression $macro_run
$excel_app.Quit()
我正在尝试制作一个可以调用任何 Excel 宏的 Powershell 脚本。这行得通,只要我事先知道参数的数量。如果我尝试通过使用所有 30 个 Microsoft.Office.Interop.Excel.Application.Run 方法参数来使其通用,我 运行 进入以下错误消息: Exception calling "Run" with "31" argument (s): "Number of parameters specified does not match the expected number."
到目前为止,这是我的尝试,从 .ps1 文件的内容开始:
param (
[Parameter()][ValidateNotNullOrEmpty()][string]$excel_file_location,
[Parameter()][ValidateNotNullOrEmpty()][string]$macro_name,
[Parameter()][object[]]$macro_parameters
)
$par = (,$null) * 30
if($macro_parameters) {
for ($i = 0; $i -lt $macro_parameters.Count -and $i -lt $par.Count; $i++) {
$par[$i] = $macro_parameters[$i]
}
}
$excel_app = New-Object -ComObject Excel.Application
$excel_app.Workbooks.Open($excel_file_location)
$excel_app.Run($macro_name, $par[0], $par[1], $par[2], $par[3], $par[4], $par[5], $par[6], $par[7], $par[8], $par[9], $par[10], $par[11], $par[12], $par[13], $par[14], $par[15], $par[16], $par[17], $par[18], $par[19], $par[20], $par[21], $par[22], $par[23], $par[24], $par[25], $par[26], $par[27], $par[28], $par[29])
$excel_app.Quit()
用于测试目的的 Excel VBA 文件是空白 Excel 2016 .xlsm 文件,其中包含此宏:
Sub DoTheThing(x As String)
Cells.Select
Selection.Style = "Good"
Range("A1").Select
ActiveCell.FormulaR1C1 = x
ActiveWorkbook.SaveAs Filename:="C:\Temp\macrotest2.xlsm", _
FileFormat:=xlOpenXMLWorkbookMacroEnabled, CreateBackup:=False
End Sub
导致错误的命令(其中ExecuteExcelVBA.ps1和macrotest.xlsm是上面描述的文件):
ExecuteExcelVBA.ps1 macrotest.xlsm DoTheThing (,"A1 value")
如果我更改 $excel_app.Run 行以删除 $par[0]
之后的所有参数,它会起作用。
我可以将我的 $par 数组值更改为某些默认值,这样 Excel 将忽略这些参数吗?
也欢迎对低效问题发表评论。
您可以结合使用 -Replace
和 -Join
运算符,使用 [=14= 的元素创建 comma-space (,
) 分隔字符串] 大批。生成的字符串可以与 .Run()
方法调用命令连接。可以使用 Invoke-Expression
调用最终字符串 ($macro_run
)。请注意在 $macro_run
赋值期间使用单引号对以防止变量被扩展。
param (
[Parameter()][ValidateNotNullOrEmpty()][string]$excel_file_location,
[Parameter()][ValidateNotNullOrEmpty()][string]$macro_name,
[Parameter()][object[]]$macro_parameters
)
$par = $macro_parameters -replace ".*",'''$&' -join ", "
$excel_app = New-Object -ComObject Excel.Application
$excel_app.Workbooks.Open($excel_file_location)
$macro_run = '$excel_app.Run($macro_name, ' + $par + ')'
Invoke-Expression $macro_run
$excel_app.Quit()