Проблемы чтения данных из CSV - проблемы сортировки и форматирования - PullRequest
0 голосов
/ 01 февраля 2020

В VB. NET я пытаюсь загрузить CSV-файл в DataTable, который в конечном итоге будет извлечен в DataGridView.

Проблема, с которой я продолжаю сталкиваться - это форматирование данных. извлекается из файла CSV.

Все данные считываются в виде строк, что является проблемой, когда я sh сортирую столбцы, содержащие числа. Кажется, что все они отсортированы по алфавиту, а не по номерам.

Поэтому я клонировал DataTable и установил для некоторых столбцов значение .DataType = System.Type.GetType("System.Int32"), а для некоторых столбцов - .DataType = System.Type.GetType("System.Decimal")

Но затем я столкнулся с новым проблема с моими данными, не вписывающимися в эти новые столбцы DataType.

Некоторые из моих столбцов данных содержат такие числа:

2,090
1,129
5,324 

А некоторые столбцы содержат такие данные:

1.82%
5.34%
54.32%

У меня большой объем данных - не менее 20000 строк или более, поэтому я хотел бы избежать циклического прохождения каждой строки, а затем каждого столбца, чтобы преобразовать значение в правильный формат.

Есть ли лучший способ сделать это?

1 Ответ

0 голосов
/ 02 февраля 2020

Мне удалось решить проблему, с которой я столкнулся, с помощью Джими

Вот как я решил ее

Imports System.ComponentModel
Imports System.Globalization
Imports System.IO
Public Class Form2

    Public Sub LoadCsvFile3(fileName As String)
        MyDataGridView.Columns.Clear()
        MyDataGridView.DataSource = Nothing

        Dim reader As New StreamReader(fileName)
        Dim csv As New CsvHelper.CsvReader(reader, New CultureInfo("en-US"))
        csv.Configuration.RegisterClassMap(Of MyColumnsMap)()
        Dim records = csv.GetRecords(Of MyColumns).ToList

        Dim myDataTable As DataTable
        myDataTable = ToDataTable(records)
        MyDataGridView.DataSource = myDataTable
        MyDataGridView.Refresh()
    End Sub

    Private Function ToDataTable(Of T)(data As IList(Of T)) As DataTable
        Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T))
        Dim dt As New DataTable()
        For i As Integer = 0 To properties.Count - 1
            Dim [property] As PropertyDescriptor = properties(i)
            dt.Columns.Add([property].Name, [property].PropertyType)
        Next
        Dim values As Object() = New Object(properties.Count - 1) {}
        For Each item As T In data
            For i As Integer = 0 To values.Length - 1
                values(i) = properties(i).GetValue(item)
            Next
            dt.Rows.Add(values)
        Next
        Return dt
    End Function

End Class

Public Class MyColumns
    Public Property MyWord As String
    Public Property MyNumber As Integer
    Public Property MyPercent As Decimal
End Class

Public NotInheritable Class MyColumnsMap
    Inherits CsvHelper.Configuration.ClassMap(Of MyColumns)
    Sub New()
        Map(Function(x) x.MyWord).Name("My Words")
        Map(Function(x) x.MyNumber).Name("My Numbers") _
            .TypeConverterOption.CultureInfo(New CultureInfo("en-US")) _
            .TypeConverterOption.NumberStyles(NumberStyles.Number)
        Map(Function(x) x.MyPercent).Name("My Percents") _
            .ConvertUsing(Function(Row)
                              Dim trimmingChars = New Char() {"%"c, "$"c}
                              Return Row.GetField(Of String)("CTR").Trim(trimmingChars)
                          End Function)
    End Sub
End Class
...