【问题标题】:Calling VBA functions with varying parameter counts from Powershell从 Powershell 调用具有不同参数计数的 VBA 函数
【发布时间】:2019-10-01 11:22:48
【问题描述】:

我正在尝试制作一个可以调用任何 Excel 宏的 Powershell 脚本。只要我事先知道参数的数量,这就是有效的。如果我尝试通过使用所有 30 个 Microsoft.Office.Interop.Excel.Application.Run 方法参数来使其通用,我会遇到以下错误消息:Exception calling "Run" with "31" argument(s): "Number of parameters specified does与预期的数字不匹配。”

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

也欢迎对效率低下的问题发表评论。

【问题讨论】:

    标签: excel vba powershell com


    【解决方案1】:

    您可以使用-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()
    

    【讨论】:

    • 这不会引发错误,但是如果我将两个参数提供给 $macro_parameters,它只会将两个参数都以连接字符串的形式提供给 VBA 中的 x 参数。
    • 如果 VBA 得到另一个参数,它会再次爆炸,因为它只被赋予 1 个参数而不是 2 个。除非你建议在 VBA 中解析连接的字符串,这不是一个选项在这里。
    • @Twon-ha 我已经更新了。请让我知道这是否有帮助。人们会对这段代码有疑问,因为Invoke-Expression 从来都不是一个有利的命令。
    • 哦,一个评估。不过,比我对每个参数计数使用带有 Run 调用的开关的解决方法要好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    相关资源
    最近更新 更多