从Powershell调用时,VBA无法创建Outlook(运行时错误429)

时间:2019-03-18 12:54:31

标签: excel vba outlook automation runtime-error

我创建了一些脚本,以帮助在执行某些分析后自动发送电子邮件。以前这已经起作用,但是由于某些原因,一些脚本失败并给出以下错误消息:

运行时错误“ 429”: ActiveX组件无法创建对象

然后将Outlook Object代码行称为错误。

重要的一点是,该脚本在我退出MS Outlook时运行,并且在Outlook已经运行时发出错误。我使用任务计划程序来运行此程序,而Outlook通常总是在运行。

Private Sub Send_Ratings_Email()


Dim OutApp As Object, OutMail As Object
Dim rng As Range
Dim StrBody As String
StrBody = "Please find  Maturities for the Current Week Below: "

Application.ScreenUpdating = False
On Error Resume Next
Set OutApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If OutApp Is Nothing Then Set OutApp = GetObject("Outlook.Application")

On Error GoTo cleanup



  Set OutMail = OutApp.CreateItem(0)
        On Error Resume Next

        Call AddAzureLabel(OutMail, "Restricted - Internal")
        With OutMail
            .To = " example.com"
            .Subject = "Weekly Maturities - W/C " & Format(Now, "dd-mmm- 
         yy")
            .HTMLBody = StrBody & RangetoHTML(rng)


            .Display  'Or use .Send
        End With
        On Error GoTo 0
        Set OutMail = Nothing


        cleanup:
        Set OutApp = Nothing
        Application.ScreenUpdating = True

仅当不在Task Scheduler上手动运行时,Powershell脚本才能工作。

3 个答案:

答案 0 :(得分:1)

您正在创建一个Outlook实例(如果它无法运行),请检查它是否已经在运行并获取正在运行的应用程序;否则,请创建一个实例:

On Error Resume Next
Set OutApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If OutApp Is Nothing Then Set OutApp = CreateObject("Outlook.Application")

答案 1 :(得分:0)

现在将其添加为答案,但实际上只是尝试以不适合注释的方式进行调试。与其他答案类似,但是想法是使用它来创建一个测试用例,让我们看看是否可以在您的Task Scheduler> Powershell案例中使它工作。

让您的PS在此处运行foofoo2过程,并且我将Outlook实例封装为一个独立的函数,以尝试保持事物清洁并隔离错误。

Option Explicit

Sub foo()
Dim olApp As Object
Set olApp = GetApplication("Outlook.Application")

End Sub

Sub foo2()
Dim olApp As Object
Set olApp = GetApplication2("Outlook.Application")
End Sub

Function GetApplication2(className As String) As Object
' function to encapsulate the instantiation of an application object
Dim theApp As Object
On Error Resume Next
Set theApp = CreateObject(className)
If theApp Is Nothing Then
    MsgBox "Unable to get a handle on " & className
Else
    MsgBox "Successfully got a handle on " & className & ", returning to caller"
End If
Set GetApplication2 = theApp
End Function


Function GetApplication(className As String) As Object
' function to encapsulate the instantiation of an application object
Dim theApp As Object
On Error Resume Next
Set theApp = GetObject(, className)
If Err.Number <> 0 Then
    MsgBox "Unable to Get" & className & ", attempting to CreateObject"
    Set theApp = CreateObject(className)
End If

If theApp Is Nothing Then
    Err.Raise Err.Number, Err.Source, "Unable to Get or Create the " & className & "!"
    Set GetApplication = Nothing
End If

MsgBox "Successfully got a handle on Outlook Application, returning to caller"

Set GetApplication = theApp

End Function

我从PS上运行时,例如:

$excel = new-object -comobject excel.application
$file = "C:\debug\ps-excel.xlsm"
$wb = $excel.workbooks.open($file)
$excel.Run("Module1.foo")

并且:

$excel.Run("Module1.foo2")

foo过程中,GetObject引发错误,但不是429错误,控制权传递到CreateObject,该实例成功实例化了应用程序。因此,不幸的是,在foo / foo2的任何组合下,我都无法重现错误,并且Outlook是否已经打开似乎也无关紧要。

这是一个有点骇人听闻的潜在解决方案

所以,这有点不合时宜,因为我认为它不能解决根本原因(并且由于我无法复制您的错误,它实际上可能无法解决任何问题),但是值得一试,如您所述:

  

重要的是,该脚本在我退出MS Outlook时运行,并在Outlook已经运行时发出错误提示

我的想法是只修改您的PS以检查正在运行的Outlook实例,然后通过stop-process Cmdlet关闭它。

try {
    stop-process -Name "outlook" -ErrorAction Stop
    Write-Host "Stopped the running instance of Outlook Application"
    } catch { 
    Write-Host "outlook was not already running"
    } 

$excel = new-object -comobject excel.application
$file = "C:\debug\ps-excel.xlsm"
$wb = $excel.workbooks.open($file)
$excel.run("Module1.foo")

答案 2 :(得分:0)

在任务计划程序任务中取消选中“以最高特权运行”