スポンサーリンク

【VB.NET】TextFieldParserを使って超簡単にCSVファイルを読み込む!

若手エンジニアから「CSVファイルの読み込み方がわからん」と言われたので書きます。最終目的としてはCSVでインポートしたデータをグリッドに表示したいらしいのですが、まずはCSV読み込むところから始めましょう。別に難しい事ではありません。「あなたならできるわ。」

スポンサーリンク

TextFieldParserクラスを使ってCSVファイルを読み込む

そんな難しいことではないので、サクサクと進めます。VB.NETには、TextFieldParserクラスというCSV(カンマ区切り)やTSV(タブ区切り)を扱うためのクラスがあります。このTextFieldParserクラスを使用すれば、アッと驚く為五郎という感じで、あっという間に取り込めます。

スポンサーリンク

実装

理屈は後にして、まずは実際にコーディングしてみましょう。習うより慣れろってやつです。

用意するコントロール

必要なコントロールは4つ。

  1. フォーム
  2. テキストボックス1(CSVファイルパスを入れるところ)
  3. ボタン(CSVインポート実行)
  4. テキストボックス2(CSV読み込み結果を表示させるところ)

f:id:neko_britannia:20200425155927j:plain

こんな感じで良いでしょう。

ソースコード

ボタンクリックしたら、横に細長いテキストボックスに入力されているCSVファイルパスからCSVファイルを読み込み、下のデカいテキストボックスにCSVファイルの中身を表示するとても簡単なものです。

Imports System.Text
Public Class From_CSV_Import
    Private Sub cmd_CSV_Import_Click(sender As Object, e As EventArgs) Handles cmd_CSV_Import.Click
        Dim strFilePath As String = Nothing
        Try
            strFilePath = txtFilePath.Text

            '未入力チェック
            If Trim(strFilePath) = "" Then
                MessageBox.Show("ファイルパス入れてね!", "未入力", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If
            'ファイル存在チェック
            If System.IO.File.Exists(strFilePath) = False Then
                MessageBox.Show("そんなファイル無いよ!", "未入力", MessageBoxButtons.OK, MessageBoxIcon.Error)
                Exit Sub
            End If

            Using objIoTFP As New Microsoft.VisualBasic.FileIO.TextFieldParser(strFilePath, Encoding.GetEncoding("Shift_JIS"))
                '読み込み時の設定
                With objIoTFP
                    '区切り文字をカンマに設定
                    .TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
                    .SetDelimiters(",")
                    '空白があった場合にTrimしない
                    .TrimWhiteSpace = False
                End With

                'CSV読み込み実行
                While Not objIoTFP.EndOfData
                    Dim arrayRow As String() = objIoTFP.ReadFields()
                    Dim strVeiwResult As String = Nothing
                    For Each objField As String In arrayRow
                        '表示
                        strVeiwResult = strVeiwResult & objField & ","
                    Next
                    '列の末尾のカンマを削除
                    strVeiwResult = strVeiwResult.TrimEnd(",")
                    'テキストボックスに表示
                    txtResult.Text = txtResult.Text & strVeiwResult & vbCrLf
                End While
            End Using
        Catch ex As Exception
            MessageBox.Show(ex.Source.ToString)
        End Try
    End Sub
End Class

とまあ、こんな感じに書きます。結果はこんな感じ。

f:id:neko_britannia:20200425160220j:plain

はい、簡単ですね。

読み込み時の設定について

読み込み前に設定すれば、色々な読み込み方が出来ます。上記のソースの場合は、

With objIoTFP
  '区切り文字をカンマに設定
  .TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
  .SetDelimiters(",")
  '空白があった場合にTrimしない
  .TrimWhiteSpace = False
End With
  • デリミタ(区切り文字)はカンマ
  • 空白があった場合にTrim(削除)しない

これだけでした。例えば、タブ区切りの場合は、SetDelimitersメソッドにタブを指定してあげればTSVファイルも読み込めます。

.SetDelimiters(“\t”)

また、フィールドにダブルクォーテーション「””」がある場合(「”いぬ”,”50歳”,”オス”」みたいなデータ)は、HasFieldsEnclosedInQuotesプロパティをTrueに設定すればOKです。

.HasFieldsEnclosedInQuotes = true

他のプロパティやメソッドはMSDNに掲載されていますので、そちらを参照下さい。

docs.microsoft.com

スポンサーリンク

Split()を使えば良いのでは?というお言葉に対して…

ええ、それでも良いかもしれません。区切り文字をカンマに指定すれば、配列になって帰って来ます。ただし、CSVに限って言えば、無理にSplit()を使う必要があるのかと思います。物好きな人はSplitを上手い事使ってますが、とても私には真似出来ません。TextFieldParserの方が断然楽です。

理由としては、

  • ヘッダ有無の考慮
  • ダブルクォーテーションの考慮

があるので、その対応だけで非常に面倒なのです。もっと色々とありますが、取り込むCSVのフォーマットやフィールド値が固定されているのであれば、Split()でも良いかもしれませんが、もっと別のところでSplit()を活躍させてあげるべきなのでは?と思います。

スポンサーリンク

編集後記

とまあこんな感じでCSV読み込めます。とても簡単です。

さて、CSVのフィールド内に改行コードが入っている場合が考えられますが、それはもう諦めましょう。任意入力されたデータをCSVに出力して、それを取り込むというのは、愚行です。改行コードを考慮してCSVを取り扱う時点で、そのシステム全体を見直した方が良いです。任意入力可能な画面上で改行を禁止する等しておくべきです。任意入力で改行を許容(というか考慮してない場合が多い)するというのは、「改行コードが混入されたデータを最後まで責任持って面倒見ますよ」と言っているようなものです。そういうシステムに携わったことがありますが、システムの中身や運用体制、メンバーの業務知識のレベルが散々でした。

参考サイト

今回の参考サイトです。

docs.microsoft.com

スポンサーリンク

鉄道記事も書いてます!

ちょっとリフレッシュして鉄道記事も読んでみませんか?

鉄道記事バックナンバーはこちら↓

鉄道コム投稿記事一覧ページ