NumericUpDown und Division durch Null

  • VB.NET

Es gibt 37 Antworten in diesem Thema. Der letzte Beitrag () ist von Uchi-Komi.

    NumericUpDown und Division durch Null

    Schönen guten Abend!

    Ein Sachse (eigentlich bin ich Thüringer) hat wieder mal ein Problem oder besser eine Aufgabe mit der er nicht selber zu recht kommt:

    Es ist mehr eine Übungsaufgabe, die ich mir stellte und zwar mit dem Ziel mit 4 NumericUpDowns (es heißt wohl global Controls?) einen Umsatzsteuerrechner zu basteln, wobei bei der Eingabe eines Betrages in ein NumericUpDown-Feld in den anderen NumericUpDown-Feldern gleich das Ergebnis angezeigt wird.

    Bei zwei Feldern funktioniert es doch bei dem Brutto-Feld gibt es eine Fehlermeldung schon bevor ein Wert eingegeben wird.

    Ich vermute, dass das Programm schon beim Starten losrechnet und dass die Variablen dann noch den Wert „0“ oder „Nothing“ haben.

    Ist das die Fehlerursache und wenn ja wie behebe ich den Fehler?

    Siehe auch die beigelegten Screenshots und den Code (Den Steuerfeldern NumericUpDown habe ich das Präfix „nud“ verliehen.

    Beste Grüße!

    Hier das Programm:

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Imports System.IO
    4. Imports System.Drawing
    5. Imports System.Windows.Forms
    6. Imports System.Drawing.Printing
    7. Imports System.Windows.Forms.DataFormats
    8. Public Class frmUmsatzsteuer
    9. Dim Netto, UmsatzsteuerEuro, UmsatzsteuerProzent, Brutto As Double
    10. Private Sub nudUmsatzsteuerEuro_ValueChanged(sender As Object, e As EventArgs) Handles nudUmsatzsteuerEuro.ValueChanged
    11. UmsatzsteuerProzent = nudUmsatzsteuerProzent.Value
    12. UmsatzsteuerEuro = nudUmsatzsteuerEuro.Value
    13. Netto = UmsatzsteuerEuro / (UmsatzsteuerProzent / 100)
    14. Brutto = Netto + UmsatzsteuerEuro
    15. nudNetto.Value = CDec(Netto)
    16. nudBrutto.Value = CDec(Brutto)
    17. End Sub
    18. Private Sub nudUmsatzsteuerProzent_ValueChanged(sender As Object, e As EventArgs) Handles nudUmsatzsteuerProzent.ValueChanged
    19. UmsatzsteuerProzent = nudUmsatzsteuerProzent.Value
    20. UmsatzsteuerEuro = Netto * UmsatzsteuerProzent / 100
    21. Brutto = UmsatzsteuerEuro + Netto
    22. nudUmsatzsteuerEuro.Value = CDec(UmsatzsteuerEuro)
    23. nudBrutto.Value = CDec(Brutto)
    24. End Sub
    25. Private Sub nudNetto_ValueChanged_1(sender As Object, e As EventArgs) Handles nudNetto.ValueChanged
    26. Netto = nudNetto.Value
    27. UmsatzsteuerProzent = nudUmsatzsteuerProzent.Value
    28. UmsatzsteuerEuro = (UmsatzsteuerProzent / 100) * Netto
    29. Brutto = Netto + UmsatzsteuerEuro
    30. nudUmsatzsteuerEuro.Value = CDec(UmsatzsteuerEuro)
    31. nudBrutto.Value = CDec(Brutto)
    32. End Sub
    33. Private Sub nudBrutto_ValueChanged(sender As Object, e As EventArgs) Handles nudBrutto.ValueChanged
    34. Brutto = nudBrutto.Value
    35. Netto = Brutto / ((UmsatzsteuerProzent / 100) + 1)
    36. UmsatzsteuerEuro = Brutto - Netto
    37. nudNetto.Value = CDec(Netto)
    38. nudBrutto.Value = CDec(Brutto)
    39. End Sub

    Bilder
    • Fehlermeldung.png

      59,91 kB, 1.294×786, 150 mal angesehen
    • Screenshot_FormularUST.png

      4,37 kB, 554×140, 135 mal angesehen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Uchi-Komi“ ()

    Hallo

    Uchi-Komi schrieb:

    Ich vermute

    Wir vermuten nicht, wie sehen nach. Es liegt sicher in deinem Interesse wenn du weist wie du solche Fehler in Zukunft finden und beheben kannst.
    Setze einen Haltepunkt und sehe nach welchen wert die Variablen haben. Dann versuche den Wert entweder zu vermeiden oder auf ihn zu reagieren.

    Tipp: Debuggen, Fehler finden und beseitigen

    Schöne Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Ich verlinke gerne, deshalb ein Link: C# WPF Visibility Problem
    Füge die EventHandler im Konstruktor hinzu (nach InitializeComponent).
    Edit: Das bezog sich auf
    Ich vermute, dass das Programm schon beim Starten losrechnet und dass die Variablen dann noch den Wert „0“ oder „Nothing“ haben.
    Die Screenshots zeigen jedoch ein anderes Problem. Jo, wie Nofear23m gesagt hat: Haltepunkt drauf und nachgucken.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Uchi-Komi schrieb:

    Nur, wie setze ich einen Haltepunkt?
    Mit F9.
    Debuggen, Fehler finden und beseitigen
    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!
    Hallo

    @RodFromGermany hat dir nun zum zweiten mal den Link gepostet. Ich denke jetzt wird es Zeit zum durchlesen. =O
    Wir könnten nir natürlich auch so helfen, aber richtig Debuggen ist wirklich essentiell. Das brauchst du wirklich. Mit dem wissen kannst du im nu selbst probleme in Sekunden lösen, das erspart dir nicht nur Zeit sondern auch Nerven.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m Jou.
    @Uchi-Komi Das eigentliche Problem besteht darin, dass jeder Anfänger glaubt, sein compilierender Code wäre fehlerfrei.
    Ich zitiere mal meinen Freund S.L.:
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    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!
    Geht gleich los!
    Ich ahnte nicht wie schnell Ihr seid!

    Tschuldigung!


    Also, die Zeile 24 ist es.

    Die Fehlermeldung ist die gleiche wie in Zeile 53 der Fehlermeldung.png

    Übrigens...
    Die Weisheit des Freundes RodFromGermany "Das eigentliche Problem besteht darin, dass jeder Anfänger glaubt, sein compilierender Code wäre fehlerfrei."
    trifft auf mich nicht zu.
    Ich suche Fehler immer zuerst bei mir.
    Alte Schule!
    Das lehrte mich auch mein Sport:
    Fällst Du auf das Kreuz, dann war man immer selbst Schuld!
    Da gibt es nichts zu erklären.

    (Nach dem 3. Bier Mauritius Bock dunkel der Zwickauer Mauritius Brauerei bin ich schon zu lustig um logische Aufgaben sachlich lösen zu können.
    Ich verbleibe bis Morgen hgegnme un d wünsche einbe gute Nachte! :) )

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Uchi-Komi“ ()

    Hallo Uchi-Komi,
    Ich habe 2 Verbesserungsvorschläge für dein Programm:

    A. Dein Programm beginnt in der Tat zu rechnen, bevor alle Variablen Werte erhalten haben.
    Ersetze "Dim Netto, UmsatzsteuerEuro, UmsatzsteuerProzent, Brutto As Double" durch

    Quellcode

    1. Dim Netto as Double = 100
    2. Dim UmsatzsteuerEuro as Double = 19
    3. Dim UmsatzsteuerProzent as Double = 19
    4. Dim Brutto as Double = 119


    B. Dein Programm ist zur Zeit so strukturiert:

    Quellcode

    1. Sub NumericUpDown1
    2. Viele Programmschritte
    3. End Sub
    4. Sub NumericUpDown2
    5. Viele Programmschritte
    6. End Sub
    7. Sub NumericUpDown3
    8. Viele Programmschritte
    9. End Sub
    10. Sub NumericUpDown4
    11. Viele Programmschritte
    12. End Sub


    Die vielen Programmschritte zum Berechnen der Werte sind 4 fach redundant in allen Subroutinen für die NumericUpDown enthalten.
    Warum lagerst du die Berechnung nicht in eine eigene Routine aus ?

    Quellcode

    1. Sub NumericUpDown1
    2. Werte_Berechnen
    3. End Sub
    4. Sub NumericUpDown2
    5. Werte_Berechnen
    6. End Sub
    7. Sub NumericUpDown3
    8. Werte_Berechnen
    9. End Sub
    10. Sub NumericUpDown4
    11. Werte_Berechnen
    12. End Sub
    13. Sub Werte_Berechnen
    14. Viele Programmschritte
    15. End Sub
    @zorroot Sehr gut und willkommen im Forum. :thumbup:
    @Uchi-Komi Machen wir es gleich richtig:

    Quellcode

    1. Sub NumericUpDown1, NumericUpDown2, NumericUpDown3, NumericUpDown4
    2. Viele Programmschritte
    3. End Sub
    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!
    Vielen Dank!
    Bezüglich Zorrot "Warum lagerst du die Berechnung nicht in eine eigene Routine aus ?": Weil jedes NumericUpDown1 m.E. einen anderen Rechengang aufrufen muss.
    Ich probiere die Vorschläge und melde mich wieder!
    Muss schnell noch 1. Advent vorbereiten, sonst gibt es Mecker ;) !

    Uchi-Komi schrieb:

    Weil jedes NumericUpDown1 m.E. einen anderen Rechengang aufrufen muss.
    4 Zahlen führen zu einem Ergebnis, das muss unabhängig davon sein, in welcher Reihenfolge die Werte geändert werden!
    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!

    zorroot schrieb:

    Ersetze "Dim Netto, UmsatzsteuerEuro, UmsatzsteuerProzent, Brutto As Double" durch


    Das habe ich gerade probiert. Die Fehlermeldung bleibt.

    RodFromGermany schrieb:

    Uchi-Komi schrieb:

    Weil jedes NumericUpDown1 m.E. einen anderen Rechengang aufrufen muss.
    4 Zahlen führen zu einem Ergebnis, das muss unabhängig davon sein, in welcher Reihenfolge die Werte geändert werden!


    Das ist korrekt.

    Ich habe schon überlegt, ob ich einen eingabeabhängigen Berechnungsalgorithmus schreiben sollte.

    Vielleicht liegt es daran?

    Das werde ich mal probieren, sofern es keine anderen Vorschläge gibt.

    Ich habe gemeint, wenn ich dem jeweiligen NumericUpDown seinen Rechenweg vorschreibe, dann erspare ich mir die komplizierte Programmierung und das Denken.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Uchi-Komi“ ()

    Uchi-Komi schrieb:

    wenn ich dem jeweiligen NumericUpDown seinen Rechenweg vorschreibe, dann erspare ich mir die komplizierte Programmierung und das Denken.
    Eher das Gegenteil. ;)
    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 habe noch mal ausführlich über das von dir geschilderte Problem nachgedacht. Eine Lösung hierfür ist logisch nicht möglich. Daher ist es auch nicht in Programmcode umsetzbar.
    Wenn sich Werte in den NumericUpDown Steuerelementen ändern, sollen Berechnungen durchgeführt werden.
    Das Ergebnis dieser Berechnungen wird in den NumericUpDown Feldern angezeigt.
    Dadurch ändern sich aber wieder die Werte und es muss erneut berechnet werden.

    Bestenfalls wird dein Programm also maximal ein einziges Mal Eingaben akzeptieren und dann endlos rechnen. Erschwerend kommt hinzu, das Visual Basic bereits beim Start deines Programms die NumericUpDown Elemente mit Werten initialisiert (sogar initialisieren muss, um einen definierten Ausgangszustand zu erzeugen!), in der Regel mit dem Wert 1. Ab dann beginnt schon das endlose Rechnen, ohne das ein Benutzer überhaupt Werte verändern könnte.

    Kurz: Logischer Zirkelbezug. Nicht umsetzbar in Programmcode.

    zorroot schrieb:

    Kurz: Logischer Zirkelbezug. Nicht umsetzbar in Programmcode.


    Ich werde mal schauen, ob ich das Dilemma mit einer Einschränkung überlisten kann.
    Mit VB - es war 2008 oder davor - habe ich das schon mal mit 3 Textfeldern hinbekommen.
    Der Auslösebefehl war KeyUp.
    Mal sehen, ob es sowas auch bei NumericUpDown gibt.

    zorroot schrieb:

    Nicht umsetzbar in Programmcode.
    Doch schon.
    @Uchi-Komi Zunächst kannst Du verhindern, dass sich die NUD-Werte ändern, wenn sich Parameter ändern, trenne Daten und GUI.
    Nimm die NUD-Werte, packe sie in Variablen, rechne mit den VAriablen, und wenn Du fertrig bist, schaltest Du die Eventhandler aus, uipdatest die NUDs und schaltest die Eventhandler wieder ein (einfach ein Boolean Flag, das dafür sorgt, das der Eventhandler ausgeführt wird).
    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:

    zorroot schrieb:

    Nicht umsetzbar in Programmcode.
    Doch schon.


    Nö. :)
    Hierzu eine einfache Frage:
    - Ich gebe Werte für Netto und Brutto ein. Das Programm berechnet mir dann die Umsatzsteuer (absolut und prozentual).
    - Nun ändere ich die Umsatzsteuer. Was soll nun berechnet werden ? Ein neuer Netto oder ein neuer Brutto Wert ?

    Meiner Meinung nach sollte Uchi-Komi die Anforderungen für sein Programm entweder deutlich genauer angeben bzw. korrigieren oder ein solches Programm ist nicht zu erstellen.

    zorroot schrieb:

    Ein neuer Netto oder ein neuer Brutto Wert ?
    In diesem Fall wäre Brutto neu zu berechnen, denn Brutto ist Netto + Mehrschweinchensteuer.
    Du als normaler Ladeneinkäufer oder als Geschäftseinkäufer solltest das wissen. ;)
    Anderenfalls wäre die Aufgabenstellung falsch.
    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:

    @Uchi-Komi Zunächst kannst Du verhindern, dass sich die NUD-Werte ändern, wenn sich Parameter ändern, trenne Daten und GUI.
    Nimm die NUD-Werte, packe sie in Variablen, rechne mit den VAriablen, und wenn Du fertrig bist, schaltest Du die Eventhandler aus, uipdatest die NUDs und schaltest die Eventhandler wieder ein (einfach ein Boolean Flag, das dafür sorgt, das der Eventhandler ausgeführt wird).


    So funktionierte es mit den Textfeldern auch. Allerdings habe ich die nicht ausschalten müssen.

    GUI werden wohl Wertzuweisungen durch Controls genannt?

    Mit

    VB.NET-Quellcode

    1. Netto = nudNetto.Value
    wäre Netto die Variable?

    Eventhandler ausschalten, d.h. nudNetto.readonly = true?