![]() |
Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Hallo,
ich habe in der DB einen Wert als Float definert. Man kann in einem anderen Feld die NKS angeben. Ich dachte mir nun, das es einfach möglich ist aus einem String (12345 -> aus einem Textfeld) mit NKS (0 -> aus der DB) und der Funktion StrToFloat einen Float zu erhalten. Leider bekomme ich eine Exception - "kein gültiger Gleitkommawert" Gibt es eine andere Möglichkeit als wenn NKS=0 dann StrToInt sonst StrToFloat? Ich denke da an sowas wie StrToFloat mit Formatangaben. Danke Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Was ist NKS? NachKommaStellen?
StrToFloat hat normalerweise kein Probleme einen String der eine GanzZahl beinhaltet in einen Float umzuwandeln. Hast Du vielleicht ein Problem mit deinem DecimalSeperator? Grüße Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Hallo Klaus,
0 scheint zu gehen, aber 1000 und 1.000 gehen nicht. Allerdings geht 1000,0 auch nicht. Danke für die Hilfe Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Aber wenn Du Deinen Wert in der DB als Float definiert hast,
warum liest Du in dann nicht als Float aus? Grüße Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Sollte Code erforderlich sein:
Delphi-Quellcode:
Cheers
function getFormatted(value: String; decPlaces: Integer): Real;
var toFormat: Real; begin if value = '' then toFormat:= 0 else toFormat:= StrToFloat(value); result:=StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat])); end; Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Du meinst in etwa so?
Delphi-Quellcode:
Das mache ich. Dann wird dieser Wert in ein Tedit Feld gepackt und dann wieder ausgelesen. Und dann knallt es.
FieldByName('count').AsFloat
Cheers Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Habe es einmal ein wenig umgemodelt.
Aber nicht getestet, für power musst Du die Unit math einbinden.
Delphi-Quellcode:
Grüße
function getFormatted(value: String; decPlaces: Integer): Real;
var toFormat: Real; begin decPlaces:=decPlaces * -1; if value = '' then toFormat:= 0 else toFormat:= StrToFloat(value); result:=toFormat* power(10,decPlaces); // end; Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Hmm. Aber
Delphi-Quellcode:
bringt mir doch den Fehler. Habe ich getraced.
toFormat:= StrToFloat(value);
|
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Als value geht z.B.
1000 1.000 1.234.564 rein und alles bringt den Fehler. |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Zitat:
den Wert der Variable value angeschaut? Und wenn Du ein deutsche Windows System verwendest, dann haben die Werte keine Tausendertrennzeichen und der DecimalSeparator ist das Komma (,). Also ist 1.234.567 kein Floatwert. Grüße Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Im Debug Inspector steht
value '1.274.847' |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Ja, ok. Deshalb auch der Betreff. Kann ich denn mit Delphi aus einem IntegerString ein Float machen?
|
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Dann setzte doch das Format kurzzeitig um:
Delphi-Quellcode:
ThousandSeparator = '.';
toFormat:= StrToFloat(value); |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Gesagt, getan. Und wieder der FormatError.
|
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Schon die überladene StrToFloat mit Format versucht?
|
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Hatte
Delphi-Quellcode:
probiert und es ging nicht.
function Tfrm_budgets.getFormatted(value: String; decPlaces: Integer): Real;
var toFormat: Real; f: TFormatSettings; begin if value = '' then toFormat:= 0 else begin f.ThousandSeparator:= '.'; f.DecimalSeparator:= ','; toFormat:= StrToFloat(value, f); end; result:=StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat])); end; |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Habe ein bischen weiter geforscht und dabei heraus bekommen, das es tatsächlich am TausenderTrennzeichen liegt.
Aber wie kann ich den . nun löschen? So wie ich es mache geht es nicht:
Delphi-Quellcode:
So steht trotzdem der Punkt (TausenderTrenner) drin.
function TestTfrm_budgets.getFormatted(value: String; decPlaces: Integer): Real;
var toFormat: Real; i: Integer; str: String; f: TFormatSettings; begin if value = '' then toFormat:= 0 else begin for i := 0 to length(value) do begin v:= ; if (value[i] <> f.ThousandSeparator) then begin str:= str + value[i]; end; end; toFormat:= StrToFloat(str); end; result:=StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat])); end; |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
StringReplace()
|
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Delphi-Quellcode:
Und wieder der Fehler. Aber er ersetzt nicht den ThousendSeparator. Muss ich den irgendwie umwandeln?
function TestTfrm_budgets.getFormatted(value: String; decPlaces: Integer): Real;
var toFormat: Real; i: Integer; str: String; f: TFormatSettings; begin if value = '' then toFormat:= 0 else begin str:= StringReplace(value, f.ThousandSeparator, '', [rfReplaceAll]); toFormat:= StrToFloat(str); end; result:=StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat])); end; Danke Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Delphi-Quellcode:
str:= StringReplace(value, '.', '', [rfReplaceAll]);
|
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Dies ist der Testfall. Und der geht auch wieder nicht. So langsam denke ich an Selbstmord :-((
Delphi-Quellcode:
procedure TestTfrm_budgets.TestgetFormatted1;
var ReturnValue: Real; decPlaces: Integer; value: string; begin value:='1.000,00'; ReturnValue := getFormatted(value, decPlaces); Assert(ReturnValue=1000.00, 'Oops'); end; function TestTfrm_budgets.getFormatted(value: String; decPlaces: Integer): Real; var toFormat: Real; str: String; begin if value = '' then toFormat:= 0 else begin str:= StringReplace(value, '.', '', [rfReplaceAll]); toFormat:= StrToFloat(value); end; result:=StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat])); end; |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Du mußt auch den String verwenden, in welchem du ersetzt hast:
Delphi-Quellcode:
str:= StringReplace(value, '.', '', [rfReplaceAll]);
toFormat:= StrToFloat(str); |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Delphi-Quellcode:
Nur solltest Du noch sehen, das wenn Du alle Punkte (.) mit StringReplace löscht
function TestTfrm_budgets.getFormatted(value: String; decPlaces: Integer): Real;
var toFormat: Integer; str: String; begin if value = '' then toFormat:= 0 else begin str:= StringReplace(value, '.', '', [rfReplaceAll]); toFormat:= StrToFloat(str); // <---- str anstelle von value end; result:=toFormat*power(10,(decplaces*-1)); end; Du ein Problem bekommen könntest wenn Dein Programm auf einem englischen OS mit den englischen Ländereinstellungen läuft. Wenn Du aus der DB sowieso nur Ganzzahlwerte ausliest und die Nachkommastelle getrennt geliefert bekommst, wäre es vielleicht sinnvoller den value mit StrToInt umzuwandeln.
Delphi-Quellcode:
[edit] sorry mkinzler, hatte Dich übersehen [/edit]
var toFormat: Integer;
.. toFormat:= StrToInt(str); Grüße Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Arggghhh.
Delphi-Quellcode:
Danke Euch beiden. Ja ja der Wald und die Bäume :-)
toFormat:= StrToFloat(str); // <---- str anstelle von value
@Klaus: In der DB sind die Felder value:Real und decPlaces:Integer. Die NKS werden nur für die Ausgabe genutzt. Also: value = 1000,00 und NKS = 0 dann Ausgabe 1000 | value = 1000,00 und NKS = 4 dann Ausgabe 1000,0000 Was ich mich frage ist, wieso ich den f.ThousandSeparator nicht nutzen kann. Dann wäre doch das Locale-Problem (en, de) gelöst. Aber leider kommt bei StringReplace(str, f.ThousandSeparator, '', [rfReplaceAll]) trotzdem wieder der ungültige Gleitkommawert raus. Und als nächstes frage ich mich, warum das hier wieder nicht geht
Delphi-Quellcode:
Ich benutze hier eine gültige Formatfunktion und will den Wert zurückwandeln. Sollte das nicht gehen?
result:= StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat]));
Danke Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Zitat:
mal eine etwas blöde Frage, was bringt es Dir wenn in value ein Wert von 12345,23 steht und NKS=4 hat dann auf ein Ergebnis zu kommen das da lautet 12345,2300 welches eigentlich keine Mehrinformation bietet als 12345,23 - oder ? Grüße Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Morgen Klaus,
jep. Aber wenn Du anfängst Summen zu bilden über Werte mit unterschiedlichen NKS ist das notwendig. So bietet zwar 123.5600 keine Mehrinfos. Wohl aber value:123.5600 + value1:125.8979 Ich habe mir das ja auch nicht ausgedacht :-) Ist halt eine Anforderung von meinem Chef :-( |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
OK, das Problem mit dem f.ThousandSeparator habe ich jetzt gelöst. Ich kann ihn verwenden, wenn ich f: TFormatSettings initialisiert habe
Delphi-Quellcode:
Bleibt noch die Frage mit dem StrToFloat(formatierterString)
GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, f);
Cheers Per |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Delphi-Quellcode:
Wenn Du toFormat mit n formatierst werden wieder Tausendertrennzeichen in den String eingeführ.
result:= StrToFloat(format('%.' + IntToStr(decPlaces) + 'n', [toFormat]));
StrToFloat mag aber keine Tausendertrennzeichen. Wenn Du hier die Nachkommastellen haben willst,machen die nur als String einen Sinn, denn wenn Du das ganze wieder in einen Floatwert konvertierst ist die Angabe von Nachkommastellen relativ zweckfrei. Die Realwerte haben nur soviele Nachkommastellen wie nötig sind.
Delphi-Quellcode:
[/delphi]
result:= StrToFloat(format('%.' + IntToStr(decPlaces) + 'f', [toFormat]));
Ist unsinning, kürzer ist
Delphi-Quellcode:
und kommt auf das gleiche heraus.
result:=toFormat;
Die getrennte Angabe von Nachkommastellen in der DB macht für mich nur Sinn wenn value ein Integerwert ist. Floats werden in der DB wohl mit der richtigen Nachkommastellenanzahl gespeichert. Vielleicht macht es noch Sinn um die Maximale Nachkommastellenanzahl zu begrenzen, dann würde aus 123456,33333333 mit NKS=4 -> 123456,3333 -> was aber die Rechengenauigkeit einschränckt. Deswegen würde ich runden, wenn das Gesamtergebnis präsentiert werden soll und nicht schon beim Einlesen der einzelnen Werte. Grüße Klaus |
Re: Fehler bei StrToFloat(StrAlsIntegerFormatiert)
Danke für die ausführliche Erklärung.
Also mal kurz zu dem Format der Daten in der DB. Ich habe in einer DB-Tabelle Monatswerte:Real für Umsatz und Mitarbeiter und und und. Die werden leider mal als 12 - oder 12,9 oder 12,987 eingetragen. Nun soll der Umsatz mit N Stellen nach dem Komma und die Mitarbeiter als "Pseudo-Integer" ohne NKS dargestellt werden. Dafür ist der ganze Aufwand. Ok nach langem hin und her habe ich jetzt folgende Lösung, die soweit zu funktionieren scheint :-)
Delphi-Quellcode:
Danke nochmal an alle die an der Lösung mitgeholfen haben.
{
Format a real value with decimal places @param value the real to format @param decPlaces the decimal places to set @return String the formatted value } function Tfrm.getFormatted(value: Real; decPlaces: Integer): String; begin result:=format('%.' + IntToStr(decPlaces) + 'n', [value]); end; { Get a float from a string @param value the string to convert @return Real the value } function Tfrm.getFloat(value: String): Real; var str: String; f: TFormatSettings; begin if value = '' then result:= 0 else begin GetLocaleFormatSettings(LOCALE_SYSTEM_DEFAULT, f); str:= StringReplace(value, f.ThousandSeparator, '', [rfReplaceAll]); result:= StrToFloat(str); end; end; Cheers Per |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:24 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