Datagridview erste Zeile Datatable soll nicht Header werden

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Lord Luxor.

    Datagridview erste Zeile Datatable soll nicht Header werden

    Hallo,

    ich und das DGV kämpfen wieder miteinander. Ich bin immer noch dabei CSVs zu importieren. Dabei soll die CSV ausgelesen werden und dann die Spalten den Feldern einer Datentabelle zugewiesen werden. Funktioniert soweit alles.
    Jetzt möchte ich noch CSV-Dateien verarbeiten können, die keine Spaltenüberschriften haben. Das kann ja auch mal vorkommen. Aber das DGV nimmt von der Datatable, die ich als Datasource dem DGV zuweise, immer die erste Zeile und wandelt diese in den Header um.

    Ich dachte, wenn ich den Header schon mal definiere und dann die Datatable zuweise, könnte das klappen. Nein, dann habe ich meine selbst eingestellten Headerspalten vor den Headerspalten aus der Datatable.



    VB.NET-Quellcode

    1. Private Sub OpenFileDialog1_FileOk(sender As Object, e As CancelEventArgs) Handles OpenFileDialog1.FileOk
    2. Dim filePath As String = OpenFileDialog1.FileName
    3. TB_filename.Text = filePath
    4. Using reader = New StreamReader(filePath)
    5. Dim csv = New CsvReader(reader, CultureInfo.InvariantCulture)
    6. Using dr = New CsvDataReader(csv)
    7. Dim dt = New DataTable
    8. dt.Load(dr)
    9. 'CSV in dt geladen
    10. If CheckBox2.Checked = True Then
    11. DataGridView1.DataSource = dt
    12. Else
    13. For i = 1 To dt.Rows.Count
    14. Dim TeBoCol As New DataGridViewTextBoxColumn
    15. DataGridView1.Columns.Add(TeBoCol)
    16. With TeBoCol
    17. .HeaderText = "Spalte " & CStr(i)
    18. .Name = "Spalte" & CStr(i)
    19. End With
    20. Next
    21. DataGridView1.DataSource = dt
    22. End If
    23. '1. Zeile dt auslesen (Spaltenüberschriften)
    24. Dim csvspalten As New DataTable
    25. csvspalten.Columns.Add("ID")
    26. csvspalten.Columns.Add("Name")
    27. Dim zaehler As Integer = 0
    28. Dim row As DataRow = dt.Rows(0)
    29. 'Einzelne Spaltenüberschriften mit ID versehen und in csvspalten ablegen
    30. If CheckBox2.Checked = True Then
    31. For Each item As DataColumn In row.Table.Columns
    32. Dim R As DataRow = csvspalten.NewRow
    33. R("ID") = zaehler + 1
    34. R("Name") = item
    35. csvspalten.Rows.Add(R)
    36. zaehler = zaehler + 1
    37. Next
    38. Else
    39. For i = 1 To row.Table.Columns.Count
    40. Dim R As DataRow = csvspalten.NewRow
    41. R("ID") = zaehler + 1
    42. R("Name") = "Spalte " & CStr(i)
    43. csvspalten.Rows.Add(R)
    44. zaehler = zaehler + 1
    45. Next
    46. End If
    47. Dim dbfelder As New DataTable
    48. dbfelder.Columns.Add("ID")
    49. dbfelder.Columns.Add("Name")
    50. dbfelder.Columns.Add("Type")
    51. Dim feldname As New List(Of String) From {"DBFeld1", "DBFeld2", "DBFeld3", "DBFeld4", "DBFeld5"}
    52. db_feldnamen = feldname
    53. Dim feldtyp As New List(Of String) From {"String", "String", "String", "Integer", "String"}
    54. db_feldtypen = feldtyp
    55. For z = 1 To feldname.Count
    56. Dim A As DataRow = dbfelder.NewRow
    57. A("ID") = CStr(z)
    58. A("Name") = feldname(z - 1)
    59. A("Type") = feldtyp(z - 1)
    60. dbfelder.Rows.Add(A)
    61. Next
    62. Dim ComboCol As New DataGridViewComboBoxColumn
    63. DataGridView2.DataSource = dbfelder
    64. DataGridView2.Columns.Add(ComboCol)
    65. DataGridView2.Columns(0).Visible = False
    66. With ComboCol
    67. .HeaderText = "CSV-Feld"
    68. .Name = "CSV"
    69. .DataSource = csvspalten
    70. .DisplayMember = "Name"
    71. .ValueMember = "ID"
    72. End With
    73. End Using
    74. End Using
    75. End Sub


    Übersehe ich da eine Eigenschaft des DGVs? Oder wie kann ich dem DGV sagen, dass es nicht die erste Zeile als Header nehmen soll?

    Bye
    Markus
    8-Bit Nerd - Retro-Computer Junkie - Elektronik-Fuzzi - Lötkolben-Jongleur
    Lord Luxors Retrogalerie llrg.me
    Da steigt man ja gar nicht durch, und wozu brauchst du 3 Tabellen?
    Du wirfst alles zusammen in eine einzige Funktion, das ist schlecht.
    Mach dir *eine* Funktion, die nichts anderes macht als eine DataTable zurückzugeben. Dieser Funktion übergibt du den Pfad zur Datei und möglichst noch die Angabe, ob die erste Zeile der CSV-Datei einen Header darstellt.
    VB hat eine tolle Funktion, die C# nicht hat (aber benutzen kann), nämlich Microsoft.VisualBasic.FileIO.TextFieldParser, den machst du dir zunutze.

    Erst wenn du eine DataTable zurückbekommst, die bereits brauchbare Column.Names aufweist, machst weiter.

    Nachtrag: Google hilft. Hinweis: Suche vielleicht nicht nach VB, sondern nach C# und TextFieldParser, da kommen eher die brauchbaren Antworten. Überstzungshilfen von C# nach VB hat das Netz auch.
    Ich nehmen an, dass du diesen hier verwendest CsvHelper

    Zitat von joshclose.github.io/CsvHelper/getting-started/

    Let's say out CSV file doesn't have a header at all.

    Quellcode

    1. 1,one
    2. 2,two


    First we need to tell the reader that there is no header record, using configuration.

    C#-Quellcode

    1. var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    2. {
    3. HasHeaderRecord = false,
    4. };
    5. using (var reader = new StreamReader("path\\to\\file.csv"))
    6. using (var csv = new CsvReader(reader, config))
    7. {
    8. var records = csv.GetRecords<Foo>();
    9. }

    @HenryV: Danke, dass es am CSVHelper lag, hätte ich nicht vermutet.

    Dksksm schrieb:

    Da steigt man ja gar nicht durch, und wozu brauchst du 3 Tabellen?
    Du wirfst alles zusammen in eine einzige Funktion, das ist schlecht.


    Das kommt auch noch, ich mache im Entwicklungsprozess das eigentlich immer so, da habe ich besseren Überblick. Wenn das funktioniert, dann optimiere ich und unterteile den Code u.U. in einzelne Funktionen.

    Aber Danke für die Tipps.
    8-Bit Nerd - Retro-Computer Junkie - Elektronik-Fuzzi - Lötkolben-Jongleur
    Lord Luxors Retrogalerie llrg.me

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Lord Luxor“ ()

    Lord Luxor schrieb:


    Das kommt auch noch, ich mache im Entwicklungsprozess das eigentlich immer so, da habe ich besseren Überblick. Wenn das funktioniert, dann optimiere ich und unterteile den Code u.U. in einzelne Funktionen.


    Ich glaube dir, dass du das glaubst. So habe ich nämlich auch anfangs "programmiert". Das ist der größte Irrtum überhaupt. Dass Du nicht weißt was dein Code macht hat deine Antwort an @HenryV schon deutlich gemacht.
    Ein möglicherweise oder augenscheinlich korrektes Ergebnis bedeutet auch nicht, etwas fehlerfrei entwickelt zu haben. Kleine Änderung irgendwo und *Bamm* alles ist im A..... Und schon geht die Sucherei los. Jemand anderes arbeitet mit deinem Tool und du bist im Urlaub, herzlichen Glückwunsch.
    Danke @Dksksm. Habe meinen Code zum Erzeugen der DT in eine separate Function ausgegliedert.

    VB.NET-Quellcode

    1. Function Dateileser(filename As String, header As Boolean) As DataTable
    2. Dim dt = New DataTable
    3. Using MyReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(filename)
    4. MyReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
    5. MyReader.Delimiters = New String() {","}
    6. MyReader.HasFieldsEnclosedInQuotes = True
    7. Dim currentRow As String()
    8. Dim zeile As Integer = 0
    9. While Not MyReader.EndOfData
    10. Try
    11. currentRow = MyReader.ReadFields()
    12. If zeile = 0 Then
    13. If header = False Then
    14. For i = 1 To currentRow.Count
    15. dt.Columns.Add("Spalte " & CStr(i), Type.GetType("System.String"))
    16. Next
    17. Dim R As DataRow = dt.NewRow
    18. For i = 0 To currentRow.Count - 1
    19. R(i) = currentRow(i)
    20. Next
    21. dt.Rows.Add(R)
    22. Else
    23. For i = 1 To currentRow.Count
    24. dt.Columns.Add(currentRow(i - 1), Type.GetType("System.String"))
    25. Next
    26. End If
    27. Else
    28. Dim R As DataRow = dt.NewRow
    29. For i = 0 To currentRow.Count - 1
    30. R(i) = currentRow(i)
    31. Next
    32. dt.Rows.Add(R)
    33. End If
    34. Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
    35. MsgBox("Zeile " & ex.Message & " ist nicht korrekt.")
    36. End Try
    37. zeile = zeile + 1
    38. End While
    39. End Using
    40. Return dt
    41. End Function


    Funktioniert jetzt wunderbar mit oder ohne Spaltenüberschrift in der CSV-Datei
    8-Bit Nerd - Retro-Computer Junkie - Elektronik-Fuzzi - Lötkolben-Jongleur
    Lord Luxors Retrogalerie llrg.me