Excel中的长时间运行

时间:2013-03-12 15:17:25

标签: .net excel vba excel-vba excel-2010

我有一个Excel电子表格,我有一个.Net库,可以完成一些相当复杂的计算。 .Net程序集通过COM公开给Excel中的VBA代码。

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

这可以防止用户与Excel交互,并在某些情况下向用户表明标题栏中的Excel是(无响应)。

我对Excel 2010中的VBA知之甚少,但有没有办法在不同的线程中产生对我的.Net库的调用并向用户显示“进行中”对话框?

5 个答案:

答案 0 :(得分:2)

这是可能的,但可能需要花费一些力气来连接所有东西。有很多方法可以解决这个问题,其中一种可能类似于:

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

答案 1 :(得分:1)

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

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

答案 2 :(得分: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

答案 3 :(得分:1)

一个有点疯狂的选择(大多数VBA解决方案都是)并且没有被提及 - 你可以产生动态VBScripts,它可以作为一个线程工作,并在后台工作并将它们挂钩到Excel。我刚才在这个博客上读过这个想法:http://www.databison.com/index.php/multithreaded-vba-an-approach-to-processing-using-vbscript/

它不是很优雅,但它是一种选择。

答案 4 :(得分:0)

您应该使用Excel-dna来执行此操作。你可以很容易地用它调用异步操作。