using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

using Excel = Microsoft.Office.Interop.Excel;

namespace CommonMP.HYMCO.OptionImpl.McStructureXmlFileEditorForDevelop
{
    /// <summary><para>class outline:</para>
    /// <para>Excel操作クラス</para>
    /// <para>
    ///       -参照COM- Microsoft Excel 11.0 Object Library (Excel2003)
    /// </para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2010/11/01][新規作成]</para>
    /// </remarks>
    public class ExcelController
    {
        /// <summary> Excel2003での1シートの最大行（2007は 1048,576） </summary>
        public static readonly int EXCEL_SHEET_MAX_ROW = 65536;

        /// <summary> シート名に使えない文字列「[]:\/?*：￥／？＊」※「\￥[]」は直接取り除く </summary>
        private System.Text.RegularExpressions.Regex m_regexRemoveChara
            = new System.Text.RegularExpressions.Regex(Properties.McStructureXmlFileEditorResources.REGEXP_REMOVE);

        /// <summary> Excel Application </summary>
        public Excel.Application xlApp = null;
        /// <summary> Excel Workbooks </summary>
        public Excel.Workbooks xlBooks = null;
        /// <summary> Excel Workbook </summary>
        public Excel._Workbook xlBook = null;
        /// <summary> Excel Sheets </summary>
        public Excel.Sheets xlSheets = null;
        /// <summary> Excel Worksheet </summary>
        public Excel._Worksheet xlSheet = null;


        /// <summary><para>method outline:</para>
        /// <para>セル名取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>string sCell = GetCellName(iRow, iCol);</para>
        /// </example>
        /// <param name="iRow">行</param>
        /// <param name="iCol">列</param>
        /// <returns>セル名(ex.A1)</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public string GetCellName(int iRow, int iCol)
        {
            string sRow = iRow.ToString();
            if (iRow == 0)
                sRow = "";

            string sCell = "";
            NumToColName(iCol, ref sCell);
            sCell += sRow;

            return sCell;
        }

        /// <summary><para>method outline:</para>
        /// <para>列番号を列名に変換する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>NumToAlpha(iNum, sCell);</para>
        /// </example>
        /// <param name="iNum">変換される番号</param>
        /// <param name="sCell">変換後の列名</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        private void NumToColName(int iNum, ref string sCell)
        {
            string sCellNm = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

            int iQuotient = 0;  // 商
            int iRemainder = 0; // 剰余
            iQuotient = Math.DivRem(iNum - 1, 26, out iRemainder);

            string sNum = "";
            if (iNum != 0)
            {
                sNum = sCellNm.Substring(iRemainder, 1);
            }

            sCell = sNum + sCell;

            if (iQuotient > 0)
            {
                NumToColName(iQuotient, ref sCell);
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>シートを切り替える</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSheet(sSheetName);</para>
        /// </example>
        /// <param name="sSheetName">シート名</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSheet(string sSheetName)
        {
            if (xlSheet != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet);
                xlSheet = null;
            }

            xlSheet = (Excel._Worksheet)xlSheets[sSheetName];
        }
        /// <summary><para>method outline:</para>
        /// <para>シートを切り替える</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSheet(iSheetNo);</para>
        /// </example>
        /// <param name="iSheetNo">シートNo</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSheet(int iSheetNo)
        {
            if (xlSheet != null)
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet);
                xlSheet = null;
            }

            xlSheet = (Excel._Worksheet)xlSheets[iSheetNo];
        }

        /// <summary><para>method outline:</para>
        /// <para>シートをコピーする</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>CopySheet(iCopyCount);</para>
        /// </example>
        /// <param name="iCopyCount">コピー数</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void CopySheet(int iCopyCount)
        {
            for (int iCnt = 0; iCnt < iCopyCount; iCnt++)
            {
                xlSheet.Copy(xlSheet, Type.Missing);
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>シートを削除</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>DeleteSheet(iSheetNo);</para>
        /// </example>
        /// <param name="iSheetNo">シートNo</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void DeleteSheet(int iSheetNo)
        {
            SetSheet(iSheetNo);
            xlSheet.Delete();
        }
        /// <summary><para>method outline:</para>
        /// <para>シートを削除</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>DeleteSheet(sSheetName);</para>
        /// </example>
        /// <param name="sSheetName">シート名</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void DeleteSheet(string sSheetName)
        {
            SetSheet(sSheetName);
            xlSheet.Delete();
        }

        /// <summary><para>method outline:</para>
        /// <para>シート名をセット</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetSheetName(sName)</para>
        /// </example>
        /// <param name="sName">セットするシート名</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetSheetName(string sName)
        {
            //シート名に使えない文字を取り除く
            string sSheetName = m_regexRemoveChara.Replace(sName, "").Replace(@"\", "").Replace(@"￥", "");
            sSheetName = sSheetName.Replace("[", "(").Replace("]", ")");
            //30文字までにする
            if (sSheetName.Length > 30)
                sSheetName = sSheetName.Substring(0, 30);

            xlSheet.Name = sSheetName;
        }

        /// <summary><para>method outline:</para>
        /// <para>セル範囲の値を取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>object[,] oData = GetRange(sCell, sCell2);</para>
        /// </example>
        /// <param name="sCell">開始セル(ex.A1)</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <returns>値(2次元配列 ※LowerBound=1で格納)</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public object[,] GetRange(string sCell, string sCell2)
        {
            object[,] val = null;
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.get_Range(sCell, sCell2);
                val = (object[,])range.get_Value(Type.Missing);
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
            return val;
        }
        /// <summary><para>method outline:</para>
        /// <para>セル範囲の値を取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>object[,] oData = GetRange(iRow, iCol, iRowCount, iColCount);</para>
        /// </example>
        /// <param name="iRow">開始行</param>
        /// <param name="iCol">開始列</param>
        /// <param name="iRowCount">行数</param>
        /// <param name="iColCount">列数</param>
        /// <returns>値(2次元配列 ※LowerBound=1で格納)</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public object[,] GetRange(int iRow, int iCol, int iRowCount, int iColCount)
        {
            string sCell = GetCellName(iRow, iCol);
            string sCell2 = GetCellName(iRow + iRowCount - 1, iCol + iColCount - 1);
            return GetRange(sCell, sCell2);
        }
        /// <summary><para>method outline:</para>
        /// <para>セルの値を取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>object oValue = GetCell(iRow, iCol);</para>
        /// </example>
        /// <param name="iRow">行</param>
        /// <param name="iCol">列</param>
        /// <returns>セルの値</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public object GetCell(int iRow, int iCol)
        {
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.Cells[iRow, iCol];
                return range.Value2;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>セルに値をセット</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCell(iRow, iCol, val);</para>
        /// </example>
        /// <param name="iRow">行</param>
        /// <param name="iCol">列</param>
        /// <param name="val">セットする値</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetCell(int iRow, int iCol, object val)
        {
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.Cells[iRow, iCol];
                range.Value2 = val;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>セルに値をセット</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCell(sCell, sCell2, val);</para>
        /// </example>
        /// <param name="sCell">開始セル(ex.A1)</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <param name="val">貼り付けデータ配列</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetCell(string sCell, string sCell2, object[,] val)
        {
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.get_Range(sCell, sCell2);
                range.Value2 = val;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>セルに値をセット</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCell(iRow, iCol, val);</para>
        /// </example>
        /// <param name="iRow">開始行</param>
        /// <param name="iCol">開始列</param>
        /// <param name="val">貼り付けデータ配列</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetCell(int iRow, int iCol, object[,] val)
        {
            string sCell = GetCellName(iRow, iCol);
            string sCell2 = GetCellName(iRow + val.GetUpperBound(0), iCol + val.GetUpperBound(1));
            SetCell(sCell, sCell2, val);
        }

        /// <summary><para>method outline:</para>
        /// <para>セルを選択状態に</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetCellActive(iRow, iCol);</para>
        /// </example>
        /// <param name="iRow">行</param>
        /// <param name="iCol">列</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetCellActive(int iRow, int iCol)
        {
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.Cells[iRow, iCol];
                xlSheet.Activate();
                range.Activate();
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>フォント設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetFont(sCell1, sCell2, iFontSize, bFontItalic);</para>
        /// </example>
        /// <param name="sCell1">開始セル(ex.A1)※未指定の場合はシート全体</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <param name="iFontSize">フォントサイズ</param>
        /// <param name="bFontItalic">true=斜体にする/false=斜体にしない</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetFont(string sCell1, string sCell2, int iFontSize, bool bFontItalic)
        {
            Excel.Range range = null;
            try
            {
                if (string.IsNullOrEmpty(sCell1))
                {   //シート全体のフォント設定
                    range = xlSheet.Cells;
                }
                else
                {
                    range = (Excel.Range)xlSheet.get_Range(sCell1, sCell2);
                }
                range.Font.Size = iFontSize;
                range.Font.Italic = bFontItalic;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>行高さ設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetRowHeight(iStartRow, iEndRow, iHeight);</para>
        /// </example>
        /// <param name="iStartRow">開始行</param>
        /// <param name="iEndRow">終了行</param>
        /// <param name="iHeight">高さ</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetRowHeight(int iStartRow, int iEndRow, int iHeight)
        {
            Excel.Range rows = null;
            Excel.Range range = null;
            try
            {
                rows = (Excel.Range)xlSheet.Rows;
                range = (Excel.Range)rows[string.Format("{0}:{1}", iStartRow, iEndRow), Type.Missing];
                range.RowHeight = iHeight;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                if (rows != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(rows);
                range = null;
                rows = null;
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>列幅設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetColWidth(sCol1, sCol2, iWidth)</para>
        /// </example>
        /// <param name="sCol1">開始列(ex.A)</param>
        /// <param name="sCol2">終了列(ex.A)</param>
        /// <param name="iWidth">幅</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetColWidth(string sCol1, string sCol2, int iWidth)
        {
            Excel.Range cols = null;
            Excel.Range range = null;
            try
            {
                cols = (Excel.Range)xlSheet.Columns;
                range = (Excel.Range)cols[string.Format("{0}:{1}", sCol1, sCol2), Type.Missing];
                range.ColumnWidth = iWidth;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                if (cols != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(cols);
                range = null;
                cols = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>指定範囲を枠線で囲む</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetRangeBorders(sCell1, sCell2);</para>
        /// </example>
        /// <param name="sCell1">開始セル(ex.A1)</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetRangeBorders(string sCell1, string sCell2)
        {
            SetRangeBorders(sCell1, sCell2, -1, true, true);
        }

        /// <summary><para>method outline:</para>
        /// <para>指定範囲を枠線で囲み背景色をセット</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetRangeBorders(sCell1, sCell2, iColorIndex, bInsideVertical, bInsideHorizontal);</para>
        /// </example>
        /// <param name="sCell1">開始セル(ex.A1)</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <param name="iColorIndex">色（ex.1=黒,34=水色,35=黄緑,36=黄色,38=ピンク,40=橙, -1=なし）</param>
        /// <param name="bInsideVertical">内側の縦線を引くか</param>
        /// <param name="bInsideHorizontal">内側の横線を引くか</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetRangeBorders(string sCell1, string sCell2, int iColorIndex, bool bInsideVertical, bool bInsideHorizontal)
        {
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.get_Range(sCell1, sCell2);
                range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeLeft].LineStyle = Excel.XlLineStyle.xlContinuous;
                range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeTop].LineStyle = Excel.XlLineStyle.xlContinuous;
                range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeBottom].LineStyle = Excel.XlLineStyle.xlContinuous;
                range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlEdgeRight].LineStyle = Excel.XlLineStyle.xlContinuous;

                if (bInsideVertical && range.Columns.Count > 1)
                    range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideVertical].LineStyle = Excel.XlLineStyle.xlContinuous;
                if (bInsideHorizontal && range.Rows.Count > 1)
                    range.Borders[Microsoft.Office.Interop.Excel.XlBordersIndex.xlInsideHorizontal].LineStyle = Excel.XlLineStyle.xlContinuous;
                
                if(iColorIndex < 0)
                    range.Interior.ColorIndex = Microsoft.Office.Interop.Excel.XlColorIndex.xlColorIndexNone;
                else
                    range.Interior.ColorIndex = iColorIndex;
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>入力規則・リスト設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SetValidationList(sCell1, sCell2, sList);</para>
        /// </example>
        /// <param name="sCell1">開始セル(ex.A1)</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <param name="sList">リスト</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SetValidationList(string sCell1, string sCell2, string sList)
        {
            Excel.Range range = null;
            try
            {
                range = (Excel.Range)xlSheet.get_Range(sCell1, sCell2);
                range.Validation.Delete();

                if (!string.IsNullOrEmpty(sList))
                {
                    range.Validation.Add(Microsoft.Office.Interop.Excel.XlDVType.xlValidateList,
                                        Excel.XlDVAlertStyle.xlValidAlertStop, 
                                        Excel.XlFormatConditionOperator.xlEqual, 
                                        sList, Type.Missing);
                }
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                range = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>セルをコピー</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>CopyCell(sCell1, sCell2, sPasteCell);</para>
        /// </example>
        /// <param name="sCell1">開始セル(ex.A1)</param>
        /// <param name="sCell2">終了セル(ex.B2)</param>
        /// <param name="sPasteCell">貼り付け先</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void CopyCell(string sCell1, string sCell2, string sPasteCell)
        {
            Excel.Range range = null;
            Excel.Range range1 = null;
            try
            {
                range = (Excel.Range)xlSheet.get_Range(sCell1, sCell2);
                range1 = (Excel.Range)xlSheet.get_Range(sPasteCell, sPasteCell);
                range.Copy(Type.Missing);
                range1.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteAll, 
                                    Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, 
                                    Type.Missing, Type.Missing);
            }
            finally
            {
                if (range != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range);
                if (range1 != null)
                    System.Runtime.InteropServices.Marshal.ReleaseComObject(range1);
                range = null;
                range1 = null;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>マクロ実行</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>MacroRun(sMacro, sArg);</para>
        /// </example>
        /// <param name="sMacro">マクロ</param>
        /// <param name="sArg">マクロの引数</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void MacroRun(string sMacro, params object[] sArg)
        {
            object[] oArg = new object[]{Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
                                         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                         Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing};
            for (int i = 0; i < sArg.Length; i++)
            {
                oArg[i] = sArg[i];
            }

            xlApp.Run(sMacro, oArg[0], oArg[1], oArg[2], oArg[3], oArg[4], oArg[5], oArg[6], oArg[7], oArg[8], oArg[9],
                        oArg[10], oArg[11], oArg[12], oArg[13], oArg[14], oArg[15], oArg[16], oArg[17], oArg[18], oArg[19],
                        oArg[20], oArg[21], oArg[22], oArg[23], oArg[24], oArg[25], oArg[26], oArg[27], oArg[28], oArg[29]);
        }

        /// <summary><para>method outline:</para>
        /// <para>シート保護設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SheetProtect(sSheetName, sPassword, isRowChange, isColChange);</para>
        /// </example>
        /// <param name="sSheetName">シート名</param>
        /// <param name="sPassword">パスワード</param>
        /// <param name="isRowChange">true=行挿入・削除可</param>
        /// <param name="isColChange">true=列挿入・削除可</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SheetProtect(string sSheetName, string sPassword, bool isRowChange, bool isColChange)
        {
            SetSheet(sSheetName);
            xlSheet.Protect(sPassword,
                            Type.Missing, Type.Missing, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing,
                            isColChange, isRowChange, Type.Missing,
                            isColChange, isRowChange, true, true, Type.Missing);
        }

        /// <summary><para>method outline:</para>
        /// <para>ブック保護設定</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>BookProtect(sPassword);</para>
        /// </example>
        /// <param name="sPassword">パスワード</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void BookProtect(string sPassword)
        {
            xlBook.Protect(sPassword, Type.Missing, Type.Missing);
        }

        /// <summary><para>method outline:</para>
        /// <para>テンプレートファイルオープン</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>OpenBook(sFilePath);</para>
        /// </example>
        /// <param name="sFilePath">テンプレートファイル名パス</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void OpenBook(string sFilePath)
        {
            //Excelｲﾝｽﾀﾝｽ作成
            xlApp = new Excel.Application();
            //非表示に設定
            xlApp.Visible = false;
            //ﾒｯｾｰｼﾞ表示なしに設定
            xlApp.DisplayAlerts = false;

            xlBooks = xlApp.Workbooks;

            if (!string.IsNullOrEmpty(sFilePath))
            {
                //Excelﾃﾝﾌﾟﾚｰﾄﾌｧｲﾙｵｰﾌﾟﾝ
                xlBook = xlBooks.Open(sFilePath, Type.Missing, true,
                                        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                        Type.Missing, Type.Missing, Type.Missing, Type.Missing,
                                        Type.Missing, Type.Missing, Type.Missing, Type.Missing);      //ReadOnlyで開く
            }
            else
            {   //新規ブック作成
                xlBooks.Add(Type.Missing);
                xlBook = xlBooks[1];
            }

            xlSheets = xlBook.Worksheets;

            //ﾒｯｾｰｼﾞ表示なしに設定
            xlApp.DisplayAlerts = false;

            if (string.IsNullOrEmpty(sFilePath))
            {   //新規ブックの場合、1シートを残して削除
                for (int iSheet = xlSheets.Count; iSheet > 1; iSheet--)
                {
                    DeleteSheet(iSheet);
                }
            }
        }
        /// <summary><para>method outline:</para>
        /// <para>新規ブック作成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>OpenBook();</para>
        /// </example>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void OpenBook()
        {
            OpenBook(null);
        }

        /// <summary><para>method outline:</para>
        /// <para>ファイル保存</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SaveBook(sOutFilePath, bClose);</para>
        /// </example>
        /// <param name="sOutFilePath">出力ファイル名パス</param>
        /// <param name="bClose">true=閉じる</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SaveBook(string sOutFilePath, bool bClose)
        {
            //保存
            xlBook.SaveAs(sOutFilePath, Type.Missing, Type.Missing, Type.Missing,
                                Type.Missing, Type.Missing, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive,
                                Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
            if(bClose)
                xlBook.Close(false, sOutFilePath, Type.Missing);
        }
        /// <summary><para>method outline:</para>
        /// <para>ファイル保存して閉じる</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>SaveBook(sOutFilePath);</para>
        /// </example>
        /// <param name="sOutFilePath">出力ファイル名パス</param>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void SaveBook(string sOutFilePath)
        {
            SaveBook(sOutFilePath, true);
        }

        /// <summary><para>method outline:</para>
        /// <para>Excelｱﾌﾟﾘｹｰｼｮﾝ終了</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>AppQuit();</para>
        /// </example>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void AppQuit()
        {
            if (xlApp != null)
                xlApp.Quit();
        }

        /// <summary><para>method outline:</para>
        /// <para>インスタンスの開放</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>Dispose();</para>
        /// </example>
        /// <returns>無し</returns>
        /// <exception cref=""></exception>
        /// <remarks><para>無し</para>
        /// <para>無し</para>
        /// </remarks>
        public void Dispose()
        {
            int iCnt = 0;
            try
            {
                //COM オブジェクト解放
                if (xlSheet != null)
                    iCnt = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet);
                if (xlSheets != null)
                    iCnt = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets);
                if (xlBook != null)
                    iCnt = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
                if (xlBooks != null)
                    iCnt = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks);
                if (xlApp != null)
                    iCnt = System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);

                xlSheet = null;
                xlSheets = null;
                xlBook = null;
                xlBooks = null;
                xlApp = null;

                GC.Collect();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            }
        }

    }
}
