我尝试使用以下代码在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")
上收到错误,指出参数不足:
异常调用"运行"用" 1"参数:"参数数量无效。 (例外 来自HRESULT:0x8002000E(DISP_E_BADPARAMCOUNT))"
程序SomeProc
不需要任何参数。
我已经阅读了run方法的msdn article,只需要一个参数。
我也试过this workaround但也因为一个无关的原因而无法工作。
有谁知道错误的原因是什么以及如何使该方法有效?
答案 0 :(得分:3)
这是OLEDB库未正确加载的驱动程序问题。
我能够完全重现您的错误,并且我能够通过从SysWow目录而不是System32打开Powershell来解决它。
尝试打开此版本的Powershell(您必须再次运行set-executionpolicy),看看它是否会执行您的脚本。
<强>%SYSTEMROOT%\ SysWow64资料\ WindowsPowerShell \ V1.0 \ powershell.exe 强>
答案 1 :(得分:2)
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")