社畜ゲートウェイ

京成・京急を中心に取り上げる阪急ファンのブログです。日本一遅い速報を届けます。

MENU

【スポンサーリンク】

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

【スポンサーリンク】

f:id:neko_britannia:20200417145314j:plain

IT関連記事なので何かそれっぽい画像

若手エンジニアから「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