![]() |
Datenbank: firebird • Version: 2.1 • Zugriff über: zeos
unerklärlicher DB-eintrag mit currency werten
Hallo zusammen,
ich habe im Zuge einer Änderung wg. Rundungsfehlern die betroffenen DB-Felde auf 6 stellen nach dem Komma erweitert. Jetzt speichere ich zb per:
Delphi-Quellcode:
die Werte in die DB.
FQuery1['NETTOPREIS']:= FNETTOPREIS;
FQuery1['BRUTTOPREIS']:= FBRUTTOPREIS; .. .. FQuery1.post; in der Variablen FBruttopreis steht definitiv 0,3 in der Variablen FNettopreis steht definitiv 0,2804 das ist soweit richtig weil in dem Fall ja mit 7 Prozent gerechnet wird. schaue ich aber in die DB, bzw lese diese wieder aus, steht im bruttopreis 0,299900 im nettopreis 0,280300 :-( hab ich jetzt ein brett vorm Kopf oder was ist die Ursache? Danke Gruss KH |
AW: unerklärlicher DB-eintrag mit currency werten
Hast du evtl. persistende DB-Felder in deinem Formular angelegt die nur auf 4 stellen laufen?
|
AW: unerklärlicher DB-eintrag mit currency werten
Zitat:
Code:
das Eingabefeld ist vom type Twaehredit.
preisnettoEdit.text := Format('%5.4f ', [Fnettopreis]);
die entsprechene Unit unten. aber wie sonst soll ich dem Benutzer einen Wert anbieten der keine 6 nachkommastellen anzeigt? :-(
Code:
kapiert hab ichs aber trotzdem noch nicht :-(
unit waehrEdit;
{ Author: Peter Johansson Aenderungen und Anpassungebn hwd-world 2009 Description: Edit for entering a currency value. Has a property called Value witch can be manipulated both by the user and the application. If a error should occur it will stil hold a value but show a exclamation sign "!" in from of the value. Usage: Just put a TCurrencyEdit on the form and use the property Value to read a valid Currency figure or of course to set it. Version: 1.01 } interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type {I'am using a TMemo becourse it can handle justification and reduced client area, to make room for the error sign and to move the cursor away from the right edge of the control} TWaehrEdit =class(TEdit) protected fValue : Currency; fOldValue : Currency; fCanvas : TControlCanvas; fIsValid : Boolean; procedure SetRects; procedure Validate; procedure SetValue(value : Currency); procedure WMSetFont(var Message: TWMSetFont); message WM_SETFONT; procedure WMSize(var Message : TWMSize); message WM_SIZE; procedure WMPaint(var Message : TWMPaint); message WM_PAINT; // procedure CMEnter(var Message : TCMGotFocus); message CM_ENTER; // procedure CMExit(var message : TCMGotFocus); message CM_EXIT; procedure KeyPress(var Key: char); override; public procedure CreateWnd;override; constructor Create(AOwner: TComponent); override; destructor Destroy;override; published property BorderStyle; property Color; // property Ctl3D; property DragCursor; property DragMode; property Enabled; property Font; // property HideSelection; property IsValid : Boolean Read fIsValid; property Value : Currency read fValue write SetValue; property ParentColor; // property ParentCtl3D; property ParentFont; property ParentShowHint; property PopupMenu; property ReadOnly; property ShowHint; property TabOrder; property TabStop; property Visible; property OnChange; property OnClick; property OnDblClick; property OnDragDrop; property OnDragOver; property OnEndDrag; property OnEnter; property OnExit; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnMouseDown; property OnMouseMove; property OnMouseUp; end; procedure Register; implementation procedure Register; Begin RegisterComponents('Standard', [TWaehrEdit]); End; procedure TWaehrEdit.SetRects; Var E : TRect; Begin E :=ClientRect; {Edit portion of CurrencyEdit} E.Right :=ClientRect.Right - 5; {Move the cursor away from the edge} E.Left :=ClientRect.Left + 20; {Make room for the error sign} Perform(EM_SETRECT,0 ,LongInt(@E)); {Set the Edit control rect} End; procedure TWaehrEdit.Validate; Begin {Try to convert text to currency - if it fails user previeus entered value} Try fValue :=StrToFloat(Text); Text :=FormatFloat('#0.00', fValue); fOldValue :=fValue; fIsValid :=True; Except fValue :=fOldValue; Text :=FormatFloat('#0.00', fValue); fIsValid :=False; End; End; procedure TWaehrEdit.SetValue(value : Currency); Begin fValue :=value; Text :=FormatFloat('#0.00', fValue); fOldValue :=fValue; fIsValid :=True; End; procedure TWaehrEdit.WMSetFont(var Message: TWMSetFont); begin inherited; SetRects; End; procedure TWaehrEdit.WMSize(var Message: TWMSize); Begin Inherited; SetRects; End; procedure TWaehrEdit.WMPaint(var Message : TWMPaint); Begin {If an error ocurred write an exclamation sign} Inherited; fCanvas.Brush.Color :=Color; fCanvas.FillRect(Rect(1, 1, ClientRect.Left + 18, ClientRect.Bottom - 1)); If not fIsValid Then fCanvas.TextOut(3, 1, '!!'); End; {procedure TWaehrEdit.CMEnter(var Message : TCMGotFocus); Begin Inherited; SelectAll; End; } {procedure TWaehrEdit.CMExit(var message : TCMGotFocus); Begin {When loosing focus try to validate the entered figure and format it nice} Validate; Inherited; End; } procedure TWaehrEdit.KeyPress(var Key: char); Begin {Only number related keys allowed. On Enter #13, try to vallidate On Escape #27 Restore the previous entered value} If (Length(Text) > 12) and (key <> #8)Then Key :=#0; If not (Key in['-', '+', '0'..'9', DecimalSeparator, #8, #13, #27]) Then key :=#0; If Key = #13 Then Begin Validate; SelectAll; End; If Key = #27 Then Begin fValue :=fOldValue; Text :=FormatFloat('#0.00', fValue); SelectAll; End; Inherited KeyPress(Key); End; procedure TWaehrEdit.CreateWnd; Begin Inherited CreateWnd; SetRects; End; constructor TWaehrEdit.Create(AOwner: TComponent); begin {Make it look and behave like a TEdit} inherited Create(AOwner); // WantReturns := False; // WordWrap :=False; Height := 23; Width := 80; fValue :=0; fIsValid :=True; fOldValue :=0; Text :='0' + DecimalSeparator + '00'; Alignment := taRightJustify; {Create the error space. If an error occurs an exclamation sign will be painted here} fCanvas :=TControlCanvas.Create; fCanvas.Control :=Self; fCanvas.Font :=Font; fCanVas.Font.Style :=Font.Style + [fsBold]; end; destructor TWaehrEdit.Destroy; Begin fCanvas.Destroy; Inherited Destroy; End; end. wie werden aus 0,2804 dann 0,280300 ? Gruss KH |
AW: unerklärlicher DB-eintrag mit currency werten
folgendes irritiert mich in dem Zusammenhang.
Wenn ich über IBexpert direkt in das Feld 0,3 eingebe und mit enter bestätige steht im Feld 0,299999 Erst nach Verlassen des DS oder nach dem Speichern wird dieser nach 0,300000 geändert :-( |
AW: unerklärlicher DB-eintrag mit currency werten
Hallo Karl-Heinz,
wie ist denn dein Feld in der DB definiert? Mir scheint, da wird nach 4 NK-Stellen abgeschnitten. Dein Brötchen zu 0,30 wird netto zu 0,280373..., abgeschnitten halt zu 0,2803 und nicht wie gewünscht zu 0,2804. Ciao Frank |
AW: unerklärlicher DB-eintrag mit currency werten
Zitat:
das DB -Feld ist decimal(18,6) |
AW: unerklärlicher DB-eintrag mit currency werten
Hallo Karl-Heinz,
das ist mir durch deinen vorherigen Post (0,3=> 0,299999) dann auch aufgegangen. Keine Idee :? Ciao Frank |
AW: unerklärlicher DB-eintrag mit currency werten
Zitat:
schade :-( |
AW: unerklärlicher DB-eintrag mit currency werten
currency hat nur 4 Nachkommastellen und rundet den Rest, das kann eine Ursache sein, also gehe ich von 6 auf 4 Stellen zurück, was auch ausreicht den Rundungsfehler auszuschalten, mal sehen :-).
Aber das nachfolgende kapier ich trotzdem noch nicht ich habe jetzt zum test mal folgendes gemacht :
Code:
in der Db steht danach 0,299900 :-(FBRUTTOPREIS := 0.300000; FQuery1['BRUTTOPREIS']:= FBRUTTOPREIS; .. .. FQuery1.post; :wall::wall: |
AW: unerklärlicher DB-eintrag mit currency werten
Man braucht folgendes Hintergrundwissen:
Der Delphi Datentyp Currency ist ein Festkommadatentyp und hat genau 4 Nachkommastellen. Solange man Currency verwendet gibt es keine Rundungsprobleme. Der Delphi Datentyp Double ist ein Flieskommadatentyp. Er hat die bekannten Rundungsprobleme. Datenbanken haben ihre eigenen Datentypen wie z.B. Decimal(18,6). Diese Datentypen kennen keine Rundungsprobleme, solange man mit SQL-Anweisungen rechnet. Leider kann Delphi den Datentyp Decimal(18,6) weder in einen Double noch in ein Currency kopieren ohne das es zu einem Genauigkeitsverlust kommt. Die Datenbank ist also genauer als alle Delphi Datentypen. :cry: ==> Feld auf 4 Nachkommastellen reduzieren oder mit den Rundungsfehlern leben. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz