2011-02-24 28 views
1

VB.NET 3.5の実験アセンブリをCOMから公開し、ExcelのVBAコードから呼び出して、いくつかのExcelイベントをトラップし、Excelでアクティブなワークブックでいくつかの機能を実行するクラスです。BackgroundWorker経由でExcelとやり取りする.NET COMアセンブリ

クラスを開始するには、Excelアプリケーションへの参照がVBAから渡されます(アセンブリでExcel用PIAを使用しています)。

私のアセンブリからアクティブなワークブックで時間のかかる操作を実行する必要があったので、操作がバックグラウンドで完了している間に操作の進捗ダイアログを表示できるように、BackgroundWorkerをWinFormで使用することに決めました。

この方法でバックグラウンドワーカーを使用してCOM経由でExcelと対話する際に問題があるかどうかを知りたいですか?理由は、アセンブリのメインクラスがExcelアプリケーションオブジェクトへの参照を保持しているため、アクティブなワークブックを特定してその上でいくつかの操作を実行できるように、これがBackgroundWorkerに渡されるということです。私は1つの手順でワークブック自体(他のオブジェクトではない)にアクセスしています。

何らかの理由で、私はExcelがこれを好まないかもしれないということを私の頭に入れています - そうですか?

+0

閉じる投票がいくつかあります。なぜこれが「本当の疑問」ではないのかわかりません。質問者は何かが合法であるかバグかを尋ねています:「この方法でバックグラウンドワーカーを使ってCOM経由でExcelとやりとりする際の問題はありますか?」 –

+0

はい、そうです、何か問題がありますか、Excelと対話する良い方法がありますか? おそらく、私は質問をよりよく表現していたはずです...! –

答えて

2

あなたはこれに参照のうえする場合:

  • 新しいスレッド(またはワーカースレッド)オフあなたのVB.NETコードをVBAからのメソッド呼び出し
  • スピンを取得し、への参照を引き渡しワークブック(またはExcel.Application、Range;それは問題ではありません)(パラメータ、統計情報を使用しても問題ありません)
  • バックグラウンドスレッドがExcelにアクセスしているときに元のスレッドを使用して

次に、いいえ。それをしてはいけない。

Excel VBAはSTA環境です。 Excel Object Modelへのアクセスはすべて、同じスレッドから行われなければなりません。スレッドを選ぶこともできません。あなたのメソッドを最初に呼び出すスレッドでなければなりません。

ワーカースレッドからExcelにアクセスするコードを実行するには、ワーカースレッドへのインターフェイスポインタを「マーシャル」する必要があります。 Mashallingは、必要に応じてスレッド間でメソッド呼び出しをシャトルするCOMラッパー(「プロキシ/スタブ」ペア)を作成します。これは、.NETでForm.Invoke()メソッドを使用した場合と同様です。私は自分の頭の上に.NETでそれを行う方法を知らない。とにかくこれは私の最初のアプローチではありません。

もう1つの方法は、ワーカースレッドからExcelオブジェクトにアクセスするのではなく、メインフォームオブジェクトでヘルパーを使用することです(フォームは必要ですか?)。あなたのワーカースレッドがForm.Invoke()を介してそれらのヘルパーに電話をかけ、UIスレッド(VBAがあなたに電話をかけていたスレッド)から実行されるようにしてください。これは機能的には最初の選択肢と同じですが、.NETではCOMの代わりに機能する点が異なります。

3つ目のアプローチは、ワーカースレッドをまったく使用しないことです。これはVBのやり方です:唯一のスレッドからUIを作成します。それを表示してから、フォームのLoadイベントから作業を行います。をしばらくして(1秒に数回)呼び出すと、UIはある程度の滑らかさの再構成で動作します。

第4の代替方法は、この問題を回避することです。プールスレッド(これはBackgroundWorkerから取得)の代わりに新しいスレッドを使用して、そこからUIを処理します。ここでは役割を逆にしています。メインスレッドはすばらしい作業を行い、余分なスレッドはフォームを作成してUIを表示します。ここでも、Form.Invoke()を使用して進行状況ウィンドウを更新してください。完了したらDispose()スレッドを確認してください。これは私の好みのアプローチかもしれません。

ちょうど砂時計のマウスポインタを使用して...ちょうど "遅い"あなたの "遅い"ですか?

+0

優秀!アドバイスのために多くのありがとう、それは私が考えている:) –

0

BackgroundWorkerの使用についてよく知らない私は、PIAとCOM経由でExcelに接続するWinformsアプリケーションで作業しました。これは、普通の古いThreadStartデリゲートを使って、ファイルがバックグラウンドでロードされている間に進行状況バーを表示するスレッドをスピンアップさせました。うまくいった。私が理解しているように、BackgroundWorkerはカバーの下ではほとんど同じように動作します。

関連する問題