VBA Outlook调用Excelmacros并等待macros完成

我从Outlook规则脚本调用Excelmacros。

这个过程是:获取邮件,运行一个运行Outlook脚本的Outlook规则,从该脚本打开Excel,运行Excelmacros,closuresExcel。

如何在Outlook规则脚本中validationExcelmacros是否已完成,以保存并closures应用程序?

Sub AskMeAlerts() Dim appExcel As Excel.Application Dim wkb As Excel.Workbook Set appExcel = CreateObject("Excel.Application") appExcel.Workbooks.Open ("C:\Ask me question workflow.xlsm") appExcel.Visible = True appExcel.Run "'Ask me question workflow.xlsm'!AskMeFlow" appExcel.DisplayAlerts = False appExcel.ActiveWorkbook.Save appExcel.Quit Set appExcel = Nothing Set wkb = Nothing End Sub 

你也可以

  1. 将您的Excelmacros移植到Outlook中并直接运行
  2. 使用一个标志来捕获代码完成

下面的代码在第一张表的A1中使用一个标记来捕获正在运行的代码(在Excel部分中)。 我也已经把你的代码(这是早期和晚期绑定的混合)

outlook代码

  Sub AskMeAlerts() Dim appExcel As Excel.Application Set appExcel = New Excel.Application With appExcel .DisplayAlerts = False .Workbooks.Open ("C:\TEMP\Ask me question workflow.xlsm") .Run "'Ask me question workflow.xlsm'!AskMeFlow" If .activeworkbook.sheets(1).[a1].Value = "Complete" Then MsgBox "Code has run" .activeworkbook.sheets(1).[a1].Value = vbNullString .activeworkbook.Save .DisplayAlerts = True .activeworkbook.Close appExcel.Quit Set appExcel = Nothing End If End With End Sub 

excel代码

 Sub AskMeFloW() 'do stuff ThisWorkbook.Sheets(1).[a1] = "Complete" End Sub 

一个非常简单的方法就是通过执行locking。

此代码是一个快速和肮脏的解决scheme,通过检查文件的存在,在预定义的地方。

C:\Ask me question workflow.xlsm添加这个子:

 Sub WrapAskMeFlow() Dim tmpFile As String tmpFile = "C:\AskMeFlow.tmp" Open tmpFile for Output as #1 Close #1 AskMeFlow Kill tmpFile End Sub 

在你的outlookmacros中添加:

  Sub AskMeAlerts() Dim appExcel As Excel.Application Dim wkb As Excel.Workbook Set appExcel = CreateObject("Excel.Application") appExcel.Workbooks.Open ("C:\Ask me question workflow.xlsm") appExcel.Visible = True appExcel.Run "'Ask me question workflow.xlsm'!WrapAskMeFlow" appExcel.DisplayAlerts = False While Dir("C:\AskMeFlow.tmp")="":DoEvents:Wend While Dir("C:\AskMeFlow.tmp")<>"":DoEvents:Wend appExcel.ActiveWorkbook.Save appExcel.Quit Set appExcel = Nothing Set wkb = Nothing End Sub 

选项1

在你的具体情况下最简单的select是build立保存和退出命令到Excelmacros,而不是Outlook。

也就是说,你可以修改你的Outlook代码来:

  Sub AskMeAlerts() Dim appExcel As Excel.Application Dim wkb As Excel.Workbook 'Is this declaration necessary for some code elsewhere? You do not use this variable and I would recommend removing the declaration. Set appExcel = CreateObject("Excel.Application") With appExcel .Workbooks.Open ("C:\Ask me question workflow.xlsm") .Visible = True .Run "'Ask me question workflow.xlsm'!AskMeFlow" 'No need to explicitly set alert values or save workbook as Excel macro will handle this. End With Set appExcel = Nothing Set wkb = Nothing 'Again, is this necessary? End Sub 

然后,您可以将以下内容添加到“Ask me question workflow.xlsm”文件的末尾:

  Application.DisplayAlerts = False ThisWorkbook.Close SaveChanges:=True Application.Quit 

注意:如果您还将手动运行macros,或者在不希望工作簿保存,closures和退出的其他用例中,则可以考虑将inputvariables添加到AskMeFlowmacros,该macros默认为False,但设置为真正的Outlook。 我认为这个问题稍微超出了这个答案的范围,所以我不会详细说明,但是让我知道你是否对这个选项感兴趣。

选项2

节录。 见Uri的解决办法 我提出的改进不会从根本上改变这个解决scheme。

选项3

根据Excel代码的性质,可以将其转换为函数并捕获输出variables。 如下所示:

 Sub AskMeAlerts() Dim appExcel As Excel.Application Dim wkb As Excel.Workbook Dim StrOutput as string StrOutput = "Excel macro did not complete." Set appExcel = CreateObject("Excel.Application") appExcel.Workbooks.Open ("C:\Ask me question workflow.xlsm") appExcel.Visible = True StrOutput = appExcel.Run "'Ask me question workflow.xlsm'!AskMeFlow" MsgBox StrOutput appExcel.DisplayAlerts = False appExcel.ActiveWorkbook.Save appExcel.Quit Set appExcel = Nothing Set wkb = Nothing End Sub 

然后,您可以将AskMeFlow更改为函数并添加以下代码:

 Function AskMeFlow() as String AskMeFlow = "Uncaught error executing Excel code." 'Your code here AskMeFlow = "Excel code completed successfully!" End Function 

如果Sub AskMeFlow在没有用户干预的情况下进行计算,我想你可以直接跟踪Excel的CalculationState

 Sub AskMeAlerts() With CreateObject("Excel.Application") .Workbooks.Open ("C:\Ask me question workflow.xlsm") .Visible = True ' Ensure Autocalculation is on .Calculation = -4105 ' xlCalculationAutomatic .DisplayAlerts = False .Run "'Ask me question workflow.xlsm'!AskMeFlow" ' Wait until calculation is done Do Until .CalculationState = 0 ' xlDone DoEvents Loop .ActiveWorkbook.Save .ActiveWorkbook.Close .Quit End With End Sub 

如果AskMeFlowWorkbook_Open事件(在“ThisWorkbook”模块中)中自动执行,那将会更好。

Excelmacros应该通过closures所有工作簿来完成,Outlook将等待打开工作簿。

在Excel中:

 // do work Application.ActiveWorkbook.Save Application.DisplayAlerts = False For Each wrkbk In Application.Workbooks If wrkbk.Name <> ThisWorkbook.Name Then wrkbk.Close Next ThisWorkbook.Save ThisWorkbook.Close 

Outlookmacros可以池,直到Workbooks.Count =零

 While appExcel.Workbooks.Count > 0 :DoEvents:Wend appExcel.DisplayAlerts = False appExcel.Quit Set appExcel = Nothing 

用下面的代码结束你的代码:

  On Error Resume Next On Error GoTo 0 ExitFunction: Set objShell = Nothing End Function