前回の続き、画像データを取り込む部分はC#でプログラムしているので、
C#からExcelの関数を呼び出してR2を取得する、というのが、今回のお題。
大きく、下記2つの手法が有るようです。
Excel Object Library を使用する方法
"ClosedXML"を使う方法
2.の方が扱いやすそうなのですが、C#の開発環境がVisualStudio2005と旧く(泣)、
ClosedXMLは未対応だったので、1.の方法で対応することにしました。
この場合ローカルにインストールされたExcelを使用するため、
異なるExcelバージョンの環境だと動きませんので要注意!
まず前準備として、C#のプロジェクトでExcelの参照設定が必要ですが、
”c# excel 操作”等で検索すると、判りやすい説明が色々出てきます、
そちらを参照して下さい。(以下、その辺の内容は割愛しています)
Excelの関数を呼び出すには?
これも検索して下記の記事を発見しました、ずばりそのものビンゴ!
http://memo-memo-and-memo.asablo.jp/blog/2013/02/15/6721444
後半部分で、CoefficientsClassというクラスが有るので流用しました、
更にExcelアプリケーションの後始末の処理を追加したものが下記。
static public class CoefficientsClass { static Excel.Application oXL = new Excel.Application(); //Excelアプリ本体 static Excel.WorksheetFunction funk = oXL.WorksheetFunction; //Excelの関数 public static Array GetCoefficients(Array y, Array x, bool a, bool b) { System.Object coefficients = funk.LinEst(y, x, a, b); //LINEST関数 Array coeffArray = (Array)coefficients; return coeffArray; } public static void CloseExcelApp() { oXL.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL); oXL = null; } }
oXLでExcelのアプリケーションを定義すると、oXL.WorksheetFunctionで、
Excelの任意の関数を呼び出せるようです、今回はLINEST関数を使いたいので、
GetCoefficients(Array y, Array x, bool a, bool b)内で、funk.LinEstを定義。
Excel同様に各パラメータを渡すと、計算結果(配列)がcoeffArrayに戻って来ます。
その都度Excelが起動することも無く、関数だけ呼べるので便利だったのですが、
タスクマネージャーにExcelのアプリが残ってしまう場合が有り、気になったので、
Excelを終了する処理を追加したのが、CloseExcelApp()の部分です。
簡単なソフトで試してみます、button1を押すと前回の簡単なサンプルデータ5個を
GetCoefficientsに渡して計算し、label1にR2の値を表示するもの。
button1を押した時の処理です。
private void button1_Click(object sender, EventArgs e) { label1.Text = ""; int[,] X = new int[2, 5]; //X軸データ X[0, 0] = 1; //X X[0, 1] = 2; X[0, 2] = 3; X[0, 3] = 4; X[0, 4] = 5; X[1, 0] = 1; //Xの二乗 X[1, 1] = 4; X[1, 2] = 9; X[1, 3] = 16; X[1, 4] = 25; int[] Y = new int[] { 11, 19, 30, 41, 48 }; //Y軸データ Array coeffArray = CoefficientsClass.GetCoefficients(Y, X, true, true); double R2 = (double)coeffArray.GetValue(3, 1); //R2の値を取り出す label1.Text = R2.ToString("F4"); CoefficientsClass.CloseExcelApp(); //Excel終了処理 }
Xは二次元配列で、X軸の値と二乗した値を入れます、YはY軸のデータをそのまま、
CoefficientsClass.GetCoefficients(Y, X, true, true); で、LINEST関数を実行します。
戻ってきたcoeffArrayから、R2をcoeffArray.GetValue(3, 1)で取り出し、
labelに表示させます、最後にCoefficientsClass.CloseExcelApp()で終了処理。
button1を押した後の画面がこちら、無事にR2を取得することが出来ました!
当然、最初にExcelのグラフで表示させた結果とも合致しています。
これにて一件落着、めでたしめでたし。