AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken unerklärlicher DB-eintrag mit currency werten
Thema durchsuchen
Ansicht
Themen-Optionen

unerklärlicher DB-eintrag mit currency werten

Ein Thema von khh · begonnen am 28. Jun 2010 · letzter Beitrag vom 28. Jun 2010
Antwort Antwort
Seite 1 von 2  1 2      
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#1

unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 16:12
Datenbank: firebird • Version: 2.1 • Zugriff über: zeos
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
Karl-Heinz

Geändert von mkinzler (28. Jun 2010 um 18:16 Uhr) Grund: Code-Tag durch delphi-Tag ersetzt
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.202 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 16:37
Hast du evtl. persistende DB-Felder in deinem Formular angelegt die nur auf 4 stellen laufen?
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#3

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 16:47
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
Karl-Heinz
  Mit Zitat antworten Zitat
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#4

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:00
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
Karl-Heinz
  Mit Zitat antworten Zitat
FrankJ28

Registriert seit: 7. Apr 2008
211 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:02
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
"Sage was du tust, und tue was du sagst"
Johannes Rau
  Mit Zitat antworten Zitat
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#6

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:04
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)
Karl-Heinz
  Mit Zitat antworten Zitat
FrankJ28

Registriert seit: 7. Apr 2008
211 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:07
Hallo Karl-Heinz,
das ist mir durch deinen vorherigen Post (0,3=> 0,299999) dann auch aufgegangen. Keine Idee
Ciao
Frank
"Sage was du tust, und tue was du sagst"
Johannes Rau
  Mit Zitat antworten Zitat
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#8

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:11
Hallo Karl-Heinz,
Keine Idee
Ciao
Frank

schade
Karl-Heinz
  Mit Zitat antworten Zitat
khh

Registriert seit: 18. Apr 2008
Ort: Südbaden
1.929 Beiträge
 
FreePascal / Lazarus
 
#9

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:20
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
Karl-Heinz

Geändert von khh (28. Jun 2010 um 17:39 Uhr)
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

AW: unerklärlicher DB-eintrag mit currency werten

  Alt 28. Jun 2010, 17:39
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.

==> Feld auf 4 Nachkommastellen reduzieren oder mit den Rundungsfehlern leben.
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:33 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz