// // Excel 関連の ツールクラス // using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using Microsoft.Office.Interop.Excel; using Microsoft.VisualBasic; using System.Diagnostics; using Excel = Microsoft.Office.Interop.Excel; using Mol; namespace Examples { /// /// 指定したエクセルファイルの(主に Workbook)オブジェクトを管理するためのクラスです。 /// 既に指定したエクセルファイルがオープンされていれば、その Workbook オブジェクトを使用します。 /// エクセルファイルがオープンされていなければ、新規にエクセルを起動してファイルをオープンします。 /// public class ExcelTool: IDisposable { [DllImport("ole32.dll")] static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); static Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046"); private Workbook m_book = null; private string m_xlsFilePath = null; /// /// ExcelToolクラスのコンストラクター。 /// エクセルファイルを記憶するだけで、エクセルの起動などは実行しません。 /// /// オープンするエクセルファイル public ExcelTool(string xlsFilePath) { m_xlsFilePath = Path.GetFullPath(xlsFilePath).ToLower(); } /// /// デストラクター /// ~ExcelTool() { Dispose(); } /// /// 標準の資源解法メソッド /// public void Dispose() { if (m_book != null) Marshal.ReleaseComObject(m_book); m_book = null; } /// /// (コンストラクターで)指定したエクセルファイルの Book オブジェクト。 /// 指定したエクセルファイル(Book オブジェクト)をオープンしているエクセルが起動していない場合は /// 新規にエクセルを起動してから、エクセルファイルをオープンします。 /// public Excel.Workbook Book { get { try { if (m_book.FullName.ToLower() == m_xlsFilePath) return m_book; } catch (Exception) { } if (m_book != null) Marshal.ReleaseComObject(m_book); m_book = GetWorkbook(m_xlsFilePath); return m_book; } } /// /// オープンしているエクセルファイルのフルパス /// public string BookPath { get { return m_book.FullName; } } /// /// ベクトルの内容をシートの指定した位置(上:rng)に書き込みます。 /// /// 書き込むベクトル /// ベクトルの値を書き込む位置を示すレンジオブジェクト /// ベクトル要素の並びが横の場合 true public void SaveVector(VectorDenseDouble V, Excel.Range rng, bool horizontal) { int n = V.Count; int ix = V.LBound; for (int i = 1; i <= n; ++i) { if (horizontal) rng.Cells[1, i] = V[ix]; else rng.Cells[i, 1] = V[ix]; ix++; } } /// /// ベクトルの内容をシートの指定した位置(上:rng)から読み込みます。 /// /// 読み込むベクトル /// ベクトルの値を読み込む位置を示すレンジオブジェクト /// ベクトル要素の並びが横の場合 true public void LoadVector(VectorDenseDouble V, Excel.Range rng, bool horizontal) { int n = V.Count; int ix = V.LBound; for (int i = 1; i <= n; ++i) { if (horizontal) V[i] = rng.Cells[1, ix].Value; else V[i] = rng.Cells[ix, 1].Value; ix++; } } /// /// 行列の内容をシートの指定した位置(上:rng)に書き込みます。 /// /// 書き込む行列 /// 行列の値を書き込む位置を示すレンジオブジェクト public void SaveMatrix(_MatrixDouble M, Excel.Range rng) { int m = M.RowCount; int n = M.ColumnCount; int ix = M.LBound; for (int i = 1; i <= m; ++i) { int jx = M.LBound; for (int j = 1; j <= n; ++j) { rng.Cells[i, j] = M[ix, jx++]; } ix++; } } /// /// 行列の内容をシートの指定した位置(上:rng)から読み込みます。 /// /// 読み込む行列 /// 行列の値を読み込む位置を示すレンジオブジェクト public void LoadMatrix(_MatrixDouble M, Excel.Range rng) { int m = M.RowCount; int n = M.ColumnCount; int ix = M.LBound; for (int i = 1; i <= m; ++i) { int jx = M.LBound; for (int j = 1; j <= n; ++j) { M[ix, jx++] = rng.Cells[i, j].Value; } ix++; } } /// /// 指定したエクセルファイルの Workbook オブジェクトを返します。 /// 既に xlsFilePath がエクセルでオープンされていれば、それを返します。 /// そうでなければエクセルを起動してから指定したファイルをオープンします。 /// /// エクセルファイルのパス /// Workbook オブジェクト public static Workbook GetWorkbook(string xlsFilePath) { Workbook book = null; string lPath = Path.GetFullPath(xlsFilePath).ToLower(); List wbs = GetOpenedWorkbooks(); foreach (Workbook wb in wbs) { if (wb.FullName.ToLower() == lPath) { book = wb; } else { Marshal.ReleaseComObject(wb); } } if (book != null) return book; // Workbook はオープンされていないので新規に Excel を起動してオープンする。 Excel.Application excel = new Excel.Application(); // Excelオブジェクト excel.Visible = true; // Excelファイルをオープンする book = (Excel.Workbook)(excel.Workbooks.Open ( xlsFilePath, // オープンするExcelファイル Type.Missing, // (省略可能)UpdateLinks (0 / 1 / 2 / 3) Type.Missing, // (省略可能)ReadOnly (True / False ) Type.Missing, // (省略可能)Format // 1:タブ / 2:カンマ (,) / 3:スペース / 4:セミコロン (;) // 5:なし / 6:引数 Delimiterで指定された文字 Type.Missing, // (省略可能)Password Type.Missing, // (省略可能)WriteResPassword Type.Missing, // (省略可能)IgnoreReadOnlyRecommended Type.Missing, // (省略可能)Origin Type.Missing, // (省略可能)Delimiter Type.Missing, // (省略可能)Editable Type.Missing, // (省略可能)Notify Type.Missing, // (省略可能)Converter Type.Missing, // (省略可能)AddToMru Type.Missing, // (省略可能)Local Type.Missing // (省略可能)CorruptLoad )); return book; } /// /// 実行中のエクセル(複数)がオープンしている全ての Book オブジェクトのリストを返します。 /// /// /// オープンされている全 Book オブジェクトのリスト。 /// 最終的に各要素の Book オブジェクトは Marshal.ReleaseComObject(book) と明示的に解放されるべき。 /// public static List GetOpenedWorkbooks() { List arr = new List(); IBindCtx pBindCtx = null; IRunningObjectTable pROT = null; IEnumMoniker pEnumMoniker = null; IMoniker[] pMonikers = { null }; IntPtr fetched = IntPtr.Zero; CreateBindCtx(0, out pBindCtx); pBindCtx.GetRunningObjectTable(out pROT); pROT.EnumRunning(out pEnumMoniker); pEnumMoniker.Reset(); while (pEnumMoniker.Next(1, pMonikers, fetched)==0) { object obj = null; Workbook pBook = null; try { pMonikers[0].BindToObject(pBindCtx, null, ref IID_IUnknown, out obj); pBook = obj as Workbook; if (pBook != null) arr.Add(pBook); } catch (Exception) {} finally { Marshal.ReleaseComObject(pMonikers[0]); } } Marshal.ReleaseComObject(pEnumMoniker); Marshal.ReleaseComObject(pROT); Marshal.ReleaseComObject(pBindCtx); return arr; } } }