Listview füllen und leeren

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von schnorklunder.

    Listview füllen und leeren

    Hallo Leute,

    ich komme bei folgendem Problem nicht weiter.

    Bei Button.Click Ereignis:

    -Programm schreibt den Inhalt der 3 Textboxen in vorhandene Excel Datei (funktioniert)
    -Programm gibt gerade den Inhalt der Excel Tabelle in Listview wieder aus (funktioniert auch)

    Sobald ich jedoch den 2. Eintrag über Button 2 bestätige, füllt sich das Listview doppelt...

    Beispiel auf 1 Spalte reduziert:

    Textbox1.text = Hallo --> Button.Click
    ---> Ausgabe in Listview =
    Hallo

    Textbox1.text = Welt ---> Button.Click
    ---> Ausgabe in Listview =
    Hallo
    Hallo
    Hallo
    Welt


    Ich dachte es wäre logisch, dann zuerst die Listview.Items.Clear() auszuführen und dann erst die Eintragungen zu machen, aber irgendwie klappt das nicht so, wie ich mir das dachte.
    Vielleicht ist auch der Ort des Befehls falsch, ich weiß es nicht ...

    Anbei mal mein Code:

    VB.NET-Quellcode

    1. Imports Microsoft.Office.Interop
    2. Public Class Form1
    3. Private MyLine As Integer = 1
    4. Private Sub cmdButton1_Click(sender As System.Object, e As System.EventArgs) Handles cmdButton1.Click
    5. ListView1.Items.Clear() 'Dachte, das ich das so lösen könnte...Geht aber nicht
    6. ' Textboxeinträge in vorhandene Excel Tabelle eintragen
    7. Dim xlObj As New Excel.Application
    8. xlObj.Visible = True
    9. Dim Mappe As Excel.Workbook = xlObj.Workbooks.Open("C:...\Test2.xlsx")
    10. Dim Tabelle As Excel.Worksheet = Mappe.Sheets("Tabelle1")
    11. Tabelle.Cells(MyLine, 1).Value = txtBox1.Text
    12. Tabelle.Cells(MyLine, 2).Value = txtBox2.Text
    13. Tabelle.Cells(MyLine, 3).Value = txtBox3.Text
    14. MyLine += 1
    15. Mappe.Save()
    16. Mappe.Close()
    17. xlObj.Quit()
    18. 'Wenn Wert vorhanden, dann Wert aus Excel auslesen und in Listview eintragen
    19. If ZelleGefuellt() = True Then
    20. For Each Xitem In ExcelRowlist
    21. Dim lvitem As ListViewItem
    22. lvitem = Me.ListView1.Items.Add(Xitem.C1)
    23. lvitem.SubItems.AddRange(New String() {Xitem.C2, Xitem.C3})
    24. Next
    25. End If
    26. End Sub
    27. ' zu generierende Spalten
    28. Private Structure ExcelRows
    29. Dim C1 As String
    30. Dim C2 As String
    31. Dim C3 As String
    32. End Structure
    33. 'Liste, in die die generierten Spalten eingetragen werden
    34. Private ExcelRowlist As List(Of ExcelRows) = New List(Of ExcelRows)
    35. Private Function ZelleGefuellt() As Boolean
    36. Dim Completed As Boolean = False
    37. 'Öffnen
    38. Dim MyExcel As New Excel.Application
    39. MyExcel.Workbooks.Open("C:\...\Test2.xlsx")
    40. 'Daten aus Excel einlesen
    41. MyExcel.Sheets("Tabelle1").activate()
    42. MyExcel.Range("A1").Activate()
    43. Dim ThisRow As New ExcelRows
    44. Do
    45. If MyExcel.ActiveCell.Value > Nothing Or MyExcel.ActiveCell.Text > Nothing Then
    46. ThisRow.C1 = MyExcel.ActiveCell.Value
    47. MyExcel.ActiveCell.Offset(0, 1).Activate()
    48. ThisRow.C2 = MyExcel.ActiveCell.Value
    49. MyExcel.ActiveCell.Offset(0, 1).Activate()
    50. ThisRow.C3 = MyExcel.ActiveCell.Value
    51. ExcelRowlist.Add(ThisRow)
    52. MyExcel.ActiveCell.Offset(1, -2).Activate()
    53. Else
    54. Completed = True
    55. Exit Do
    56. End If
    57. Loop
    58. 'Schließen
    59. MyExcel.Workbooks.Close()
    60. MyExcel = Nothing
    61. Return Completed
    62. End Function
    63. End Class


    Ich hoffe ihr versteht was ich da versuche und könnt mir auf die Sprünge helfen.

    Viele Grüße

    Stefan

    schnorklunder schrieb:

    VB.NET-Quellcode

    1. MyLine += 1

    Du musst MyLine wieder auf Null oder Deinen Wert setzen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich weiß nicht, ob ich deinen Hinweis richtig verarbeitet habe, aber die Umsetzung hat erstmal noch nichts gebracht.

    VB.NET-Quellcode

    1. Private Sub cmdButton1_Click(sender As System.Object, e As System.EventArgs) Handles cmdButton1.Click
    2. ''ListView1.Items.Clear(Xitem.C1)
    3. ' Textboxeinträge in vorhandene Excel Tabelle eintragen
    4. Dim xlObj As New Excel.Application
    5. xlObj.Visible = True
    6. Dim Mappe As Excel.Workbook = xlObj.Workbooks.Open("C:\Users\Lappi-Schnork\Desktop\Test2.xlsx")
    7. Dim Tabelle As Excel.Worksheet = Mappe.Sheets("Tabelle1")
    8. Tabelle.Cells(MyLine, 1).Value = txtBox1.Text
    9. Tabelle.Cells(MyLine, 2).Value = txtBox2.Text
    10. Tabelle.Cells(MyLine, 3).Value = txtBox3.Text
    11. MyLine += 1
    12. MyLine = 1 ' 1. Versuch an dieser Stelle
    13. Mappe.Save()
    14. Mappe.Close()
    15. xlObj.Quit()
    16. MyLine = 1 ' 2.Versuch an dieser Stelle
    17. ...


    MyLine = 0 lässt er nicht zu (sicher weil es Spalte 0 nicht gibt) und an den beiden gezeigten Positionen hat es keinen Einfluss.

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

    Setz doch einen Haltepunkt an den Beginn der Prozedur und sieh Dir an, was beim Debuggen passiert.
    Du musst natürlich Excel gleichzeitig beobachten.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Es scheint wirklich nur ein Problem in der Darstellung zu geben, denn die Werte werden korrekt in die Excel Datei eingespeichert.

    Nur ist die Ausgabe in der Listview nicht korrekt...

    Beim schrittweisen debuggen sieht eigentlich fast alles gut aus. Ich habe irgendwie die Vermutung, dass es an diesem Teil liegt

    VB.NET-Quellcode

    1. If ZelleGefuellt() = True Then
    2. For Each Xitem In ExcelRowlist
    3. Dim lvitem As ListViewItem
    4. lvitem = Me.ListView1.Items.Add(Xitem.C1)
    5. lvitem.SubItems.AddRange(New String() {Xitem.C2, Xitem.C3})
    6. Next
    7. End If


    Er addet nicht nur das neu die letzten beiden durch Button.Click eingetragenen Werte zur Listview, sondern lässt zusätzlich auch den alten Eintrag in der Listview stehen.

    Leider kann ich das nicht einfach verhindern, indem ich als erstes Ereignis beim Button.Click "Excel.Rowlist.Clear()" eingebe...

    Hat jemand eine Idee, wie ich das verbessern kann?
    Mach mal Option Strict On und erkläre mal bitte, was Dein Code machen soll.
    UNd dann überlegen wir, ob das, was da steht, Deiner Beschreibung entspricht oder nicht.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Guten Morgen Rod,

    ok dann zuerst die Erklärung, was gemacht werden soll.

    1. Der Inhalt der Textboxen 1-3 soll in eine vorhandene Excel-Tabelle eingetragen werden (funktioniert)
    2. Gleichzeitig soll die Tabelle wieder ausgelesen werden, und jeden neuen Eintrag in der Listview anzeigen (Der Anwender soll quasi seine Eingaben direkt in der Listview wiederfinden)

    Zu Option Strict On:

    gibt mir einige unschöne Meldungen, die ich versuche auszumerzen, so schon gelungen bei

    Dim Tabelle As Excel.Worksheet = CType(Mappe.Sheets("Tabelle1"), Excel.Worksheet)
    ...
    CStr(MyExcel.ActiveCell.Value)

    Beides waren Programmvorschläge und was anderes wüsste ich nicht zu machen.

    Allerdings bleiben 3 Einträge vom Typ "Option Strict On lässt spätes Binden nicht zu" übrig, wo ich nicht weiß, wie ich das korrigieren kann.


    Tabelle.Cells(MyLine, 1).Value = txtBox1.Text
    Tabelle.Cells(MyLine, 2).Value = txtBox2.Text
    Tabelle.Cells(MyLine, 3).Value = txtBox3.Text

    Die Zeilen stammen aus folgendem Code-Teil:

    VB.NET-Quellcode

    1. Private Sub cmdButton1_Click(sender As System.Object, e As System.EventArgs) Handles cmdButton1.Click
    2. ' Textboxeinträge in vorhandene Excel Tabelle eintragen
    3. Dim xlObj As New Excel.Application
    4. xlObj.Visible = True
    5. Dim Mappe As Excel.Workbook = xlObj.Workbooks.Open("C:\...\Test2.xlsx")
    6. Dim Tabelle As Excel.Worksheet = CType(Mappe.Sheets("Tabelle1"), Excel.Worksheet)
    7. Tabelle.Cells(MyLine, 1).Value = txtBox1.Text
    8. Tabelle.Cells(MyLine, 2).Value = txtBox2.Text
    9. Tabelle.Cells(MyLine, 3).Value = txtBox3.Text
    10. MyLine += 1
    11. Mappe.Save()
    12. Mappe.Close()
    13. xlObj.Quit()


    Wie kriegen wir die 3 Fehler ausgemerzt? Tabelle ist ja definiert, MyLine auch (Private MyLine As Integer = 1)
    OK. Mit Excel ist das so eine Sache und die Table.Values sind nicht von ohne, da mach mal Option Strict wieder auf Off.
    Spätes Binden:
    Die Variable nicht als Object, sondern asl Excel.Irgendwas deklarieren, das zeigt er an, wenn Du mit der Maus drauf bist.
    Kannst Du bitte mal den ganzen Code hochpacken, da seh ich vielleicht mehr als so.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. Imports Microsoft.Office.Interop
    2. Public Class Form1
    3. Private MyLine As Integer = 1
    4. Private Sub cmdButton1_Click(sender As System.Object, e As System.EventArgs) Handles cmdButton1.Click
    5. ' Textboxeinträge in vorhandene Excel Tabelle eintragen
    6. Dim xlObj As New Excel.Application
    7. xlObj.Visible = True
    8. Dim Mappe As Excel.Workbook = xlObj.Workbooks.Open("C:\...\Test2.xlsx")
    9. Dim Tabelle As Excel.Worksheet = CType(Mappe.Sheets("Tabelle1"), Excel.Worksheet)
    10. Tabelle.Cells(MyLine, 1).Value = txtBox1.Text
    11. Tabelle.Cells(MyLine, 2).Value = txtBox2.Text
    12. Tabelle.Cells(MyLine, 3).Value = txtBox3.Text
    13. MyLine += 1
    14. Mappe.Save()
    15. Mappe.Close()
    16. xlObj.Quit()
    17. 'Wenn Wert vorhanden, dann Wert aus Excel auslesen und in Listview eintragen
    18. If ZelleGefuellt() = True Then
    19. For Each Xitem In ExcelRowlist
    20. Dim lvitem As ListViewItem
    21. lvitem = Me.ListView1.Items.Add(Xitem.C1)
    22. lvitem.SubItems.AddRange(New String() {Xitem.C2, Xitem.C3})
    23. Next
    24. End If
    25. End Sub
    26. ' zu generierende Spalten für die Listview
    27. Private Structure ExcelRows
    28. Dim C1 As String
    29. Dim C2 As String
    30. Dim C3 As String
    31. End Structure
    32. 'Liste, in die die generierten Spalten eingetragen werden
    33. Private ExcelRowlist As List(Of ExcelRows) = New List(Of ExcelRows)
    34. Private Function ZelleGefuellt() As Boolean
    35. Dim Completed As Boolean = False
    36. 'Excel öffnen
    37. Dim MyExcel As New Excel.Application
    38. Dim Mappe As Excel.Workbook = MyExcel.Workbooks.Open("C:\...\Test2.xlsx")
    39. Dim Tabelle As Excel.Worksheet = CType(Mappe.Sheets("Tabelle1"), Excel.Worksheet)
    40. 'Daten aus Excel einlesen
    41. MyExcel.Range("A1").Activate()
    42. Dim ThisRow As New ExcelRows
    43. Do
    44. If CStr(MyExcel.ActiveCell.Value) > Nothing Or CStr(MyExcel.ActiveCell.Text) > Nothing Then
    45. ThisRow.C1 = CStr(MyExcel.ActiveCell.Value)
    46. MyExcel.ActiveCell.Offset(0, 1).Activate()
    47. ThisRow.C2 = CStr(MyExcel.ActiveCell.Value)
    48. MyExcel.ActiveCell.Offset(0, 1).Activate()
    49. ThisRow.C3 = CStr(MyExcel.ActiveCell.Value)
    50. ExcelRowlist.Add(ThisRow)
    51. MyExcel.ActiveCell.Offset(1, -2).Activate()
    52. Else
    53. Completed = True
    54. Exit Do
    55. End If
    56. Loop
    57. 'Excel schließen
    58. MyExcel.Workbooks.Close()
    59. MyExcel = Nothing
    60. Return Completed
    61. End Function
    62. End Class


    Hoffe es ist genügend auskommentiert.

    Habe eventuell eine neue Vermutung...Zeile 62. Vielleicht fügt er deshalb zu viele Zeilen in die Listview (weil er immer wieder von vorne anfängt) Kann aber auch woanders dran liegen :/
    In den beiden Prozeduren hast Du 2 verschiedene Instanzen auf die Tabelle, die sich beißen, wenn Excel offen ist und nicht ersetzt werden soll.
    Teste mal Dein Programm, wenn die Datei in Excel geöffnet ist.
    Im ListView kommt bei mir nix an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

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

    Ich habe es mal einfacher versucht und die Excel-Durchsuch-Prozedur mal rausgelassen und bin zur Lösung des Problems gekommen (denke ich) ;)

    VB.NET-Quellcode

    1. Private Sub cmdButton1_Click(sender As System.Object, e As System.EventArgs) Handles cmdButton1.Click
    2. ' Textboxeinträge in vorhandene Excel Tabelle eintragen
    3. Dim xlObj As New Excel.Application
    4. xlObj.Visible = True
    5. Dim Mappe As Excel.Workbook = xlObj.Workbooks.Open("C:\Users\Lappi-Schnork\Desktop\Test2.xlsx")
    6. Dim Tabelle As Excel.Worksheet = CType(Mappe.Sheets("Tabelle1"), Excel.Worksheet)
    7. Tabelle.Cells(MyLine, 1).Value = txtBox1.Text
    8. Tabelle.Cells(MyLine, 2).Value = txtBox2.Text
    9. Tabelle.Cells(MyLine, 3).Value = txtBox3.Text
    10. MyLine += 1
    11. With ListView1.Items
    12. Dim item As ListViewItem
    13. item = .Add(txtBox1.Text)
    14. item.SubItems.Add(txtBox2.Text)
    15. item.SubItems.Add(txtBox3.Text)
    16. End With
    17. Mappe.Save()
    18. Mappe.Close()
    19. xlObj.Quit()
    20. End Sub


    Danke nochmal Rod!

    RodFromGermany schrieb:

    Im ListView kommt bei mir nix an.

    Der ListView bleibt immer noch leer.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Bei mir wird der ListView gefüllt, sowohl mit der Prozedur als auch in dem gekürzten Code.
    Dafür sind bei mir die folgenden Zeilen verantwortlich:

    VB.NET-Quellcode

    1. With ListView1.Items
    2. Dim item As ListViewItem
    3. item = .Add(txtBox1.Text)
    4. item.SubItems.Add(txtBox2.Text)
    5. item.SubItems.Add(txtBox3.Text)
    6. End With


    zum Excel-offen-Thema:

    Wenn die Datei geöffnet ist, wird es etwas kompliziert, da er dann eine Kopie vom Dokument erstellen will und das nicht Sinn der Sache ist.
    Spalten: Mein Fehler, ich hatte noch keine Spalten hinzugefügt.
    Ja, jetzt sieht es richtig gut aus.
    Probier mal, nur auf eine Instanz der Datei zuzugreifen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    Probier mal, nur auf eine Instanz der Datei zuzugreifen.


    Du meinst, wenn bspw. nur etwas in Textbox1 steht und man beim nächsten Button.Click Ereignis nur etwas in Textbox2 einträgt?
    Das führt bisher dazu, dass unabhängig von dem Inhalt der Textboxen und der bisherigen Einträge stur die nächste Zeile beschrieben wird.

    Das ist für mich aber nicht weiter schlimm...Ich werde den Button.Click dann so gestalten, dass dieser erst benutzt werden kann, wenn alle 3 textboxen Werte beinhalten.

    In meinem Programm sollen auf der nächsten Form 2 DropDown Menüs zur Verfügung stehen, die den Inhalt der Listview Spalte 1 beinhalten. Erstmal muss ich mich aber mal umgucken, ob ich dazu was finde, ansonsten melde ich mich wieder mit einem neuen Thema :)

    Grüße

    Stefan
    Nein. Ich meine, dass es auch dann ordentlich funktioniert, wenn die Datei in Excel geöffnet ist, dann kannst Du Dir ggf. das ListView sparen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!