C#でExcelのシートをコピーする

C#で既存のExcelのシートを別のブックにコピーします。例えば、既存のシートを加工するアプリを作ったときに、その既存のシートに上書きするようにすると、エラーが起きたときにファイルが壊れそうで怖いですよね。ということで、シートの編集用に既存のシートを別のブックにコピーしてみます。

目次

  1. C#でExcelを呼び出すときの注意
  2. 新しいブックにシートをコピーしてみた
    1. ライブラリの参照
    2. アプリを作ってみる
    3. 試してみた
  3. 使用上の注意

C#でExcelを呼び出すときの注意

C#からExcelを操作する場合は、リソース管理について注意が要ります。

COMオブジェクトを解放しないとExcelのプロセスが残るので、解放しなければなりません。方法については、 C#とVB.NETの入門サイト に詳しく書かれています。COMの参照カウントについては いげ太のブログ で解説されています。これをしないと、アプリ終了後もExcelのプロセスが残る場合があります。

新しいブックにシートをコピーしてみた

MSDSですと このページ が参考になると思います。

流れとしては、Excelアプリケーションを1つ起動して、コピー元のシートを含むブックと新しいブックを開き、コピー元のシートを新しいブックにコピーします。

ライブラリの参照

まず、Visual Studio上でライブラリの参照を追加します。ソリューションエクスプローラーの「参照」を右クリックして、「参照の追加」を選びます。

参照の追加

そうすると「参照マネージャー」ウィンドウが開くので、「COM」→「タイプライブラリ」の順に選択して、「Microsoft Excel 15.0 Object Library」にチェックを付けて「OK」ボタンをクリックします。ライブラリの名前は、PCにインストールされているExcelのバージョンによって異なります。

参照マネジャー

そうすると、ソリューションエクスプローラーに参照が追加されます。

参照が追加された

名前空間にMicrosoft.Office.Interop.Excelを追加します。

using Microsoft.Office.Interop.Excel;

アプリを作ってみる

フォームをロードしたら既存のExcelファイルを開いて新しいブックにコピーする、というアプリを作ってみます。

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_copy
{
    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;
            try
            {
                // コピー元のブック(ファイル)を開く
                Microsoft.Office.Interop.Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(@"ここにコピー元のファイル名を記す");
                try
                {
                    // コピー元のシートを選択する
                    Worksheet ExcelWorksheet = ExcelWorkbook.Sheets[1];
                    try
                    {
                        // 新規のブックを作る
                        Microsoft.Office.Interop.Excel.Workbook OutputWorkbook = ExcelApp.Workbooks.Add();
                        try
                        {
                            Worksheet OutputWorksheet = OutputWorkbook.Sheets[1];
                            try
                            {
                                // シート1の後ろにコピーする
                                ExcelWorksheet.Copy(Type.Missing, OutputWorksheet);
                                ExcelApp.Visible = true;
                            }
                            finally
                            {
                                if (OutputWorksheet != null)
                                {
                                    System.Runtime.InteropServices.Marshal.ReleaseComObject(OutputWorksheet);
                                }
                            }
                        }
                        finally
                        {
                            if (OutputWorkbook != null)
                            {
                                try
                                {
                                    OutputWorkbook.Close();
                                }
                                finally
                                {
                                    System.Runtime.InteropServices.Marshal.ReleaseComObject(OutputWorkbook);
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (ExcelWorksheet != null)
                        {
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelWorksheet);
                        }
                    }
                }
                finally
                {
                    if (ExcelWorkbook != null)
                    {
                        try
                        {
                            ExcelWorkbook.Close();
                        }
                        finally
                        {
                            System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelWorkbook);
                        }
                    }
                }
            }
            finally
            {
                if (ExcelApp != null)
                {
                    try
                    {
                        ExcelApp.Quit();
                    }
                    finally
                    {
                        System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp);
                    }
                }
            }
        }
    }
}

すごい階層のネストですね。当初はコピー先のブックを新しいExcelアプリケーションで作るようにしていたのですが、どうも同一Excelアプリ内のブック間でないとコピーできないようです。これでしばらくハマりました。

試してみた

コピー元として、下図のようなシートを準備しました。

Excelサンプル

作ったアプリを実行すると、シートがコピーされたブックを保存するかどうか問い合わせるダイアログが開きます。ここで「保存」を選ぶと、「名前を付けて保存」のダイアログが開きます。

保存ダイアログ

名前を付けてファイルを保存するか、または「保存しない」をクリックすると、Excelは自動的に終了します。保存したファイルを開いてみると、下図のようにコピーされたシートが1枚目のシートの次にあります。

結果

使用上の注意

シートをコピーすると、書式やセルに記入されている数値/数式はコピーされますが、マクロはコピーされません。

使用環境は下記です。

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

  • Excel 2013

  • Windows 8.1

公開日

広告