如何处理" Microsoft Excel正在等待另一个应用程序来完成一个OLE动作"

时间:2017-05-31 15:25:10

标签: excel vba ole

当使用excel自动化其他MS-Office应用程序时,我经常会得到正确的提示,说Microsoft Excel is waiting for another application to complete an OLE action.

这仅在自动执行冗长任务时才会发生。

我该如何以适当的方式解决这个问题?

最近的两个例子(我重新编写代码不太重要):

  • 使用Access.Application从Excel创建accdb-Database,并通过对大量数据运行相当复杂的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模板和返回接收器的动态SQL查询,在.docm中从Excel创建邮件合并

    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中。然而,这似乎是一个可怕的想法,因为实际上可能存在我需要被警告的情况。

2 个答案:

答案 0 :(得分:4)

我将添加@Tehscript链接的代码。
我认为这是我在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

答案 1 :(得分:0)

我也尝试了COM API代码,该代码有效。但这仅在您看不到错误的情况下才有用-每次触发错误都会延迟30秒,这对我来说不可行。

我所做的更好的更改是关闭了Drive File Stream(Google产品)中的“ Microsoft Office中的实时显示”。 (到目前为止!)为我解决了这个问题。我猜想这与另一个excel插件之间存在某种冲突。