粗茶でございます日本語 プログラミング 言語 「なでしこ」 大好き 

この記事に含まれるtag :
なでしこ2.0  プラグイン  C#  Excel  

スポンサーサイト

   ↑  --/--/-- (--)  カテゴリー: スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

(記事編集) http://nadesocha.blog.fc2.com/?overture" target="_new

--/--/-- | Comment (-) | ホーム | ↑ ページ先頭へ ↑ |

C#とエクセル

   ↑  2010/10/31 (日)  カテゴリー: C#

プラグインでエクセル起動


 プラグインからエクセルを操作してみました。

 通常、C#からエクセルを操作するには、COMオブジェクトを利用するわけですが、COMオブジェクトはアンマネージドであり、アプリケーションの終了時に参照カウントを解放(メモリ解放)しなければ、プロセスに残ってしまうという問題があります。

 C#とCOM連携についてインターネットで検索すると、皆さんこの参照カウントの解放に苦労されています。しかしながら、Visual Studio 2010になり、フレームワークが.NET Framework 4になったことにより、どうやら自動的にメモリ解放されるようで、開発時にCOMオブジェクトの参照カウントを意識しなくても良いらしいです。(本当のところはわかりませんので、詳しい方は教えて下さい)

COMオブジェクトの実例


 Visual C# 2010 Expressにおいて、対象のフレームワークを「.NET Framework 4」に設定し、次のプロジェクトをビルドして実行します。デバッグのままだと、参照カウントが残ってしまいますので注意です。

プロジェクト名:NakoPluginSocha3
参 照 設 定:Libnako、Microsoft.CSharp、Microsoft.Office.Interop.Excel、System、System.Windows.Forms
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using NakoPlugin;
using Excel = Microsoft.Office.Interop.Excel;
//using System.Runtime.InteropServices;

namespace NakoPluginSocha3
{
public class NakoPluginSocha3 : INakoPlugin
{
//--- プラグインの宣言 ---
string _description = "エクセル操作テスト by 粗茶";
double _version = 1.0;
//--- プラグイン共通の部分 ---
public double TargetNakoVersion { get { return 2.0; } }
public bool Used { get; set; }
public string Name { get { return this.GetType().FullName; } }
public double PluginVersion { get { return _version; } }
public string Description { get { return _description; } }
//--- 関数の定義 ---
public void DefineFunction(INakoPluginBank bank)
{
bank.AddFunc("エクセル処理", "", NakoVarType.Void, _xl, "エクセルを開いてセルの値を取得する", "えくせるしょり");
}
// プラグインの初期化処理
public void PluginInit(INakoInterpreter runner)
{
}
// プラグインの終了処理
public void PluginFin(INakoInterpreter runner)
{
}
// Define Method
public Object _xl(INakoFuncCallInfo info)
{
dynamic xlApp = new Excel.Application { Visible = true };
var xlBooks = xlApp.Workbooks;
var xlBook = xlBooks.Open(@"Sample.xlsx"); //ファイルをフルパスで指定
var xlSheets = xlBook.Worksheets;
var xlSheet = xlSheets[1];
var xlCells = xlSheet.Cells;
var xlRange = xlCells[1, 1];

var a1val = xlRange.Value2;

//--- COMオブジェクト解放 ---
//Marshal.ReleaseComObject(xlRange);
//Marshal.ReleaseComObject(xlCells);
//Marshal.ReleaseComObject(xlSheet);
//Marshal.ReleaseComObject(xlSheets);

xlBook.Close(false);

//--- COMオブジェクト解放 ---
//Marshal.ReleaseComObject(xlBook);
//Marshal.ReleaseComObject(xlBooks);

xlApp.Quit();

//--- COMオブジェクト解放 ---
//Marshal.ReleaseComObject(xlApp);

MessageBox.Show(a1val.ToString());

return null;
}
}
}

なでしこプログラム


エクセル処理。

 実行すると、エクセルを起動し、指定したブックを開いて、最初のシートにあるA1セルの値を取得します。

 実行後は、DemoCNako2のProgram.csにより、コンソールが開いたままとなります。この時点ではまだ、プロセスにEXCEL.EXEが残っています。

 Enterキーを押してコンソールを終了します。この時点で、プロセスにEXCEL.EXEが残っていないことが確認できました。

COM解放を検証してみる


 さて、上記の動作を検証してみます。

COMオブジェクトの手動解放


 COMオブジェクトを手動で解放するには、上記プログラムのコメントアウトした部分を実行します。
using System.Runtime.InteropServices;

と、
            //--- COMオブジェクト解放 ---
Marshal.ReleaseComObject(xlRange);
Marshal.ReleaseComObject(xlCells);
Marshal.ReleaseComObject(xlSheet);
Marshal.ReleaseComObject(xlSheets);
//--- COMオブジェクト解放 ---
Marshal.ReleaseComObject(xlBook);
Marshal.ReleaseComObject(xlBooks);
//--- COMオブジェクト解放 ---
Marshal.ReleaseComObject(xlApp);

の部分です。
 本当は、自動解放に任せずに、自分で解放したほうが確実です。

プログラム実行中のエラー


 プログラム実行中にエラーが発生したら、エクセルがプロセスに残ってしまいます。

プログラム終了の処理


 アプリケーションの終了が、プログラムによるものであれば、COMオブジェクトは自動的に解放されますが、ユーザーによるものであれば、プロセスに残ります。
 上記のプログラムの場合、実行終了時にコンソール画面が表示されたままになります。これは、DemoCNako2.ProgramクラスのMain関数の最後に、
            Console.ReadLine();

があるためです。これはユーザーの入力を待っている状態です。
 ここで、Enterキーを押せば、プログラムは次の処理へ移り、アプリケーションはプログラムにより終了されます。すると、COMオブジェクトは自動的に解放され、EXCEL.EXEはプロセスに残りません。
 ところが、コンソール画面を右上の「×」で閉じた場合、Main関数の途中でアプリケーションが中断された形となり、COMオブジェクトは解放されず、EXCEL.EXEがプロセスに残ったままになります。

 これらの問題を解消するため、アプリケーションが、エラー発生やユーザーによる終了となっても、正しくCOMオブジェクトを解放するようにプログラミングしなければなりません。

 COMオブジェクト・・・なかなか手強い相手です。
 私のスキルではここまでが精一杯でした。
 勇者の皆様、あとはよろしくお願いします。
関連記事

この記事に含まれるtag : なでしこ2.0 プラグイン C# Excel 

FC2スレッドテーマ : プログラミング (ジャンル : コンピュータ

(記事編集) http://nadesocha.blog.fc2.com/blog-entry-138.html

2010/10/31 | Comment (0) | Trackback (0) | ホーム | ↑ ページ先頭へ ↑ |

Comment

コメント:を投稿する 記事: C#とエクセル

お気軽にコメント:をぞうぞ。
非公開 (管理人のみ閲覧可能なコメント:) にしたい場合には、ロック にチェックを入れてください。

  任意 : 後から修正や削除ができます。
  非公開コメント:として投稿する。(管理人にのみ公開)

Trackback

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。