![【C#】Excelファイルを操作するコツ!](https://celebpanda.com/wp/wp-content/uploads/2021/05/AdobeStock_419893950-1-scaled.jpeg)
動物園で餌の人参を馬にあげようと思い、指を噛まれたてから、馬より人参を嫌いになったセレブパンダだお。
今日はC#からエクセルを利用する際のポイントを説明します。
API - application programming interface concept with person using a laptop computer
C#でエクセルを利用するライブラリーが用意されています。そのやり方でハマったので、シェアします。
・遅延バインディングと事前バインディングによる違い
遅延バインディングとは、動的にライブラリを呼び出すやり方です。
メリットは、エクセルのバージョンを気にしなくてよいことが挙げられます。
Excel2011のライブラリとExcel2013のライブラリは名前が違います。
当然、Excel2013しかインストールされていない場合、Excel2011のライブラリで作ったものは動きません。
サンプルはこんな感じ。
Type objectClassType = Type.GetTypeFromProgID("Excel.Application");
事前バインディングは、事前にライブラリを参照する方法です。
メリットは、型チェックなど事前に行えることです。
using Microsoft.Office.Interop.Excel;
Application app = new Application();
Workbook wkbook = _application.Workbooks.Open(@"c:\books1.xlsx");
C#からエクセルを遅延バインディングで出力して、エクセルを終了するコードを実装してもゾンビのようにエクセルが無くならいのです。
デバックで調べてみると、DisconnectedContext が検出されました。とエラーが発生していました。
変更前のソース
if (null != cellRange) Marshal.ReleaseComObject(cellRange);
if (null != sheet) Marshal.ReleaseComObject(sheet);
if (null != book) Marshal.ReleaseComObject(book);
if (null != excel) (Marshal.ReleaseComObject(excel);
この処理で、エクセルを閉じていたつもりが、実際には、エラーになっていました。
参考にしたサイトがこちら。
https://holiday-engineer.sakura.ne.jp/software/excel-error-disconnectedcontext1/
このサイトでは、各変数を(object)でキャストしろとありました。そこで変更したコードがこちら。
if (null != (object)cellRange) Marshal.ReleaseComObject((object)cellRange);
if (null != (object)sheet) Marshal.ReleaseComObject((object)sheet);
if (null != (object)book) Marshal.ReleaseComObject((object)book);
if (null != (object) excel) (Marshal.ReleaseComObject((object)excel);
確かに、エラーはなくなりました。
でも、エクセルはゾンビのまま!
結局、プロセスを直接消すという荒業で解決しました。
if (null != (object)cellRange) Marshal.ReleaseComObject((object)cellRange);
if (null != (object)sheet) Marshal.ReleaseComObject((object)sheet);
if (null != (object)book) Marshal.ReleaseComObject((object)book);
if (null != (object)excel)
{
while ( (Marshal.ReleaseComObject((object)excel) > 0) );
}
foreach (var p in Process.GetProcessesByName("EXCEL"))
{
if (p.MainWindowTitle == "")
{
p.Kill();
}
}
EXCELというプロセスでタイトルが空文字のものを消すというコードです。
これで解決しました。
ちなみに、事前バインディングは問題なくEXCELは消えます。
これも参考にしたサイトは以下です。
感謝です。
では、まただお。