using System;
using System.Collections;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
class ExcelLateBind
{
private object oApp;
private object oBook;
private object oBooks;
private object oSheet;
private object oSheetCount;
private object oSheets;
private object oRange;
private object oLastCell;
private object oCells;
private object oCell;
private object oValue;
private object[] Params;
private string FilePath;
public string OpenFile { get; private set; }
public bool IsOpen { get; private set; }
public bool IsSelectSheet { get; private set; }
public int SheetCount { get; private set; }
public int OpenPageNo { get; private set; }
public int MaxCol { get; private set; }
public int MaxRow { get; private set; }
private bool MessageShow;
public string ErrorMessage { get; private set; }
//コンストラクタ
public ExcelFileControl(string ExcelFilePath, bool ShowMessageBox)
{
FilePath = ExcelFilePath;
IsOpen = false;
IsSelectSheet = false;
MessageShow = ShowMessageBox;
ErrorMessage = "";
Type oClassType;
oClassType = Type.GetTypeFromProgID("Excel.Application");
oApp = Activator.CreateInstance(oClassType);
oBooks = oApp.GetType().InvokeMember("Workbooks", BindingFlags.GetProperty, null, oApp, null);
}
//デストラクタ
~ExcelFileControl()
{
Release();
GC.Collect();
}
///
/// 指定されたファイルを開きます
///
///
public bool Open()
{
bool ret = false;
if (File.Exists(Path.GetDirectoryName(FilePath) + "\\~$" + Path.GetFileName(FilePath)))
{
MessageBox.Show("別プロセスでファイルを使用中のため開くことが出来ません。", "既にファイルが開かれています。", MessageBoxButtons.OK, MessageBoxIcon.Information);
Close(false);
return ret;
}
try
{
Params = new object[15];
Params[0] = FilePath;
for (int i = 1; i < Params.Length; i++)
Params[i] = Type.Missing;
ReleaseObject(oSheetCount);
ReleaseObject(oSheets);
ReleaseObject(oBook);
if (File.Exists(FilePath))
oBook = oBooks.GetType().InvokeMember("Open", BindingFlags.GetProperty, null, oBooks, Params);
else
oBook = oBooks.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, oBooks, null);
oSheets = oBook.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, oBook, null);
oSheetCount = oSheets.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, oSheets, null);
SheetCount = (int)oSheetCount;
OpenFile = FilePath;
ret = true;
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("ファイルを開くのに失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:FileOpen)",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
IsOpen = ret;
return ret;
}
///
/// 最後に1枚シートを追加して、追加したシートを選択します
///
///
public bool AddSheet()
{
bool ret = false;
if (!IsOpen)
{
ErrorMessage = "ファイルを開いてからシートの選択を実行してください。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"シート追加エラー (IsOpen = false)");
return ret;
}
try
{
ReleaseObject(oSheetCount);
ReleaseObject(oSheets);
oSheets = oBook.GetType().InvokeMember("Worksheets", BindingFlags.GetProperty, null, oBook, null);
oSheetCount = oSheets.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, oSheets, null);
SheetCount = (int)oSheetCount;
SelectSheet(SheetCount);
Params = new object[4];
Params[0] = Type.Missing;
Params[1] = oSheet;
Params[2] = 1;
Params[3] = Type.Missing;
ReleaseObject(oSheetCount);
oSheet = oSheets.GetType().InvokeMember("Add", BindingFlags.InvokeMethod, null, oSheets, Params);
oSheetCount = oSheets.GetType().InvokeMember("Count", BindingFlags.GetProperty, null, oSheets, null);
SheetCount = (int)oSheetCount;
IsSelectSheet = true;
OpenPageNo = SheetCount;
OpenFile = FilePath;
ret = true;
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("シートの追加に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:AddSheet)",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
IsOpen = ret;
return ret;
}
///
/// 最後に1枚シートを追加して、追加したシートを選択します
///
/// 追加するシートの名前を指定します
///
public bool AddSheet(string SheetName)
{
bool ret = false;
try
{
if (AddSheet())
{
Params = new object[1];
Params[0] = SheetName;
oSheet.GetType().InvokeMember("Name", BindingFlags.SetProperty, null, oSheet, Params);
ret = true;
}
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("シートの追加に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:AddSheet[string SheetName = \"" + SheetName + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
IsOpen = ret;
return ret;
}
///
/// エクセルのシートを選択します
///
/// シート名を指定
public void SelectSheet(string SheetName)
{
if (!IsOpen)
{
ErrorMessage = "ファイルを開いてからシートの選択を実行してください。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"シート選択エラー (IsOpen = false)");
return;
}
object Name;
int SheetNo = 0;
int lp = 0;
try
{
foreach (object sheet in (IEnumerable)oSheets)
{
lp++;
Name = sheet.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, sheet, null);
if (SheetName == Name.ToString())
{
SheetNo = lp;
break;
}
}
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("シートの選択に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:SelectSheet[string SheetName = \"" + SheetName + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
if (SheetNo == 0)
{
ErrorMessage = "指定されたシート名を見つけることが出来ませんでした。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"シート選択エラー (SheetNo = 0)");
return;
}
SelectSheet(SheetNo);
}
///
/// エクセルのシートを選択します
///
/// シート番号を指定
public void SelectSheet(int SheetNo)
{
if (!IsOpen)
{
ErrorMessage = "ファイルを開いてからシートの選択を実行してください。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"シート選択エラー (IsOpen = false)");
return;
}
try
{
Params = new object[1];
Params[0] = SheetNo;
OpenPageNo = SheetNo;
ReleaseObject(oLastCell);
ReleaseObject(oCells);
ReleaseObject(oSheet);
oSheet = oSheets.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, oSheets, Params);
oCells = oSheet.GetType().InvokeMember("Cells", BindingFlags.GetProperty, null, oSheet, null);
Params = new object[2];
Params[0] = 11;
Params[1] = Type.Missing;
oLastCell = oCells.GetType().InvokeMember("SpecialCells", BindingFlags.InvokeMethod, null, oCells, Params);
MaxCol = (int)oLastCell.GetType().InvokeMember("Column", BindingFlags.GetProperty, null, oLastCell, null);
MaxRow = (int)oLastCell.GetType().InvokeMember("Row", BindingFlags.GetProperty, null, oLastCell, null);
IsSelectSheet = true;
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("シートの選択に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:SelectSheet[int SheetNo = \"" + SheetNo.ToString() + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
}
///
/// セルの値を取得します
///
/// Cellを指定(例:B5)
///
public string GetValue(string Cell)
{
string ret = "";
int col = 0;
int row = 0;
CellStringToColAndRow(Cell, ref col, ref row);
ret = GetValue(col, row);
return ret;
}
///
/// セルの値を取得します
///
/// 列文字を指定
/// 行番号を指定
///
public string GetValue(string col, int row)
{
string ret = "";
ret = GetValue(ColStringToColNumber(col), row);
return ret;
}
///
/// セルの値を取得します
///
/// 列番号を指定
/// 行番号を指定
///
public string GetValue(int col, int row)
{
string ret = "";
if (!IsSelectSheet)
{
ErrorMessage = "シートの指定がされていません。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"値取得エラー (IsSelectSheet = false)");
return null;
}
try
{
Params = new object[2];
Params[0] = row;
Params[1] = col;
oCell = oCells.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, oCells, Params);
oValue = oCell.GetType().InvokeMember("Text", BindingFlags.GetProperty, null, oCell, null);
ReleaseObject(oValue);
ReleaseObject(oCell);
ret = oValue.ToString();
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("値の取得に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:GetValue[int col = \"" + col.ToString() + "\", int row = \"" + row.ToString() + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return null;
}
return ret;
}
//IsNumeric関数の代用
///
/// 数値として扱える文字列かどうかを判定します
///
/// 判断したい文字列
/// 数値として扱える場合:true
private bool IsNum(string strText)
{
double d;
if (double.TryParse(strText, System.Globalization.NumberStyles.Float, System.Globalization.NumberFormatInfo.CurrentInfo, out d) == true)
return true;
else
return false;
}
//列の文字列から列番号を判定する
private int ColStringToColNumber(string col)
{
int ret = 0;
for (int i = 0; i < col.Length; i++)
{
ret += Convert.ToInt32(Convert.ToChar(col.Substring(i, 1).ToUpper())) - 64;
if (i != 0)
ret += 26;
}
return ret;
}
//Cellの指定文字列を行と列に分割
private void CellStringToColAndRow(string Cell, ref int col, ref int row)
{
for (int i = 1; i <= Cell.Length; i++)
if (!IsNum(Cell.Substring(Cell.Length - i, 1)))
{
col = ColStringToColNumber(Cell.Substring(0, Cell.Length - i + 1));
row = int.Parse(Cell.Substring(Cell.Length - i + 1));
break;
}
}
///
/// セルに値をセットします
///
/// Cellを指定(例:B5)
/// セットしたい文字列を指定
public void SetValue(string Cell, string value)
{
if (!IsSelectSheet)
{
ErrorMessage = "シートの指定がされていません。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"値セットエラー (IsSelectSheet = false)");
return;
}
try
{
Params = new object[2];
Params[0] = Cell;
Params[1] = Missing.Value;
oRange = oSheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, oSheet, Params);
Params = new object[1];
Params[0] = value;
oRange.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, oRange, Params);
ReleaseObject(oRange);
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("値の設定に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:SetValue[Cell = \"" + Cell + "\", value = \"" + value + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
///
/// セルに値をセットします
///
/// 列文字を指定
/// 行番号を指定
/// セットしたい文字列を指定
public void SetValue(string col, int row, string value)
{
SetValue(col + row.ToString(), value);
}
///
/// セルに値をセットします
///
/// 列番号を指定
/// 行番号を指定
/// セットしたい文字列を指定
public void SetValue(int col, int row, string value)
{
SetValue(ColNumberToColString(col) + row, value);
}
//列の番号から列文字を判定する とりあえず文字列3桁まで対応
private string ColNumberToColString(int col)
{
string ret = "";
int iChar = 0;
int add = 0;
iChar = col / (int)Math.Pow(26, 2);
if (iChar != 0)
{
col -= iChar * (int)Math.Pow(26, 2);
ret += Convert.ToChar(iChar + 64).ToString();
iChar = 0;
add = 1;
}
iChar = col / 26;
if (iChar != 0 && col > 26)
{
if (col % 26 == 0)
iChar--;
col -= iChar * 26;
ret += Convert.ToChar(iChar + 64).ToString();
iChar = 0;
}
iChar = col;
ret += Convert.ToChar(iChar + 64 + add).ToString();
return ret;
}
///
/// 範囲を指定して、全体(中セルも含めて)に罫線を描きます
///
/// 開始セルを指定します
/// 終了セルを指定します
/// 線のスタイルを設定します(XlLineStyleクラスで定義されている値を使用できます)
/// 線の太さを設定します(XlLineWeightクラスで定義されている値を使用できます)
public void SetBorderLine(string StartCell, string EndCell, XlLineStyle LineStyle, XlLineWeight LineWeight)
{
if (!IsSelectSheet)
{
ErrorMessage = "シートの指定がされていません。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"罫線描画エラー (IsSelectSheet = false)");
return;
}
object oBorders = null;
object[] oLineStyle = new object[1];
object[] oLineWeight = new object[1];
ReleaseObject(oRange);
oLineStyle[0] = LineStyle;
oLineWeight[0] = LineWeight;
try
{
Params = new object[1];
Params[0] = StartCell + ":" + EndCell;
oRange = oSheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, oSheet, Params);
oBorders = oRange.GetType().InvokeMember("Borders", BindingFlags.GetProperty, null, oRange, null);
oBorders.GetType().InvokeMember("LineStyle", BindingFlags.SetProperty, null, oBorders, oLineStyle);
if (LineStyle != XlLineStyle.None && LineStyle != XlLineStyle.Double)
oBorders.GetType().InvokeMember("Weight", BindingFlags.SetProperty, null, oBorders, oLineWeight);
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("罫線の描画に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:SetBorderLine[StartCell = \"" + StartCell + "\", EndCell = \"" + EndCell + "\", LineStyle = \"" + LineStyle.ToString() + "\", LineWeight = \"" + LineWeight.ToString() + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
ReleaseObject(oBorders);
}
///
/// 範囲を指定して、全体(中セルも含めて)に罫線を描きます
///
/// 開始セルを指定します
/// 終了セルを指定します
/// セルのどの位置に罫線を描くかを設定します(XlDrawLineで定義されている値を使用できます)
/// 線のスタイルを設定します(XlLineStyleクラスで定義されている値を使用できます)
/// 線の太さを設定します(XlLineWeightクラスで定義されている値を使用できます)
public void SetBorderLine(string StartCell, string EndCell, XlDrawLine BorderLinePosition, XlLineStyle LineStyle, XlLineWeight LineWeight)
{
if (!IsSelectSheet)
{
ErrorMessage = "シートの指定がされていません。";
if (MessageShow)
MessageBox.Show(ErrorMessage,
"罫線描画エラー (IsSelectSheet = false)");
return;
}
object oBorders = null;
object oBorder = null;
object[] oLineStyle = new object[1];
object[] oLineWeight = new object[1];
object[] oBorderLinePos = new object[1];
ReleaseObject(oRange);
oLineStyle[0] = LineStyle;
oLineWeight[0] = LineWeight;
oBorderLinePos[0] = BorderLinePosition;
try
{
Params = new object[1];
Params[0] = StartCell + ":" + EndCell;
oRange = oSheet.GetType().InvokeMember("Range", BindingFlags.GetProperty, null, oSheet, Params);
oBorders = oRange.GetType().InvokeMember("Borders", BindingFlags.GetProperty, null, oRange, null);
oBorder = oBorders.GetType().InvokeMember("_Default", BindingFlags.GetProperty, null, oBorders, oBorderLinePos);
oBorder.GetType().InvokeMember("LineStyle", BindingFlags.SetProperty, null, oBorder, oLineStyle);
if (LineStyle != XlLineStyle.None && LineStyle != XlLineStyle.Double)
oBorder.GetType().InvokeMember("Weight", BindingFlags.SetProperty, null, oBorder, oLineWeight);
}
catch (Exception ex)
{
ErrorMessage = ex.ToString();
if (MessageShow)
MessageBox.Show("罫線の描画に失敗しました。" + Environment.NewLine
+ Environment.NewLine
+ "エラーの詳細は以下の通りです。" + Environment.NewLine
+ "エラー発生個所:" + ex.Source + Environment.NewLine
+ "エラー内容:" + ErrorMessage,
"例外エラー発生 (ExcelFileControl:SetBorderLine[StartCell = \"" + StartCell + "\", EndCell = \"" + EndCell + "\", BorderLinePosition = \"" + BorderLinePosition + "\" LineStyle = \"" + LineStyle.ToString() + "\", LineWeight = \"" + LineWeight.ToString() + "\"])",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
ReleaseObject(oBorder);
ReleaseObject(oBorders);
}
///
/// Excelファイルを閉じます
///
/// 保存するかどうかを設定します
public void Close(bool save)
{
Params = new object[1];
Params[0] = false;
oApp.GetType().InvokeMember("Visible", BindingFlags.SetProperty, null, oApp, Params);
oApp.GetType().InvokeMember("DisplayAlerts", BindingFlags.SetProperty, null, oApp, Params);
oApp.GetType().InvokeMember("UserControl", BindingFlags.SetProperty, null, oApp, Params);
Params = new object[2];
Params[0] = save;
Params[1] = FilePath;
oBook.GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, oBook, Params); //BookのClose
oBooks.GetType().InvokeMember("Close", BindingFlags.InvokeMethod, null, oBooks, null); //BooksのClose
oApp.GetType().InvokeMember("Quit", BindingFlags.InvokeMethod, null, oApp, null); //ApplicationのClose
IsSelectSheet = false;
IsOpen = false;
Release();
GC.Collect();
}
private void ReleaseObject(object o)
{
if (o != null)
if (Marshal.IsComObject(o))
{
Marshal.ReleaseComObject(o);
o = null;
}
}
private void Release()
{
ReleaseObject(oValue);
ReleaseObject(oCell);
ReleaseObject(oCells);
ReleaseObject(oLastCell);
ReleaseObject(oRange);
ReleaseObject(oSheet);
ReleaseObject(oSheetCount);
ReleaseObject(oSheets);
ReleaseObject(oBook);
ReleaseObject(oBooks);
ReleaseObject(oApp);
}
//罫線のStyle
public enum XlLineStyle : int
{
Normal = 1,
Dash = -4115,
DashDot = 4,
DashDashDot = 5,
Double = -4119,
None = -4142,
SlashDashDot = 13
}
//罫線の太さ
public enum XlLineWeight : int
{
Normal = 2,
Medium = -4138,
Thick = 4,
Thin = 1
}
//罫線の描画位置
public enum XlDrawLine : int
{
Tilt_UpperLeft = 5,
Tilt_UpperRight = 6,
Edge_Left = 7,
Edge_Top = 8,
Edge_Bottom = 9,
Edge_Right = 10,
Inside_Vertical = 11,
Inside_Horizon = 12
}
}