运行 代码时挂起

Hangs when running a code

在这里我正在寻找一种适用的方法...

How can send the running VBA procedures to background for prevent workbook hangs until the VBA statements running are finished.

在 运行 一个 VBA 程序时挂起...

指出 Document.PrintOut 内置过程具有 Background 参数,该参数使宏在 Microsoft Word 打印文档时继续。

Excel 挂起 而 运行 .Send 下面的代码

程序
Dim iMsg As Object
Dim iConf As Object

Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")

With iMsg
    Set .Configuration = iConf
    .To = strTo
    .ReplyTo = "Email Address"
    .From = """Sender Name (Email Address)"" <EmailAddress>"
    .Subject = strSubject
    .TextBody = strBody
    .AddAttachment ThisWorkbook.Path & "\Temp\" & ThisWorkbook.Name
    .Send
End With

Excel 挂起For Next 在下面的代码中循环:

Sub PrintIt()

Dim objWord As Word.Application
Dim objDocTotal As Word.Document
Dim objDoc As Word.Document
Dim i As Integer
Dim strOutfile As String
Dim rg As Word.Range

    ActiveSheet.OLEObjects("SalaryPaycheck").Activate
    Set objWord = GetObject(, "Word.Application")
    objWord.Visible = False
    Set objDoc = objWord.ActiveDocument
    Set objDocTotal = Documents.Add
    objWord.Application.DisplayAlerts = wdAlertsNone
    objWord.Application.ScreenUpdating = False

    For i = worksheetfunction.Min(range("Table1[Column1]") To _
        worksheetfunction.Max(range("Table1[Column1]")

        Range("Key").Value = i

        With objDoc
            .Fields.Update
            .Content.Copy
        End With

        Set rg = objDocTotal.Content
        With rg
            .Collapse Direction:=wdCollapseEnd
            If i > 1 Then .InsertBreak wdPageBreak
            .PasteAndFormat wdFormatOriginalFormatting
        End With
    Next i


    strOutfile = "<Path>\Salary.pdf"

    objDocTotal.ExportAsFixedFormat outputfileName:= _
                                    strOutfile, exportformat:=wdExportFormatPDF, _
                                    openafterexport:=False, optimizefor:=wdExportOptimizeForPrint, Range:= _
                                    wdExportAllDocument, From:=1, To:=1, Item:=wdExportDocumentContent



    objDocTotal.Close False
    objWord.Quit
    Set objDoc = Nothing
    Set objWord = Nothing

End Sub

在上述情况下,平均 CPU 利用率大约低于 40%!

我们从 Excel 2007 年知道支持多线程 (support.microsoft.)

Why Excel hangs when running some codes (as exampled above) while the codes running, up to they have terminated or end?

How can prevent Workbooks hanging in above same as the Background's argument ability for PrintOut procedure in MS-Word which said at top of here?

此致。

让我总结一下你的问题,并尽量让你清楚..

Since multi-threaded processing is enabled for Excel, why can't I run my VBA code on multiple threads?

因为VBA不支持多线程。所有 VBA 代码都在一个线程(主线程)上运行。

Okay, I get that. Now since Excel itself is multi-threaded, why does it freeze while the VBA code is running?

好吧,VBA 代码在主线程上运行。主线程还用于显示 Excel GUI 和做其他事情。现在,当您的 VBA 代码是 运行 时,它会阻塞主线程,因此会冻结。阅读这篇文章:Multithreaded Recalculation in Excel 了解更多关于在多线程上运行的内容:

再一次,工作簿将 总是 挂起,只要你有 VBA 代码 需要一些时间处理时间 运行。您可以通过编写如下简单的代码来测试它:

For i = 1 To 100000
    Debug.Print (i)
Next

..并观察 Excel 冻结,直到循环结束。

So, how can I prevent the workbook from freezing? Is there no way to achieve this?

嗯,你提出了两种情况:

  1. For循环:

    您可以通过在循环内添加 DoEvents 来解决此问题。 DoEvents 的作用是 产生代码的执行以允许处理其他 消息。所以,前面的代码看起来像 以下:

    For i = 1 To 100000
        Debug.Print (i)
        DoEvents
    Next
    

    但是,在您的代码 运行 时允许用户更改工作簿并不是一个好的做法。有时我确实使用 DoEvents (例如,当显示用户表单时),但我确保 而我的代码是 运行 用户无权访问代码正在使用 sheet。

  2. CDO.Message.Send方法:

    我相信它在后台运行,如果配置正确,应该不会阻塞线程。检查 this question.

希望对您有所帮助。