2

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

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

这会阻止用户与 Excel 交互,并且在某些情况下会向用户指示 Excel 在标题栏中(未响应)。

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

4

5 回答 5

2

这是可能的,但可能需要一些努力才能将所有内容连接起来。有很多方法可以解决这个问题,其中一种可能类似于:

  • VBA 在 UI 线程上调用 C# COM 对象
  • C# COM 对象启动一个BackgroundWorker来运行计算。请注意,您不能从BackgroundWorkerDoWork事件处理程序访问 Excel 对象模型。如果您想在计算过程中更新 Excel,BackgroundWorker则应使用该ReportProgress方法在 UI 线程上报告进度。
  • ProgressChanged事件处理程序(在 UI 线程上运行)中,C# 代码可以直接更新 Excel 对象模型,也可以调用 VBA 代码来执行更新。
  • VBA 代码可以在 BackgroundWorker 运行时显示进度对话框,以避免任何重入问题。
于 2013-03-12T15:38:09.920 回答
1

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

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

于 2013-03-12T15:25:56.400 回答
1

使用 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

于 2013-03-12T15:30:45.013 回答
1

一种有点疯狂的替代方案(大多数 VBA 解决方案都是)并且没有被提及——您可以生成动态 VBScript,它们几乎可以作为线程工作并在后台工作并将它们连接到 Excel。我不久前在这个博客上读到了这个想法:http ://www.databison.com/index.php/multithreaded-vba-an-approach-to-processing-using-vbscript/

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

于 2013-03-12T17:33:40.500 回答
0

您应该使用 Excel-dna 来执行此操作。使用它调用异步操作将相当容易。

于 2015-02-19T09:52:41.633 回答