[C#] プログラムからExcelファイルを読み書きする方法

Excelに保存したデータを利用して、何かプログラムを作ろうとした場合、通常はExcelマクロなんかを使うことが多いと思う。

実際、マクロはVBA(言語的には旧Visual Basic 6.0)を利用するため、コーディングの難易度が低く、ちょっとした表計算やグラフ作成なら簡単に扱うことができ便利。

だけど、既存のExcelにマクロ追加など手を加えたくなかったり、複数のExcelデータを利用した処理を行いたかったり、他システムとの連携や、ちょっと複雑な処理を加えたいといった場合は、マクロはでは役不足。

C#からExcelを利用するプログラムについて作り方をよく忘れてしまうんで、覚書きとしてメモっておくことにした。
10
開発言語はC#(VB.NETなども同様)で、実行環境にはExcelが必要。

今回は、Visual Studio 2010 Professional + Microsoft Office Excel 2007
の組み合わせで実行したけど、
Visual Studio 2012 Express for Windows Desktop + Microsoft Excel 2010
の組み合わせでも問題なく動作した。

<追記>
Visual Studio 2013+Microsoft Excel 2013とかも基本的に同じようなやり方で動作する。

作成方法

  1. Visual Studioを起動し、Windowsフォームアプリケーション(Visual C#)の新規プロジェクトを作成する。
    01
  2. ソリューションエクスプローラーのポップアップメニューから[参照の追加]を開く。
    02
  3. [参照の追加]ダイアログの[COM]タブで「Microsoft Excel 12.0 Object Library」を追加する。
    ※12.0(Excel2007?)ではなくても14.0(Excel2010?)などでもOK。
    03
  4. ソリューションエクスプローラーの[参照設定]に、以下の2つが追加されたことを確認する。
    ・Microsoft.Office.Core
    ・Microsoft.Office.Interop.Excel
    04
  5. Form1のGUI編集で、TextBoxとButtonコントロールを以下のような感じで配置する。
    05
  6. 実行ボタン(button1)をダブルクリックし、空のbutton1_Clickイベントを作成しておく。
    private void button1_Click(object sender, EventArgs e)
    {
    
    }
    
  7. Form1.csのソース編集で、以下のコードを貼り付ける。(button1_Clickも上書き)
    06

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Excel = Microsoft.Office.Interop.Excel;
    namespace WindowsFormsApplication1
    {
    	public partial class Form1 : Form
    	{
    		private static string fileName = System.IO.Directory.GetCurrentDirectory() + "\\sample.xls";
    		public Form1()
    		{
    			InitializeComponent();
    		}
    
    		private void Form1_Load(object sender, EventArgs e)
    		{
    			textBox1.ReadOnly = true;
    			textBox1.Text = fileName;
    		}
    
    		private void button1_Click(object sender, EventArgs e)
    		{
    			this.Cursor = Cursors.WaitCursor;   // マウスカーソルを砂時計
    			Excel.Application oExcelApp = null; // Excelオブジェクト
    			Excel.Workbook oExcelWBook = null;  // Excel Workbookオブジェクト
    			try
    			{
    				oExcelApp = new Excel.Application();
    				oExcelApp.DisplayAlerts = false; // Excelの確認ダイアログ表示有無
    				oExcelApp.Visible = false;       // Excel表示有無
    				// Excelファイルをオープンする(第一パラメタ以外は省略可)
    				oExcelWBook = (Excel.Workbook)(oExcelApp.Workbooks.Open(
    					fileName,      // Filename
    					Type.Missing,  // UpdateLinks
    					Type.Missing,  // ReadOnly
    					Type.Missing,  // Format
    					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
    				));
    				Excel._Worksheet oWSheet = (Excel._Worksheet)oExcelWBook.ActiveSheet;
    				// セルA1の値を取得
    				MessageBox.Show("セルA1の値:" + oWSheet.Cells[1, 1].Value);
    				// セルA2に更新時刻を書き込み
    				oWSheet.Cells[2, 1] = DateTime.Now.ToString("HH時mm分ss秒");
    				Excel.Range oRange = oWSheet.Cells[2, 1];   // セル選択
    				oRange.Font.Size = 8;
    				oRange.Font.Name = "MS 明朝";
    				oRange.Font.Color = 0xFF0000;
    				oRange.Interior.Color = 0x44FFFF;
    				// [Microsoft Excel - 互換性チェック]ダイアログの表示有無
    				oExcelWBook.CheckCompatibility = false;
    				oExcelWBook.SaveAs(fileName);    // Excel保存
    				MessageBox.Show(
    				"保存しました。",
    				Application.ProductName,
    				MessageBoxButtons.OK,
    				MessageBoxIcon.Information);
    			}
    			catch (System.IO.FileNotFoundException)
    			{
    				MessageBox.Show(
    				"Excelファイルの操作に失敗しました。\n",
    				Application.ProductName,
    				MessageBoxButtons.OK,
    				MessageBoxIcon.Warning);
    			}
    			finally
    			{
    				oExcelWBook.Close(Type.Missing, Type.Missing, Type.Missing);
    				oExcelApp.Quit();
    			}
    			this.Cursor = Cursors.Default;  // マウスカーソルを戻す
    		}
    	}
    }
    
  8. 読み込み&書き込みするためのExcelファイルを用意。
    “sample.xls”を新規作成し、セルA1に適当な文字を書いて保存しておく。
    07
  9. プログラムをビルドして実行。(exeと同じフォルダにsample.xlsを用意)
    08
    実行すると、バックグラウンドでExcelが起動され、セルA1に書いた値が表示される。
  10. [OK]ボタンを押すと、今度はセルA2に書き込み処理が行われる。
    09
  11. “sample.xls”を開くと、セルA2に更新日時が出力されている。
    10

今回は値の入出力だけ行ったけど、フォント変更や書式設定、印刷、シート操作、罫線を引いたりグラフを作成することも出来るらしい。

でも今回のサンプルは、実行時にバックグラウンドでExcelを起動しているので実行に少し時間がかかる。
(ちなみに「oExcelApp.Visible = false;」の行を”true”にするとExcelの画面も表示される)

このExcel起動や、大きなデータを読み書きした場合、処理中はGUIが固まり、画面操作や画面を閉じることも出来なくなってしまう。
今回はサンプルということで、他の処理は割愛したけど、これら重たい処理をBackgroundWorkerなどで別スレッド化し、ProgressBarで進捗表示した方がいいかもね。

あと、作成したexeファイルを他のPCで実行するとき、勿論、Excelが必要となるけど、それ以外にもDLLが必要となる。

Microsoft.Office.Interop.Excel.dll
Microsoft.Vbe.Interop.dll
office.dll
stdole.dll

とりあえず、このサンプル程度なら上記DLLで動作するけど、必要なDLLを調べるためには、Visual Studio Professional Editionとかで、インストーラ(セットアップ/デプロイメント プロジェクト)を作れば分かる。
DLLのみの再配布ができるかどうか分からないけど、Setup付きなら大丈夫かな。

<追記>
上記取り消し線部分の話は、.NET Framework 3.5までのお話。

↓こちらにも追記したんだけど、.NET Framework 4以降ではDLLを再配布する必要がない。
[C#] Excelを使ったプログラムとインストーラの作成
これタイトルが紛らわしい(自分も知らなかった)けど、配布のためにインストーラ作成する必要はないです。


Tagged: ,

Leave a comment

メールアドレスが公開されることはありません。

CAPTCHA


*