AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

ThousandSeparator - nur ein Mythos?

Ein Thema von Kurt Wallander · begonnen am 13. Apr 2022 · letzter Beitrag vom 18. Apr 2022
Antwort Antwort
Seite 1 von 2  1 2      
Kurt Wallander

Registriert seit: 11. Mai 2020
Ort: Freiberg
35 Beiträge
 
Delphi 10.4 Sydney
 
#1

ThousandSeparator - nur ein Mythos?

  Alt 13. Apr 2022, 11:08
Delphi-Version: 10.4 Sydney
Hallo, ihr Mitkämpfer
Ich brüte seit Wochen über ein Problem: ich möchte eine Extended-Variable mit ThousandSeparator ausgeben, aber mit Leerstellen anstatt der Punkte. LT: Hilfe zum Formatbefehl stehen dazu die Typen "n" und "m" zur Verfügung. Beim Typ "n" gibt es nur die Standard-Version mit den Punkten. Schluß, aus!
Beim Typ "m" wird die Möglichkeit von anderen Versionen erwähnt, gesteuert von der Systemvariablen ThousandSeparator, die mit einem char-Zeichen zu belegen ist. Gleichzeitig kann man auch das Dezimalzeichen und das Währungszeichen festlegen. Also schreibe ich in der create-Routine des Formulars
Code:
ThousandSeparator:=' '
. System.SysUtils ist selbstverständlich geladen, trotzdem meckert der Compiler: ein undeklarierter
Operator.
Weiteres Stöbern in der Hilfe rät zu einer Deklaration in eine TFormatsetting-Struktur. Die Eingabe
Code:
[B]var[/B] ForSet : TFormatSetting;
und dann
Code:
ForSet:=TFormatSetting.Create;
ForSet.ThousandSeparator:=' '
"TFormatSetting", "Create" und "ThousandSeparator" gefallen dem Compiler nicht. Übersetzt bekomme ich das Ganze nur, wenn ich ThousandSeparator als const definiere. Ergebnis: im Ausgabestring die erwähnten Punkte, egal ob Type "n" oder "m". Beim letzteren bekomme ich noch das €-Zeichen nachgeschmissen. Auch wenn ich das Währungszeichen als leerer String vereinbare. Die Hilfa zu TFormatSetting ist korrupt.
In der Delphi-Praxis wurde dieses Thema ebenfalls schon diskutiert - offensichtlich haben es alle aufgegeben.
Hat jemand eine zündende Idee. Ich nutze 10.4 CE und Windows 11.
Viele vorösterliche Grüße
Kurt
  Mit Zitat antworten Zitat
hhcm

Registriert seit: 12. Feb 2006
Ort: Wegberg
309 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: ThousansSeparator - nur ein Mythos?

  Alt 13. Apr 2022, 11:51
Das verstehe ich nicht.

Delphi-Quellcode:
program Project;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  AFormatSettings: TFormatSettings;

const
  Zahl: Extended = 1234567890;

begin
  try
    AFormatSettings := TFormatSettings.Create;
    AFormatSettings.ThousandSeparator := #32; // Oder auch so ' '
    Writeln(Format('%n', [Zahl], AFormatSettings));
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.
Ergibt bei mir (10.4 und 11 Pro)

Code:
1 234 567 890,00
Chris
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#3

AW: ThousansSeparator - nur ein Mythos?

  Alt 13. Apr 2022, 14:35
Weiteres Stöbern in der Hilfe rät zu einer Deklaration in eine TFormatsetting-Struktur.
Es heißt ja auch TFormatSettings und nicht TFormatSetting.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Kurt Wallander

Registriert seit: 11. Mai 2020
Ort: Freiberg
35 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: ThousansSeparator - nur ein Mythos?

  Alt 14. Apr 2022, 17:54
Hallo Uwe,
vielen Dank für deine Anregungen. Habe sie sogleich in mein Programm eingebaut. Die Ausgabe mit dem 1000er-Trennzeichen erfolgt immer in einer if ... else if Struktur, die insgesamt 6 Ebenen umfaßt. Und dort wird jeweils die erste der möglichen Outputs angekrittelt mit AFormatSettings als unbekannt. Aber das ganze kann nicht kompiliert werden.
Nun habe ich dein Konsolen-Beispiel in eine VCL-Fassung gebracht und kann alles normal übersetzen, linken und exekutieren. Nun erscheint der Runtime-Error 217 (bei der Adresse 619834). alles komisch.

Code:
unit Test_1000_Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}


var
  AFormatSettings: TFormatSettings;

const
  Zahl: Extended = 1234567890;

begin
  try
    AFormatSettings := TFormatSettings.Create;
    AFormatSettings.ThousandSeparator := #32; // Oder auch so ' '
    Writeln(Format('%n', [Zahl], AFormatSettings));
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Vielleicht kommt der Fehler vom writeln-Befehl. Welchen Message-Dialog müßte da stehen?
Und noch eine andere Frage. In meinen Programm verwende ich einen Aufzählungstyp
Code:
type
   TZ = (ab,bc,cd,de,ef,fg)
Nun wollte ich zu Testzwecken den aktuellen Wert von TZ ausgeben. Es scheint aber kein Format dafür zu geben. Oder ist so ein Konstrukt ein integer-Subtyp?
Einen fleißigen Osterhasen (für die Enkel).
Kurt
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.415 Beiträge
 
Delphi 7 Professional
 
#5

AW: ThousansSeparator - nur ein Mythos?

  Alt 14. Apr 2022, 18:23
Das Beispiel ist ein Kommandozeilenprogramm, Deine "Übersetzung" aber nicht.

ReadLn und WriteLn sind was für die Kommandozeile.

In 'ner VCL-Anwendung kann man 'ne Ausgabe u. a. über ShowMessage machen.

Also WriteLn durch ShowMessage ersetzen und ReadLn entfernen.
  Mit Zitat antworten Zitat
mmw

Registriert seit: 10. Sep 2019
Ort: OWL
322 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: ThousansSeparator - nur ein Mythos?

  Alt 14. Apr 2022, 18:31
hallo,

so sollte es funktionieren.

Delphi-Quellcode:
const
  Zahl: Extended = 1234567890;

var
  AFormatSettings: TFormatSettings;


begin
 AFormatSettings := TFormatSettings.Create;
  try
    AFormatSettings.ThousandSeparator := ' '; // Oder auch so ' '
    showMessage(Format('%n', [Zahl], AFormatSettings));
  except
     on E: Exception do begin
     ShowMessage(E.ClassName+ ': '+ E.Message);
    end;
  end;
 end;

Gruß
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.009 Beiträge
 
Delphi 12 Athens
 
#7

AW: ThousansSeparator - nur ein Mythos?

  Alt 14. Apr 2022, 22:48
Hallo Uwe,
vielen Dank für deine Anregungen. Habe sie sogleich in mein Programm eingebaut.
Ich war das nicht...
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Kurt Wallander

Registriert seit: 11. Mai 2020
Ort: Freiberg
35 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: ThousansSeparator - nur ein Mythos?

  Alt 15. Apr 2022, 12:24
Danke mmw, es klappt! Wieder was dazugelernt.
  Mit Zitat antworten Zitat
Kurt Wallander

Registriert seit: 11. Mai 2020
Ort: Freiberg
35 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: ThousansSeparator - nur ein Mythos?

  Alt 16. Apr 2022, 10:07
Irgendeine Teufelei steckt doch noch dahinter. Kaum hatte ich verkündet, daß der ThousandSeparator im Beispielprogramm funktioniert, habe ich das in meinen eigentlichen Programm umgesetzt und folgende Überrachung erlebt:
Code:
procedure TForm1.Plop(Sender: TObject);
var
   dummy            : Extended;
   AFormatSettings  : TFormatSettings;
begin
   if Tageszahl=JuDay then
   begin
      Label24.Caption:='1. 1. 4713 v. Chr. (jul. Kal.)  ';
      JD:=To_JD(Sekunde,Minute,Stunde,Tag,Monat,Jahr,KalTyp);
      AFormatSettings.Create;
      try
         AFormatSettings.ThousandSeparator:=' ';
         Edit1.Text:=[COLOR="red"][U]Format[[/U]/COLOR]('JD = %.6n',[JD, AFormatSettings]);
      except
         on E:Exception do
         begin
            ShowMessage(E.ClassName+ ': '+ E.Message);
         end;
      end;
   end
   else if Tageszahl=MJuDay then
   begin
      Dummy:=JD-0.5;
JD ist die Extended-Variable und hat einen Wert von mehr als 2400000. Die Prozedur Plop wird vom Timer im 10-Sekunden-Takt aufgerufen.
Der Compiler hat was gegen den Formatbefehl: es existiere keine overload-Variante, die mit den angegebenen Parametern aufgerufen werden könne. Auskommentieren von "AFormatSettings" besänftigt den Compiler, aber ich habe dann natürlich wider die Punkte als 1000erTrennzeichen. (Für Purititianer: die angedeutete Abfrage mit den geschachtelten "else if" ließe sich mit einer case-Anweisung sicherlich eleganter lösen.)
Wo liegt der Hase im Pfeffer?
Kurt
  Mit Zitat antworten Zitat
TKanne

Registriert seit: 6. Aug 2007
Ort: Berlin
24 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: ThousansSeparator - nur ein Mythos?

  Alt 16. Apr 2022, 10:34
Moin,

AFormatSettings.create;
ist falsch, es muss heißen:

AFormatSettings := TFormatSettings.Create;

Gruß
  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 00:43 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