unbekannte csv (und xls) importieren und filtern

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von Dksksm.

    unbekannte csv (und xls) importieren und filtern

    Neu

    Hallo ihr lieben
    Ich habe mir vor einiger Zeit mal eine Funktion geschrieben, mit der ich csv und xls in ein DGV lade (ohne DataSet). Hiermit importiere ich Preislisten.
    Für die Daten im DGV kann ich dann festlegen in welcher Spalte was steht - also Artikelname in Spalte 2, ArtikelNr. in Spalte 1, usw.
    Nach einem Klick auf eine DGV row, werden die Artikelmerkmale dann entsprechend meinen Einstellungen in Textboxen geschrieben, damit ich sie weiter verarbeiten kann und im Bestand speichern kann.

    Nun möchte ich aber die importiere Liste durchsuchbar machen. Ich denke an dieser Stelle macht es dann Sinn das DGV an eine Bindingsource zu binden, damit ich die BS.Filter Methode verwenden kann und mir nicht fürs DGV irgendwas basteln muss.
    Also habe ich meinen Code so geändert, dass nicht mehr direkt ins DGV importiert wird, sondern in eine DatTable, welche dann über eine Bindingsource am DGV hängt - das klappt.

    Nun scheitere ich aber an der Filter Methode, denn mi sind ja die Spaltennamen (bzw. deren Menge) unbekannt.
    Diese also mit Namen ansprechen "​ source1.Filter = "artist = 'Dave Matthews' OR cd = 'Tigerlily'";" klappt nicht.

    Wie filtere ich meine unbekannte Liste am besten?
    Dazu habe ich eine kleine Demo angehängt. Den xls Import habe ich dazu auskommentiert, damit keine Zusatz dll benötigt wird.
    Es geht also nur csv. Eine csv Datei liegt im Hauptordner der Solution bei.
    [color=rgb(230, 230, 230); font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 14px; white-space: pre; background-color: rgb(47, 47, 47)]
    [/color]
    Dateien
    • DGVTest.zip

      (23,08 kB, 9 mal heruntergeladen, zuletzt: )

    Neu

    Damit ich das auch verstehe: Du importierst eine CSV, hast dann die Daten im DGV und dann willst Du was in die TextBox eingeben. Was denn zum Beispiel? Und was soll dann im DGV angezeigt werden? Wie soll es denn im besten Fall laufen? Deine Beispieldaten geben leider zuwenig her, damit ich mir ein Bild davon machen kann. Konkretere Daten wären sinnvoll. Wenn in der 1. Spalte der Artikelname oder in der 2. die Kategorie oder sowas immer stehen würde, ließe sich da bestimmt was machen (allerdings m.E. ohne BS-Filter)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Neu

    So, kleine Änderungen und es läuft. Kannst testen mit dem Text:
    Column_1 = '2.1' OR Column_5 = '2.5'

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Private bs As New BindingSource
    4. Private Sub Import()
    5. TBFilter.Text = String.Empty
    6. 'Open File Dialog zum öffnen der csv
    7. Dim Filepath As String
    8. Using O As New OpenFileDialog With {.Filter = "Preislisten(*.xls, *.xlsx, *.csv) | *.xls;*.xlsx;*.csv", .Multiselect = False, .Title = "Rechnung auswählen"}
    9. O.InitialDirectory = ".\\.\\"
    10. If O.ShowDialog <> 1 Then Exit Sub
    11. Filepath = O.FileName
    12. End Using
    13. Dim extension = Path.GetExtension(Filepath)
    14. Dim tbl = New DataTable
    15. If extension = ".csv" Then
    16. Dim lines = IO.File.ReadAllLines(Filepath)
    17. Dim colCount = lines.First.Split(","c).Length
    18. For i = 1 To colCount
    19. tbl.Columns.Add(New DataColumn("Column_" & i, GetType(String)))
    20. Next
    21. For Each line In lines
    22. Dim objFields = From field In line.Split(","c)
    23. Dim count As Integer = 0
    24. For Each item In objFields
    25. count += 1
    26. If count > colCount Then
    27. tbl.Columns.Add(New DataColumn("Column_" & count, GetType(String)))
    28. colCount += 1
    29. End If
    30. Next
    31. Dim newRow = tbl.Rows.Add()
    32. newRow.ItemArray = objFields.ToArray()
    33. Next
    34. Else
    35. 'Else Zweig habe ich auskommentiert - damit kein Import von EPPLUS nötig ist
    36. 'Dim ExcelFile As FileInfo = New FileInfo(Filepath)
    37. 'Using package As ExcelPackage = New ExcelPackage(ExcelFile)
    38. ' Dim worksheet As ExcelWorksheet = package.Workbook.Worksheets(1)
    39. ' 'benötigte Spalten erstellen
    40. ' Dim ColAmount = worksheet.Dimension.[End].Column
    41. ' For i = 1 To ColAmount
    42. ' tbl.Columns.Add(New DataColumn("Column_" & i, GetType(String)))
    43. ' Next
    44. ' 'Zellenweise einlesen der Daten aus Excel
    45. ' For i = 1 To worksheet.Dimension.[End].Row '1. Schleife durch Rows
    46. ' Dim objFields As New List(Of String)
    47. ' For j = 1 To ColAmount '2. Schleife durch Spalten
    48. ' If worksheet.Cells(i, j).Value IsNot Nothing Then
    49. ' objFields.Add(worksheet.Cells(i, j).Value.ToString)
    50. ' End If
    51. ' Next
    52. ' Dim newRow = tbl.Rows.Add()
    53. ' newRow.ItemArray = objFields.ToArray()
    54. ' Next
    55. 'End Using
    56. End If
    57. bs.DataSource = tbl
    58. bs.Filter = String.Empty
    59. DataGridView1.DataSource = bs
    60. End Sub
    61. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    62. Import()
    63. End Sub
    64. Private Sub TBFilter_TextChanged(sender As Object, e As EventArgs) Handles TBFilter.TextChanged
    65. bs.Filter = String.Empty
    66. If TBFilter.Text.Length > 0 Then
    67. Try
    68. bs.Filter = TBFilter.Text
    69. Catch ex As Exception
    70. bs.Filter = String.Empty
    71. End Try
    72. End If
    73. 'Hier soll im TextChange Event die Liste im DGV gefiltert werden
    74. End Sub
    75. End Class

    Neu

    Ich meine genau das, was @Dksksm gemacht hat, es sollen aber alle Columns durchsucht werden.

    Mein Problem ist aber, dass ja die Anzahl der Columns immer variiert.
    Liste 1 hat 5 Spalten, Liste 2 hat z.B. 8 Spalten.
    Es soll aber alles durchsucht werden.

    ErfinderDesRades schrieb:

    wie können dir die Spalten unbekannt sein

    Ich meine damit, bei jedem Import unterschiedlich

    VaporiZed schrieb:

    Damit ich das auch verstehe: Du importierst eine CSV, hast dann die Daten im DGV und dann willst Du was in die TextBox eingeben. Was denn zum Beispiel? Und was soll dann im DGV angezeigt werden? Wie soll es denn im besten Fall laufen?

    Ich importiere wie gesagt Preislisten in die DataTable, welche über die BS am DGV hängt.
    Mit der Textbox möchte ich dies Filtern (eine Suchfunktion quasi).
    Wenn mir in der Liste also 3 Einträge angezeigt werden:
    1. 1 | 123 | Cola | 3€
    2. 2 | 456 | Cola Light | 3€
    3. 3 | 789 | Pepsi | 2,80€
    Gebe ich nun in die TB Cola ein, sollen Eintrag 1 und 2 angezeigt werden.
    Gebe ich Light ein, soll nur Eintrag 2 angezeigt werden.
    Wichtig ist mir hierbei (und das ist mein eigentliches Problem), dass immer alle Spalten durchsucht werden.
    (Also eine Suche nach 3 z.B. zeigt alle Zeilen (1 und 2 wegen Preis, die dritte wegen der ersten Spalte)
    Aber die Spaltenanzahl varriert ja eben - je nach importierter csv Datei.

    Muss ich dann beim Filtern (oder eben beim importieren) die Menge der Spalten auslesen (oder speichern) und dann in einer Schleife meinen Suchstring zusammenbauen? Also sinngemäß:

    VB.NET-Quellcode

    1. For each column in DataTAble
    2. Filterstring &= column.name = Suchstring
    3. Next

    Oder geht eben genau das eleganter?

    Neu

    DerSmurf schrieb:

    Also eine Suche nach 3 z.B. zeigt alle Zeilen (1 und 2 wegen Preis, die dritte wegen der ersten Spalte)
    Eine blöde Frage jetzt dazu:
    Was wird angezeigt, wenn du jetzt eine 5 angibst?

    DerSmurf schrieb:

    Aber die Spaltenanzahl varriert ja eben - je nach importierter csv Datei.
    Was würde dann in den anderen Spalten stehen?

    Verstehe ich dich da jetzt richtig: In der Textbox wird ein Suchstring eingegeben, denn du in allen Colums absuchen willst und bei einem Treffer die Zeile ausfiltert...
    Weil - dann brauchst deinen Filterstring jedesmal in Abhängigkeit deiner Anzahl Colums neu in einer OR-Kombination, wie oben @Dksksm gepostet hat, erstellen und auf den BS.Filter zuweisen...

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VB1963“ ()

    Neu

    VB1963 schrieb:

    Eine blöde Frage jetzt dazu:
    Was wird angezeigt, wenn du jetzt eine 5 angibst?

    Na, dann wird jede Zelle nach "5" durchsucht. Es wird dann nur der zweite Eintrag angezeigt, da dort in Spalte 2 456 steht.

    VB1963 schrieb:

    Was würde dann in den anderen Spalten stehen?

    Den Inhalt kenne ich vorher nicht. In der Regel sind die importierten Preislisten alle ähnlich. art.Nr. / EAN / Name / EK / Mwst. / UVP
    Manche Preislisten bomardieren dich aber mit Infos. Z.B. Beschreibung, Maße, Lagerstandort, usw.

    VB1963 schrieb:

    Verstehe ich dich da jetzt richtig: In der Textbox wird ein Suchstring eingegeben, denn du in allen Colums absuchen willst und bei einem Treffer die Zeile ausfiltert...

    absolut korrekt.
    Und dazu fällt mir dann eben nur die oben gepostete Lösung ein:

    VB.NET-Quellcode

    1. For each col in DT
    2. Filterstring &= col.name = Suchstring
    3. next


    Die erscheint mir aber irgendwie nicht so sauber.


    Neu

    Ums Eck gedacht. einfach eine Spalte 0 mit der ganzen Zeile zufügen und nur in der Column_0 suchen.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Private bs As New BindingSource
    4. Private tbl As New DataTable
    5. Private Sub Import()
    6. 'Open File Dialog zum öffnen der csv
    7. Dim Filepath As String
    8. Using O As New OpenFileDialog With {.Filter = "Preislisten(*.xls, *.xlsx, *.csv) | *.xls;*.xlsx;*.csv", .Multiselect = False, .Title = "Rechnung auswählen"}
    9. O.InitialDirectory = "..\\..\\"
    10. If O.ShowDialog <> 1 Then Exit Sub
    11. Filepath = O.FileName
    12. End Using
    13. Dim extension = Path.GetExtension(Filepath)
    14. TBFilter.Text = String.Empty
    15. tbl = New DataTable
    16. If extension = ".csv" Then
    17. Dim lines = IO.File.ReadAllLines(Filepath)
    18. Dim colCount = lines.First.Split(","c).Length
    19. For i = 0 To colCount
    20. tbl.Columns.Add(New DataColumn("Column_" & i, GetType(String)))
    21. Next
    22. For Each line In lines
    23. Dim objFields = (From field In line.Split(","c)).ToList()
    24. Dim count As Integer = 0
    25. For Each item In objFields
    26. count += 1
    27. If count > colCount Then
    28. tbl.Columns.Add(New DataColumn("Column_" & count, GetType(String)))
    29. colCount += 1
    30. End If
    31. Next
    32. objFields.Insert(0, line)
    33. Dim newRow = tbl.Rows.Add()
    34. newRow.ItemArray = objFields.ToArray()
    35. Next
    36. Else
    37. 'Else Zweig habe ich auskommentiert - damit kein Import von EPPLUS nötig ist
    38. 'Dim ExcelFile As FileInfo = New FileInfo(Filepath)
    39. 'Using package As ExcelPackage = New ExcelPackage(ExcelFile)
    40. ' Dim worksheet As ExcelWorksheet = package.Workbook.Worksheets(1)
    41. ' 'benötigte Spalten erstellen
    42. ' Dim ColAmount = worksheet.Dimension.[End].Column
    43. ' For i = 1 To ColAmount
    44. ' tbl.Columns.Add(New DataColumn("Column_" & i, GetType(String)))
    45. ' Next
    46. ' 'Zellenweise einlesen der Daten aus Excel
    47. ' For i = 1 To worksheet.Dimension.[End].Row '1. Schleife durch Rows
    48. ' Dim objFields As New List(Of String)
    49. ' For j = 1 To ColAmount '2. Schleife durch Spalten
    50. ' If worksheet.Cells(i, j).Value IsNot Nothing Then
    51. ' objFields.Add(worksheet.Cells(i, j).Value.ToString)
    52. ' End If
    53. ' Next
    54. ' Dim newRow = tbl.Rows.Add()
    55. ' newRow.ItemArray = objFields.ToArray()
    56. ' Next
    57. 'End Using
    58. End If
    59. bs.DataSource = tbl
    60. bs.Filter = String.Empty
    61. DataGridView1.DataSource = bs
    62. DataGridView1.Columns("Column_0").Visible = False
    63. End Sub
    64. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    65. Import()
    66. End Sub
    67. Private Sub TBFilter_TextChanged(sender As Object, e As EventArgs) Handles TBFilter.TextChanged
    68. bs.Filter = String.Empty
    69. If TBFilter.Text.Length > 0 AndAlso tbl.Rows.Count > 0 Then
    70. Try
    71. bs.Filter = $"[Column_0] like '*{TBFilter.Text}*'"
    72. Catch ex As Exception
    73. bs.Filter = String.Empty
    74. End Try
    75. End If
    76. 'Hier soll im TextChange Event die Liste im DGV gefiltert werden
    77. 'Column_1 = '2.1' OR Column_5 = '2.5'
    78. End Sub
    79. End Class


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

    Neu

    Sicher ist das Pseudocode und mir ist bewusst, dass die Idee dahinter wohl nicht die Beste ist.
    Ich habe versucht, dies mit

    DerSmurf schrieb:

    Also sinngemäß:

    zu verdeutlichen. Aber ist mir wohl nicht gelungen :o)
    Der vollständigkeit halber hier der Code, der mir im Kopf rumgeistert: (dafür habe ich colcount Klassenweit gültig gemacht)
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Sub TBFilter_TextChanged(sender As Object, e As EventArgs) Handles TBFilter.TextChanged
    2. Dim searchstring = ""
    3. If TBFilter.Text.Length > 0 Then
    4. searchstring = TBFilter.Text
    5. For i = 1 To colcount
    6. Searchstring &= "Column_" & i & " = '" & Searchstring & "'"
    7. If i < colcount Then Searchstring &= " OR "
    8. Next
    9. End If
    10. bs.Filter = String.Empty
    11. If searchstring <> "" Then
    12. Try
    13. bs.Filter = searchstring
    14. Catch ex As Exception
    15. bs.Filter = String.Empty
    16. End Try
    17. End If
    18. End Sub


    Aber die Lösung von @Dksksm aus Post 11 ist natürlich die Lösung des Problems.

    Neu

    Hier mal ein komplett anderer Ansatz:

    Zunächst einmal schreibst du dir eine Basisklasse für alle Datenmodelle die es zu importieren gilt:

    Basisklasse Entity

    VB.NET-Quellcode

    1. Public Class Base
    2. End Class



    Diese Basisklasse kann zunächst erstmal gar nichts außer existieren. Anschließend schreibst du dir zwei Attribute die du für die Datenmodelle brauchst:

    Order Attribut

    VB.NET-Quellcode

    1. <AttributeUsage(AttributeTargets.Property, Inherited:=False, AllowMultiple:=False)>
    2. Public NotInheritable Class OrderAttribute
    3. Inherits Attribute
    4. Private ReadOnly _Order As Integer
    5. Public Sub New(ByVal Optional OrderNumber As Integer = 0)
    6. _Order = OrderNumber
    7. End Sub
    8. Public ReadOnly Property Order As Integer
    9. Get
    10. Return _Order
    11. End Get
    12. End Property
    13. End Class



    ElementName Attribut

    VB.NET-Quellcode

    1. <AttributeUsage(AttributeTargets.Property, Inherited:=False, AllowMultiple:=False)>
    2. Public NotInheritable Class ElementNameAttribute
    3. Inherits Attribute
    4. Private ReadOnly _ElementName As String
    5. Public Sub New(ByVal Optional Name As String = "")
    6. _ElementName = Name
    7. End Sub
    8. Public ReadOnly Property ElementName As String
    9. Get
    10. Return _ElementName
    11. End Get
    12. End Property
    13. End Class



    Dann benötigst du eine Logic-Klasse für den Im- und Export:

    Logic

    VB.NET-Quellcode

    1. Public Class Serializer(Of T As New)
    2. Public Shared Function Serialize(FileName As String, Data As T, HeaderVisible As Boolean, Optional Separator As Char = ";"c) As String
    3. Dim HeadlineWritten As Boolean = False
    4. Dim ExportText As String = String.Empty
    5. If Data.GetType().IsGenericType AndAlso TypeOf Data Is IEnumerable Then
    6. For Each elem In TryCast(Data, IEnumerable)
    7. Dim Properties = (From prop In elem.GetType().GetProperties()
    8. Where Attribute.IsDefined(prop, GetType(Entity.OrderAttribute))
    9. Order By TryCast(prop.GetCustomAttributes(GetType(Entity.OrderAttribute), False).FirstOrDefault(), Entity.OrderAttribute).Order
    10. Select prop).ToList()
    11. If HeaderVisible AndAlso Not HeadlineWritten Then
    12. HeadlineWritten = True
    13. add(ExportText, String.Join(Separator, Properties.Select(Function(n) TryCast(n.GetCustomAttributes(GetType(Entity.ElementNameAttribute), False).FirstOrDefault(), Entity.ElementNameAttribute).ElementName).ToList()))
    14. End If
    15. add(ExportText, String.Join(Separator, Properties.Select(Function(n) n.GetValue(elem)).ToList()))
    16. Next
    17. Else
    18. Dim Properties = (From prop In Data.GetType().GetProperties()
    19. Where Attribute.IsDefined(prop, GetType(Entity.OrderAttribute))
    20. Order By TryCast(prop.GetCustomAttributes(GetType(Entity.OrderAttribute), False).FirstOrDefault(), Entity.OrderAttribute).Order
    21. Select prop).ToList()
    22. If HeaderVisible AndAlso Not HeadlineWritten Then
    23. HeadlineWritten = True
    24. add(ExportText, String.Join(Separator, Properties.Select(Function(n) TryCast(n, Reflection.PropertyInfo).GetCustomAttributes(GetType(Entity.ElementNameAttribute), False).FirstOrDefault()).ToList()))
    25. End If
    26. add(ExportText, String.Join(Separator, Properties.Select(Function(n) n.GetValue(n)).ToList()))
    27. End If
    28. Dim ret As String = ExportText
    29. Using x As New StreamWriter(FileName, False, Text.Encoding.UTF8)
    30. x.WriteLine(ret)
    31. End Using
    32. Return ret
    33. End Function
    34. Public Shared Function Deserialize(FileName As String, SkipFirstLine As Boolean, Optional Separator As Char = ";"c) As List(Of T)
    35. Dim ret As String
    36. Dim FirstLineSkipped As Boolean = False
    37. Using x As New StreamReader(FileName, Text.Encoding.UTF8)
    38. ret = x.ReadToEnd()
    39. End Using
    40. Dim Properties As List(Of Reflection.PropertyInfo) = (From prop In GetType(T).GetProperties()
    41. Where Attribute.IsDefined(prop, GetType(Entity.OrderAttribute))
    42. Order By TryCast(prop.GetCustomAttributes(GetType(Entity.OrderAttribute), False).FirstOrDefault(), Entity.OrderAttribute).Order
    43. Select prop).ToList()
    44. Dim Liste As New List(Of T)
    45. Dim elem As New T
    46. Dim Lines As List(Of String) = ret.Split(Chr(10), Chr(13)).ToList()
    47. For Each Line In Lines
    48. If Not String.IsNullOrWhiteSpace(Line) Then
    49. If SkipFirstLine AndAlso Not FirstLineSkipped Then
    50. FirstLineSkipped = True
    51. Continue For
    52. End If
    53. Dim Values As List(Of String) = Line.Split(Separator).ToList()
    54. Dim Counter As Integer = 0
    55. For Each Proper In Properties
    56. Select Case Proper.PropertyType
    57. Case GetType(String)
    58. GetType(T).GetProperty(Proper.Name).SetValue(elem, Values(Counter).ToString)
    59. Case GetType(Char)
    60. GetType(T).GetProperty(Proper.Name).SetValue(elem, CChar(Values(Counter)))
    61. Case GetType(Short)
    62. GetType(T).GetProperty(Proper.Name).SetValue(elem, CShort(Values(Counter)))
    63. Case GetType(Integer)
    64. GetType(T).GetProperty(Proper.Name).SetValue(elem, CInt(Values(Counter)))
    65. Case GetType(Long)
    66. GetType(T).GetProperty(Proper.Name).SetValue(elem, CLng(Values(Counter)))
    67. Case GetType(Single)
    68. GetType(T).GetProperty(Proper.Name).SetValue(elem, CSng(Values(Counter)))
    69. Case GetType(Double)
    70. GetType(T).GetProperty(Proper.Name).SetValue(elem, CDbl(Values(Counter)))
    71. Case GetType(Decimal)
    72. GetType(T).GetProperty(Proper.Name).SetValue(elem, CDec(Values(Counter)))
    73. Case GetType(Boolean)
    74. GetType(T).GetProperty(Proper.Name).SetValue(elem, CBool(Values(Counter)))
    75. Case GetType(Date)
    76. GetType(T).GetProperty(Proper.Name).SetValue(elem, CDate(Values(Counter)))
    77. Case GetType(Nullable(Of Short))
    78. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Short)), CShort(Values(Counter))))
    79. Case GetType(Nullable(Of Integer))
    80. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Integer)), CInt(Values(Counter))))
    81. Case GetType(Nullable(Of Integer))
    82. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Long)), CLng(Values(Counter))))
    83. Case GetType(Nullable(Of Single))
    84. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Single)), CSng(Values(Counter))))
    85. Case GetType(Nullable(Of Double))
    86. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Double)), CDbl(Values(Counter))))
    87. Case GetType(Nullable(Of Decimal))
    88. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Decimal)), CDec(Values(Counter))))
    89. Case GetType(Nullable(Of Boolean))
    90. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Boolean)), CBool(Values(Counter))))
    91. Case GetType(Nullable(Of Date))
    92. GetType(T).GetProperty(Proper.Name).SetValue(elem, If(Values(Counter) Is Nothing, CType(Nothing, Nullable(Of Date)), CDate(Values(Counter))))
    93. End Select
    94. Counter += 1
    95. Next
    96. Liste.Add(elem)
    97. elem = New T
    98. End If
    99. Next
    100. Return Liste
    101. End Function
    102. End Class



    Und anschließend legst du dir für jeden Importtyp eine Klasse an, die vom Basisdatenmodel erbst. Die Reihenfolge der Spalten in der CSV steuerst du über das OrderAttribut, Spaltenüberschriften über das ElementName-Attribut.
    Ein Entität würde dann beispielsweise so aussehen:

    ExampleClass

    VB.NET-Quellcode

    1. Public Class ExampleClass
    2. Inherits Base
    3. <Order(1), ElementName("Nr")>
    4. Public Property ID As Integer
    5. <Order(2), ElementName("Text")>
    6. Public Property Text As String
    7. <Order(3), ElementName("Name")>
    8. Public Property Name As String
    9. End Class



    Export zu CSV:
    Export CSV

    VB.NET-Quellcode

    1. Serializer(Of List(Of ExampleClass)).Serialize("C:\Temp\Testfile.csv",
    2. New List(Of ExampleClass) From
    3. {
    4. New ExampleClass With {.ID = 1, .Name = "Testname1", .Text = "TestText1"},
    5. New ExampleClass With {.ID = 2, .Name = "Testname2", .Text = "TestText2"},
    6. New ExampleClass With {.ID = 3, .Name = "Testname3", .Text = "TestText3"}
    7. }, False)



    Import CSV

    VB.NET-Quellcode

    1. Dim ExampleList As List(Of ExampleClass) = Serializer(Of ExampleClass).Deserialize("C:\Temp\Testfile.csv", False)



    Ich weiß nicht ob sich das auf deinen speziellen Fall anwenden lässt, aber eine generische Liste ist mit Lamda durchsuchbar und filterbar.

    "Suchfunktion"

    VB.NET-Quellcode

    1. Dim SearchResults As List(Of ExampleClass) = ExampleList.Select(function(n) String.Concat(n.ID.ToString(), n.Text, n.Name)).Where(function(n) n.Contains(SUCHBEGRIFF)).ToList()




    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

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