运行 在 Powershell 中访问宏
Running Access Macro in Powershell
我正在尝试使用以下代码 运行 PowerShell (v4.0 Windows 8.1) 中的 Access 2010 宏:
$Access = New-Object -com Access.Application
$Access.OpenCurrentDatabase("SomePath", $False, "Password")
$Access.Run("SomeProc")
$Access.CloseCurrentDatabase()
$Access.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Access)
Remove-Variable Access
我在 $Access.Run("SomeProc")
行收到一个错误,指出没有指定足够的参数:
Exception calling "Run" with "1" argument(s): "Invalid number of parameters. (Exception
from HRESULT: 0x8002000E (DISP_E_BADPARAMCOUNT))"
过程SomeProc
不需要任何参数。
我已经阅读了 运行 方法中的 msdn article 并且只需要一个参数。
我也试过 this workaround 但由于不相关的原因也没有成功。
有谁知道错误的原因以及如何使该方法起作用?
C# 签名是这样的:
public object Run(string Procedure, ref object Arg1, ... ref object Arg30) ...
这意味着 COM Arg 可选参数在 .NET 中不是可选的,因为它们被显式标记为 [ref]。即使您不使用它们,您也需要提供所有 32 个参数。
假设您有以下 VBA 代码:
Public Sub Greeting(ByVal strName As String)
MsgBox ("Hello, " & strName & "!"), vbInformation, "Greetings"
End Sub
您可以这样调用它:
$Access = New-Object -com Access.Application
$Access.OpenCurrentDatabase("Database1.accdb")
$runArgs = @([System.Reflection.Missing]::Value) * 31
$runArgs[0] = "Greeting" #Method Name
$runArgs[1] = "Jeno" #First Arg
$Access.GetType().GetMethod("Run").Invoke($Access, $runArgs)
在你的情况下它将是:
$runArgs = @([System.Reflection.Missing]::Value) * 31
$runArgs[0] = "SomeProc"
$Access.GetType().GetMethod("Run").Invoke($Access, $runArgs)
我可能会尝试向访问对象添加一个助手:
Add-Member -InputObject $Access -MemberType ScriptMethod -Name "Run2" -Value {
$runArgs = @([System.Reflection.Missing]::Value) * 31
for($i = 0; $i -lt $args.Length; $i++){ $runArgs[$i] = $args[$i] }
$this.GetType().GetMethod("Run").Invoke($this, $runArgs)
}
然后你就可以像你期望的那样使用Run2了:
$Access.Run2("Greeting", "Jeno")
$Access.Run2("SomeProc")
这是一个驱动程序问题,OLEDB 库未正确加载。
我能够准确地重现你的错误,并且我能够通过从你的 SysWow 目录而不是 System32 打开 Powershell 来解决这个问题。
尝试打开此版本的 Powershell(您必须再次 运行 set-executionpolicy),看看它是否会执行您的脚本。
%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe
我正在尝试使用以下代码 运行 PowerShell (v4.0 Windows 8.1) 中的 Access 2010 宏:
$Access = New-Object -com Access.Application
$Access.OpenCurrentDatabase("SomePath", $False, "Password")
$Access.Run("SomeProc")
$Access.CloseCurrentDatabase()
$Access.Quit()
[System.Runtime.InteropServices.Marshal]::ReleaseComObject($Access)
Remove-Variable Access
我在 $Access.Run("SomeProc")
行收到一个错误,指出没有指定足够的参数:
Exception calling "Run" with "1" argument(s): "Invalid number of parameters. (Exception from HRESULT: 0x8002000E (DISP_E_BADPARAMCOUNT))"
过程SomeProc
不需要任何参数。
我已经阅读了 运行 方法中的 msdn article 并且只需要一个参数。
我也试过 this workaround 但由于不相关的原因也没有成功。
有谁知道错误的原因以及如何使该方法起作用?
C# 签名是这样的:
public object Run(string Procedure, ref object Arg1, ... ref object Arg30) ...
这意味着 COM Arg 可选参数在 .NET 中不是可选的,因为它们被显式标记为 [ref]。即使您不使用它们,您也需要提供所有 32 个参数。
假设您有以下 VBA 代码:
Public Sub Greeting(ByVal strName As String)
MsgBox ("Hello, " & strName & "!"), vbInformation, "Greetings"
End Sub
您可以这样调用它:
$Access = New-Object -com Access.Application
$Access.OpenCurrentDatabase("Database1.accdb")
$runArgs = @([System.Reflection.Missing]::Value) * 31
$runArgs[0] = "Greeting" #Method Name
$runArgs[1] = "Jeno" #First Arg
$Access.GetType().GetMethod("Run").Invoke($Access, $runArgs)
在你的情况下它将是:
$runArgs = @([System.Reflection.Missing]::Value) * 31
$runArgs[0] = "SomeProc"
$Access.GetType().GetMethod("Run").Invoke($Access, $runArgs)
我可能会尝试向访问对象添加一个助手:
Add-Member -InputObject $Access -MemberType ScriptMethod -Name "Run2" -Value {
$runArgs = @([System.Reflection.Missing]::Value) * 31
for($i = 0; $i -lt $args.Length; $i++){ $runArgs[$i] = $args[$i] }
$this.GetType().GetMethod("Run").Invoke($this, $runArgs)
}
然后你就可以像你期望的那样使用Run2了:
$Access.Run2("Greeting", "Jeno")
$Access.Run2("SomeProc")
这是一个驱动程序问题,OLEDB 库未正确加载。
我能够准确地重现你的错误,并且我能够通过从你的 SysWow 目录而不是 System32 打开 Powershell 来解决这个问题。
尝试打开此版本的 Powershell(您必须再次 运行 set-executionpolicy),看看它是否会执行您的脚本。
%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe