我有一个Excel电子表格,我有一个.Net库,它可以完成一些相当复杂的计算。 .Net程序集通过COM暴露给Excel中的VBA代码。Excel中的长时间运行
当我呼叫到.Net库时,Excel UI线程在计算过程中被阻塞。
这可以防止用户与Excel进行交互,并且在某些情况下向用户指示Excel在标题栏中是(Not Responding)。
我不太了解Excel 2010中的VBA,但有什么方法可以在不同的线程中产生对我的.Net库的调用,并向用户展示“进行中”对话框?
我有一个Excel电子表格,我有一个.Net库,它可以完成一些相当复杂的计算。 .Net程序集通过COM暴露给Excel中的VBA代码。Excel中的长时间运行
当我呼叫到.Net库时,Excel UI线程在计算过程中被阻塞。
这可以防止用户与Excel进行交互,并且在某些情况下向用户指示Excel在标题栏中是(Not Responding)。
我不太了解Excel 2010中的VBA,但有什么方法可以在不同的线程中产生对我的.Net库的调用,并向用户展示“进行中”对话框?
这是可能做到这一点,但可能需要一些努力来连线一切。有许多方法,你可以接近这一点,其中一个看起来是这样的:
BackgroundWorker
的DoWork
事件处理程序访问Excel对象模型。如果要在计算过程中更新Excel,则BackgroundWorker
应使用ReportProgress
方法报告UI线程上的进度。ProgressChanged
事件处理程序(它在UI线程上运行)中,C#代码可以直接更新Excel对象模型,也可以调用VBA代码来执行更新。有可能是NO,你不能在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=Documentation
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/library/office/ff796219%28v=office.14%29.aspx
一个有点疯狂的选择(大多数VBA解决方案)并没有被提及 - 你可以产生动态VBScripts,它可以作为一个线程工作,并在后台工作,并将它们绑定到Excel中。前段时间我在这个博客上看到了这个想法:http://www.databison.com/index.php/multithreaded-vba-an-approach-to-processing-using-vbscript/
这不是很优雅,但它是一个选项。
你应该使用Excel-dna来做到这一点。你将很容易用它调用异步操作。