Autor Beitrag
michaelarban
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 34



BeitragVerfasst: Fr 30.07.10 17:47 
hallo,

wie kann ich in Delphi am besten prüfen, ob ein String eine Zahl im "Geld-Format" enthält,

z.B.:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
myBetrag := '1.234.567';
myBetrag := '1.234.567,89';
myBetrag := '1234567';
myBetrag := '1234567,08';
myBetrag := '10.234.567';

aber nicht so was:
ausblenden Delphi-Quelltext
1:
2:
3:
myBetrag := '1.2.34.567';
myBetrag := '1.23,4.567';
myBetrag := '1.234.567,897';

kennt ihr solche Delphi-Funktionen oder entsprechende Reguläre Ausdrücke?

danke

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 30.07.10 19:52 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function IsMyCurrencyFormat(const Value: string): Boolean;
var
  Temp: Double;
  SepPos: Integer;
begin
  Result := TryStrToFloat(Value, Temp);
  if Result then
  begin
    SepPos := Pos(DecimalSeparator, Value);
    Result := (SepPos = 0or (SepPos = Length(Value) - 2);
  end;
end;
Ungetestet, aber so müsste es passen.
// EDIT: klar, Boolean :D


Zuletzt bearbeitet von jaenicke am Sa 31.07.10 09:12, insgesamt 1-mal bearbeitet
Stundenplan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 128
Erhaltene Danke: 32

Win 7
Delphi 7 Pers., C# (VS 2010 Express)
BeitragVerfasst: Fr 30.07.10 20:43 
Muss der Rückgabewert nicht Boolean sein? :gruebel:
HotCoffee
Hält's aus hier
Beiträge: 14

Suse Linux 11, Win Xp SP 3, Win 2000, Win 98,

BeitragVerfasst: Fr 30.07.10 21:34 
Hallo,
also ich würde das wie folgt lösen.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
function  isCurrency  (pCheck : String) : Boolean;
VAR i,a         : integer;
begin
  result:=TRUE;
  a:=0;
  FOR i:=length(pCheck) DOWNTO 1 do
  begin
    a:=a+1;
    IF ((pCheck[i]='.'AND (a=4)) OR ((pCheck[i]=','AND (a<=3)) 
    THEN a:=0 
    ELSE 
      IF (pCheck[i]='.'OR (pCheck[i]=','
      THEN result:=FALSE
  end;
  pCheck:=stringreplace(pCheck,'.','',[RFREPLACEALL]);
  try
   IF (strtofloat(pCheck)*100-trunc(strtofloat(pCheck)*100)=0THEN;
  except 
    result:=FALSE
  end;
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 31.07.10 09:24 
Also erstens akzeptiert der Code auch "4,", also nur das Komma ohne Nachkommastellen. Zweitens hast du leider den DecimalSeparator nicht berücksichtigt, was wenn das Windows englisch eingestellt ist?

Ja, und dann:
user profile iconHotCoffee hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  try
   IF (strtofloat(pCheck)*100-trunc(strtofloat(pCheck)*100)=0THEN;
  except 
    result:=FALSE
  end;
Autsch, schau dir mal an wie es richtig geht (wie bei mir mit TryStrToFloat (oder auch TryStrToCurr gibts)...).

Jetzt habe ich meine Variante getestet, aber leider ignoriert TryStrToFloat den ThousandSeparator. Alles ist korrekt gesetzt, es sagt aber, dass es keine gültige Zahl sei... :autsch:
Von den Nachkommastellen her passt es. Also geht wohl wirklich nur stellenweise alles analysieren.
HotCoffee
Hält's aus hier
Beiträge: 14

Suse Linux 11, Win Xp SP 3, Win 2000, Win 98,

BeitragVerfasst: Sa 31.07.10 12:40 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Autsch

Okay :D du hast Recht, ich habs mir nochmal angeschaut und festgestellt, dass ich Try doof finde. Daher habe ich mal etwas anderes gebastelt. Diese Funktion überprüft, ob es sich um eine Währung handelt, egal ob sie Deutsch oder Englisch angegeben ist. Sie wird aufgerufen durch IsCurrency( ZuUeberpruefendeZahl,' ',0);.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function IsCurrency(Str : String; Sep  : Char; Co : Integer) : Boolean;
VAR l : Char;
begin
 l:=Str[length(Str)];
 delete(Str,length(Str),1);
 IF length(Str)>0
 THEN
   IF l in ['0'..'9']
   THEN result:=IsCurrency(Str,Sep,Co+1)
   ELSE
      IF l in [',','.']
      THEN IF (0<Co) AND (CO<3AND (Sep=' ')
           THEN result:=IsCurrency(Str,l,0)
           ELSE
            IF (Co=3AND (Sep<>l)
            THEN result:=IsCurrency(Str,Sep,0)
            ELSE result:=FALSE
      ELSE result:=FALSE
 ELSE result:=TRUE;
end;

Wenn es nur auf deutsche Währung reagieren soll, dann einfach in Zeile 12 ein  And (l=',') und ergänzen, sowie in Zeile 15 (Sep='.') ändern.
Ich weiss, umständlich, dafür funktioniert es :D
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Sa 31.07.10 13:34 
@jaenicke: Das lässt sich ja leicht korrigieren.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function ThousandsSetCorrect(value: string): Boolean;
var
  i: Byte;
begin
  Result := value[1] <> ThousandSeparator;
  if Result and (Pos(DecimalSeparator) > 3then
    for i := 1 to Pos(DecimalSeparator) - 1 do
      if value[i] = ThousandSeparator then
        Result := Result and
          (Pos(DecimalSeparator) > i) and
          (0 = (Pos(DecimalSeparator) - i) mod 3);
end;


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function cIsMyCurrencyFormat(value: string): Boolean;
begin
  Result :=
    IsMyCurrencyFormat(StringReplace(value, ThousandSeparator, '', [rfReplaceAll])) and
    IsThousandsSetCorrect(value);
end;


ist aber ebenfalls ungetestet.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 31.07.10 17:42 
Ok, nach dem ganzen Pos usw. poste ich dann doch noch ne Variante, die das alles direkt macht:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
function IsCurrencyString(const AValue: string; ADecimalSeparator,
  AThousandSeparator: Char): Boolean; overload;
var
  i, DecCounter: Integer;
  ThousandSep: Boolean;
begin
  DecCounter := 0;
  Result := True;
  ThousandSep := False;
  for i := Length(AValue) downto 1 do
    if AValue[i] in ['0'..'9'then
      if ThousandSep and (DecCounter > 2then
        Result := False
      else
        Inc(DecCounter)
    else if AValue[i] = ADecimalSeparator then
      if (i = 1or (i <> Length(AValue) - 2then
        Result := False
      else
        DecCounter := 0
    else if AValue[i] = AThousandSeparator then
    begin
      ThousandSep := True;
      if (i = 1or (DecCounter <> 3then
        Result := False
      else
        DecCounter := 0
    end
    else
      Result := False;
end;

function IsCurrencyString(const AValue: string): Boolean; overload;
begin
  Result := IsCurrencyString(AValue, DecimalSeparator, ThousandSeparator);
end;
Entweder man übergibt explizite Zeichen für die Trennzeichen oder es werden die des Systems benutzt. Funktioniert in einem Durchlauf durch die Buchstaben und braucht keine Umwandlung oder Pos oder so. ;-)

Beispielaufruf:
ausblenden Delphi-Quelltext
1:
  ShowMessage(BoolToStr(IsCurrencyString('1.222.333,55'), True));