我从Outlook规则脚本调用Excel宏。
过程是: 获取邮件,运行运行Outlook脚本的Outlook规则,从该脚本打开Excel,运行Excel宏,关闭Excel。
如何在Outlook规则脚本中验证Excel宏已完成,以保存并关闭应用程序?
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
答案 0 :(得分:4)
你可以
下面的代码使用第一张表的A1中的标记来捕获正在运行的代码(在Excel部分中)。我也整理了你的代码(它是早期和后期绑定的混合)
展望代码
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
答案 1 :(得分:2)
一种非常简单的方法是实现锁定。
通过在预定义的位置检查文件是否存在,此代码是一种快速而又脏的解决方案。
在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
在Outlook宏中添加:
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
答案 2 :(得分:2)
选项1
在您的特定情况下,最简单的选项是将保存和退出命令构建到Excel宏而不是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
然后,您可以将以下内容添加到“向我提问问题workflow.xlsm”文件的末尾:
Application.DisplayAlerts = False
ThisWorkbook.Close SaveChanges:=True
Application.Quit
注意:如果您还将手动运行宏,或者在您不希望工作簿保存,关闭和退出的其他用例中,您可以考虑将一个输入变量添加到AskMeFlow宏,默认为False但由Outlook设置为True。我认为这稍微超出了这个答案的范围,所以我不会进一步详细说明,但如果您对此选项感兴趣,请告诉我。
选项2
数据被编辑。见Uri的解决方案;我建议的改进并没有从根本上改变这个解决方案。
选项3
根据Excel代码的性质,您可以将其转换为函数并捕获输出变量。如下所示:
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
答案 3 :(得分:1)
如果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”模块中),那会更好。
答案 4 :(得分:1)
Excel宏应该通过关闭所有工作簿来完成, 当Outlook仍然打开工作簿时,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
Outlook宏可以汇总到Workbooks.Count = 0
While appExcel.Workbooks.Count > 0 :DoEvents:Wend
appExcel.DisplayAlerts = False
appExcel.Quit
Set appExcel = Nothing
答案 5 :(得分:-1)
使用以下代码结束您的代码:
On Error Resume Next
On Error GoTo 0
ExitFunction:
Set objShell = Nothing
End Function