Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi CSV anpassen (https://www.delphipraxis.net/206659-csv-anpassen.html)

Moombas 18. Jan 2021 07:46

AW: CSV anpassen
 
Wie Klaus bereits hier schrieb: https://www.delphipraxis.net/1481022-post3.html
Wäre es am Besten, eine klare Struktur als CSV zu haben.
Wobei ich immer die Variante mit "" bevorzuge, dann wäre das bei dir:
"Anrede";"Titel";"Nachname";"Vorname";"mit" //wozu das "mit" auch immer steht

Diese kann man dann (zumindest in Lazarus) mittels bereits existierender Funktion in ein Grid laden:
Delphi-Quellcode:
Grid.LoadFromCSVFile('Dateiname')
Dies kannst du dann entsprechend viel leichter behandeln und die Fehlerquote ist geringer.

Oben bitte mal ignorieren, ich denke du willst aus deinen Daten eine richtige CSV machen, diese also "korrigieren".

Woher kommt denn deine Text/CSV-Datei? Musst du sie wirklich selber anpassen oder wäre es nicht ggf. Sinnvoller die Quelle anzupassen (wenn möglich).

Jumpy 18. Jan 2021 09:12

AW: CSV anpassen
 
Könnte man das nicht irgendwie OOP sauber lösen, anstatt so eine Stringlist Orgie?

Man erstellt ein Objekt für eine Person mit den Benötigten Feldern, übergibt dann den jetzigen langen String für eine Person an das Objekt. Darin wird der String zerlegt und auf die Felder verteilt. Dann kriegt das Objekt noch eine ToCSVString Funktion oder so, die das in der richtigen Reihenfolge mit Semikolon getrennt raus gibt.

Bei der Zerlegung des String bleiben natürlich trotzdem die bisher genannten Probleme zu Unterscheiden, was was ist.

Uwe Raabe 18. Jan 2021 11:02

AW: CSV anpassen
 
Zitat:

Zitat von Klaus01 (Beitrag 1481096)
.. wie schonmal angemerk, würde ich die Titel zusammenfassem.

Würde ich auch machen. Hier mal eine rudimentäre Funktion dafür:
Delphi-Quellcode:
function MakeCSV(Line: string): string;
var
  lst: TStringList;
  M: Integer;
  N: Integer;
begin
  lst := TStringList.Create;
  try
    { Anrede }
    N := Line.IndexOf(' ');
    lst.Add(Line.Substring(0, N));
    Line := Line.Remove(0, N + 1);
    { Titel }
    N := Line.LastIndexOf('.');
    if N > 0 then begin
      { Punkt mitnehmen }
      lst.Add(Line.Substring(0, N + 1));
      Line := Line.Remove(0, N + 2);
    end
    else begin
      { kein Titel }
      lst.Add('');
    end;
    { gibt es einen Vornamen? }
    N := Line.IndexOf(',');
    if N > 0 then begin
      { Nachname }
      lst.Add(Line.Substring(0, N));
      { Komma und Leerzeichen mit entfernen }
      Line := Line.Remove(0, N + 2);
      { Vorname }
      N := Line.IndexOf(' ');
      lst.Add(Line.Substring(0, N));
      Line := Line.Remove(0, N + 1);
    end
    else begin
      { Nachname }
      N := Line.IndexOf(' ');
      lst.Add(Line.Substring(0, N));
      Line := Line.Remove(0, N + 1);
      { kein Vorname }
      lst.Add('');
    end;
    { "mit" }
    lst.Add(Line);

    Result := lst.CommaText;
  finally
    lst.Free;
  end;
end;

julchen 18. Jan 2021 19:55

AW: CSV anpassen
 
Hallo,

vielen Dank für eure Hilfe und die tollen Codebeispiele.
Hätte ich nieeeeee geschafft.
Mit dem Titel habe ich mir überlegt, das ein Eintrag für alle Titel reicht.
Werde Morgen mit dem Code weiterarbeiten. Melde mich dann wieder.
Bis dahin und ich noch einen schönen Abend euch allen.
VG Julia

Rollo62 19. Jan 2021 08:06

AW: CSV anpassen
 
Zitat:

Zitat von julchen (Beitrag 1481151)
Hätte ich nieeeeee geschafft.

Dooooch, sicher.
Übung mach die Meisterin :-D

Blup 20. Jan 2021 10:12

AW: CSV anpassen
 
@Jumpy
OOP bedeuted nicht, das alle Methoden die irgendetwas mit dem Datenobjekt zu tun haben, auch im Datenobjekt implementiert werden.
Methoden für den Export oder Import gehören dann eher in eine Klasse die das entsprechende Dateiformat representiert.

Da es sich hier um zwei verschiedene Formate handelt, würde ich den Export und Import zumindest in zwei Methoden aufteilen.
Das erhöht vieleicht auch die Lesbarkeit.

Als Trennzeichen soll das Semikolon genutz werden.
Ich habe den Code von Uwe Raabe ein bischen abgewandelt https://www.delphipraxis.net/1481113-post23.html

Delphi-Quellcode:
type
  TMyData = record
    Anrede: string;
    Titel: string;
    Nachname: string;
    Vorname: string;
    mit: string;
  end;

function TextToMyData(ALine: string): TMyData;
var
  N: Integer;
begin
  { "Anrede" immer vorhanden }
  N := ALine.IndexOf(' ');
  Result.Anrede := ALine.Substring(0, N);
  ALine := ALine.Remove(0, N + 1);

  { "Titel" ein oder mehrere optional }
  N := ALine.LastIndexOf('.');
  if N > 0 then
  begin
    { Punkt mitnehmen }
    Result.Titel := ALine.Substring(0, N + 1);
    ALine := ALine.Remove(0, N + 2);
  end;

  { "mit" immer vorhanden }
  N := ALine.LastIndexOf(' ');
  if N > 0 then
  begin
    Result.mit := ALine.Substring(N + 1);
    ALine := ALine.Remove(N);
  end;

  { "Vorname" optional }
  N := ALine.IndexOf(',');
  if N > 0 then
  begin
    Result.Vorname := ALine.Substring(N + 1);
    Result.Vorname := Result.Vorname.Trim;
    ALine := ALine.Remove(N);
  end;

  { "Nachname" immer vorhanden }
  Result.Nachname := ALine.Trim;
end;

function MyDataToCSV(const AValue: TMyData): string;
var
  lst: TStringList;
begin
  lst := TStringList.Create;
  try
    lst.QuoteChar := '"';
    lst.Delimiter := ';';
    lst.StrictDelimiter := True;

    { Anrede;Titel;Nachname;Vorname;mit }
    lst.Add(AValue.Anrede);
    lst.Add(AValue.Titel);
    lst.Add(AValue.Nachname);
    lst.Add(AValue.Vorname);
    lst.Add(AValue.mit);

    Result := lst.DelimitedText;
  finally
    lst.Free;
  end;
end;

procedure TForm1.TestClick(Sender: TObject);
var
  i: Integer;
  s: string;
  v: TMyData;
begin
  Memo2.Lines.Clear;
  for i := 0 to Memo1.Lines.Count - 1 do
  begin
    s := Memo1.Lines[i];
    { leere Zeilen ignorieren (Textdateien enthalten als letztes Zeichen häufig noch einen Zeilenumbruch) }
    if s.Length > 0 then
    begin
      v := TextToMyData(s);
      s := MyDataToCSV(v);
      Memo2.Lines.Add(s);
    end;
  end;
end;

julchen 22. Jan 2021 19:00

AW: CSV anpassen
 
Hallo,

meine Beispieltexte haben noch eine zweite Hälfte, die für mich bis her nicht das Problem waren, da es fest definierte Zeichen gibt, die ich mit StringReplace gegen ein Semikolon tauschen konnte.
Mit eurem Code laufen die Texte auseinander.

Aus:
Herr Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr Dr. Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr Dr. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr Prof. Dr. Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr Prof. Dr. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)

Wird:
Herr;;Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00;;Uhr)
Herr;;Mustermann;Max mit ABCDEFGHI/00A (1): Terminplan(08:00;Uhr)
Herr;Dr.;Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00;Max mit ABCDEFGHI/00A (1): Terminplan(08:00;Uhr)
Herr;Dr.;Mustermann;Max mit ABCDEFGHI/00A (1): Terminplan(08:00;Uhr)
Herr;Prof. Dr.;Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00;Max mit ABCDEFGHI/00A (1): Terminplan(08:00;Uhr)
Herr;Prof. Dr.;Mustermann;Max mit ABCDEFGHI/00A (1): Terminplan(08:00;Uhr)

Ich habe mit den Codes so ein bisschen rumgespielt und auch versucht, die Variante von Blup an mein Problem anzupassen und zu erweitern, da es die für mich einfachste Variante war, die ich verstehen konnte.

Das Problem ist wohl wirklich, den Vornamen zu fassen :-(

Uwe Raabe 22. Jan 2021 19:37

AW: CSV anpassen
 
Ich denke, mein obiges Codebeispiel kommt mit den Texten ganz gut klar.

EmWieMichael 23. Jan 2021 10:08

AW: CSV anpassen
 
Ohne jemanden entmutigen zu wollen (und ich kenn ja auch die Qualität der zu untersuchenden Daten nicht), aber spätestens wenn Sätze wie

Herr Dr. Mustermann, K. mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr von Mustermann, Klaus W. mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)

auftauchen, wird klar, dass die hier vorgestellten Lösungen nicht funktionieren.

Die Logik zur Ermittlung des Vornamens ist doch relativ simpel:
Ist das aktuelle Wort nicht 'mit' und der Familienname ist bereits identifiziert, dann ist das Wort der Vorname.

Uwe Raabe 23. Jan 2021 11:54

AW: CSV anpassen
 
Zitat:

Zitat von EmWieMichael (Beitrag 1481440)
Ohne jemanden entmutigen zu wollen (und ich kenn ja auch die Qualität der zu untersuchenden Daten nicht), aber spätestens wenn Sätze wie

Herr Dr. Mustermann, K. mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
Herr von Mustermann, Klaus W. mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)

auftauchen, wird klar, dass die hier vorgestellten Lösungen nicht funktionieren.

Wenn keine vollständigen Regeln definiert sind, kann man halt nur eine Analyse der verfügbaren Daten vornehmen und passende Regeln daraus ableiten. Sobald dann aber Daten auftauchen, für die diese Regeln nicht gelten, muss man halt nochmal ran. Das ist dann halt nicht zu vermeiden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:11 Uhr.
Seite 3 von 5     123 45      

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