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
你也可以
- 将您的Excelmacros移植到Outlook中并直接运行
- 使用一个标志来捕获代码完成
下面的代码在第一张表的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
如果AskMeFlow
在Workbook_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