csvの取込みが列のレイアウトが変わるたびに作るのが面倒だったので作りました。
まだ、これで取込なかったcsvファイルは経験していので、基本的には大丈夫かと。
プログラム
Imports System.IO
Imports System.Reflection
Public Class CSVReader(Of T As {New})
Public Sub LoadEntities(ByRef entities As List(Of T), filePath As String)
Dim reader As FileIO.TextFieldParser
Dim propertyNames As List(Of String)
reader = New FileIO.TextFieldParser(filePath, System.Text.Encoding.GetEncoding("shift_jis"))
reader.TextFieldType = FileIO.FieldType.Delimited
reader.SetDelimiters(",")
'CSVの1行目の列名を取得
propertyNames = New List(Of String)(reader.ReadFields)
While Not reader.EndOfData
Dim entity = New T
Dim recodeData = reader.ReadFields
For i As Integer = 0 To propertyNames.Count - 1
Dim columnName As String = propertyNames(i)
Dim data As Object = recodeData(i)
SetData(entity, columnName, data)
Next
entities.Add(entity)
End While
reader.Dispose()
End Sub
Private Sub SetData(ByVal entity As T, ByVal propertyName As String, ByVal data As Object)
Dim members As PropertyInfo()
Dim member As PropertyInfo
members = entity.GetType.GetProperties
member = members.FirstOrDefault(Function(x) x.Name = propertyName)
member.SetValue(entity, Convert.ChangeType(data, member.PropertyType))
End Sub
End Class
使い方
まずは取込み後となるオブジェクトを生成するために、Entityクラスを作ります。今回は前回の記事「CSVWriter」でも使ったクラスを流用します。
Public Class Ingredient
Property id As Integer
Property Name As String
Property Quantity As String
End Class
注意点が2つあります。
- csvファイルの列名とproperty名を一致させておくこと
- パラメータなしのインスタンスコンストラクターがあること
2つ目については、CSVWriterの時のように引数を持っているNewメソッドを生成している場合、Listオブジェクトを生成する時にエラーになります。
そんな時は、Entityクラス(今回はIngredient.vb)で、引数を持っていない、空っぽのNewメソッドを記述していただければ解決します。
では、実際にCSVReaderを実行した例です。
Dim recipe As New List(Of Ingredient)
Dim reader As New CSVReader(Of Ingredient)
reader.LoadEntities(recipe, "C:\Temp\output.csv")
これで取込み完了です。
解説
解説内容はCSVWriterの全く同じです。そちらを参考にしてください。
コメント