2013-03-12 52 views
2

我有一个Excel电子表格,我有一个.Net库,它可以完成一些相当复杂的计算。 .Net程序集通过COM暴露给Excel中的VBA代码。Excel中的长时间运行

当我呼叫到.Net库时,Excel UI线程在计算过程中被阻塞。

这可以防止用户与Excel进行交互,并且在某些情况下向用户指示Excel在标题栏中是(Not Responding)。

我不太了解Excel 2010中的VBA,但有什么方法可以在不同的线程中产生对我的.Net库的调用,并向用户展示“进行中”对话框?

回答

2

这是可能做到这一点,但可能需要一些努力来连线一切。有许多方法,你可以接近这一点,其中一个看起来是这样的:

  • VBA调用C#COM对象的UI线程
  • C#的COM对象开始BackgroundWorker运行计算。请注意,您不能从BackgroundWorkerDoWork事件处理程序访问Excel对象模型。如果要在计算过程中更新Excel,则BackgroundWorker应使用ReportProgress方法报告UI线程上的进度。
  • ProgressChanged事件处理程序(它在UI线程上运行)中,C#代码可以直接更新Excel对象模型,也可以调用VBA代码来执行更新。
  • 在BackgroundWorker运行时,VBA代码可以显示“进度”对话框,以避免任何重入问题。
1

有可能是NO,你不能在C#中使用另一个线程。 Excel是单线程应用程序,该线程是UI线程,因此使用Excel的对象模型阻止UI。

另一种方法是使用OpenXmlSdk并使用它在单独的线程上对Excel数据的副本执行操作,然后将数据加载回来。根据数据大小和计算时间,它可能非常值得。我在Word中使用了大约100页的文档,并将处理时间从10分钟缩短到< 30秒,这30秒中的大部分时间用于将数据导出和导入到Word中。 Excel在这方面往往要快一点。

1

这很难做到使用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

2http://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

0

你应该使用Excel-dna来做到这一点。你将很容易用它调用异步操作。