C#でExcelから配列に読み込んで、配列からExcelに書き出す

C#で、既存のExcelのシートの全データを配列に読み込んで、別のシートに読み込んだデータを書き出してみます。シートのコピーが目的ではなくて、書き出す前に必要に応じて配列のデータをC#でゴニョゴニョできるわけです。単純にシートをコピーするだけなら、 もっと簡単な方法 があります。

目次

  1. シナリオ
  2. 試してみた

シナリオ

下記のような流れになります。

  1. コピー元のシートの使用範囲を指定してrangeオブジェクトを作る。

  2. オブジェクト型の配列に読み込む。

  3. 配列の大きさに合わせて、出力用のrangeオブジェクトを作る。

  4. 出力用のrangeオブジェクトに配列の内容を書き込む。

コードはこんな感じです。使う前に、ライブラリの参照を追加してください。コードを読みやすくするために、COMオブジェクトの解放の手続きは省略してますので、このまま使うとリソース不足になる場合があります。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;

namespace excel_trial
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 入力

            // Excelを起動する
            Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
            ExcelApp.Visible = false;

            // ブック(ファイル)を開き、1つ目のシートを選択する
            Microsoft.Office.Interop.Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(@"コピー元のファイル名");
            Worksheet ExcelWorksheet = ExcelWorkbook.Sheets[1];
            ExcelWorksheet.Select();

            // 読み込む範囲を指定する
            // Microsoft.Office.Interop.Excel.Range InputRange = ExcelWorksheet.UsedRange; // 使用範囲だけを選択する場合
            Microsoft.Office.Interop.Excel.Range InputRange = ExcelWorksheet.Range[ExcelWorksheet.Cells[1, 1], ExcelWorksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell)];

            // 指定された範囲のセルの値をオブジェクト型の配列に読み込む
            // object[,] InputObject = (System.Object[,])InputRange.Value2; // 計算結果を読む場合
            object[,] InputObject = (System.Object[,])InputRange.Formula; // 数式を読む場合

            // クローズ
            ExcelWorkbook.Close();
            ExcelApp.Quit();

            // 出力

            // Excelを起動し、新規のブックを作り、1つ目のシートを選択する
            Microsoft.Office.Interop.Excel.Application OutputApp = new Microsoft.Office.Interop.Excel.Application();
            OutputApp.Visible = true;
            Microsoft.Office.Interop.Excel.Workbook OutputWorkbook = OutputApp.Workbooks.Add();
            Worksheet OutputWorksheet = OutputWorkbook.Sheets[1];
            OutputWorksheet.Select();

            // 書き込む範囲を指定する
            Microsoft.Office.Interop.Excel.Range OutputRange = OutputWorksheet.Range[OutputWorksheet.Cells[1, 1], OutputWorksheet.Cells[InputObject.GetLength(0), InputObject.GetLength(1)]];

            // 指定された範囲にオブジェクト型配列の値を書き込む
            // OutputRange.Value2 = InputObject;
            OutputRange.Formula = InputObject;

            // クローズ
            OutputWorkbook.Close();
            OutputApp.Quit();
        }
    }
}

読み込む際のrangeオブジェクトのセル範囲指定についてですが、なぜかget_Rangeメソッドが使えなかったので、worksheet.Range[]を使いました。worksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell)はシートの使用範囲の右下のセルのことです。worksheet.Range[worksheet.Cells[1, 1], worksheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell)]でA1セルから使用範囲の右下のセルまでを指定できます。A1セルからでなくて良ければ、worksheet.UsedRangeの方が簡単です。

rangeオブジェクトと配列の間でデータをやりとりするときに、range.value2を使うとセルの計算結果が、range.formulaを使うと数式が得られます。

試してみた

下図のシートを使って試してみました。

サンプル

出力結果はこうなります。

結果

E6セルが数式になってますね。range.formulaでなくrange.value2を使うとE6セルには296.2という数値が入ります。

実施例は下記の環境でのものです。

  • Visual Studio 2015 Express for Windows Desktop (C#)

  • Excel 2013

  • Windows 8.1

公開日

広告