DecimalSeparator
DecimalSeparator
Hallo,
ich möchte in meinem Programm den Punkt als Dezimaltrenner verwenden. Dazu habe ich im OnCreate-Ereignis eingegeben: DecimalSeparator := '.';
Wenn ich jetzt in einem Button schreibe Label.Caption := StrToFloat(X); wird der Wert auch korrekt mit einem Punkt angezeigt.
Wenn ich Label.Caption := StrToFloat(X); aber in einem Timer eingebe, meldet Lazarus "X is an invalid float".
Was könnte ich da wohl falsch machen?
ich möchte in meinem Programm den Punkt als Dezimaltrenner verwenden. Dazu habe ich im OnCreate-Ereignis eingegeben: DecimalSeparator := '.';
Wenn ich jetzt in einem Button schreibe Label.Caption := StrToFloat(X); wird der Wert auch korrekt mit einem Punkt angezeigt.
Wenn ich Label.Caption := StrToFloat(X); aber in einem Timer eingebe, meldet Lazarus "X is an invalid float".
Was könnte ich da wohl falsch machen?
-
- Beiträge: 98
- Registriert: Di 4. Aug 2015, 15:29
- OS, Lazarus, FPC: Linux, Raspbian, Windows
- CPU-Target: 64/32 Bit
Re: DecimalSeparator
Hallo Andromeda,
einem Caption-Feld kannst Du nur Zeichenketten übergeben,
funktioniert.
Eine Funktion, die die Fließpunktzahl formatiert aufbereitet, ist FloatToStrF(). http://www.freepascal.org/docs-html/rtl ... ostrf.html
Beste Grüße
Andreas
einem Caption-Feld kannst Du nur Zeichenketten übergeben,
Code: Alles auswählen
Label.Caption := FloatToStr(X);
Eine Funktion, die die Fließpunktzahl formatiert aufbereitet, ist FloatToStrF(). http://www.freepascal.org/docs-html/rtl ... ostrf.html
Beste Grüße
Andreas
Ubuntu 14.04 LTS / Raspbian / Windows: Lazarus ab 0.9 bis 3.0
Re: DecimalSeparator
Entschuldigung,
ich habe mich verschrieben.
Label.Caption := FloatToStr(X); funktioniert in einem Button, aber nicht in einem Timer.
ich habe mich verschrieben.
Label.Caption := FloatToStr(X); funktioniert in einem Button, aber nicht in einem Timer.
-
- Beiträge: 98
- Registriert: Di 4. Aug 2015, 15:29
- OS, Lazarus, FPC: Linux, Raspbian, Windows
- CPU-Target: 64/32 Bit
Re: DecimalSeparator
Hallo Andromeda,
in einem Timer brauchst Du natürlich eine der folgnden Funktionen:
Beste Grüße
Andreas
in einem Timer brauchst Du natürlich eine der folgnden Funktionen:
Code: Alles auswählen
StrToTime()
StrToDate()
StrToDateTime()
Andreas
Ubuntu 14.04 LTS / Raspbian / Windows: Lazarus ab 0.9 bis 3.0
Re: DecimalSeparator
Es tut mir leid, aber da habe ich mich wohl schlecht ausgedrückt.
Ich möchte einen Real-Wert, der als Dezimaltrenner einen Punkt enthält, also beispielsweise "2.5" in einem Label anzeigen. Dazu schreibe ich: Label.Caption := FloatToStr(X). Damit das funktioniert, habe ich im OnCreate-Ereignis des Formulars "DecimalSeparator := '.'" angegeben. Das funktioniert auch, wenn ich Label.Caption := FloatToStr(X) in einem Button ausführe. Da die Anzeige aber jede Stunde aktualisiert werden soll, schreibe ich Label.Caption := FloatToStr(X) in einen Timer, der auf eine Stunde eingestellt ist, und dann funktioniert es nicht mehr.
Dann meldet Lazarus nach einer Stunde "X is an invalid float".
Ich hoffe, das war jetzt verständlicher.
Ich möchte einen Real-Wert, der als Dezimaltrenner einen Punkt enthält, also beispielsweise "2.5" in einem Label anzeigen. Dazu schreibe ich: Label.Caption := FloatToStr(X). Damit das funktioniert, habe ich im OnCreate-Ereignis des Formulars "DecimalSeparator := '.'" angegeben. Das funktioniert auch, wenn ich Label.Caption := FloatToStr(X) in einem Button ausführe. Da die Anzeige aber jede Stunde aktualisiert werden soll, schreibe ich Label.Caption := FloatToStr(X) in einen Timer, der auf eine Stunde eingestellt ist, und dann funktioniert es nicht mehr.
Dann meldet Lazarus nach einer Stunde "X is an invalid float".
Ich hoffe, das war jetzt verständlicher.
Re: DecimalSeparator
Also bei mir geht's.
Der berichtete Fehler liegt mit Sicherheit nicht am Timer. Verwendest du Nicht-Standard-Komponenten? Ich könnte mir vorstellen, dass übereifrige Programmierer dort die FormatSettings zurücksetzen.
Ansonsten kannst du in der Timer-Routine einfach den DecimalSeparator nochmals auf Punk setzen:
Generell zum Ändern der Formateinstellungen: Ich hoffe, du bist der einzige Anwender deines Programms. Deine anderen Benutzer werden dir die Änderung übel nehmen...
Ein besserer Weg wäre, die Formateinstellungen nur zu ändern, wenn es unbedingt sein muss, etwa um eine Textdatei mit Dezimalpunkt einzulesen, und danach wieder zurückzusetzen. Und wenn du unbedingt den Dezimalpunkt haben willst, warum änderst du nicht die Formateinstellungen in Windows systemübergreifend?
Code: Alles auswählen
var
x: Double;
procedure TForm1.Timer1Timer(Sender: TObject);
var
x: Double;
begin
x := random*1000;
Label1.Caption := FloatToStr(x);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DecimalSeparator := '.';
end;
Ansonsten kannst du in der Timer-Routine einfach den DecimalSeparator nochmals auf Punk setzen:
Code: Alles auswählen
procedure TForm1.Timer1Timer(Sender: TObject);
begin
DecimalSeparator := '.';
Label1.Caption := FloatToStr(x);
end;
// oder:
procedure TForm1.Timer1Timer(Sender: TObject);
var
fs: TFormatSettings;
begin
fs := FormatSettings;
fs.DecimalSeparator := '.';
Label1.Caption := FloatToStr(x, fs);
end;
Ein besserer Weg wäre, die Formateinstellungen nur zu ändern, wenn es unbedingt sein muss, etwa um eine Textdatei mit Dezimalpunkt einzulesen, und danach wieder zurückzusetzen. Und wenn du unbedingt den Dezimalpunkt haben willst, warum änderst du nicht die Formateinstellungen in Windows systemübergreifend?
Re: DecimalSeparator
Vielen Dank für Eure Antworten.
Der Zweck des Ganzen ist, dass das Programm auch auf einem Notebook laufen soll, auf dem ein englisches Windows installiert ist. Im Programm werden ziemlich viele Werte aus dem Internet geladen, die alle sowieso schon einen Punkt als Dezimaltrenner enthalten. Mit denen werden dann auch noch ein paar Berechnungen durchgeführt und dann werden die Ergebnisse angezeigt. Das Beste wäre natürlich, dass die Ergebnisse auf einem deutschen Rechner ein Komma enthalten, auf dem englischen aber einen Punkt.
Wie gehe ich denn dann dabei vor?
Der Zweck des Ganzen ist, dass das Programm auch auf einem Notebook laufen soll, auf dem ein englisches Windows installiert ist. Im Programm werden ziemlich viele Werte aus dem Internet geladen, die alle sowieso schon einen Punkt als Dezimaltrenner enthalten. Mit denen werden dann auch noch ein paar Berechnungen durchgeführt und dann werden die Ergebnisse angezeigt. Das Beste wäre natürlich, dass die Ergebnisse auf einem deutschen Rechner ein Komma enthalten, auf dem englischen aber einen Punkt.
Wie gehe ich denn dann dabei vor?
Re: DecimalSeparator
Also:
(1) Das "DecimalSeparator := '.'" im FormCreate muss weg.
(2) In der Routine, in der die eingelesenen Strings in Floats umgewandelt werden, deklariere
(3) Zu jeder Zahl-String-Konvertierungsroutine gibt es eine überladene Version, der man die zu verwendenden Formatsettings hinzufügen kann. Also:
Auf diese Weise bleiben die Ländereinstellungen des Programms unverändert, und der Dezimalpunkt kommt nur da zum Einsatz, wo er benötigt wird.
(1) Das "DecimalSeparator := '.'" im FormCreate muss weg.
(2) In der Routine, in der die eingelesenen Strings in Floats umgewandelt werden, deklariere
Code: Alles auswählen
var
fs: TFormatSettings;
begin
fs := DefaultFormatSettings;
fs.DecimalSeparator := '.';
Code: Alles auswählen
zahl := StrToFloat(str, fs);
//bzw:
str := FloatToStr(zahl, fs);
-
- Beiträge: 320
- Registriert: Sa 21. Mär 2009, 17:31
- OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
- CPU-Target: 64 Bit
Re: DecimalSeparator
Das gehört zu Schnullis WitzenAndreasMR hat geschrieben:Hallo Andromeda,
in einem Timer brauchst Du natürlich eine der folgnden Funktionen:Beste GrüßeCode: Alles auswählen
StrToTime() StrToDate() StrToDateTime()
Andreas

-
- Beiträge: 6918
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: DecimalSeparator
Wen es zwingend immer ein Punkt als Trenner sein soll, dann guckst du am bestern die beiden Methode Val und Str an, diese beiden arbeiten immer mit einem Punkt, unabhängig von den Ländereinstellungen.Ich möchte einen Real-Wert, der als Dezimaltrenner einen Punkt enthält,
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: DecimalSeparator
Es muss nicht immer zwingend ein Punkt sein. Am liebsten wäre es mir, wenn das Programm den Dezimaltrenner verwendet, der auf dem Rechner von Haus aus eingestellt ist. In den Ausgabelabels sollten dann auf einem Rechner mit deutschem Windows ein Komma und auf dem Notebook mit englischem Windows ein Punkt erscheinen. Mit welchem Dezimaltrenner das Programm intern arbeitet, ist ja eigentlich egal.
-
- Beiträge: 1102
- Registriert: Di 5. Aug 2008, 09:37
- OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
- CPU-Target: 32/64,PPC(+64), ARM
- Wohnort: Eindhoven (Niederlande)
Re: DecimalSeparator
oder auf windows:wp_xyz hat geschrieben:Code: Alles auswählen
var fs: TFormatSettings; begin fs := DefaultFormatSettings; fs.DecimalSeparator := '.';
Code: Alles auswählen
var
fs: TFormatSettings;
begin
getlocaleformatsettings(LCID_English,fs);