If ..Then..Else liefert Müll

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Yanbel.

    If ..Then..Else liefert Müll

    Hallo zusammen

    Ich habe ein kleines Problem, was ich mir nicht wirklich erklären kann.
    Ein simpler vergleich zweier Labels. Das ergebnis ist aber falsch.
    Ich versteh den Fehler nicht. Was mach ich denn hier falsch?

    VB.NET-Quellcode

    1. Private Sub OverviewDataGridView_SelectionChanged(sender As Object, e As EventArgs) Handles OverviewDataGridView.SelectionChanged
    2. If BQ_Ux_Lbl.Text > Soll_BQ_Lbl.Text Then
    3. PB3.Visible = True
    4. Else
    5. PB3.Visible = False
    6. End If
    7. End Sub
    Bilder
    • Abbild1.PNG

      13,69 kB, 806×169, 55 mal angesehen
    @heinosh
    Du musst die Strings erst in doubel umwandeln.

    VB.NET-Quellcode

    1. Private Sub OverviewDataGridView_SelectionChanged(sender As Object, e As EventArgs) Handles OverviewDataGridView.SelectionChanged
    2. If Convert.ToDouble(BQ_Ux_Lbl.Text) > Convert.ToDouble(Soll_BQ_Lbl.Text) Then
    3. PB3.Visible = True
    4. Else
    5. PB3.Visible = False
    6. End If
    7. End Sub
    Um hier etwas Inhalt und Erklärung rein zu bringen, funktioniert eine Text-Sortierung anders als eine Zahlensortierung.
    Beim TEXT ist:
    13 < 2

    Bei einer Zahl ist
    13 > 2

    Warum? Weil beim Text, Zeichen für Zeichen verglichen wird, von links nach rechts und die 1 der 13 ist kleiner als die 2, also ist 13 kleiner als 2.
    Ähnlich wie
    abc < bc ist, weil a < b ist.
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    Es war einmal ein kleiner Bär... der wollte eine Geschichte hörn... Da erzählte ihm seine Mutti:
    ... Nun solltest es selber wissen. :'D
    Danke...
    Nachdem ich dem ich nun die NULL-Werte aussortiere, funktioniert es.

    Hier meine Lösung.

    VB.NET-Quellcode

    1. Private Sub OverviewDataGridView_SelectionChanged(sender As Object, e As EventArgs) Handles OverviewDataGridView.SelectionChanged
    2. If IsNumeric(BQ_Ux_Lbl.Text) Then
    3. If CDbl(BQ_Ux_Lbl.Text) > CDbl(Soll_BQ_Lbl.Text) Then
    4. PB3.Visible = True
    5. Else
    6. PB3.Visible = False
    7. End If
    8. Else
    9. PB3.Visible = False
    10. End If
    11. End Sub
    Sorry.....bin kein Profi und auch nicht perfekt.

    Hoffe so ist es "besser"

    VB.NET-Quellcode

    1. Private Sub OverviewDataGridView_SelectionChanged(sender As Object, e As EventArgs) Handles OverviewDataGridView.SelectionChanged
    2. Dim BQ_Soll = Convert.ToString(Soll_BQ_Lbl.Text)
    3. Dim BQ = Convert.ToString(BQ_Ux_Lbl.Text)
    4. If BQ > BQ_Soll Then
    5. PB3.Visible = True
    6. Else
    7. PB3.Visible = False
    8. End If
    9. End Sub
    Wenn wir schon dabei sind Strings in Zahlen zu verwandeln, dann sollte man die .Parse bzw. .TryParse Methoden verwenden. Double.TryParse() erfüllt hierbei 2 Aufgaben auf einmal. Zum einen, sollte es sich bei dem eingegebenen String nicht um eine konvertierbare Zahl handeln, so gibt die Funktion false zurück. Zum anderen erhält man, sofern das Parsen erfolgreich war im Out-Parameter den Wert als Double zurück.

    So gut wie alle primitiven Datentypen haben diese .Parse und .TryParse Methoden.
    Hier noch ein kleiner Hinweis, den du beim Vergleich von Double- und Single-Werten im .NET beachten solltest.

    Wenn du zwei Ergebnisse einer Berechnung vom TypDouble oder Single miteinander vergleichst dann funktionieren die Operatoren < und > sehr gut. Der Operator = liefert allerdings nicht selten ein falsches Ergebnis, sodass beispielsweise beim Ergebnis einer Berechnng 4,25 <> 4,25 sein kann, selbst wenn die Werte auch in den darauffolgenden Nachkommestellen exakt übereinstimmen.

    Grund dafür ist, dass die Werte in .NET als binäre Brüche behandelt werden. Sollte ein binärer Bruch nicht korrekt darstellbar sein, weil der Wertebereich, in dem binäre Brüche arbeiten, überschritten wird, dann verwendet .NET eine Annäherungsgleichung anstelle des binären Bruchs. Diese Annäherungsgleichung liefert bei zwei Rechenwegen totsicher ein unterschiedliches Ergebnis. Im obengenannten Beispiel liefert Näherungrechnung #1 das Ergebnis 4,25000...001 und Näherungrechnung #2 das Ergebnis 4,249999999... (ist übrigens ziemlich ätzend bei Unittests). Beim Operator = daher niemals mit Single oder Double Werten arbeiten, sondern beispielsweise mit Decimal oder (sofern möglich) den Vergleich direkt auf der Datenbank durchführen.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    @Yanbel Oder Du testest auf genau dieses Epsilon:

    VB.NET-Quellcode

    1. Const EPSILON As Double = 1e-12 ' oder so
    2. If Math.Abs(value1 - value2) < EPSILON Then
    3. ' gleich
    4. End If
    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!