Hallo Delphi-Gemeinde,
ich haben einen komischen Effekt mit dem
MSSQL-2017 im Delphi Rio (
Win32/
VCL-Anwendung) (WIN-10).
Ich möchte aus einer Rechnung die Summe aller Netto-Beträge, multipliziert mit deren Steuersatz als Brutto-Betrag ermitteln.
Aber irgendwie bekomme ich komische, falsch gerundete Beträge zurück.
Hier ein
SQL der das Problem verdeutlichen soll:
Code:
Select
sum (l.[Preis]) as Netto_Org
, round(sum ([Preis]),2) as Netto_Round
, 206.5 * 1.19 as Brutto_Korrekt
, round(206.5 * 1.19,2) as Brutto_Korrekt_round
, sum( l.[Preis] * ( (r.steuersatz +100) / 100)) as Brutto_Org
, sum( round(l.[Preis],2) * ( (r.steuersatz +100) / 100)) as Brutto_1
, round(sum( round(l.[Preis],2) * ( (r.steuersatz +100) / 100)),2) as Brutto_2
, round( sum( l.[Preis] * ( (r.steuersatz +100) / 100)),2) as Brutto_3
, round( sum( l.[Preis] * 1.19) ,2) as Brutto_4
, sum( round( l.[Preis] * 1.19 ,2)) as Brutto_5
, sum( round( l.[Preis],2) * 1.19 ) as Brutto_6
from RechnungListe l, Rechnung r
where ....
group by r.steuersatz;
also Ergebnis dieser
Query bekomme ich:
Code:
Netto_Org Netto_Round Brutto_Korrekt Brutto_Korrekt_round Brutto_Org Brutto_1 Brutto_2 Brutto_3 Brutto_4 Brutto_5 Brutto_6
----------- ----------- -------------- -------------------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
206,5 206,5 245,735 245,74 245,735 245,735 245,73 245,73 245,73 245,72 245,735
Alle Einzelpositionen (l.[Preis]) sind floats und mit 2 Nachkommastellen gespeichert.
Der Netto-Betrag dieser Rechnung ist tatsächlich 206.50 (€), der Steuersatz ist 19 (%).
Schaut man sich aber [Brutto_1], [Brutto_2] oder [Brutto_3] an, stimmen die Rundung nicht. [Brutto_4], [Brutto_5] und [Brutto_6] sind Versuche mögliche Fehler auszuschließen.
Und jetzt wird's richtig wild.
Fetsche ich den [Netto_Org]-Wert heraus (im Debugger = 206.5) und schreibe den Wert in eine extended-Variable, multipliziere mit 1.19 erhalte ich wieder 245.735
Runde ich anschließen die Variable mit RoundTo (Wert,-2) bekomme ich 245.73 heraus, statt 245.74.
Delphi-Quellcode:
var
nPow, nValue : extended;
begin
nPow := power(10,2);
// Test 1
nValue :=
ADO.FieldByName('
Netto_org').AsFloat;
// 206.5 laut Debugger
nValue := nValue * 1.19;
nValue := RoundTo(nValue,-2);
// = 245.73 , falsch
// Test 2
nValue :=
ADO.FieldByName('
Netto_org').AsFloat;
// 206.5 laut Debugger
nValue := nValue * 1.19;
nValue := nValue * nPow;
nValue := nValue + 0.5;
nValue := trunc(nValue);
// <- hier passiert etwas komisches !! 24574 wird zu 24573 ???
nValue := nValue/nPow;
// = 245.73 , falsch
// Test 3
nValue := 206.5;
nValue := nValue * 1.19;
nValue := RoundTo(nValue,-2);
// = 245.74 , korrekt.
// Test 4
nValue :=
ADO.FieldByName('
Netto_round').AsFloat;
// ebenfalls 206.5 laut Debugger
nValue := nValue * 1.19;
nValue := RoundTo(nValue,-2);
// = 245.74 , korrekt.
Irgendwie bekomme ich von der Datenbank nicht den korrekten Wert zurück, bzw. die Rundung im
SQL-Server funktioniert nicht richtig.
Kann mir jemand erklären was hier schief läuft?
Danke.