-
Excel ファイルを VB.NET から操作することはいろんなシステムで要求されます。 例えば、検索されたデータ一覧を Excel ファイルに出力することや、 印刷用のテンプレート Excel ファイルを読込んで、そこにデータを設定し、出力する等です。
それで、今回は Microsoft.Office.Interop.Excel COM参照による方法について示します。 Microsoft.Office.Interop.Excel を利用するには対象となるパソコンに Excel がインストールされている必要があります。
先ずはプロジェクトに Microsoft.Office.Interop.Excel の参照設定を行う必要があります。
以下は、メニューの中の「プロジェクト(P)」⇒「参照の追加(R)...」を開いて Microsoft Excel 15.0 Object Library を選択したところです。 15.0 の部分は Excel のバージョンにより変わります。参照設定が終わると、左図の様にソリューションエクスプローラの中の「参照設定」に Microsoft.Office.Interop.Excel が現れます。
これで、プログラムの中でエクセルを利用する準備が終わりました。
早速簡単なエクセルファイルを上書きする例を示します。
今回の例はフォームにボタンを1個設置しそのクリックイベントで処理を行います。
ファイル名を「test.xlsx」とし、そのファイルの中のシートの先頭セルに "TEST123" の文字列を設定し、登録します。 (「test.xlsx」は前もって作成しておきます。)
エクセルを使う手順は以下の様に行います。- Excel オブジェクトを生成しアプリケーション起動
- Excel の Workbook のコレクションである Workbooks の取得
- Workbooks オブジェクトにより既存の Excel ファイルを Workbook に開く
- Excel の Worksheet のコレクションである Worksheets 取得
- Excel の Worksheets から先頭のシート Worksheet 取得
- シート内の処理を行う
- Workbook オブジェクトによりファイルに保存
- Worksheet オブジェクトの解放
- Worksheets オブジェクトの解放
- Workbook オブジェクトを閉じてから解放
- Workbooks オブジェクトの解放
- Excel オブジェクトを閉じる
- Excel アプリケーションの解放
以下の様にオブジェクトを順を追って参照を取得し、対象となるワークシートに処理を行った後で 逆順でオブジェクトの解放を行います。
Excel.Application ⇒ Workbooks ⇒ Workbook ⇒ Worksheets ⇒ Worksheets
オブジェクトの解放用の関数は、Marshalクラスの COM オブジェクトの解放用関数 System.Runtime.InteropServices.Marshal.ReleaseComObject を使います。 (エクセルオブジェクトは COM オブジェクトとして動作するためです)
簡単なエクセル処理の例1
Imports Microsoft.Office.Interop Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Excel のアプリケーション参照用オブジェクト Dim xlsApplication As Excel.Application = Nothing 'Excel の Workbooks 参照用オブジェクト (Workbook の Collection) Dim xlsWorkbooks As Excel.Workbooks = Nothing 'Excel の Workbooks 内の1個の Workbook 参照用オブジェクト Dim xlsWorkbook As Excel.Workbook = Nothing 'Excel の Workbook 内の Worksheets 参照用オブジェクト (Worksheet の Collection) Dim xlsWorkSheets As Excel.Sheets = Nothing 'Excel の Sheets 内の1個の Worksheet 参照用オブジェクト Dim xlsWorkSheet As Excel.Worksheet = Nothing 'Excel の Sheet 内の1個のセル Range 参照用オブジェクト Dim xlsRange As Excel.Range = Nothing 'フルパスでのファイル名 (ファイル名のみだと Excel 側のデフォルトのフォルダになるはず) Dim strFileName As String = My.Application.Info.DirectoryPath & "\test.xlsx" 'Excel アプリケーション起動 xlsApplication = New Excel.Application 'Excel の Workbooks 取得 xlsWorkbooks = xlsApplication.Workbooks 'Excel非表示 xlsApplication.Visible = False xlsApplication.DisplayAlerts = False '既存 Excel ファイルを開く xlsWorkbook = xlsWorkbooks.Open(strFileName) 'Excel の Worksheets 取得 xlsWorkSheets = xlsWorkbook.Worksheets 'Excel の Worksheet 取得 xlsWorkSheet = CType(xlsWorkSheets.Item(1), Excel.Worksheet) 'シート名称 xlsWorkSheet.Name = "シート名test" 'セル選択 xlsRange = xlsWorkSheet.Range("A1") 'セルに値設定 xlsRange.Value = "TEST123" MRComObject(xlsRange) '保存時の問合せダイアログを非表示に設定 xlsApplication.DisplayAlerts = False 'ファイルに保存 (Excel 2007~ブック形式) xlsWorkbook.SaveAs(Filename:=strFileName, FileFormat:=Excel.XlFileFormat.xlOpenXMLWorkbook) '保存時の問合せダイアログを表示に戻す xlsApplication.DisplayAlerts = True '終了処理 'xlsWorkSheet の解放 MRComObject(xlsWorkSheet) 'xlsWorkSheets の解放 MRComObject(xlsWorkSheets) 'xlsWorkbookを閉じる xlsWorkbook.Close(False) 'xlsWorkbook の解放 MRComObject(xlsWorkbook) 'xlsWorkbooks の解放 MRComObject(xlsWorkbooks) 'Excelを閉じる xlsApplication.Quit() 'xlsApplication を解放 MRComObject(xlsApplication) End Sub 'COM オブジェクトへの参照を解放 Private Sub MRComObject(ByRef objCom As Object) If Not objCom Is Nothing Then Try System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom) Catch ' Finally '参照を解除する objCom = Nothing End Try End If End Sub End Class
各処理の途中でエラーが発生した場合には COM オブジェクトの解放が行われない場合がありますので、 変数の宣言以降を Try … Catch … End で括って更に終了処理を Finally にまとめて以下の様にすれば解消できるはずです。
簡単なエクセル処理の例2
Imports Microsoft.Office.Interop Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Excel のアプリケーション参照用オブジェクト Dim xlsApplication As Excel.Application = Nothing 'Excel の Workbooks 参照用オブジェクト (Workbook の Collection) Dim xlsWorkbooks As Excel.Workbooks = Nothing 'Excel の Workbooks 内の1個の Workbook 参照用オブジェクト Dim xlsWorkbook As Excel.Workbook = Nothing 'Excel の Workbook 内の Worksheets 参照用オブジェクト (Worksheet の Collection) Dim xlsWorkSheets As Excel.Sheets = Nothing 'Excel の Sheets 内の1個の Worksheet 参照用オブジェクト Dim xlsWorkSheet As Excel.Worksheet = Nothing 'Excel の Sheet 内の1個のセル Range 参照用オブジェクト Dim xlsRange As Excel.Range = Nothing 'フルパスでのファイル名 (ファイル名のみだと Excel 側のデフォルトのフォルダになるはず) Dim strFileName As String = My.Application.Info.DirectoryPath & "\test.xlsx" Try 'Excel アプリケーション起動 xlsApplication = New Excel.Application 'Excel の Workbooks 取得 xlsWorkbooks = xlsApplication.Workbooks 'Excel非表示 xlsApplication.Visible = False xlsApplication.DisplayAlerts = False '既存 Excel ファイルを開く xlsWorkbook = xlsWorkbooks.Open(strFileName) 'Excel の Worksheets 取得 xlsWorkSheets = xlsWorkbook.Worksheets 'Excel の Worksheet 取得 xlsWorkSheet = CType(xlsWorkSheets.Item(1), Excel.Worksheet) 'シート名称 xlsWorkSheet.Name = "シート名test" 'セル選択 xlsRange = xlsWorkSheet.Range("A1") 'セルに値設定 xlsRange.Value = "TEST123ABC" MRComObject(xlsRange) '保存時の問合せダイアログを非表示に設定 xlsApplication.DisplayAlerts = False 'ファイルに保存 (Excel 2007~ブック形式) xlsWorkbook.SaveAs(Filename:=strFileName, FileFormat:=Excel.XlFileFormat.xlOpenXMLWorkbook) '保存時の問合せダイアログを表示に戻す xlsApplication.DisplayAlerts = True Catch ex As Exception MsgBox(ex.Message) Finally '終了処理 'xlsWorkSheet の解放 MRComObject(xlsWorkSheet) 'xlsWorkSheets の解放 MRComObject(xlsWorkSheets) 'xlsWorkbook のオブジェクトが存在すれば閉じる If Not xlsWorkbook Is Nothing Then xlsApplication.DisplayAlerts = False xlsWorkbook.Close() xlsApplication.DisplayAlerts = True End If 'xlsWorkbook の解放 MRComObject(xlsWorkbook) 'xlsWorkbooks の解放 MRComObject(xlsWorkbooks) 'xlsApplication のオブジェクトが存在すれば閉じる If Not xlsApplication Is Nothing Then xlsApplication.DisplayAlerts = False xlsApplication.Quit() xlsApplication.DisplayAlerts = True End If 'xlsApplication を解放 MRComObject(xlsApplication) End Try End Sub 'COM オブジェクトへの参照を解放 Private Sub MRComObject(ByRef objCom As Object) If Not objCom Is Nothing Then Try System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom) Catch ' Finally '参照を解除する objCom = Nothing End Try End If End Sub End Class
関連する記事
⇒access vba でWordを起動しファイル保存時のファイル名変更について(DocumentBeforeSave : Word保存前イベント)
⇒access vba でExcelを起動しファイル保存でのファイル名変更について(WorkbookBeforeSave : Excel保存前イベント)
⇒access vba でのWord処理用クラスの作成(ファイル保存時イベント[DocumentBeforeSave]でのファイル名変更処理を含む)
⇒access vba でのWord文書の文字列検索と置換について(Word処理用クラスに文字列置換関数を追加)
⇒access vba Bookmarkオブジェクトで文書の先頭にカーソルを移動する(Word処理用クラスに文書の先頭移動関数を追加)
PR -
親フォームから表示された子フォームから、呼び出し元の親フォームのコントロールをアクセスする方法として以下の記事に在りますが、 今回はそれと似た方法ですが少し違った方法で行います。
⇒親フォームのコントロールを子フォームからアクセスする方法
今回の方法は、親フォームで子フォームを表示する時に、自分自身のフォームをオーナー(所有者)として処理します。 また、子フォームの方では自分自身のオーナーを DirectCast で親フォームだとして、親の持つコントロールへアクセスします。
以下の例では、親フォームから子フォームを呼出した時に、子フォームから親フォームのテキストボックスの 「Text」を取得し、子フォームのテキストボックスの「Text」に初期設定します。
その後、子フォームのボタンを押下することで、親フォームのテキストボックスの「Text」に 子フォームのテキストボックスの「Text」を再設定します。
以下の画像は、親フォームから子フォームを表示し、子フォームのテキストボックスに「ABCD」を入力し「親への設定」ボタンを押下した時の様子です。
以下の今回の処理のソースを示します。子フォームを表示する時に ShowDialog を使いますが、親フォームである自分自身を引数で渡します。 そうすると子フォームの Owner プロパティに親フォームオブジェクトのインスタンスが渡せます。親フォームのクラス
'''
''' 子フォームを呼出す親フォーム2 ''' Public Class frmParentCtrlMain '''''' 「サブフォーム表示」ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'プロパティテストウインドウ生成 Dim frmParentCtrlSub As New frmParentCtrlSub 'ウインドウ表示(指定した所有者を持つモーダルダイアログとしてフォームを表示) frmParentCtrlSub.ShowDialog(Me) 'プロパティテストウインドウ廃棄 frmParentCtrlSub.Dispose() frmParentCtrlSub = Nothing End Sub End Class子フォームのクラス
'''
''' メインフォームを参照する子フォーム ''' Public Class frmParentCtrlSub '''''' フォームロードイベント ''' Private Sub frmPropTextSub_Load(sender As Object, e As EventArgs) Handles Me.Load 'メイン側のTextBox1の内容を取得し、サブ側に設定 Me.TextBox1.Text = DirectCast(Me.Owner, frmParentCtrlMain).TextBox1.Text End Sub '''''' 「設定(プロパティ)」ボタンクリックイベント ''' Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'メイン側のTextBox1に、サブ側のTextBox1の内容を設定 DirectCast(Me.Owner, frmParentCtrlMain).TextBox1.Text = Me.TextBox1.Text ''自分を閉じる 'Me.Close() End Sub End Class子フォームで使っている DirectCast は DirectCast 演算子と言われるもので、 指定されたオブジェクトをある型にキャストするための演算子です。
DirectCast(変数, キャスト後の型).「キャストされた型が持つプロパティ、メソッド等」
この DirectCast は「変数」を強制的にキャストされた型と処理するため、 間違った型にキャストすると当然のことながらエラーが発生します。 (存在しないプロパティを参照したり、存在しないメソッドを実行する場合)
DirectCast により直接親フォームの TextBox1 を参照していますが、 これが出来るのはなぜかと言いますと、親フォーム内で TextBox1 が Friend として宣言されているからです。 Friend 宣言のオブジェクトは同じプロジェクト内ならばどこからでも参照可能だからです。 通常フォームのデザイン画面でコントロールを張り付けた時に自動で Friend なオブジェクトとして生成されます。
ここで Friend の様な変数やクラス等の宣言のキーワードについて少し説明します。 宣言には Public, Friend, Protected, Private, Dim 等があります。
宣言キーワード アクセス可能な個所 説明 Public 全ての箇所からアクセス可能 同一プロジェクトに限らず他のプロジェクトからもアクセスできます Friend 同一プロジェクトからアクセス可能 同一プロジェクトであればどこからでもアクセスできます。 Protected 自分自身のクラス、及び派生クラスからアクセス可能 他のプロジェクトでも派生クラスであればアクセスできます。 Protected Friend 同一プロジェクトからアクセス可能
他のプロジェクトは派生クラスがアクセス可能Protected Friend の両方の機能を併せ持つ。 Private 自分自身のクラスからアクセス可能 派生クラスでもアクセス不可なので、純粋にローカルなものとして扱います。 Dim 自分自身のクラスからアクセス可能 Dim はクラスのメンバー変数や関数内の自動変数として宣言する宣言文です。
クラス内の変数はなるべく Private で宣言し、外部から操作するもののみ Public や Friend にする方が 宜しいかと思います。また、変数そのものを Public にするのではなく、プロパティとしてアクセス可能な様にするべきかと思います。
-
EXCELファイルの拡張子が xlsx のファイルですが、多分 EXCEL2007以降のバージョンでEXCEL2010,2013,2015などで出力される形式があります。 このファイルですが、中身はXMLファイルの集まりが圧縮されているそうなのです。 お恥ずかしい限りですが、つい最近まで知らなかったのですが、EXCELファイルをZIPファイルにリネームし圧縮を解凍すれば中身が見られます。
そこで、どうなっているのかを調べてみたので順に見ていきます。
■先ずはテスト用のEXCELファイルを作成します。簡単な内容のデータを作成します。
■フォルダの中に test.xlsx ファイルが作成されました。
■test.xlsx ファイルのコピーを作成します。
■test.xlsx のコピーファイルのファイル名を test.zip に変更します。
■test.zip ファイルを展開してやります。
以下は test.zip ファイルの上で右クリックをしたところですが、その中の「すべて展開(T)...」を選択します。 (私のPCでは各種ツールが入っていますので、変なメニューも表示されていますが)
■展開結果は以下の様になります。
展開された中のXMLファイルを見てみます。 XMLファイルの中身を見たい場合にはXML表示ソフトを使いますが、以下のフリーソフト「XMLEDITOR.NET(xml.exe)」が使いやすいと思います。 このソフトを使ってXMLファイルをのぞいてみます。
⇒XMLEDITOR .NETについて
■\test\xl\worksheets フォルダの中の sheet1.xml ファイルを「XMLEDITOR.NET(xml.exe)」で見てみます。
以上からエクセルのファイルは各種のXMLファイルで構成されていることが分かります。 尚、今回なぜエクセルの中身を解析する必要が在ったかと言いますと、PHPでのエクセル出力で、エクセルのグラフの表現がどうなっているかを調査するためでした。
VB.NETからエクセルを使う場合はエクセルのオブジェクトからそのメソッド等を利用して操作ができるので、中身までは意識しませんが、 PHPからの処理ではPHPExcleライブラリだけでは難しい部分もありますので、参考になればと思います。関連する記事
⇒Excel ファイルの操作について(Microsoft.Office.Interop.Excel COM参照)
-
以前の記事でCSVファイルに書込む処理を紹介しましたが、 今回はその関数を利用して DataGridViw コントロールからCSVファイルへのデータ書込みを行います。
⇒CSVファイルの書込について :[System.IO.StreamWriter]
DataGridViw から WriteCsv:CSVファイル書込処理 に指示する文字列配列を作成し、ファイル書込みを行います。 DataGridViw の列ヘッダーからCSVの先頭行のヘッダーデータを取得します。 更に DataGridViw の各行データから、その行のセルデータから文字列配列を作成します。
最初フォームに DataGridView コントロールを配置すると AllowUserToAddRows プロパティが True なので、 DataGridView の最後の行に新規行(*行)が表示される様になります。 (この設定のままで、どんどん新規のデータを入力できます。)
この新規行は何も入力がされていない状態ですので、 CSVファイルにはデータとして登録しない様に DataGridView の行の IsNewRow プロパティが True の場合には 処理しない様にしています。
尚、以下の例ではフォームロードイベント処理で DataGridView の列数を5個として生成を行っています。DataGridView からCSVファイルへの書込
Public Class frmDGV2CSV ' フォームロード時処理 Private Sub frmDGV2CSV_Load(sender As Object, e As EventArgs) Handles Me.Load Try 'DataGridView列数を5に固定 Dim arrColName() As String = {"COL1", "COL2", "COL3", "COL4", "COL5"} For Each strName As String In arrColName Me.dgv.Columns.Add(strName, strName) Next Catch ex As Exception 'エラー MsgBox(ex.Message) End Try End Sub ' [WriteCSV From DataGridView]ボタンクリック処理 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Try 'DataGridViewからCSVファイルへの書込処理の呼出 If WriteCsvFromDGV(Me.dgv, "testw.csv") = True Then MsgBox("CSVファイル書込・正常") Else MsgBox("CSVファイル書込・エラー") End If Catch ex As Exception 'エラー MsgBox(ex.Message) End Try End Sub ''' ----------------------------------------------------------------------------- ''' <summary> ''' DataGridViewからCSVファイルへの書込処理 ''' (WriteCsv:CSVファイルの書込処理の利用による) ''' </summary> ''' <param name="dgv">DataGridView</param> ''' <param name="astrFileName">ファイル名</param> ''' ----------------------------------------------------------------------------- Private Function WriteCsvFromDGV(ByVal dgv As DataGridView, ByVal astrFileName As String) As Boolean WriteCsvFromDGV = False Try 'DataGridView全体のデータ領域 Dim arrData()() As String = Nothing '1行分を読込 Dim arrHead As String() = Nothing '列ヘッダの名称取得 For col As Integer = 0 To Me.dgv.Columns.Count - 1 '1列分の領域拡張 ReDim Preserve arrHead(col) '列のヘッダデータ退避 arrHead(col) = CStr(Me.dgv.Columns(col).HeaderCell.Value) Next '1行分の領域拡張 ReDim Preserve arrData(0) '列ヘッダ名退避 arrData(0) = arrHead 'データ行数分の処理 For row As Integer = 0 To Me.dgv.Rows.Count - 1 '新規行は処理しない If Me.dgv.Rows(row).IsNewRow Then Continue For End If '1行分を読込 Dim arrLine As String() = Nothing '列数分の処理 For col As Integer = 0 To Me.dgv.Columns.Count - 1 '1列分の領域拡張 ReDim Preserve arrLine(col) '列データ退避 arrLine(col) = CStr(Me.dgv.Rows(row).Cells(col).Value) Next '1行分の領域拡張 ReDim Preserve arrData(row + 1) '1行データ退避 arrData(row + 1) = arrLine Next '実際のCSVファイルの書込み Return WriteCsv(astrFileName, arrData) Catch ex As Exception 'エラー MsgBox(ex.Message) End Try End Function ''' ----------------------------------------------------------------------------- ''' <summary> ''' CSVファイルの書込処理 ''' </summary> ''' <param name="astrFileName">ファイル名</param> ''' <param name="aarrData">書込データ文字列の2次元配列</param> ''' <returns>True:結果OK, False:NG</returns> ''' <remarks>カラム名をファイルに出力したい場合は、書込データの先頭に設定すること</remarks> ''' ----------------------------------------------------------------------------- Private Function WriteCsv(ByVal astrFileName As String, ByVal aarrData As String()()) As Boolean WriteCsv = False 'ファイルStreamWriter Dim sw As System.IO.StreamWriter = Nothing Try 'CSVファイルに書込に使うEncoding Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("Shift_JIS") '書き込むファイルを開く sw = New System.IO.StreamWriter(astrFileName, False, enc) For Each arrLine() As String In aarrData Dim blnFirst As Boolean = True Dim strLIne As String = "" For Each str As String In arrLine If blnFirst = False Then '「,」(カンマ)の書込 sw.Write(",") End If blnFirst = False '1カラムデータの書込 str = """" & str & """" sw.Write(str) Next '改行の書込 sw.Write(vbCrLf) Next '正常終了 Return True Catch ex As Exception 'エラー MsgBox(ex.Message) Finally '閉じる If sw IsNot Nothing Then sw.Close() End If End Try End Function End Class
DataGridView にデータを入力したところのフォームの表示は以下の様になります。
[WriteCSV From DataGridView] ボタンを押下すると以下の様なCSVファイルが書き込まれます。
CSVファイルの内容
"COL1","COL2","COL3","COL4","COL5" "111","22222","33333","4444","55555" "aaa","bbb","cccccc","ddd","ee" "AAA","22","CCCCC","DDDD","EEE"
関連する記事
⇒CSVファイルの読込について :[Microsoft.VisualBasic.FileIO.TextFieldParser]
⇒CSVファイルの書込について :[System.IO.StreamWriter]
⇒CSVファイルの DataGridView への読込について
-
以前の記事でCSVファイルを読込む処理を紹介しましたが、 今回はその関数を利用して DataGridViw コントロールへのデータ設定を行います。
⇒CSVファイルの読込について :[Microsoft.VisualBasic.FileIO.TextFieldParser]
DataGridViw への設定では ReadCsv:CSVファイル読込処理 から返された文字列配列を基に、各カラムに文字列として設定を行います。 DataGridViw は列が無いと対象セルへの設定ができないので、 ReadCsv 処理後最初に先頭行の列数を設定します。また、各行の設定の前で列数の変化があれば拡張を行っています。CSVファイルの DataGridView への読込
Imports Microsoft.VisualBasic.FileIO Public Class frmCSV2DGV ''' ----------------------------------------------------------------------------- ''' <summary> ''' CSVファイルの読込処理 ''' </summary> ''' <param name="astrFileName">ファイル名</param> ''' <param name="ablnTab">区切りの指定(True:タブ区切り, False:カンマ区切り)</param> ''' <param name="ablnQuote">引用符フラグ(True:引用符で囲まれている, False:囲まれていない)</param> ''' <returns>読込結果の文字列の2次元配列</returns> ''' ----------------------------------------------------------------------------- Private Function ReadCsv(ByVal astrFileName As String, ByVal ablnTab As Boolean, ByVal ablnQuote As Boolean) As String()() ReadCsv = Nothing 'ファイルStreamReader Dim parser As Microsoft.VisualBasic.FileIO.TextFieldParser = Nothing Try 'Shift-JISエンコードで変換できない場合は「?」文字の設定 Dim encFallBack As System.Text.DecoderReplacementFallback = _ New System.Text.DecoderReplacementFallback("?") Dim enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("shift_jis", _ System.Text.EncoderFallback.ReplacementFallback, encFallBack) 'TextFieldParserクラス parser = New Microsoft.VisualBasic.FileIO.TextFieldParser(astrFileName, enc) '区切りの指定 parser.TextFieldType = FieldType.Delimited If ablnTab = False Then 'カンマ区切り parser.SetDelimiters(",") Else 'タブ区切り parser.SetDelimiters(vbTab) End If If ablnQuote = True Then 'フィールドが引用符で囲まれているか parser.HasFieldsEnclosedInQuotes = True End If 'フィールドの空白トリム設定 parser.TrimWhiteSpace = False Dim strArr()() As String = Nothing Dim nLine As Integer = 0 'ファイルの終端までループ While Not parser.EndOfData 'フィールドを読込 Dim strDataArr As String() = parser.ReadFields() '戻り値領域の拡張 ReDim Preserve strArr(nLine) '退避 strArr(nLine) = strDataArr nLine += 1 End While '正常終了 Return strArr Catch ex As Exception 'エラー MsgBox(ex.Message) Finally '閉じる If parser IsNot Nothing Then parser.Close() End If End Try End Function ''' ----------------------------------------------------------------------------- ''' <summary> ''' CSVファイルのDataGridViewへの読込処理 ''' (ReadCsv:CSVファイルの読込処理の利用による) ''' </summary> ''' <param name="dgv">DataGridView</param> ''' <param name="astrFileName">ファイル名</param> ''' <param name="ablnTab">区切りの指定(True:タブ区切り, False:カンマ区切り)</param> ''' <param name="ablnQuote">引用符フラグ(True:引用符で囲まれている, False:囲まれていない)</param> ''' ----------------------------------------------------------------------------- Private Sub ReadCsvToDGV(ByVal dgv As DataGridView, ByVal astrFileName As String, Optional ByVal ablnTab As Boolean = False, Optional ByVal ablnQuote As Boolean = False) Try 'CSVファイル読込処理 Dim arrCsv()() As String = ReadCsv(astrFileName, ablnTab, ablnQuote) 'DataGridView クリア dgv.Rows.Clear() '列数の設定 dgv.ColumnCount = arrCsv(0).Length Dim row As Integer = 0 For Each arr In arrCsv 'DataGridView 新規行を追加 dgv.Rows.Add() 'DataGridViewの列数がデータ配列数より小さい場合は列拡張 If dgv.ColumnCount < arr.Length Then dgv.ColumnCount = arr.Length End If For col As Integer = 0 To arr.Length - 1 'セルに列、行を指定して値の設定 dgv(col, row).Value = arr(col) Next '次の行へ row += 1 Next Catch ex As Exception 'エラー MsgBox(ex.Message) End Try End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'CSVファイルをDataGridViewへ読込処理 ReadCsvToDGV(Me.DataGridView1, "test2.csv") End Sub End Class
以下の様なCSVファイルを読込みます。CSVファイルの内容
TEST1,TEST2,TEST3 1000,2000,3000 aaaa,bbbb,cccc,dddd 000,111,4444,55555,6666 AAAAAAA,BBBBB
読込んだフォームの表示は以下の様になります。
この場合 DataGridViw の列ヘッダに設定はしていませんので、CSVファイルの先頭行にヘッダが存在する場合を考慮した 読込関数を以下に記します。DataGridViw への設定関数と実行例の部分のみを抜粋しています。CSVファイルの DataGridView への読込2
''' ----------------------------------------------------------------------------- ''' <summary> ''' CSVファイルのDataGridViewへの読込処理 ''' (ReadCsv:CSVファイルの読込処理の利用による) ''' </summary> ''' <param name="dgv">DataGridView</param> ''' <param name="astrFileName">ファイル名</param> ''' <param name="ablnTab">区切りの指定(True:タブ区切り, False:カンマ区切り)</param> ''' <param name="ablnQuote">引用符フラグ(True:引用符で囲まれている, False:囲まれていない)</param> ''' <param name="ablnHeader">先頭行が列ヘッダ</param> ''' <param name="ablnExtendColumn">列数の拡張を行う指示</param> ''' ----------------------------------------------------------------------------- Private Sub ReadCsvToDGV(ByVal dgv As DataGridView, ByVal astrFileName As String, Optional ByVal ablnTab As Boolean = False, Optional ByVal ablnQuote As Boolean = False, Optional ByVal ablnHeader As Boolean = False, Optional ByVal ablnExtendColumn As Boolean = True) Try 'CSVファイル読込処理 Dim arrCsv()() As String = ReadCsv(astrFileName, ablnTab, ablnQuote) 'DataGridView クリア dgv.Rows.Clear() Dim row As Integer = 0 Dim blnFirst As Boolean = True For Each arr In arrCsv If blnFirst = True Then blnFirst = False If ablnHeader = True Then '先頭行が列ヘッダの場合 dgv.Columns.Clear() For Each strColName In arr dgv.Columns.Add(strColName, strColName) Next Continue For Else '列数の設定 dgv.ColumnCount = arrCsv(0).Length End If End If 'DataGridView 新規行を追加 dgv.Rows.Add() 'DataGridViewの列数がデータ配列数より小さい場合は列拡張 If ablnExtendColumn = True And dgv.ColumnCount < arr.Length Then dgv.ColumnCount = arr.Length End If For col As Integer = 0 To arr.Length - 1 If col >= dgv.Columns.Count Then Exit For End If 'セルに列、行を指定して値の設定 dgv(col, row).Value = arr(col) Next '次の行へ row += 1 Next Catch ex As Exception 'エラー MsgBox(ex.Message) End Try End Sub Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'CSVファイルをDataGridViewへ読込処理:先頭行が列ヘッダで列数拡張 ReadCsvToDGV(Me.DataGridView1, "test2.csv", False, False, True, True) MsgBox("OK") 'CSVファイルをDataGridViewへ読込処理:先頭行が列ヘッダで列数拡張無し ReadCsvToDGV(Me.DataGridView1, "test2.csv", False, False, True, False) End Sub
実行結果(先頭行が列ヘッダで列数拡張)は以下の様になります。
メッセージ表示後(先頭行が列ヘッダで列数拡張無し)の表示は以下の様になります。
関連する記事
⇒CSVファイルの読込について :[Microsoft.VisualBasic.FileIO.TextFieldParser]
⇒CSVファイルの書込について :[System.IO.StreamWriter]
⇒DataGridView からCSVファイルへの書込について