2

Excel スプレッドシートと、かなり複雑な計算を行う .Net ライブラリがあります。.Net アセンブリは、COM を介して Excel の VBA コードに公開されます。

.Net ライブラリを呼び出すと、計算の進行中に Excel UI スレッドがブロックされます。

これにより、ユーザーは Excel を操作できなくなり、場合によっては、Excel がタイトル バーに (応答なし) であることがユーザーに示されます。

Excel 2010 の VBA についてはよくわかりませんが、別のスレッドで .Net ライブラリへの呼び出しを生成し、ユーザーに "進行中" ダイアログを表示する方法はありますか?

4

5 に答える 5

2

可能ですが、すべてを配線するには少し手間がかかる場合があります。これにはいくつかの方法がありますが、そのうちの 1 つは次のようになります。

  • VBA は UI スレッドで C# COM オブジェクトを呼び出します
  • C# COM オブジェクトは、BackgroundWorkerを開始して計算を実行します。BackgroundWorkerDoWorkイベント ハンドラーから Excel オブジェクト モデルにアクセスできないことに注意してください。計算の進行中に Excel を更新する場合はBackgroundWorker、メソッドを使用ReportProgressして UI スレッドで進行状況を報告する必要があります。
  • イベント ハンドラー (UI スレッドで実行されるProgressChanged) では、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

Excel VBA はほぼシングルスレッド同期であるため、VBA を使用してこれを行うのは困難です。ただし、Excel 2010 は非同期 UDF をサポートしています。.NET からこれを実行する方法については、Excel DNA または Addin Express を参照してください。
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 ソリューションはそうです)、言及されていない代替案の 1 つです。ほとんどの場合スレッドとして機能し、バックグラウンドで動作し、Excel にフックできる動的な VBScript を生成することができます。少し前にこのブログでこのアイデアについて読みました: http://www.databison.com/index.php/multithreaded-vba-an-approach-to-processing-using-vbscript/

あまりエレガントではありませんが、オプションです。

于 2013-03-12T17:33:40.500 に答える