Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   unerklärlicher DB-eintrag mit currency werten (https://www.delphipraxis.net/152587-unerklaerlicher-db-eintrag-mit-currency-werten.html)

khh 28. Jun 2010 15:12

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:
     FQuery1['NETTOPREIS']:= FNETTOPREIS;
     FQuery1['BRUTTOPREIS']:= FBRUTTOPREIS;
     ..
     ..

     FQuery1.post;
die Werte in die DB.

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

Bernhard Geyer 28. Jun 2010 15:37

AW: unerklärlicher DB-eintrag mit currency werten
 
Hast du evtl. persistende DB-Felder in deinem Formular angelegt die nur auf 4 stellen laufen?

khh 28. Jun 2010 15:47

AW: unerklärlicher DB-eintrag mit currency werten
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1032114)
Hast du evtl. persistende DB-Felder in deinem Formular angelegt die nur auf 4 stellen laufen?

sind zwar normale Eingabefelder,aber tatsächlich auf 4 Stellen formatiert.
Code:
preisnettoEdit.text := Format('%5.4f ', [Fnettopreis]);
das Eingabefeld ist vom type Twaehredit.
die entsprechene Unit unten.

aber wie sonst soll ich dem Benutzer einen Wert anbieten der keine 6 nachkommastellen anzeigt? :-(
Code:
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.
kapiert hab ichs aber trotzdem noch nicht :-(
wie werden aus 0,2804 dann 0,280300 ?
Gruss KH

khh 28. Jun 2010 16:00

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 :-(

FrankJ28 28. Jun 2010 16:02

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

khh 28. Jun 2010 16:04

AW: unerklärlicher DB-eintrag mit currency werten
 
Zitat:

Zitat von FrankJ28 (Beitrag 1032123)
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

Hi Frank
das DB -Feld ist decimal(18,6)

FrankJ28 28. Jun 2010 16:07

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

khh 28. Jun 2010 16:11

AW: unerklärlicher DB-eintrag mit currency werten
 
Zitat:

Zitat von FrankJ28 (Beitrag 1032125)
Hallo Karl-Heinz,
Keine Idee :?
Ciao
Frank


schade :-(

khh 28. Jun 2010 16:20

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:

FBRUTTOPREIS := 0.300000;
FQuery1['BRUTTOPREIS']:= FBRUTTOPREIS;  

..
..
FQuery1.post;
in der Db steht danach 0,299900 :-(
:wall::wall:

shmia 28. Jun 2010 16:39

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.
Seite 1 von 2  1 2      

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