【发布时间】: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) < 5 Then GoTo skpStatement更改为if Len(statement) >=5 Then。它消除了不必要的GoTo语句,只需测试您确实想要执行代码而不是不想想要执行代码的情况。