VBA中的多线程

Ksh*_*KJ- 55 excel multithreading vba excel-vba

这里有人知道如何让VBA运行多个线程吗?我正在使用Excel.

Tho*_*mas 56

无法使用VBA本地完成.VBA内置于单线程公寓中.获取多个线程的唯一方法是在VBA之外的其他东西中构建一个具有COM接口并从VBA调用它的DLL.

信息:OLE线程模型的描述和工作


Ana*_*com 20

您可能已经了解到VBA本身并不支持多线程.有3种方法可以实现多线程:

  1. COM/dlls - 例如C#和Parallel类在不同的线程中运行
  2. 使用VBscript工作线程 - 在单独的VBscript线程中运行您的VBA代码
  3. 使用例如通过VBscript执行的VBA工作线程 - 复制Excel工作簿并并行运行宏.

我在这里比较了所有的线程方法:http://analystcave.com/excel-multithreading-vba-vs-vbscript-vs-c-net/

考虑到方法#3,我还制作了一个VBA多线程工具,可以让您轻松地向VBA添加多线程:http://analystcave.com/excel-vba-multithreading-tool/

请参阅以下示例:

多线程For循环

Sub RunForVBA(workbookName As String, seqFrom As Long, seqTo As Long)
    For i = seqFrom To seqTo
        x = seqFrom / seqTo
    Next i
End Sub

Sub RunForVBAMultiThread()
    Dim parallelClass As Parallel 

    Set parallelClass = New Parallel 

    parallelClass.SetThreads 4 

    Call parallelClass.ParallelFor("RunForVBA", 1, 1000) 
End Sub
Run Code Online (Sandbox Code Playgroud)

异步运行Excel宏

Sub RunAsyncVBA(workbookName As String, seqFrom As Long, seqTo As Long)
    For i = seqFrom To seqTo
        x = seqFrom / seqTo
    Next i
End Sub

Sub RunForVBAAndWait()
    Dim parallelClass As Parallel

    Set parallelClass  = New Parallel

    Call parallelClass.ParallelAsyncInvoke("RunAsyncVBA", ActiveWorkbook.Name, 1, 1000) 
    'Do other operations here
    '....

    parallelClass.AsyncThreadJoin 
End Sub
Run Code Online (Sandbox Code Playgroud)


sta*_*lee 13

我正在寻找类似的东西,官方的答案是否定的.但是,我在ExcelHero.com上找到了Daniel的有趣概念.

基本上,您需要创建worker vbscripts来执行您想要的各种事情并让它报告回excel.对于我正在做的事情,从各种网站检索HTML数据,效果很好!

看一看:

http://www.excelhero.com/blog/2010/05/multi-threaded-vba.html

  • @JimmyPena但是如果脚本正在完成所有工作,并且返回的结果只需要很少的处理,那么这在减少处理时间方面仍然有效(尽管如此,它不是真正的线程).您正在排队一些非常小的操作而不是非常大的操作. (2认同)

Joh*_*man 8

我正在添加这个答案,因为程序员从更现代的语言进入VBA并在VBA中搜索Stack Overflow进行多线程处理可能并不知道有几种本机VBA方法有时可以帮助弥补VBA缺乏真正的多线程.

如果多线程的动机是拥有一个响应更快的UI,当执行长时间运行的代码时它不会挂起,VBA确实有一些经常在实践中工作的低技术解决方案:

1)可以使用户表单无模式显示 - 这允许用户在表单打开时与Excel交互.这可以在运行时通过将Userform的ShowModal属性设置为false来指定,也可以通过放置行来作为来自加载的动态完成

UserForm1.Show vbModeless
Run Code Online (Sandbox Code Playgroud)

在用户表单的初始化事件中.

2)DoEvents声明.这会导致VBA放弃对OS的控制,以执行事件队列中的任何事件 - 包括Excel生成的事件.典型的用例是在代码执行时更新图表.如果没有DoEvents,在运行宏之前不会重新绘制图表,但使用Doevents可以创建动画图表.这种想法的变体是创建进度表的常见技巧.在一个执行10,000,000次(并由循环索引i控制)的循环中,您可以拥有一段代码,如:

If i Mod 10000 = 0 Then
    UpdateProgressBar(i) 'code to update progress bar display
    DoEvents
End If
Run Code Online (Sandbox Code Playgroud)

这些都不是多线程 - 但在某些情况下它可能是一个足够的kludge.

  • 我同意 - 我只是认为指出一些有时有用的纯VBA克隆是不会有害的 (5认同)