2011-08-05 1 views
0

古いVB6/* .xlaコードをC#アプリケーションに変換するのに多くの時間を費やしましたが、今では自分自身をメジャーパフォーマンスホール。 C#(VS 2010)のExcelを自動化すると、パフォーマンスに大きな影響を与えるようです。私はテストVB6アプリケーションで「正確な」コードを書いて、約1〜2秒で計算を実行します。 C#のコードが1分以上かかるところ。コードの一般的な流れは次のとおりです(ClientはVB6またはC#アプリケーションのいずれかです)。ExcelオートメーションVB6クライアントアプリケーションとC#クライアントアプリケーションのパフォーマンス

- のみのクライアントアプリケーションの存続期間中に一度行っては

  1. クライアントが作成して開き、ExcelのApplication

  2. クライアントは、計算に必要な必要なアドインをロードするためにExcelを自動化します。

    - 各計算のために行わが

  3. を行うクライアントは、既存の* .xlsファイルを閉じて、所望の* .xlsファイルを開くために、Excelを自動化します。

  4. クライアントは3

  5. クライアントが追加Excelからマクロを呼び出すステップで開かれた* .XLSの構成を取得するにはExcelAppObject.Run(「AddIn.xla!GetConfiguration」)を使用して追加Excelからマクロを呼び出しますExcelAppObject.Run( "AddIn.xla!LoadInputs"、InputsXmlString)を使用します。

    1. マクロは、InputsXmlStringをMSXML.DOMDocument40オブジェクトに読み込みます。
    2. マクロは=偽Application.Calculation = xlCalculationManualが
    3. マクロセットApplication.EnableEvents(入力のいくつかの「テーブル」を投入スピードアップするために)オン
    4. マクロ上のすべての「構成」入力/テーブルループ'入力'ワークシートを開き、それらをクリアします(xmlに渡された 'すべての'入力が含まれていない場合)
    5. マクロは渡されたすべてのxmlをループし、 '入力'ワークシートの適切な場所にロードします。
  6. クライアントはMSXML.DOMDocument40オブジェクトにDataXmlStringマクロ負荷

    1. ExcelAppObject.Run( "AddIn.xla!GetResults"、DataXmlString)を使用して追加Excelからマクロを呼び出します。
    2. マクロは '入力'ワークシートのすべての '構成済み'データ値をループしてクリアします(xmlに渡されたデータに 'すべて'データが含まれていないか、前の計算をクリアしている場合)
      これはLoadInputsとは異なります。私たちは、「入力」のワークシート上の適切な場所
    3. マクロセットにマクロ負荷にDataXmlStringからすべてのデータを入力は、すべての計算のために同じですが、「参加者データが」明らかにそれぞれの計算のための異なるバッチ計算
    4. を持つことができますApplication.EnableEvents = true
    5. マクロはアプリケーションをオンにします。Calculation = xlCalculationAutomatic(計算がすべてのデータ/入力がロードされたことを確実にするため)
    6. マクロは設定されたすべての結果セルをループし、Xml文字列で返します。

だから、あなたが見ることができるように、それぞれの計算のために、私は3つだけの「クロスプロセス」を持って試してみて、その知られている「貧困層の性能を最小化するために、Excel(GetConfiguration、LoadInputs、およびGetResults)に、クライアントからの呼び出しを問題。問題は、VB6アプリケーションから正確に同じコードが呼び出された場合、4-6ステップは約2秒かかることです。クライアントアプリケーションがC#アプリケーションの場合、4-6は約70秒かかります。 すべてこの70秒は、計算を自動に戻すときに手順6で発生します。

Excelと従来のVB6アプリケーションを自動化するC#アプリケーションには既知の問題がありますか?またはC#コードを保持できるようにVB6と同じパフォーマンスを実現するための回避策がありますか?

+0

アプリケーションをリリースモードでビルドし、Visual Studio以外で実行してみてください。 – Stu

+0

私たちはリリースを組み込んでいます。デバッグを開始して問題を発見するために、私たちは現在、LINQPad全体の 'ブローカ'コード/フレームワークの代わりに、より簡単な直接的なスクリプトでLINQPadをテストしています。 – Terry

+0

だから、デバッガを一切取り付けずに実行しようとしましたか? – Stu

答えて

0

COM Interopを使用してExcelとのやりとりを行うためにC#を使用すると、一般にパフォーマンスの観点から非常に貧弱です。 C#を続行したい場合、Excel DNAまたはAddin Expressを参照してくださいC#からはるかに高速なXLLインタラクションを使用することができます。 Excelとのインタラクションのために現在利用可能な技術選択肢の簡単な評価については、http://fastexcel.wordpress.com/2011/07/07/excel-udf-technology-choices-snakes-ladders-with-vba-vb6-net-c-com-xll-interop/を参照してください。

C#の主なパフォーマンスのボトルネックは、通常ExcelからC#にデータを転送することです。各データ転送呼び出しは大きなオーバーヘッドを発生させるため、通常は配列を使用して大きなデータブロックを転送する方がはるかに高速です。

+0

あなたは私の主な問題を逃したかもしれないと思う。私はC#からExcelへのコールを「3」に最小化しました。しかし、呼び出し元のクライアントが* C#のときにApplication.Calculation = xlCalculationAutomatic(Excel/VBA内)を回すという単純な動作は、クライアントがVB6の場合とは大きく異なり、パフォーマンスが大幅に異なります。私は、クライアントからExcelへの複数の呼び出し(VB6またはC#に関係なく)が悪いことを理解しています。これが最小限に抑えられている理由です。 – Terry

+0

Charles - 私はあなたの製品を読んでいます。私はそれが私たちの計算を助けるかどうかわからないが、私の会社はスプレッドシートの「所有者」ではない。他の「開発者」がそれらを私たちに提供するので、異なるクライアントのすべてのスプレッドシートを更新する必要があります。だから私はあなたの製品が提供する可能性があることを正確に把握し、すべての変換を実行するのに必要な努力の価値があるかどうかを再度見直しています。 – Terry

+0

テリー:私は混乱しています - あなたの実際の計算時間が増えましたか(ステップ5、あなたはc#UDFを使用していますか?)か、計算結果を読むのにかかる時間(ステップ6、結果セルをループするのは、一つずつ)? –

関連する問題