none
Denkhilfe gesucht RRS feed

  • Frage

  • Hallo zusammen,

    ich Bastele mir gerade einen zusammen, das ist so schrecklich, dass ich den Code nicht zeigen möchte.

    Ich möchte an einem Betrag feststellen, ob der Betrag gleich einem anderen Betrag ist.
    Also ob eine Rechnung bezahlt ist.
    Es wird auch ein Bereich (Range) übergeben, der auch als Bezahl gültig ist.
    Also z.B., wenn der eingegangene Betrag >= oder <= als 5€ dem Rechnungsbetrag ist.

    Was ich jetzt in als Ergebnis haben soll, ist z.B.
    Ist der Betrag bezahlt, 

    1 Bezahlt (Differenz zu Eingangsbetrag =0)
    2 In Range grösser dem Betrag.
    3 In Range kleiner dem Betrag.
    4 zuviel Bezahlt, ausserhalb Range.
    5 zu wenig bezahlt.

    Wie geht das elegant.

    Falls jemand darüber nachdenken mag, bin ich gespannt wie das aussieht.

    Gruss Peter

    Dienstag, 17. März 2015 16:23

Antworten

  • Hallo Peter,

    da gibt es eigentlich nichts zu würgen, nur auf die Reihenfolge der Vergleiche kommt es an. Eine Alternative zu Stefans Lösung:

        Public Shared Function BetragVergleichen(istBetrag As Decimal, sollBetrag As Decimal, erlaubteAbweichung As Decimal) As Integer
            Dim minBetrag As Decimal = sollBetrag - erlaubteAbweichung
            Dim maxBetrag As Decimal = sollBetrag + erlaubteAbweichung
            Select Case True
                Case istBetrag = sollBetrag
                    Return 1
                Case istBetrag < minBetrag
                    Return 5
                Case istBetrag > maxBetrag
                    Return 4
                Case istBetrag > sollBetrag
                    Return 3
                Case istBetrag < sollBetrag
                    Return 2
            End Select
            Return 0 ' sollte nie passieren (bei richtigem Datentyp ;)
        End Function
    
        For Each betrag In {1000D, 1050D, 950D, 1200D, 800D}
            Console.WriteLine("{0} => {1}", betrag, BetragVergleichen(betrag, 1000D, 100D))
        Next

    Beachte, dass man Gleitkommazahlen nur bedingt auf Gleichheit testen kann, siehe u. a. System.Double. Kommt oben 0 zurück, bist Du darauf reingefallen.

    Gruß Elmar

    • Als Antwort markiert peter haus Mittwoch, 18. März 2015 09:54
    Dienstag, 17. März 2015 18:30
    Beantworter

Alle Antworten

  • Hallo Peter,

    um eine Zahl gegen einen Wertebereich zu prüfen, hab ich mir mal eine Erweiterungsmethode geschrieben.

    <Extension()> _
    Public Function IsInRange( ByVal Value As Int64, ByVal MinValue As Int64, ByVal MaxValue As Int64 ) As Boolean
    
    Dim Result As Boolean = True
        If Value < MinValue OrElse Value > MaxValue Then
            Result = False
        End If
    
        Return Result
    
    End Function
    

    In deinem Fall könnte man anstelle von Boolean bspw. einen Enum zurückgeben und die Prüfung entsprechend erweitern.

    <Extension()> _
    Public Function IsInRange( ByVal Value As Int64, ByVal Value2, ByVal MinValue As Int64, ByVal MaxValue As Int64 ) As NumericRangeCheckResult
    
    Dim Result As NumericRangeCheckResult = NumericRangeCheckResult.Undefined
    
        If Value = Value2 Then
            Result = NumericRangeCheckResult.Equal
        ElseIf Value > MaxValue Then
            Result = NumericRangeCheckResult.OutOfRangeGreaterThan
        ElseIf Value < MinValue Then
            Result = NumericRangeCheckResult.OutOfRangeLessThan
        ...
        End If
    
        Return Result
    
    End Function
    
    ...
    
    Public Enum NumericRangeCheckResult As Integer
    
        Undefined             = 0
    
        Equal                 = 1
        InRangeGreaterThan    = 2
        InRangeLessThan       = 3
        OutOfRangeGreaterThan = 4
        OutOfRangeLessThan    = 5
    
    End Enum

    Den Rest bekommst Du sicher problemlos selbst hin :)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 17. März 2015 16:45
    Moderator
  • Danke Stefan,

    ich muss mir deinen Code morgen mal zu Gemüte führen.

    Gerade mit den Werten innerhalb Range + oder - hab ich rumgewürgt, danach ob sie grösser der + oder - Range sind.

    Nochmals Dank und Gruss
    Peter

    Dienstag, 17. März 2015 17:48
  • Hallo Peter,

    ach komm. Die Hauptarbeit ist gemacht. Alles, was gleich dem Wert oder außerhalb des Bereichs ist, wird schon behandelt. Bleibt also nur noch, ob größer oder des Werts. Also Value > Value2 und Value < Value2. Im Bereich ist das in dem Fall so oder so.

    Sollst ja auch was dabei lernen :)

    Den Aufruf poste ich aber mal noch fürs bessere Verständnis:

    Dim Amount      As Int64 = 100
    Dim PayedAmount As Int64 = 102
    Dim CheckResult As NumericRangeCheckResult
        CheckResult = PayedAmount.IsInRange( Amount, Amount - 5, Amount + 5 )
    


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community



    Dienstag, 17. März 2015 18:04
    Moderator
  • Hallo Peter,

    da gibt es eigentlich nichts zu würgen, nur auf die Reihenfolge der Vergleiche kommt es an. Eine Alternative zu Stefans Lösung:

        Public Shared Function BetragVergleichen(istBetrag As Decimal, sollBetrag As Decimal, erlaubteAbweichung As Decimal) As Integer
            Dim minBetrag As Decimal = sollBetrag - erlaubteAbweichung
            Dim maxBetrag As Decimal = sollBetrag + erlaubteAbweichung
            Select Case True
                Case istBetrag = sollBetrag
                    Return 1
                Case istBetrag < minBetrag
                    Return 5
                Case istBetrag > maxBetrag
                    Return 4
                Case istBetrag > sollBetrag
                    Return 3
                Case istBetrag < sollBetrag
                    Return 2
            End Select
            Return 0 ' sollte nie passieren (bei richtigem Datentyp ;)
        End Function
    
        For Each betrag In {1000D, 1050D, 950D, 1200D, 800D}
            Console.WriteLine("{0} => {1}", betrag, BetragVergleichen(betrag, 1000D, 100D))
        Next

    Beachte, dass man Gleitkommazahlen nur bedingt auf Gleichheit testen kann, siehe u. a. System.Double. Kommt oben 0 zurück, bist Du darauf reingefallen.

    Gruß Elmar

    • Als Antwort markiert peter haus Mittwoch, 18. März 2015 09:54
    Dienstag, 17. März 2015 18:30
    Beantworter
  • Hallo Peter,

    vielen Dank für dein Codeschnipsel.

    Ja peinlich. Da wo ich es gestern nicht mehr raffte war, es ist viel verständlicher, wenn man zuerst mal alles andere raus nimmt, und am Schluss das InRange prüft.

    Guss Peter

    Mittwoch, 18. März 2015 09:50
  • Hallo Elmar,

    das ist's.

    Am Anfang minBetrag und maxBetrag, die erlaubte Abweichung berechnen.
    Und alles ist übersichtlicher.
    Gestern hat sich alles nur noch im Kopf gedreht.
    Sieht auf jeden Fall besser aus, als das gebastel von gestern.

    Ich Dank Dir.
    Gruss Peter

    Mittwoch, 18. März 2015 09:54