Toshichan4
@Toshichan4

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

C# で 既に開かれているEXCELファイルをオープンした際の例外処理について(COM)

解決したいこと

c# .NET8 にてInterop.Excelで EXCEL アプリを操作しています。

xlBooks.Open() でEXCELファイルをオープンする際に
既にファイルが開かれている場合の例外を処理したいのですが、
何をキャッチすれば良いのかわかりません。
どなたかご教示願います。

発生している問題・エラー

下記のコードにて
(1)すでに開いている EXCEL ファイルをさらに開こうとした場合
EXCELのエラーメッセージBox が開いて
['******.xlsx'は別のアプリケーションで開かれています。ファイルを閉じてもう一度お試しください。]
と表示されます。
この時、コンソールに書き出した ex では
「オープンエラーSystem.Runtime.InteropServices.COMException (0x800A03EC): ‥‥次の理由が考えられます。
• ファイル名またはパスが存在しません。
• ファイルが他のプログラムによって使用されています。
• 保存しようとしているブックと同じ名前のブックが現在開かれています。」
と表示されます。
その後、本プログラムを終了させた後にタスクマネージャで確認すると、EXCELのプロセスが残ってしまっています。

(2)存在しない EXCEL ファイルを開こうとした場合
EXCELのエラーメッセージBoxは開かれず、この時、コンソールに書き出した ex では 上記(1)と同じ内容が表示されます。
その後、本プログラムを終了させた後にタスクマネージャで確認すると、EXCELのプロセスは削除されているのが確認できます。

(1)の場合にも、例外をキャッチしてプログラム終了後にEXCELのプロセスが残らないようにしたいのですが、どのように処理すれば良いのでしょうか。
ご教示願います。

			int i_xlBooksCount = xlBooks.Count;

            try
			{
				xlBook[iTestSpec] = xlBooks.Open(OpenFileName);
			}
			catch (Exception ex)
			{
				if (xlBooks.Count != i_xlBooksCount + 1)
				{
					Console.WriteLine("オープンエラー" + ex);
                    
 					Marshal.ReleaseComObject(xlBooks);
					Marshal.ReleaseComObject(xlApp);
               }
            }

例)

NameError (uninitialized constant World)

または、問題・エラーが起きている画像をここにドラッグアンドドロップ

該当するソースコード

ソースコードを入力

例)

def greet
  puts Hello World
end

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

0

3Answer

例外をキャッチしてプログラム終了後にEXCELのプロセスが残らないようにしたいのですが、どのように処理すれば良いのでしょうか。

finally 句を追加して、その中にリリースするためのコードを書いてはいかがですか?

0Like

Comments

  1. @Toshichan4

    Questioner

    ご回答いただきありがとうございます。
    ただ申し訳ないのですが、今日、昨日の状況を一旦再現してから finally 句の検証をしようとしたのですが、昨日の状況の再現ができず、昨日お示しした catch 句だけで、EXCELのプロセスは正常に終了し残らない状態です。(コードの変更はしていないはずなで、昨日はさんざん苦しんだのですが‥‥)
    とはいえ、一応、finally 句を追加して ここにcatch 句の中身を移動し、catch 句 自身の中身はすべてコメントにした状態で、正常にEXCELのプロセスが残らない状態になることは確認しました。ありがとうございます。
    なんだか、お騒がせして申し訳なかったです。
    また何かありましたらご質問させていただきます。失礼しました。

以前javaで類似問題を対応したことあります。excelファイル開く前、一時tempファイルにコピーしてからおこなう方法です。面倒ですけれど。

0Like

Comments

  1. @Toshichan4

    Questioner

    コメントありがとうございます。
    もし、問題が再現するようなら、対策の一つの候補として検討させていただきます。

 プロセスが残っているのは、Excelが閉じられる前に例外処理を行なったためだと思います。また、存在しないファイルは当然開けないので、「プロセスが削除されている」というよりかは「プロセスが始まらなかった」の方が正しいです。
 
 もし、XSSFWorkBookクラスを使っているのであれば、Close()メソッドなどを定義して、そこでXSSFWorkBookクラスのDispose()メソッドを呼ぶのがいいでしょう。

XSSFWorkBook _xssFWorkBook = new();    // プロパティ
public void Close()
{
    _xssFWorkBook.Dispose();
}
0Like

Comments

  1. @Toshichan4

    Questioner

    ご回答ありがとうございます。
    XSSFWorkBook については認識がなかったので少しだけ調べてみたのですが、JAVAで EXCELファイルを操作する等の際に関係するものと認識しました。
    私が行いたいのは、C#から EXCELのアプリケーションそのものを開いて、EXCEL シートが見える状態でこれに対して種々の操作をすることですので、今回は方向性が違うのかなと考えています。お手数ありがとうございました。

Your answer might help someone💌