DecimalSeparator

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Andromeda
Beiträge: 120
Registriert: So 4. Jan 2015, 20:18

DecimalSeparator

Beitrag von Andromeda »

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?

AndreasMR
Beiträge: 98
Registriert: Di 4. Aug 2015, 15:29
OS, Lazarus, FPC: Linux, Raspbian, Windows
CPU-Target: 64/32 Bit

Re: DecimalSeparator

Beitrag von AndreasMR »

Hallo Andromeda,

einem Caption-Feld kannst Du nur Zeichenketten übergeben,

Code: Alles auswählen

 
Label.Caption := FloatToStr(X); 
 
funktioniert.

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

Andromeda
Beiträge: 120
Registriert: So 4. Jan 2015, 20:18

Re: DecimalSeparator

Beitrag von Andromeda »

Entschuldigung,

ich habe mich verschrieben.

Label.Caption := FloatToStr(X); funktioniert in einem Button, aber nicht in einem Timer.

AndreasMR
Beiträge: 98
Registriert: Di 4. Aug 2015, 15:29
OS, Lazarus, FPC: Linux, Raspbian, Windows
CPU-Target: 64/32 Bit

Re: DecimalSeparator

Beitrag von AndreasMR »

Hallo Andromeda,

in einem Timer brauchst Du natürlich eine der folgnden Funktionen:

Code: Alles auswählen

 
StrToTime()
StrToDate()
StrToDateTime()
 
Beste Grüße

Andreas
Ubuntu 14.04 LTS / Raspbian / Windows: Lazarus ab 0.9 bis 3.0

Andromeda
Beiträge: 120
Registriert: So 4. Jan 2015, 20:18

Re: DecimalSeparator

Beitrag von Andromeda »

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.

wp_xyz
Beiträge: 5153
Registriert: Fr 8. Apr 2011, 09:01

Re: DecimalSeparator

Beitrag von wp_xyz »

Also bei mir geht's.

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

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;
 
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?

Andromeda
Beiträge: 120
Registriert: So 4. Jan 2015, 20:18

Re: DecimalSeparator

Beitrag von Andromeda »

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?

wp_xyz
Beiträge: 5153
Registriert: Fr 8. Apr 2011, 09:01

Re: DecimalSeparator

Beitrag von wp_xyz »

Also:
(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 := '.';
 
(3) Zu jeder Zahl-String-Konvertierungsroutine gibt es eine überladene Version, der man die zu verwendenden Formatsettings hinzufügen kann. Also:

Code: Alles auswählen

 
  zahl := StrToFloat(str, fs);
  //bzw:
  str := FloatToStr(zahl, fs);
 
Auf diese Weise bleiben die Ländereinstellungen des Programms unverändert, und der Dezimalpunkt kommt nur da zum Einsatz, wo er benötigt wird.

BeniBela
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

Beitrag von BeniBela »

AndreasMR hat geschrieben:Hallo Andromeda,

in einem Timer brauchst Du natürlich eine der folgnden Funktionen:

Code: Alles auswählen

 
StrToTime()
StrToDate()
StrToDateTime()
 
Beste Grüße

Andreas
Das gehört zu Schnullis Witzen :mrgreen:

Mathias
Beiträge: 6918
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: DecimalSeparator

Beitrag von Mathias »

Ich möchte einen Real-Wert, der als Dezimaltrenner einen Punkt enthält,
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.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Andromeda
Beiträge: 120
Registriert: So 4. Jan 2015, 20:18

Re: DecimalSeparator

Beitrag von Andromeda »

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.

marcov
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

Beitrag von marcov »

wp_xyz hat geschrieben:

Code: Alles auswählen

 
var
  fs: TFormatSettings;
begin
  fs := DefaultFormatSettings;
  fs.DecimalSeparator := '.';
 
oder auf windows:

Code: Alles auswählen

 
var
  fs: TFormatSettings;
begin
  getlocaleformatsettings(LCID_English,fs);
 

Antworten