我有一个 Excel 电子表格和一个 .Net 库,它可以进行一些相当复杂的计算。.Net 程序集通过 COM 公开给 Excel 中的 VBA 代码。
当我调用 .Net 库时,Excel UI 线程在计算过程中被阻塞。
这会阻止用户与 Excel 交互,并且在某些情况下会向用户指示 Excel 在标题栏中(未响应)。
我对 Excel 2010 中的 VBA 不太了解,但是有没有办法在不同的线程中产生对我的 .Net 库的调用并向用户显示“进行中”对话框?
我有一个 Excel 电子表格和一个 .Net 库,它可以进行一些相当复杂的计算。.Net 程序集通过 COM 公开给 Excel 中的 VBA 代码。
当我调用 .Net 库时,Excel UI 线程在计算过程中被阻塞。
这会阻止用户与 Excel 交互,并且在某些情况下会向用户指示 Excel 在标题栏中(未响应)。
我对 Excel 2010 中的 VBA 不太了解,但是有没有办法在不同的线程中产生对我的 .Net 库的调用并向用户显示“进行中”对话框?
这是可能的,但可能需要一些努力才能将所有内容连接起来。有很多方法可以解决这个问题,其中一种可能类似于:
BackgroundWorker
的 DoWork
事件处理程序访问 Excel 对象模型。如果您想在计算过程中更新 Excel,BackgroundWorker
则应使用该ReportProgress
方法在 UI 线程上报告进度。ProgressChanged
事件处理程序(在 UI 线程上运行)中,C# 代码可以直接更新 Excel 对象模型,也可以调用 VBA 代码来执行更新。很可能不,你不能在 C# 中使用另一个线程。Excel 是一个单线程应用程序,该线程是 UI 线程,因此使用 Excel 的对象模型会阻塞 UI。
另一种方法是使用OpenXmlSdk并使用它在单独的线程上对 Excel 数据的副本执行操作,然后重新加载数据。根据数据的大小和计算时间,它可能非常值得。我在 Word 中对大约 100 页的文档使用了这种技术,它将处理时间从 10 分钟缩短到 <30 秒,其中大部分 30 秒用于从 Word 导出和导入数据。Excel 在该领域往往要快一些。
使用 VBA 很难做到这一点,因为 Excel VBA 几乎是单线程同步的。但 Excel 2010 确实支持异步 UDF:查看 Excel DNA 或 Addin Express 以获取有关从 .NET 执行此操作的一些帮助。
http://exceldna.codeplex.com/wikipage?title=Performing%20Asynchronous%20Work&referringTitle=文档
http://www.add-in-express.com/add-in-net/index.php
2: http: //www.add-in-express.com/add-in-net/index.php
您也可以从基于 C 的 XLL
http://msdn.microsoft.com/en-us/执行此操作图书馆/办公室/ff796219%28v=office.14%29.aspx
一种有点疯狂的替代方案(大多数 VBA 解决方案都是)并且没有被提及——您可以生成动态 VBScript,它们几乎可以作为线程工作并在后台工作并将它们连接到 Excel。我不久前在这个博客上读到了这个想法:http ://www.databison.com/index.php/multithreaded-vba-an-approach-to-processing-using-vbscript/
它不是很优雅,但它是一种选择。
您应该使用 Excel-dna 来执行此操作。使用它调用异步操作将相当容易。