如何应对"Microsoft Excel is waiting for another application to complete an OLE action"
How to deal with "Microsoft Excel is waiting for another application to complete an OLE action"
当使用 excel 自动化其他 MS-Office 应用程序时,我经常收到仅确定提示 Microsoft Excel is waiting for another application to complete an OLE action.
只有在自动执行冗长的任务时才会出现这种情况。
我怎样才能以适当的方式处理这个问题?
两个最近的例子(我认为代码不太重要):
使用 Access.Application
从 Excel 创建 accdb 数据库,并通过 运行 相当复杂的 SQL 大量查询来填充它数据。
Public Function createDB(pathDB As String, pathSQL As String) As String
Dim dbs As DAO.Database
Dim sql As String
Dim statement As Variant, file As Variant
Dim sErr As String, iErr As Integer
With New Access.Application
With .DBEngine.CreateDatabase(pathDB, dbLangGeneral)
For Each file In Split(pathSQL, ";")
sql = fetchSQL(file)
For Each statement In Split(sql, ";" & vbNewLine)
If Len(statement) < 5 Then GoTo skpStatement
Debug.Print statement
On Error Resume Next
.Execute statement, dbFailOnError
With Err
If .Number <> 0 Then
iErr = iErr + 1
sErr = sErr & vbCrLf & "Error " & .Number & " | " & Replace(.Description, vbCrLf, vbNullString)
.Clear
End If
End With
On Error GoTo 0
skpStatement:
Next statement
Next file
End With
.Quit acQuitSaveAll
End With
dTime = Now() - starttime
' Returnwert
If sErr = vbNullString Then sErr = "Keine Fehler"
createDB = "Zeit: " & Now & " | Dauer: " & Format(dTime, "hh:mm:ss") & " | Anzahl Fehler: " & iErr & vbCrLf & sErr
' Log
With ThisWorkbook
'...
.Saved = True
.Save
End With
End Function
在 Word.Application
中从 Excel 创建邮件合并,使用现有且相当大的 .docm
-模板和动态 SQL- 查询 returns 收据
Set rst = GetRecordset(ThisWorkbook.Sheets("Parameter").Range("A1:S100"))
With New Word.Application
.Visible = False
While Not rst.EOF
If rst!Verarbeiten And Not IsNull(rst!Verarbeiten) Then
Debug.Print rst!Sql
.Documents.Open rst!inpath & Application.PathSeparator & rst!infile
stroutfile = fCheckPath(rst!outpath, True) & Application.PathSeparator & rst!outfile
.Run "quelle_aendern", rst!DataSource, rst!Sql
.Run MacroName:="TemplateProject.AutoExec.SeriendruckInDokument"
Application.DisplayAlerts = False
.ActiveDocument.ExportAsFixedFormat _
OutputFileName:=stroutfile _
, ExportFormat:=wdExportFormatPDF _
, OpenAfterExport:=False _
, OptimizeFor:=wdExportOptimizeForPrint _
, Range:=wdExportAllDocument _
, From:=1, To:=1 _
, Item:=wdExportDocumentContent _
, IncludeDocProps:=False _
, KeepIRM:=True _
, CreateBookmarks:=wdExportCreateNoBookmarks _
, DocStructureTags:=False _
, BitmapMissingFonts:=True _
, UseISO19005_1:=False
Application.DisplayAlerts = True
For Each doc In .Documents
With doc
.Saved = True
.Close SaveChanges:=wdDoNotSaveChanges
End With
Next doc
End If
rst.MoveNext
Wend
.Quit
End With
备注:
- 当 运行 规模较小时(例如,当查询较少的记录或使用不太复杂的模板时),两种代码都 运行 流畅。
- 在这两种情况下,当我
OK
通过所有重新出现的提示时,代码最终将以所需的结果结束。
因此,我想我没有遇到错误(它也不会触发错误处理程序),而是类似超时的问题。
根据其他来源的建议,我确实将我的代码包装到 Application.DisplayAlerts = False
中。然而,这似乎是一个可怕的想法,因为实际上可能存在需要提醒我的情况。
我会在评论中添加@Tehscript 链接到的代码。
You can solve this by using the COM API to remove VBA's message filter.
This will prevent COM from telling VBA to displaying a message box when it
thinks the process you're calling has blocked. Note that if the process
really has blocked for some reason this will prevent you from receiving any
notification of that. [source]
我认为这是我在 2006 年用于解决相同问题的代码(有效)。
Private Declare Function _
CoRegisterMessageFilter Lib "OLE32.DLL" _
(ByVal lFilterIn As Long, _
ByRef lPreviousFilter) As Long
Sub KillMessageFilter()
'''Original script Rob Bovey
'''https://groups.google.com/forum/?hl=en#!msg/microsoft.public.excel.programming/ct8NRT-o7rs/jawi42S8Ci0J
'''http://www.appspro.com/
Dim lMsgFilter As Long
''' Remove the message filter before calling Reflections.
CoRegisterMessageFilter 0&, lMsgFilter
''' Call your code here....
''' Restore the message filter after calling Reflections.
CoRegisterMessageFilter lMsgFilter, lMsgFilter
End Sub
我也尝试了 COM API 代码,它有效。但它仅在您看不到错误时才有用 - 每次触发错误时 30 秒的延迟仍然会发生,这对我来说是行不通的。
我所做的更好的更改是在虚拟云端硬盘(google 产品)中关闭“Microsoft Office 中的实时状态”。这已经(到目前为止!)为我解决了这个问题。我猜这和另一个 excel 插件之间存在某种冲突。
当使用 excel 自动化其他 MS-Office 应用程序时,我经常收到仅确定提示 Microsoft Excel is waiting for another application to complete an OLE action.
只有在自动执行冗长的任务时才会出现这种情况。
我怎样才能以适当的方式处理这个问题?
两个最近的例子(我认为代码不太重要):
使用
Access.Application
从 Excel 创建 accdb 数据库,并通过 运行 相当复杂的 SQL 大量查询来填充它数据。Public Function createDB(pathDB As String, pathSQL As String) As String Dim dbs As DAO.Database Dim sql As String Dim statement As Variant, file As Variant Dim sErr As String, iErr As Integer With New Access.Application With .DBEngine.CreateDatabase(pathDB, dbLangGeneral) For Each file In Split(pathSQL, ";") sql = fetchSQL(file) For Each statement In Split(sql, ";" & vbNewLine) If Len(statement) < 5 Then GoTo skpStatement Debug.Print statement On Error Resume Next .Execute statement, dbFailOnError With Err If .Number <> 0 Then iErr = iErr + 1 sErr = sErr & vbCrLf & "Error " & .Number & " | " & Replace(.Description, vbCrLf, vbNullString) .Clear End If End With On Error GoTo 0 skpStatement: Next statement Next file End With .Quit acQuitSaveAll End With dTime = Now() - starttime ' Returnwert If sErr = vbNullString Then sErr = "Keine Fehler" createDB = "Zeit: " & Now & " | Dauer: " & Format(dTime, "hh:mm:ss") & " | Anzahl Fehler: " & iErr & vbCrLf & sErr ' Log With ThisWorkbook '... .Saved = True .Save End With End Function
在
Word.Application
中从 Excel 创建邮件合并,使用现有且相当大的.docm
-模板和动态 SQL- 查询 returns 收据Set rst = GetRecordset(ThisWorkbook.Sheets("Parameter").Range("A1:S100")) With New Word.Application .Visible = False While Not rst.EOF If rst!Verarbeiten And Not IsNull(rst!Verarbeiten) Then Debug.Print rst!Sql .Documents.Open rst!inpath & Application.PathSeparator & rst!infile stroutfile = fCheckPath(rst!outpath, True) & Application.PathSeparator & rst!outfile .Run "quelle_aendern", rst!DataSource, rst!Sql .Run MacroName:="TemplateProject.AutoExec.SeriendruckInDokument" Application.DisplayAlerts = False .ActiveDocument.ExportAsFixedFormat _ OutputFileName:=stroutfile _ , ExportFormat:=wdExportFormatPDF _ , OpenAfterExport:=False _ , OptimizeFor:=wdExportOptimizeForPrint _ , Range:=wdExportAllDocument _ , From:=1, To:=1 _ , Item:=wdExportDocumentContent _ , IncludeDocProps:=False _ , KeepIRM:=True _ , CreateBookmarks:=wdExportCreateNoBookmarks _ , DocStructureTags:=False _ , BitmapMissingFonts:=True _ , UseISO19005_1:=False Application.DisplayAlerts = True For Each doc In .Documents With doc .Saved = True .Close SaveChanges:=wdDoNotSaveChanges End With Next doc End If rst.MoveNext Wend .Quit End With
备注:
- 当 运行 规模较小时(例如,当查询较少的记录或使用不太复杂的模板时),两种代码都 运行 流畅。
- 在这两种情况下,当我
OK
通过所有重新出现的提示时,代码最终将以所需的结果结束。 因此,我想我没有遇到错误(它也不会触发错误处理程序),而是类似超时的问题。
根据其他来源的建议,我确实将我的代码包装到 Application.DisplayAlerts = False
中。然而,这似乎是一个可怕的想法,因为实际上可能存在需要提醒我的情况。
我会在评论中添加@Tehscript 链接到的代码。
You can solve this by using the COM API to remove VBA's message filter. This will prevent COM from telling VBA to displaying a message box when it thinks the process you're calling has blocked. Note that if the process really has blocked for some reason this will prevent you from receiving any notification of that. [source]
我认为这是我在 2006 年用于解决相同问题的代码(有效)。
Private Declare Function _
CoRegisterMessageFilter Lib "OLE32.DLL" _
(ByVal lFilterIn As Long, _
ByRef lPreviousFilter) As Long
Sub KillMessageFilter()
'''Original script Rob Bovey
'''https://groups.google.com/forum/?hl=en#!msg/microsoft.public.excel.programming/ct8NRT-o7rs/jawi42S8Ci0J
'''http://www.appspro.com/
Dim lMsgFilter As Long
''' Remove the message filter before calling Reflections.
CoRegisterMessageFilter 0&, lMsgFilter
''' Call your code here....
''' Restore the message filter after calling Reflections.
CoRegisterMessageFilter lMsgFilter, lMsgFilter
End Sub
我也尝试了 COM API 代码,它有效。但它仅在您看不到错误时才有用 - 每次触发错误时 30 秒的延迟仍然会发生,这对我来说是行不通的。
我所做的更好的更改是在虚拟云端硬盘(google 产品)中关闭“Microsoft Office 中的实时状态”。这已经(到目前为止!)为我解决了这个问题。我猜这和另一个 excel 插件之间存在某种冲突。