![]() |
"Sicheres" Umwandeln von Zeichenkette in Zahl
Moin,
ivh muss relativ häufig Daten aus CSV-Dateien einlesen, bzw. die User bei uns im Haus bekommen Exceltabellen aus den unterschedlichsten Ländern und da ist eine willkürliche Formatierung von Zahlen fast selbstverständlich. Ich habe mir gerade eine kleine Hilfsfunktion geschrieben, die zumindest für deutsche und englische Formatierungen funktionieren sollte. Ich hätte gerne noch ein paar Ideen bzw. Vorschläge von euch, wie das ganze vielleicht noch umfassender werden kann, ohne gleich dafür einen zig-tausend Zeilen Block zu erstellen...
Delphi-Quellcode:
Moin
function SaveStringTofloat(aString: string): Double;
const Kickchar = ' €$'; Sepchar = ',.'; var i, y: Integer; sLang: string; dezSep: char; begin Result := 0; y := 0; sLang := ''; // Festgelegten Dezimalseparator merken dezSep := DecimalSeparator; try if aString <> '' then begin // für die Umwandlung den '.' als Dezimalseparator festlegen DecimalSeparator := '.'; // Zuerst alle Falschzeichen raus for i := 1 to length(Kickchar) do aString := StringReplace(aString, KickChar[i], '', [RfReplaceAll]); for i := Length(aString) downto 1 do begin // die übergebene Zeichenkette von rechts aufdröseln // und die Anzahl der Zeichen merken, da der Dezimalseparator eigentlich nicht // weiter als vier zeichen von rechts vorhanden sein sollte // Ok, bei mehr als drei Nachkommastellen fahren wir gegen sie Wand... krach, bumms, quietsch inc(y); // mögl. Dezimalseparator gefunden if pos(aString[i], SepChar) > 0 then begin if (y <= 4) and (sLang = '') then begin if aString[i] = ',' then sLang := 'de' else sLang := 'en'; end; // Bei mehr als 4 Stellen von rechts und keinem erkanntem Dezimalseparator bisher // wird es wohl eine 1000er-Formatierung sein if (y > 4) and (sLang = '') then begin if aString[i] = '.' then slang := 'de' else sLang := 'en'; end; end; end; if sLang <> '' then begin if (slang = 'de') then begin // Deutsch: '.' als 1000-er Formatierung entfernen // Dezimalseparator wird auf '.' ersetzt aString := StringReplace(aString, '.', '', [rfReplaceAll]); aString := StringReplace(aString, ',', '.', [rfReplaceAll]); end else // kein deutsch, also ',' als 1000-er Formatierung entfernen aString := Stringreplace(aString, ',', '', [rfReplaceAll]); end; result := StrTofloat(astring); end; finally DecimalSeparator := dezSep; end; end; |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Wirklich Delphi 2006 oder darf es auch etwas moderner sein?
|
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Anderer Ansatz:
CSV-Dateien mit Excel öffnen und dann mit Excelmitteln auslesen. Dazu könnte man Excel aus Delphi heraus fernsteuern. (Allerdings kann man da auch nicht absolut sicherstellen, dass das lokale Excel mit jeder beliebigen CSV-Datei vom Rest der Welt sicher und korrekt umgehen kann.) Ein schon etwas älteres Tutorial ist hier zu finden: ![]() Egal was Du bei Deinem Ansatz machst und wie gut Du ihn umgesetzt bekommst. Irgendwann kommt eine Datei, die nicht passt. ![]() |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Ja, zu meiner Schande mus ich gestehen, dass das größte Projekt bei uns noch in 2006 geschrieben ist.
Den Umzug zu Beerlin oder Tokyo habe ich noch nicht vollzogen... |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Ich kenne jetzt nicht die genauen Anforderungen, aber so spontan würde ich es mit
Delphi-Quellcode:
und verschiedenen FormatSettings versuchen. Natürlich würde die Kenntnis der Sprache vorab deutlich helfen.
function TryStrToFloat(const S: string; out Value: Single;
const FormatSettings: TFormatSettings): Boolean; overload; |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Wie gesagt, das sind je nach Zulieferer die verschiedensten Sprachen Italien, Türkei, Spanien...
Wir bekommen auch Dateien aus china, aber die lassen wir mal aussen vor |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Zitat:
Bzw.. falls ihr das Format festlegt, dann könnt ihr auch den Dezimalseparator bestimmen. Dann muss jeder Kunde nur schauen dass er es richtig abspeichert und ihr könnt ohne Probleme alles lesen ohne 353 verschiedene Sprachen/Notationen unterstützen zu müssen. |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Um meinen Vorschlag mal zu konkretisieren (hoffe mal, das geht alles unter D2006):
Delphi-Quellcode:
var
AllFormatSettings: array of TFormatSettings; procedure InitFormatSettings; const cLocales: array[0..5] of Integer = ( 1031, { German } 1033, { English } 1040, { Italian } 1055, { Turkish } 3082, { Spanish } LOCALE_USER_DEFAULT); var I: Integer; begin SetLength(AllFormatSettings, Length(cLocales)); for I := 0 to Length(cLocales) - 1 do begin GetLocaleFormatSettings(cLocales[I], AllFormatSettings[I]); end; end; function TryStrToFloatAll(const S: string; out Value: Double): Boolean; var I: Integer; begin Result := True; for I := 0 to Length(AllFormatSettings) - 1 do begin if TryStrToFloat(S, Value, AllFormatSettings[I]) then Exit; end; Result := False; end; |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Zitat:
Im Englischen ist die Zahl 10,345 für den PC eine 10345 Im Deutschen ist die Zahl 10,345 für den PC ein 10 und ein paar Zerquetschte. Daher kann keine Lösung garantieren, dass die Zahlen korrekt interpretiert werden, wenn der Nutzer nicht darüber wacht. ...:cat:... |
AW: "Sicheres" Umwandeln von Zeichenkette in Zahl
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:15 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