我目前正在开发一个 .NET WinForms 应用程序,该应用程序读取 8 个相同格式的 csv 文件,并将每个 CSV 文件的数据存储在一个对象中,并提供修改/检索数据的方法。
CSV 文件的每一行都包含有关策略的数据。
我正在使用的类/对象的结构是这样的:
政策
该类/对象存储与单个策略相关的所有数据,即 CSV 文件的一行。该类有一个名为 polData
的成员,它是一个 OrderedDictionary
。 polData
将每个字段存储为字符串,并以字段标题作为键。
数据文件
此类/对象存储从 csv 文件读取的所有数据,即每个策略。该类有一个名为 polCollection
的成员,它是一个 OrderedDictionary
。 polCollection
使用策略 ID 作为键存储所有策略对象。
对于这两个类,我都使用了 OrderedDictionary
,因为我需要保留将数据添加到字典中的顺序。
创建并填充这些对象后,我需要将其中一个输出到 datagridview
。因此,我想使用字典中的数据创建一个DataTable
。请在下面找到我的方法。我的直觉是有一种更有效的方法,因此我希望得到任何反馈:
在DataFile
类中,我有以下方法:
Public Function toDataTable() As DataTable
Dim dt As New DataTable
Dim fieldHeader As String
Dim i As Integer
Dim pol As Policy
'//add columns to datatable
'//there are 68 columns.
'//the calcFieldHeader function returns the header string based on the header index
For i = 0 To 67
fieldHeader = tools.calcFieldHeader(i)
dt.Columns.Add(fieldHeader)
Next i
'//loop through each policy in polCollection
'//add policy rows to datatable
For Each key In polCollection.keys
pol = polCollection(key)
dt.Rows.Add(pol.toArray)
Next key
Return dt
End Function
在Policy
类中,我有以下方法:
Public Function toArray() As String()
Dim result(67) As String
Dim inx As Integer
inx = 0
For Each key In polData.keys
result(inx) = polData(key).ToString
inx = inx + 1
Next (key)
Return result
End Function
最佳答案
您不需要使用字典。将 CSV 直接解析到数据表中。
Private Function csvToDatatable(files As List(Of String), Optional skipxLines As Integer = 0) As DataTable
Dim vbReader As Microsoft.VisualBasic.FileIO.TextFieldParser
Dim dt As New DataTable
'loop through the files from the list
For Each filePath In files
If File.Exists(filePath) Then
'keep track of lineCount for each file
Dim lineCount As Integer = 1
'setup TextFieldParser for CSV
vbReader = New Microsoft.VisualBasic.FileIO.TextFieldParser(filePath)
vbReader.TextFieldType = FileIO.FieldType.Delimited
vbReader.SetDelimiters(",")
While Not vbReader.EndOfData
Try
'read each line item
Dim currentRow = vbReader.ReadFields()
'Option skip x lines incase there are header records
If lineCount > skipxLines Then
'set generic columns using count of fields
If dt.Columns.Count = 0 Then
For i = 0 To UBound(currentRow)
dt.Columns.Add("Column" & i.ToString)
Next
Else
If UBound(currentRow) <> dt.Columns.Count - 1 Then
'check to make sure array of fields is the same size as data columns
Throw New Microsoft.VisualBasic.FileIO.MalformedLineException
End If
End If
'add row with data from currentRow array
dt.Rows.Add(currentRow)
End If
Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
MsgBox("Line " & lineCount & " in file " & filePath & " is not valid and will be skipped.")
End Try
lineCount += 1
End While
End If
Next
Return dt
End Function
此函数的使用如下所示。
Dim fileList As New List(Of String)
fileList.Add("C:\exports\texting.csv")
fileList.Add("C:\exports\texting2.csv")
theGrid.DataSource = csvToDatatable(fileList, 1)
theGrid.DataBind()
在此示例中,我假设存在 header 记录。
关于.net - 从字典生成数据表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17468764/