Ich möchte eine Zahl kaufmännisch Runden und schaffe das nicht unter allen Umständen in Lotus Script korrekt zu programmieren.
Dafür gibt es ja den Befehl Round. Da ist aber, meiner Meinung nach, in der Doku schon ein Fehler drin, den ich reproduzieren kann:
' Round to one decimal place.
Print Round(4.23, 1) ' Prints 4.2 -> RICHTIG
Print Round(4.35, 1) ' Prints 4.4 -> RICHTIG
Print Round(4.45, 1) ' Prints 4.4 ->
FALSCH, sollte eigentlich 4.5 ausgeben, oder?
Damit kann ich den Round Befehl nicht nutzen. Deswegen mache ich bisher in meiner Programmierung folgendes:
1. verschiebe das Komma nach rechts durch Multiplikation mit 100 (für 2 Nachkommastellen, bei 3 Stellen muß 1000 genommen werden, usw.)
2. danach addiere ich 0,5
3. mit dem Skript Befehl Fix entferne ich die Nachkommastellen
4. verschiebe das Komma nach links durch Division mit 100 (für 2 Nachkommastellen, bei 3 Stellen muß 1000 genommen werden, usw.)
Code:
Fix( ( Wert * 100 ) + 0,5 ) / 100
Das funktioniert schon seit fast 2 Jahrzehnten gut. Bis ich eine Beschwerde Anfang der Woche bekommen habe, daß die MWSt. nicht korrekt berechnet wird.
Zu meinem Erstaunen, mußte ich festellen, daß tatsächlich der Cent Betrag nicht ok ist. Ich kann aber keinen Fehler in meiner Logik entdecken, bzw. bin ratlos wie ich den Fehler lösen soll.
Zum besseren Verständniss warum ich ratlos bin, habe ich 4 Beispiele und den Code zum Test angehängt.
Ein Beispiel mit dem Wert 64,3652 (gerundet 64,37):
64,3652 * 100 = 6436,52
6436,52 + 0,5 = 6437,02
Fix( 6437,02 ) = 6437
6437 / 100 = 64,37
Alles ok soweit. Dann schaun wir mal was mit 64,365 passiert (gerundet 64,37):
64,365 * 100 = 6436,5
6436,5 + 0,5 = 6437
Fix( 6437 ) = 6436
6436 / 100 = 64,36
Ups, nicht mehr so gut. Dasselbe mache ich mal mit dem Wert 64,2652 (gerundet 64,27):
64,2652 * 100 = 6426,52
6426,52 + 0,5 = 6427,02
Fix( 6427,02 ) = 6427
6427 / 100 = 64,27
Alles ok soweit. Dann schaun wir mal was mit 64,265 passiert (gerundet 64,27):
64,265 * 100 = 6426,5
6426,5 + 0,5 = 6427
Fix( 6427 ) = 6427
6427 / 100 = 64,27
Auch alles gut! Ob mir jemand das Verhalten erklären kann, weiß ich nicht. Aber vielleicht gibt es andere Möglichkeiten die ich noch nicht bedacht habe.
Wer bis hier gekommen ist
und sich dann meine Beispiele ansieht, der könnte sich folgendes fragen: warum nimmt der eigentlich Fix und nicht CInt um eine Zahl mit Nachkommastellen in eine Zahl ohne Nachkommastellen umzuwandeln?
Ganz einfach: das hatte ich tatsächlich damals programmiert, bis ein Fall aufgetreten ist, in dem der Befehl CInt/CLng ähnlich falsch reagiert hat. Die Zahl finde ich leider nicht mehr und frage deswegen bei Euch, ob das Problem beim Runden bekannt ist und jemand Ideen hat.
Hier ist ein Skript Code Beispiel, mit dem das Verhalten geprüft werden kann:
Dim WertOriginal As Double
Dim WertGerundet As Double
WertOriginal = 64.3652
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,37 = RICHTIG
WertOriginal = 64.365
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,36 = FALSCH
WertOriginal = 64.2652
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,27 = RICHTIG
WertOriginal = 64.265
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,27 = RICHTIG
Nochmal ein Beispiel mit den Befehlen Round, CDbl, CInt und DLng:
Dim WertOriginal As Double
Dim WertGerundet As Double
WertOriginal = 64.3652
WertGerundet = Round( WertOriginal, 2 ) ' WertGerundet = 64,37 = RICHTIG
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,37 = RICHTIG
WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ) ' WertGerundet = 64,3702 = RICHTIG aber nicht gerundet
WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,37 = RICHTIG
WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,37 = RICHTIG
WertOriginal = 64.365
WertGerundet = Round( WertOriginal, 2 ) ' WertGerundet = 64,36 = FALSCH
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,36 = FALSCH
WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ) ' WertGerundet = 64,37 = RICHTIG
WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,37 = RICHTIG
WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,37 = RICHTIG
WertOriginal = 64.2652
WertGerundet = Round( WertOriginal, 2 ) ' WertGerundet = 64,27 = RICHTIG
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,27 = RICHTIG
WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ) ' WertGerundet = 64,2702 = RICHTIG aber nicht gerundet
WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,27 = RICHTIG
WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,27 = RICHTIG
WertOriginal = 64.265
WertGerundet = Round( WertOriginal, 2 ) ' WertGerundet = 64,26 = FALSCH
WertGerundet = Fix( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ' WertGerundet = 64,27 = RICHTIG
WertGerundet = CDbl( ( ( WertOriginal * 100.0 ) + 0.5 ) / 100 ) ' WertGerundet = 64,27 = RICHTIG
WertGerundet = CInt( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,27 = RICHTIG
WertGerundet = CLng( ( ( WertOriginal * 100.0 ) + 0.5 ) ) / 100 ' WertGerundet = 64,27 = RICHTIG