【VB.NET】エクセルファイルを操作する方法
Microsoft.Office.Interop.Excel を使用したエクセルファイルを操作する方法を説明します。
ただしこの方法は、ExcelのDLLを使用するため、MicrosoftのExcelをインストールしていないと使えません。
事前準備
まずは、プログラム実行に必要なdllの参照を追加します。
プロジェクトにマウスを合わせて、参照マネージャーを開きます。
COMタブから Microsoft Excel xx.x ObjectLibrary の参照を追加します。
※今回はMicrosoft Excel 16.0 ObjectLibrary の参照を追加しています。
- Microsoft.Office.Core
- Microsoft.Office.Interop.Excel
が参照追加されます。
Microsoft.Office.Interop ライブラリをインポートします。
Imports Microsoft.Office.Interop
今回使用しているのは、Microsoft Excel 16.0 ObjectLibrary ですが、これはエクセルのバージョンでいうところの 2016 または、2019 または、Office 365 にあたります。
その他のエクセルのバージョンとライブラリーの関係は以下通り
Excel 2016・2019 Office 365 (Ver16)
Excel 2013 (Ver15)
Excel 2010 (Ver14)
Excel 2007 (Ver12)
Excel 2003 (Ver11)
Excel 2002 (Ver10)
Excel 2000 (Ver9)
Excel 97 (Ver97)
Excel 95 (Ver7)
実装例
実際に実行すると、VB.NETを通して実際にエクセル操作が行われているのがわかります。
Imports Microsoft.Office.Interop Module Module1 Sub Main() Dim excelName As String = "C:\tmp\Sample.xlsx" Dim oXls As Excel.Application ' Excelオブジェクト Dim oWBook As Excel.Workbook ' Workbookオブジェクト oXls = New Excel.Application() ' 動きを確認のためExcelのウィンドウを表示する oXls.Visible = Boolean.TrueString ' Excelファイルをオープンする oWBook = 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 ' ブックの内容を取得 Console.WriteLine(oWBook.Name) 'ブックの名前 Console.WriteLine(oWBook.FullName) 'ブックのフルパス Console.WriteLine(oWBook.Title) 'ブックのタイトル Console.WriteLine(oWBook.Subject) 'ブックの件名 Console.WriteLine(oWBook.Author) 'ブックの作成者 '二秒間(2000ミリ秒)停止する System.Threading.Thread.Sleep(2000) ' 与えられたワークシート名から、Worksheetオブジェクトを得る Dim sheetName As String = "Sheet2" Dim oSheet As Excel.Worksheet ' Worksheet オブジェクト oSheet = oWBook.Sheets(getSheetIndex(sheetName, oWBook.Sheets)) Dim sCellVal As String Dim rng As Excel.Range ' Range オブジェクト ' A1セルの内容を取得 rng = oSheet.Cells(1, 1) sCellVal = rng.Text.ToString() Console.WriteLine(sCellVal) ' A1セルの値 ' B2セルの内容書込み rng = DirectCast(oSheet.Cells(2, 2), Excel.Range) rng.Value = "てすと" 'クローズ処理 oWBook.Close(Type.Missing, Type.Missing, Type.Missing) oXls.Quit() End Sub ''' 指定されたワークシート名のインデックスを返す 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 End Module
自動計算の設定
エクセルの書き込みが遅いので調査したところ関数で自動計算しているのが原因だったことがあります。
「エクセルのメニュー」→「数式」→「計算方法の設定」をVB.NETから設定する方法です。
Excel.Application.Calculation
プロパティで設定します。
'Excel が再計算を制御します。(自動) Excel.Application.Calculation = Excel.XlCalculation.xlCalculationAutomatic 'ユーザーが要求すると、計算が完了します。(手動) Excel.Application.Calculation = Excel.XlCalculation.xlCalculationManual 'Excel が再計算を制御しますが、テーブル内の変更は無視します。(データテーブル以外自動) Excel.Application.Calculation = Excel.XlCalculation.xlCalculationSemiautomatic
配列を作って行単位で設定する方法
1次配列を作成して行に対して値を設定します。
サンプルコード
'一次配列を作成 Dim starr = {"a", "b", "c"} '1行目1列から1行目3列の値を設定 oSheet.Range(oSheet.Cells(1, 1), oSheet.Cells(1, 3)).Value = starr
2次元配列を作って範囲全体に値を設定する方法
考え方は、行単位に設定する方法と同じですが、こちらは2次元配列を作成して、複数行かつ複数列に値をいっぺんに設定します。
エクセルへのアクセス回数を減らすことで、処理速度の向上が見込めます。
サンプルコード
'二次元配列を作成 Dim starr(100, 100) As Integer For i = 1 To 100 For j = 1 To 100 starr(i, j) = j Next Next '1行目1列から100行目100列の値を設定 oSheet.Range(oSheet.Cells(1, 1), oSheet.Cells(101, 100)).Value = starr
コメント