【问题标题】:How to deal with "Microsoft Excel is waiting for another application to complete an OLE action"如何处理“Microsoft Excel 正在等待另一个应用程序完成 OLE 操作”
【发布时间】:2017-05-31 15:25:10
【问题描述】:

在使用 excel 自动化其他 MS-Office 应用程序时,我经常收到 ok-only 提示说Microsoft Excel is waiting for another application to complete an OLE action.

这只发生在自动执行冗长的任务时。

我该如何以适当的方式处理这个问题?

最近的两个例子(我认为代码不太重要):

  • 从 Excel 中创建一个带有 Access.Application 的 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 中使用现有的相当大的.docm 模板和动态SQL 查询在Word.Application 中创建邮件合并

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

【问题讨论】:

  • 我们需要更多上下文。这两种方法有什么关系?邮件合并是否连接到正在构建的数据库?你在哪里调用这两个例程?不清楚为什么每次都需要即时构建整个数据库。
  • 最后,看来你已经安装了 MS Access,考虑使用它来调用其他办公应用,因为它可以说具有更好的对象模型和应用程序/自动化环境。
  • 似乎关闭该消息是在解决 症状 而不是实际问题。如果您的查询有性能问题,解决方案不是告诉客户停止抱怨 - 解决方案是让查询在合理的时间内完成。您是否缺少索引?您的查询是否以低效的方式编写?刷新时间超过 7 秒的任何事情都应该以不同的方式完成。考虑在一夜之间进行繁重的处理并将结果转储到一个表中,然后简单地查询该表。哦,等等,访问。祝你好运!
  • 一点免费的代码审查:请考虑将If Len(statement) &lt; 5 Then GoTo skpStatement 更改为if Len(statement) &gt;=5 Then。它消除了不必要的GoTo 语句,只需测试您确实想要执行代码而不是不想想要执行代码的情况。

标签: excel vba ole


【解决方案1】:

我将在 cmets 中添加 @Tehscript 链接到的代码。

您可以通过使用 COM API 删除 VBA 的消息过滤器来解决此问题。 这将阻止 COM 告诉 VBA 显示一个消息框,当它 认为您正在调用的进程已阻塞。注意如果过程 由于某种原因确实已被阻止,这将阻止您收到任何 通知。 [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

【讨论】:

  • @Tehscript ,Darren:感觉就像我把婴儿和洗澡水一起扔了出去。然而,我确实需要那个浴缸。对我有用,非常感谢!
【解决方案2】:

我也尝试了 COM API 代码,它有效。但它仅在您没有看到错误的情况下才有用 - 每次触发错误时 30 秒的延迟仍然会发生,这对我来说是行不通的。

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

【讨论】:

    猜你喜欢
    • 2014-04-18
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    相关资源
    最近更新 更多