System.InvalidOperationException bei Me.TableNewRow

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    System.InvalidOperationException bei Me.TableNewRow

    Hallo zusammen,

    vorweg möchte ich sagen das ich DataSet Only arbeite, nach den Tutorials von @ErfinderDesRades

    Ich arbeite an einem Übungsprogramm wo ich unter anderem Artikel anlegen kann.
    Dazu habe ich einen DialogForm angelegt und mit folgendem Code wird der Artikel angelegt.

    VB.NET-Quellcode

    1. ​Case sender Is btnArtikelAnlegen : bsArtikel.EditNew(Of dlgArtikel)()

    Nun ist es so das ich die Artikelnummer nicht manuell eingeben möchte, sonder sie soll automatisch vergeben werden.
    Z.B. soll die erste 1000 sein und dann immer um 1 erhöht werden.
    Ich hatte das mit einer List(Of Integer) gelöst.

    VB.NET-Quellcode

    1. ​Dim Liste As New List(Of Integer)
    2. For i = 0 To bsArtikel.Count - 1
    3. Dim rwArt = DirectCast(DirectCast(bsArtikel(i), DataRowView).Row, ArtikelRow)
    4. Liste.Add(rwArt.ArtikelNummer)
    5. Next
    6. ' Prüfen ob Liste Leer
    7. Dim ArtNr As Integer
    8. Dim maximum As Integer
    9. Dim minimum As Integer
    10. If Liste.Count = 0 Then
    11. ArtNr = 10000 'Aller erste Artikelnummer
    12. Else
    13. maximum = Liste.Max
    14. minimum = Liste.Min
    15. ArtNr = maximum + 1
    16. End If
    17. rwArt.ArtikelNummer = ArtNr


    Das funktioniert, aber scheint nicht sonderlich schön programmiert zu sein, mir wurde jedenfalls gesagt das es einen anderen Weg gibt.
    Mir wurde das .TableNewRow Event ans Herz gelegt. So kam dann nach langer Zeit des lesens folgender Code heraus.

    VB.NET-Quellcode

    1. Partial Public Class ArtikelDataTable
    2. Private Sub ArtikelDataTable_TableNewRow(sender As Object, e As DataTableNewRowEventArgs) Handles Me.TableNewRow
    3. Dim rwArtikel = DirectCast(e.Row, ArtikelRow)
    4. With rwArtikel
    5. .Artikelnummer = NaechsteArtikelNummer()
    6. End With
    7. End Sub
    8. Private Function NaechsteArtikelNummer() As Int32
    9. Dim NeueArtikelNummer As Int32 = Me.AsEnumerable.Max(Function(m) m.Artikelnummer)
    10. If NeueArtikelNummer = Nothing Then
    11. NeueArtikelNummer = 1000
    12. Else
    13. NeueArtikelNummer += 1
    14. End If
    15. Return NeueArtikelNummer
    16. End Function
    17. End Class


    Damit wird dann jedesmal die Artikelnummer um eins erhöht sobald eine neue ArtikelRow angelegt wird.
    Da ich ja immer Daten im Projekt hatte um alles zu testen lief auch alles. Nun wollte ich aber mal einen Test machen wie das Programm läuft wenn noch gar keine Daten eingegeben sind.
    Und Zack, auf die schnauze gefallen. Ich bekomme folgende Exception: System.InvalidOperationException: "Die Sequenz enthält keine Elemente." bei dieser Zeile

    VB.NET-Quellcode

    1. ​Dim NeueArtikelNummer As Int32 = Me.AsEnumerable.Max(Function(m) m.Artikelnummer)


    Klar, ist ja auch nichts drin.
    Wie kann ich das nun abfragen ohne das eine Exception fliegt?
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    Gegenfrage: Warum verwendest Du dann nicht gleich für die Spalte Artikelnummer die Einstellungen AutoIncrementSeed = 1000 und AutoIncrementStep = 1 im tDS-Designer?
    Fang doch mit nem einfachen Test an, bevor Du ne LINQ-Abfrage startest:

    VB.NET-Quellcode

    1. Private Function NaechsteArtikelNummer() As Int32
    2. If Me.Count = 0 Then Return 1000
    3. Return NeueArtikelNummer = Me.AsEnumerable.Max(Function(m) m.Artikelnummer) + 1
    4. End Function
    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.
    Hallo,
    @MichaHo, @VaporiZed
    wenn ich für die Spalte Artikelnummer die Einstellung Autoincrement aktiviere und AutoInrementSeed = 1000 und AutoIncrementStep = 1 setze funktioniert es erst. Aber es ist nicht fortlaufend. Wenn ich mal einen Dialog Cancel, wird beim nächsten mal eine Zahl Übersprungen.
    z.b 1000 ist der erste , nächste wäre 1001, diesen Cancel ich. Der nächste hat dann 1002 und nicht wie es soll 1001.
    So ist es ja auch bei den ID´s, deswegen kann/soll man diese ja nicht für solche sachen nutzen.

    @VaporiZed
    Auf diese einfache Abfrage bin ich nicht gekommen, dabei ist es so simpel erst zu fragen ob eine ArtikelRow vorhanden ist.
    Allerdings bekomme ich bei folgendem Code den Fehler "Option Strict On lässt keine Impliziten Konvertierungen von Boolean in Integer zu."

    VB.NET-Quellcode

    1. Partial Public Class ArtikelDataTable
    2. Private Sub ArtikelDataTable_TableNewRow(sender As Object, e As DataTableNewRowEventArgs) Handles Me.TableNewRow
    3. Dim rwArtikel = DirectCast(e.Row, ArtikelRow)
    4. With rwArtikel
    5. .Artikelnummer = NaechsteArtikelNummer()
    6. End With
    7. End Sub
    8. Private Function NaechsteArtikelNummer() As Int32
    9. Dim NeueArtikelNummer As Int32
    10. If Me.Count = 0 Then Return 1000
    11. Return NeueArtikelNummer = Me.AsEnumerable.Max(Function(m) m.Artikelnummer) + 1
    12. End Function
    13. End Class


    Ich habe doch gar keinen Boolean.

    EDIT:

    Habe die Lösung , allerdings verstehe ich den Fehler mit dem Boolean nicht. Kann mir den jemand erklären?
    Hier noch die Lösung:

    VB.NET-Quellcode

    1. ​Partial Public Class ArtikelDataTable
    2. Private Sub ArtikelDataTable_TableNewRow(sender As Object, e As DataTableNewRowEventArgs) Handles Me.TableNewRow
    3. Dim rwArtikel = DirectCast(e.Row, ArtikelRow)
    4. With rwArtikel
    5. .Artikelnummer = NaechsteArtikelNummer()
    6. End With
    7. End Sub
    8. Private Function NaechsteArtikelNummer() As Int32
    9. If Me.Count = 0 Then Return 1000
    10. Dim NeueArtikelNummer = Me.AsEnumerable.Max(Function(m) m.Artikelnummer) + 1
    11. Return NeueArtikelNummer
    12. End Function
    13. End Class
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.

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

    Return NeueArtikelNummer = Me.AsEnumerable.Max(Function(m) m.Artikelnummer) + 1

    das wird im Return wohl als Boolscher Ausdruck gewertet.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    8|
    Natürlich Hunz.
    Sollte heißen:

    VB.NET-Quellcode

    1. Private Function NaechsteArtikelNummer() As Int32
    2. If Me.Count = 0 Then Return 1000
    3. Return Me.AsEnumerable.Max(Function(m) m.Artikelnummer) + 1
    4. End Function
    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.
    @VaporiZed
    Danke, das ist natürlich kürzer.

    @mrMo
    deiner Aussage entnehme ich das Du Dir auch nicht ganz sicher bist, warum.
    Gibt es eine Möglichkeit dies irgendwie zu überprüfen? Der Datentyp Boolean ist hier ja nicht vorhanden. Und Intellisens sagt auch das es ein Integer werden soll.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    Ich bin mir sicher. Um die Aussage zu validieren mach ne Function mit Boolean als Rückgabewert und mach darin

    Return NeueArtikelNummer = Me.AsEnumerable.Max(Function(m) m.Artikelnummer) + 1
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Unvermeidlich, ja. Aber warum sollte man einen Artikel löschen? Ich denke das macht man nicht, oder?
    Im Grunde ist es aber so das ich immer alles ordentlich haben möchte. Wenn mal eine Zeile gelöscht wird, gut, dann ist da eine Lücke.
    Aber die Chance das da mehrere und evtl. sogar grössere Lücken enstehen, ist geringer.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.

    Akanel schrieb:

    Aber warum sollte man einen Artikel löschen?
    Das kommt sehr auf Deine Daten und Dein Programm an. Ich habe in meinen Programmen immer irgendwas, was früher oder später gelöscht wird. Lass es Daten sein, die nur eine bestimmte Lebensdauer haben (gesetzliche Aufbewahrungsfristen, Erinnerungen, die "verfallen"), Gesetze, die sich ändern oder Sortimentswechsel. "But nothing is quiet forever, especially staying together."
    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.