2013年11月24日日曜日

SheetAccessor

using Microsoft.Office.Core;
using OfficeExcel = Microsoft.Office.Interop.Excel;

namespace Core.File.Excel
{
    /// <summary>
    /// ExcelのSheetアクセサー
    /// </summary>
    public class SheetAccessor : BaseExcelAccessor
    {
        #region 構築・破棄

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="worksheet"></param>
        /// <param name="application">ExcelApplicationアクセサー</param>
        private SheetAccessor(OfficeExcel.Worksheet worksheet, ExcelAccessor application)
            :base(application)
        {
            Worksheet = worksheet;
        }

        /// <summary>
        /// 構成子
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="application">ExcelApplicationアクセサー</param>
        /// <returns></returns>
        internal static SheetAccessor GetAccessor(OfficeExcel.Worksheet worksheet, ExcelAccessor application)
        {
            return new SheetAccessor(worksheet, application);
        }

        #endregion

        #region プロパティ

        /// <summary>Worksheet</summary>
        private OfficeExcel.Worksheet Worksheet { get; set; }

        /// <summary>名前</summary>
        public string Name
        {
            get
            {
                return Worksheet.Name;
            }
            set
            {
                Worksheet.Name = value;
            }
        }

        #endregion

        #region WorkSheet

        /// <summary>
        /// シート-移動
        /// </summary>
        /// <param name="after">指定したシートの後ろへ移動</param>
        public void Move(SheetAccessor after)
        {
            Worksheet.Move(System.Type.Missing, after.Worksheet);
        }

        /// <summary>
        /// シート-コピー
        /// </summary>
        /// <param name="after">指定したシートの後ろへコピー</param>
        public void Copy(SheetAccessor after)
        {
            Worksheet.Copy(System.Type.Missing, after.Worksheet);
        }

        /// <summary>
        /// 選択
        /// </summary>
        public void Select()
        {
            Worksheet.Select();
        }

        #endregion

        #region Cell

        /// <summary>Sheets</summary>
        private OfficeExcel.Range cells;
        /// <summary>Sheets</summary>
        private OfficeExcel.Range Cells
        {
            get
            {
                if (this.cells == null)
                {
                    this.cells = Worksheet.Cells;
                    ReleaseComObjects.Add(this.cells);
                }
                return this.cells;
            }
        }

        /// <summary>
        /// Cell取得
        /// </summary>
        /// <param name="rowIndex">行インデックス</param>
        /// <param name="columnIndex">列インデックス</param>
        /// <returns></returns>
        public CellAccessor GetCell(int rowIndex, int columnIndex)
        {
            OfficeExcel.Range cell = Cells[rowIndex, columnIndex];

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(cell);

            return CellAccessor.GetAccessor(cell, Worksheet, Application);
        }
        /// <summary>
        /// Cell取得
        /// </summary>
        /// <param name="row1Index">行1インデックス</param>
        /// <param name="column1Index">列1インデックス</param>
        /// <param name="row2Index">行2インデックス</param>
        /// <param name="column2Index">列2インデックス</param>
        /// <returns></returns>
        public CellAccessor GetCell(int row1Index, int column1Index, int row2Index, int column2Index)
        {
            OfficeExcel.Range cell1 = Cells[row1Index, column1Index];
            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(cell1);

            OfficeExcel.Range cell2 = Cells[row2Index, column2Index];
            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(cell2);

            OfficeExcel.Range range = Worksheet.get_Range(cell1, cell2);
            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(range);

            return CellAccessor.GetAccessor(range, Worksheet, Application);
        }
        /// <summary>
        /// Cell取得
        /// </summary>
        /// <param name="name">名前付き名前</param>
        /// <returns></returns>
        public CellAccessor GetCell(string name)
        {
            OfficeExcel.Range cell = Worksheet.get_Range(name);

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(cell);

            return CellAccessor.GetAccessor(cell, Worksheet, Application);
        }
        /// <summary>
        /// Cell取得
        /// </summary>
        /// <param name="name1">名前付きCell1</param>
        /// <param name="name2">名前付きCell2</param>
        /// <returns></returns>
        public CellAccessor GetCell(string name1, string name2)
        {
            OfficeExcel.Range cell = Worksheet.get_Range(name1, name2);

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(cell);

            return CellAccessor.GetAccessor(cell, Worksheet, Application);
        }

        #endregion

        #region Shepe

        /// <summary>Sheets</summary>
        private OfficeExcel.Shapes shapes;
        /// <summary>Sheets</summary>
        private OfficeExcel.Shapes Shapes
        {
            get
            {
                if (this.shapes == null)
                {
                    this.shapes = Worksheet.Shapes;
                    ReleaseComObjects.Add(this.shapes);
                }
                return this.shapes;
            }
        }

        /// <summary>
        /// Shepe取得
        /// </summary>
        /// <returns></returns>
        public ShapeAccessor AddShape(ExcelShapeType shapeType, float left = 0, float top = 0, float width = 0, float height = 0)
        {
            OfficeExcel.Shape shape = Shapes.AddShape((MsoAutoShapeType)shapeType, left, top, width, height);

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(shape);

            return ShapeAccessor.GetAccessor(shape, Worksheet, Application);
        }

        /// <summary>
        /// Connector取得
        /// </summary>
        /// <returns></returns>
        public ConnectorAccessor AddConnector(ExcelConnectorType connectorType, float beginX = 0, float beginY = 0, float endX = 0, float endY = 0)
        {
            OfficeExcel.Shape connector = Shapes.AddConnector((MsoConnectorType)connectorType, beginX, beginY, endX, endY);

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(connector);

            return ConnectorAccessor.GetAccessor(connector, Application);
        }

        #endregion
    }
}

BookAccessor

using System.Collections.Generic;
using System.Text;
using OfficeExcel = Microsoft.Office.Interop.Excel;

namespace Core.File.Excel
{
    /// <summary>
    /// ExcelのBookアクセサー
    /// </summary>
    public class BookAccessor : BaseExcelAccessor
    {
        #region 構築・破棄

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="application">ExcelApplicationアクセサー</param>
        private BookAccessor(OfficeExcel.Workbook workbook, ExcelAccessor application)
            :base(application)
        {
            Workbook = workbook;
        }

        /// <summary>
        /// 構成子
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="application">ExcelApplicationアクセサー</param>
        /// <returns></returns>
        internal static BookAccessor GetAccessor(OfficeExcel.Workbook workbook, ExcelAccessor application)
        {
            return new BookAccessor(workbook, application);
        }

        #endregion

        #region プロパティ

        /// <summary>Workbook</summary>
        private OfficeExcel.Workbook Workbook { get; set; }

        /// <summary>Sheets</summary>
        private OfficeExcel.Sheets sheets;
        /// <summary>Sheets</summary>
        private OfficeExcel.Sheets Sheets
        {
            get
            {
                if (this.sheets == null)
                {
                    this.sheets = Workbook.Sheets;
                    ReleaseComObjects.Add(this.sheets);
                }
                return this.sheets;
            }
        }

        /// <summary>フルネーム</summary>
        public string FullName
        {
            get
            {
                return Workbook.FullName;
            }
        }

        /// <summary>ファイル名</summary>
        public string Name
        {
            get
            {
                return Workbook.Name;
            }
        }

        /// <summary>パス</summary>
        public string Path
        {
            get
            {
                return Workbook.Path;
            }
        }

        #endregion

        #region WorkBook

        /// <summary>
        /// 保存
        /// </summary>
        public void Save()
        {
            Workbook.Save();
        }

        /// <summary>
        /// 名前を付けて保存
        /// </summary>
        /// <param name="absolutePath">絶対パス</param>
        public void SaveAs(string absolutePath)
        {
            Workbook.SaveAs(ConvertIllegalBookName(absolutePath));
        }

        /// <summary>
        /// 禁則文字変換
        /// 1 )コロン        :
        /// 2 )角カッコ      [ ]
        /// </summary>
        /// <param name="name"></param>
        public string ConvertIllegalBookName(string name)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(System.IO.Path.GetDirectoryName(name));
            sb.Append(@"\");

            string tmp = System.IO.Path.GetFileNameWithoutExtension(name);
            tmp = tmp.Replace(@":", "");
            tmp = tmp.Replace(@":", "");
            tmp = tmp.Replace(@"[", "");
            tmp = tmp.Replace(@"[", "");
            tmp = tmp.Replace(@"]", "");
            tmp = tmp.Replace(@"]", "");
            sb.Append(tmp);

            sb.Append(System.IO.Path.GetExtension(name));

            return sb.ToString();
        }

        /// <summary>
        /// 閉じる
        /// </summary>
        /// <param name="saveChanges">true:変更を保存して閉じる</param>
        public void Close(bool saveChanges = false)
        {
            Workbook.Close(saveChanges);
        }

        #endregion

        #region Worksheet

        /// <summary>
        /// Sheet取得
        /// </summary>
        /// <param name="index">インデックス</param>
        /// <returns></returns>
        public SheetAccessor GetSheet(int index)
        {
            OfficeExcel.Worksheet worksheet = Sheets[index];

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(worksheet);

            return SheetAccessor.GetAccessor(worksheet, Application);
        }

        /// <summary>
        /// Sheet取得
        /// </summary>
        /// <param name="name">名前</param>
        /// <returns></returns>
        public SheetAccessor GetSheet(string name)
        {
            foreach(OfficeExcel.Worksheet worksheet in Sheets)
            {
                // 解放COMオブジェクト追加
                ReleaseComObjects.Add(worksheet);

                if (worksheet.Name.Equals(name))
                {
                    return SheetAccessor.GetAccessor(worksheet, Application);
                }
            }

            throw new KeyNotFoundException();
        }

        /// <summary>
        /// Sheetを追加
        /// </summary>
        /// <returns></returns>
        public SheetAccessor AddSheet()
        {
            OfficeExcel.Worksheet lastWorksheet = Sheets[Sheets.Count];
            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(lastWorksheet);

            OfficeExcel.Worksheet worksheet = Sheets.Add(System.Type.Missing, lastWorksheet, System.Type.Missing, System.Type.Missing);
            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(worksheet);

            return SheetAccessor.GetAccessor(worksheet, Application);
        }

        /// <summary>
        /// Sheetを追加
        /// </summary>
        /// <param name="name">名前</param>
        /// <returns></returns>
        public SheetAccessor AddSheet(string name)
        {
            SheetAccessor sheet = AddSheet();
            sheet.Name = ConvertIllegalSheetName(name);
            return sheet;
        }

        /// <summary>
        /// 禁則文字変換
        /// 1 )コロン        :
        /// 2 )円記号        ¥
        /// 3 )疑問符        ?
        /// 4 )角カッコ      [ ]
        /// 5 )スラッシュ     /
        /// 6 )アスタリスク  *
        /// </summary>
        /// <param name="name"></param>
        public string ConvertIllegalSheetName(string name)
        {
            string tmp = name;
            tmp = tmp.Replace(@":", "");
            tmp = tmp.Replace(@":", "");
            tmp = tmp.Replace(@"\", "");
            tmp = tmp.Replace(@"¥", "");
            tmp = tmp.Replace(@"?", "");
            tmp = tmp.Replace(@"?", "");
            tmp = tmp.Replace(@"[", "");
            tmp = tmp.Replace(@"[", "");
            tmp = tmp.Replace(@"]", "");
            tmp = tmp.Replace(@"]", "");
            tmp = tmp.Replace(@"/", "");
            tmp = tmp.Replace(@"/", "");
            tmp = tmp.Replace(@"*", "");
            tmp = tmp.Replace(@"*", "");

            return tmp;
        }

        #endregion
    }
}

BaseExcelAccessor

using System.Collections.Generic;

namespace Core.File.Excel
{
    /// <summary>
    /// ベース:Excelアクセサー
    /// </summary>
    public abstract class BaseExcelAccessor
    {
        #region 構築・破棄

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="application">ExcelApplicationアクセサー</param>
        protected BaseExcelAccessor(ExcelAccessor application)
        {
            Application = application;
        }

        #endregion

        #region プロパティ

        /// <summary>ExcelApplicationアクセサー</summary>
        protected ExcelAccessor Application { get; private set; }

        /// <summary>解放COMオブジェクト</summary>
        protected List<object> ReleaseComObjects
        {
            get
            {
                return Application.ReleaseComObjects;
            }
        }

        #endregion
    }
}

ExcelAccessor

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using OfficeExcel = Microsoft.Office.Interop.Excel;

namespace Core.File.Excel
{
    /// <summary>
    /// Excelアクセサー
    /// </summary>
    public class ExcelAccessor : IDisposable
    {
        #region 構築・破棄

        /// <summary>
        /// コンストラクタ
        /// </summary>
        private ExcelAccessor()
        {
            // 初期設定
            Init();
        }

        /// <summary>
        /// 構成子
        /// </summary>
        /// <returns></returns>
        public static ExcelAccessor GetAccessor()
        {
            return new ExcelAccessor();
        }

        /// <summary>
        /// 破棄
        /// </summary>
        public void Dispose()
        {
            Quit();
            foreach(object releaseComObject in ReleaseComObjects)
            {
                Marshal.ReleaseComObject(releaseComObject);
            }
        }

        #endregion

        #region プロパティ

        /// <summary>Application</summary>
        private OfficeExcel.Application application;
        /// <summary>Application</summary>
        private OfficeExcel.Application Application
        {
            get
            {
                if (this.application == null)
                {
                    this.application = new OfficeExcel.Application();
                    ReleaseComObjects.Add(this.application);
                }
                return this.application;
            }
        }

        /// <summary>Workbooks</summary>
        private OfficeExcel.Workbooks workbooks;
        /// <summary>Workbooks</summary>
        private OfficeExcel.Workbooks Workbooks
        {
            get
            {
                if (this.workbooks == null)
                {
                    this.workbooks = Application.Workbooks;
                    ReleaseComObjects.Add(this.workbooks);
                }
                return this.workbooks;
            }
        }

        /// <summary>解放COMオブジェクト</summary>
        private List<object> releaseComObjects;
        /// <summary>解放COMオブジェクト</summary>
        public List<object> ReleaseComObjects
        {
            get
            {
                if (this.releaseComObjects == null)
                {
                    this.releaseComObjects = new List<object>();
                }
                return this.releaseComObjects;
            }
        }

        /// <summary>確認メッセージ表示設定</summary>
        public bool DisplayAlerts
        {
            get
            {
                return Application.DisplayAlerts;
            }
            set
            {
                Application.DisplayAlerts = value;
            }
        }

        /// <summary>Visible</summary>
        public bool Visible
        {
            get
            {
                return Application.Visible;
            }
            set
            {
                Application.Visible = value;
            }
        }

        /// <summary>ActiveWindow</summary>
        private OfficeExcel.Window ActiveWindow
        {
            get
            {
                OfficeExcel.Window window = Application.ActiveWindow;
                ReleaseComObjects.Add(window);
                return window;
            }
        }

        /// <summary>ウィンドウ枠の固定</summary>
        public bool FreezePanes
        {
            get
            {
                return ActiveWindow.FreezePanes;
            }
            set
            {
                ActiveWindow.FreezePanes = value;
            }
        }

        #endregion

        #region メソッド

        /// <summary>
        /// 初期設定
        /// </summary>
        private void Init()
        {
            DisplayAlerts = false;
        }

        /// <summary>
        /// Bookを開く
        /// </summary>
        /// <param name="absolutePath">絶対パス</param>
        /// <returns></returns>
        public BookAccessor OpenBook(string absolutePath)
        {
            OfficeExcel.Workbook workbook = Workbooks.Open(
                absolutePath, // オープンする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
            );

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(workbook);

            return BookAccessor.GetAccessor(workbook, this);
        }

        /// <summary>
        /// Bookを追加
        /// </summary>
        /// <returns></returns>
        public BookAccessor AddBook()
        {
            OfficeExcel.Workbook workbook = Workbooks.Add();

            // 解放COMオブジェクト追加
            ReleaseComObjects.Add(workbook);

            return BookAccessor.GetAccessor(workbook, this);
        }

        /// <summary>
        /// 終了
        /// </summary>
        private void Quit()
        {
            Application.Quit();
        }

        /// <summary>
        /// マクロ実行
        /// </summary>
        /// <returns></returns>
        public dynamic Run(string macro, params object[] args)
        {
            object[] arg30 = new object[30];
            for(int i = 0; i < arg30.Length; i++)
            {
                arg30[i] = Type.Missing;
            }

            for(int i = 0; i < args.Length; i++)
            {
                arg30[i] = args[i];
            }

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

        #endregion
    }
}