.NETには「COM相互運用」と呼ばれる機能があり、COMコンポーネントを手軽に呼び出すことができる。一方、ExcelをはじめとするOffice製品は、その機能をマクロ(VBA)などからも活用できるようにCOMコンポーネントとして実装されている。このため、COM相互運用を使えば.NETアプリケーションから容易にExcelやWordのファイルを開き、それをさまざまに操作することが可能だ。本稿ではその基本的な記述方法として、Excelファイルをオープンしてワークシート上のセルの内容を参照する例を紹介する。
参照の追加
アプリケーションからExcelにアクセスするには、まずExcelが公開するCOMコンポーネントへの参照をプロジェクトに追加する。これには[参照の追加]ウィンドウで[COM]タブを選択し、「Microsoft Excel 12.0 Object Library」(Excel 2007の場合。Excel 2003の場合は「Microsoft Excel 11.0 Object Library」を選択)。
これにより、ソリューション・エクスプローラの「参照設定」のツリーには「Microsoft.Office.Core」と「Microsoft.Office.Interop.Excel」(Excel 2003の場合は「Excel」)が追加される。
これで、アプリケーションからExcelファイルにアクセス可能になる。
Excelがインストールされているにもかかわらず、[参照の追加]ウィンドウでExcelのコンポーネントが見つからない場合は、Officeのセットアップで「.NET プログラミングのサポート」がチェックされているかを確認してみるといいだろう。もしもチェックされていないようならチェックしておく。
なお、以降で示しているコード例はExcel 2007のCOMコンポーネントを使用した場合のものである。
Excelファイルをオープンする
まずはMicrosoft.Office.Interop.Excel.Applicationオブジェクトを生成する。これはWindowsのスタート・メニューからExcelを起動するのと同じようなものだ。Applicationオブジェクトを新規作成するには次のように記述する。
Excel.Application oXls; // Excelオブジェクト
oXls = new Excel.Application();
Dim oXls As Excel.Application ' Excelオブジェクト
oXls = New Excel.Application()
新規作成した変数oXlsを使って、次は目的のファイルをオープンする。Excelでファイルをオープンすると、ワークブックを表すWorkbookオブジェクトが返され、これ以降の操作はこのオブジェクトに対して行う。
なお、本稿で示しているコードを使用する場合には、ファイルの先頭部分で次のようにして名前空間をインポートしておく必要がある。
using Excel = Microsoft.Office.Interop.Excel;
Imports Microsoft.Office.Interop
この記述により、例えばMicrosoft.Office.Interop.Excel名前空間のApplicationクラスは、C#でもVBでも「Excel.Application」と記述できる。
Excelファイルのオープンは、Workbooks.Openメソッドを使うのだが、このメソッドのパラメータが非常に多い。通常のExcelファイル(.xls)を開く場合は、ファイル名だけを指定すればいいので、省略可能なほかのパラメータには「Type.Missing」を指定して“空”のパラメータを渡すようにする。Workbooks.Openメソッドの詳細については、オンライン・ヘルプなどを参照していただきたい。
string excelName = "C:\\sample.xls";
Excel.Application oXls; // Excelオブジェクト
Excel.Workbook oWBook; // workbookオブジェクト
oXls = new Excel.Application();
oXls.Visible = true; // 確認のためExcelのウィンドウを表示する
// Excelファイルをオープンする
oWBook = (Excel.Workbook)(oXls.Workbooks.Open(
excelName, // オープンする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
));
Dim excelName As String = "C:\sample.xls"
Dim oXls As Excel.Application ' Excelオブジェクト
Dim oWBook As Excel.Workbook ' Workbookオブジェクト
oXls = New Excel.Application()
oXls.Visible = True ' 確認のためExcelのウィンドウを表示する
' Excelファイルをオープンする
oWBook = DirectCast((oXls.Workbooks.Open( _
excelName, _
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)), _
Excel.Workbook)
ワークシートの選択
Workbooks.Openメソッドの実行によりワークブックであるWorkbookオブジェクトが取得できた。続いてはこれに含まれるワークシートを取得する。ワークブックには複数のワークシートを格納できるので、目的のワークシートをワークシート名により探し出す必要がある。
本稿の例では、単純にワークブックに含まれるワークシートを順番に見ていき、ワークシート名が一致したら、それが目的のワークシートであると判断している。なおワークシートのインデックスは1から始まっているので注意が必要だ。
// 指定されたワークシート名のインデックスを返すメソッド
private int getSheetIndex(string sheetName, Excel.Sheets shs)
{
int i = 0;
foreach (Excel.Worksheet sh in shs)
{
if (sheetName == sh.Name)
{
return i + 1;
}
i += 1;
}
return 0;
}
// 与えられたワークシート名から、Worksheetオブジェクトを得る
string sheetName = "Sheet2";
Excel.Worksheet oSheet; // Worksheetオブジェクト
oSheet = (Excel.Worksheet)oWBook.Sheets[
getSheetIndex(sheetName, oWBook.Sheets)];
' 指定されたワークシート名のインデックスを返すメソッド
Private Function getSheetIndex(ByVal sheetName As String, ByVal shs As Excel.Sheets) As Integer
Dim i As Integer = 0
For Each sh As Microsoft.Office.Interop.Excel.Worksheet In shs
If sheetName = sh.Name Then
Return i + 1
End If
i += 1
Next
Return 0
End Function
' 与えられたワークシート名から、Worksheetオブジェクトを得る
Dim sheetName As String = "Sheet2"
Dim oSheet As Excel.Worksheet ' Worksheet オブジェクト
oSheet = DirectCast(oWBook.Sheets( _
getSheetIndex(sheetName, oWBook.Sheets)), Excel.Worksheet)
セルの内容を読み込む
ここまでの操作でワークシートを得ることができたので、最後に目的のセルの内容を参照する。セルの内容はWorksheetオブジェクトのCellsプロパティで取得できるが、Cellsプロパティが返すRangeオブジェクトから内容を取得する方が分かりやすい。
Rangeオブジェクトはワークシート上の指定された範囲のセルを管理するのだが、1つのセルをRangeオブジェクトに割り当てて、そのRangeオブジェクトからセルの中身がアクセスできる。Rangeオブジェクトには、セルの内容を取り出すTextプロパティや計算式を示すFormulaプロパティ、セルの表示形式を表すNumberFormatプロパティなどが提供されている。
セルの指定は、
Cells[row, column]
のように行うが、row、columnはともに1始まりである。従って「A1」のセルは、Cells[1, 1]となる。
string sCellVal;
Excel.Range rng; // Rangeオブジェクト
rng = (Excel.Range)oSheet.Cells[1, 1];
sCellVal = rng.Text.ToString(); // A1セルの内容
Dim sCellVal As String
Dim rng As Excel.Range ' Range オブジェクト
rng = DirectCast(oSheet.Cells(1, 1), Excel.Range)
sCellVal = rng.Text.ToString() ' A1セルの内容
Rangeオブジェクトに含まれるセルの値を取得するには、ValueプロパティかTextプロパティを用いる。Textプロパティは、セルの値が文字列化されたものを取得できるが、セルの表示形式で指定されている形式によって得られる内容が異なる。ここではセルの内容が文字列か数値の判断がつかないと仮定しているでTextプロパティを使っているが、状況によってはValueプロパティの方が妥当な場合もある。セルの内容を参照するのではなく、セルに値をセットする場合はValueプロパティを使用する必要がある。
すべての処理が終了したら、Workbookオブジェクトをクローズし、Excelを終了しておく。
oWBook.Close(Type.Missing, Type.Missing, Type.Missing);
oXls.Quit();
oWBook.Close(Type.Missing, Type.Missing, Type.Missing)
oXls.Quit()
本稿は、Excelファイルの内容を読み取る方法のみを紹介したが、ApplicationオブジェクトやWorkbookオブジェクトなどに含まれるほかのメソッドを使って、新規にワークシートを作成してファイルに保存したり、セルの内容を修正して保存したりすることもできる。ワークシート上のセルにアクセスするところまでを理解すれば、Excelファイルの処理は意外と簡単に行えるはずだ。
カテゴリ:クラス・ライブラリ 処理対象:COMコンポーネント
使用ライブラリ:Applicationクラス(Microsoft.Office.Interop.Excel名前空間)
使用ライブラリ:Workbookクラス(Microsoft.Office.Interop.Excel名前空間)
使用ライブラリ:Worksheetクラス(Microsoft.Office.Interop.Excel名前空間)
使用ライブラリ:Rangeクラス(Microsoft.Office.Interop.Excel名前空間)
Copyright© Digital Advantage Corp. All Rights Reserved.