//
// 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;
}
}
}