从Powershell调用具有不同参数计数的VBA函数

时间:2019-05-14 12:18:24

标签: excel vba powershell com

我正在尝试制作可以调用任何Excel宏的Powershell脚本。只要我事先知道参数的数量,此方法就有效。如果我尝试通过使用全部30个Microsoft.Office.Interop.Excel.Application.Run方法参数来使它通用,则会遇到以下错误消息:使用“ 31”个参数调用“ Run”的异常:“参数数量指定的数字与预期的数字不匹配。“

到目前为止,这是我的尝试,从.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忽略这些参数吗?

也欢迎对低效发表评论。

1 个答案:

答案 0 :(得分:2)

您可以结合使用-Replace-Join运算符,使用,数组的元素来创建逗号分隔的字符串($macro_parameters)。所得的字符串可以与.Run()方法调用命令连接在一起。可以使用$macro_run调用最后一个字符串(Invoke-Expression)。请注意,在$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()