停止对VBA函数的并发访问

停止对VBA函数的并发访问,vba,concurrency,synchronization,mutex,Vba,Concurrency,Synchronization,Mutex,在Excel中,我定义了一个VBA函数来搜索文件。我想阻止并发访问此函数,因为否则硬盘会受到不必要的重击 这是我定义的函数: Public Function findDocument(docName As String) findDocument = findDocumentInFolder(docName, "C:\Correspondence") End Function 然后,我使用以下公式调用excel中的数千个单元格: =findDocument(<cell refer

在Excel中,我定义了一个VBA函数来搜索文件。我想阻止并发访问此函数,因为否则硬盘会受到不必要的重击

这是我定义的函数:

Public Function findDocument(docName As String)
    findDocument = findDocumentInFolder(docName, "C:\Correspondence")
End Function
然后,我使用以下公式调用excel中的数千个单元格:

=findDocument(<cell reference>)
=findDocument()
在java中,我们可以通过使用synchronized关键字来控制并发访问。VBA中是否有任何等效项


另外,我假设它是并发运行的,因为在excel窗口的右下角,它显示:
计算:(4个处理器)):9%
VBA及其主机应用程序在STA COM线程上运行:VBA代码中不会考虑并发性。即使是在MTA管理的线程上运行的.NET代码也需要通过COM互操作将自己封送到STA上,而涉及COM的MT问题几乎都很有趣

这就是说,一个访问文件系统的UDF,在数千个单元格中使用,无论如何都可能会让Excel屈服


我建议尝试另一种方法-可能将结果缓存在
字典中
,以避免在重复输入的情况下不必要地命中文件系统(如果数据中存在重复输入),和/或制作一个按钮触发的宏过程,扫描给定的表列以运行
FindDocumentInfo文件夹
,并将结果直接写入这些单元格,不要让它们成为每次重新计算工作簿时都不必要地重新计算的UDF。

VBA及其宿主应用程序在STA COM线程上运行:VBA代码中不会考虑并发性。即使是在MTA管理的线程上运行的.NET代码也需要通过COM互操作将自己封送到STA上,而涉及COM的MT问题几乎都很有趣

这就是说,一个访问文件系统的UDF,在数千个单元格中使用,无论如何都可能会让Excel屈服


我建议尝试另一种方法-可能将结果缓存在
字典中
,以避免在重复输入的情况下不必要地命中文件系统(如果数据中存在重复输入),和/或创建一个按钮触发的宏过程,扫描给定的表列以运行
FindDocumentInfo文件夹
,并将结果直接写入这些单元格,而不是创建一个UDF,每次重新计算工作簿时都不必重新计算。

VBA中甚至可以有多个线程吗?!不要担心VBA中根本没有并发性,就像@cyboashu在VBA中说的没有并发性一样。有关“缓存”UDF结果以避免重新计算结果的过度工作的信息,请参见此处:我认为,理论上,您可以在多个线程中运行VBA——前提是您在完全独立的Excel实例中并行运行同一个工作表宏(即,不复制/重命名工作簿并在同一Excel实例中同时打开,而是运行Excel-打开工作簿,打开新的单独Excel(它将具有不同的进程ID)并打开同一工作簿并运行它))。VBA中甚至可以有多个线程吗?!不要担心VBA中根本没有并发性,就像@cyboashu在VBA中说的没有并发性一样。有关“缓存”UDF结果以避免重新计算结果的过度工作的信息,请参见此处:我认为,理论上,您可以在多个线程中运行VBA——前提是您在完全独立的Excel实例中并行运行同一个工作表宏(即,不要复制/重命名工作簿并在同一个Excel实例中同时打开,而是运行Excel-打开工作簿,打开新的单独Excel(它将具有不同的进程ID),然后打开同一个工作簿并运行)。谢谢,我添加了一些日志记录,并确认搜索一次运行一个。还感谢缓存/按钮按下的建议,我会给他们一个shot感谢垫,我添加了一些日志,并确认搜索一次运行一个。也感谢缓存/按钮按下的建议,我会给他们一个机会