4

Excel ワークブックをバッチ プロセス (JobScheduler の下) で実行できるようにするために、C# で Excel のラッパーを作成しました。私の問題はこれです...

コードの実行に時間がかかりすぎるか、ジョブ スケジューラを介して終了する必要がある場合、ラッパーはこの終了イベントを処理する必要があります。この目的のために、私は追加しました

SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);

コードに。ConsoleCtrlCheck メソッドで、共通の終了ルーチンを呼び出します (通常または終了の状況で使用されます)。このルーティングは、MS の推奨に従って次のことを行います。

ワークブックを
閉じて解放します Excel
ガベージ コレクションを閉じて解放します

その後、呼び出された Excel メソッド (エントリ ポイント) のリターン コードで終了します。これはうまくいきます。

ただし、VBA コードがまだ実行中の場合、Interop オブジェクトはワークブックを閉じたり、アプリケーションを終了したりしても応答しません。これは、すべてが遅くなったり、モーダル ダイアログが発行されたりしたことが原因である可能性があります。これに対処するために、この共通ルーチンの先頭に以下を追加しました...

  • KillExcel メソッドを実行する新しいスレッドを作成する
  • KillExcel メソッドは、指定された期間 (通常の終了コードが機能する可能性があるため) スリープしてから、プロセスを強制終了します。
  • 通常のコードが機能する場合、スレッドで Abort を呼び出します
private static void Cleanup()
{
    // Give this X seconds then terminate
    mKillThread = new Thread(KillExcel);
    mKillThread.IsBackground = false;
    mKillThread.Start();
    ...
    // close the workbooks and excel application
    // Marshal.FinalReleaseComObject etc

    GC.Collect();
    GC.WaitForPendingFinalizers();

    // Not sure if necessary but makes sure Process gone
    try
    {
        Process p = Process.GetProcessById(mExcelPid);
        p.WaitForExit();
    }
    catch(ArgumentException)
    {}

    mKillThread.Abort();
}

private static void KillExcel()
{
    Thread.Sleep(Settings.Default.KillWaitMilliSeconds);

    if (mLog.IsInfoEnabled)
        mLog.Info(string.Format("Waited {0} seconds, killing Excel process [{1}]",Settings.Default.KillWaitMilliSeconds/1000, mExcelPid));

    try
    {
        Process p = Process.GetProcessById(mExcelPid);

        if (!p.HasExited)
            p.Kill();
    }
    catch(ArgumentException)
    {
    }
}

私の質問は、これについてもっと良い方法がありますか、それともジョブ終了イベントでExcelプロセスが確実に削除されるようにするために必要な方法ですか?

4

2 に答える 2

1

あなたがやっていることは、Excelを完全に確実に終了させる標準的な方法です。COM Interop が関係していること、および Excel には孤立したインスタンスを残すという厄介な習慣があることを考えると、従う方法はほとんど間違いありません。

ただし、vba コードにアクセスでき、それを制御できる場合は、VBA コードで他のコードを実行できるようにするためにできる基本的なことが 1 つあります。

DoEvents

私の経験では、重い計算を実行する前後にその 1 行のコードを配置することで、通常、Excel は定期的なイベントを適切に処理できます。通常、これは UI 関連の操作に推奨されますが、ワークシート/アプリケーション イベントを適切に機能させるためにも機能します。

お役に立てれば。

于 2013-02-20T08:56:27.100 に答える
0

VBAロジックをEPPLUSのようなサードパーティのライブラリに置き換えることができる可能性はありますか?それははるかに速いでしょう....

于 2013-02-20T09:06:49.657 に答える