CSV anpassen
Hallo,
Ich habe eine Liste, die ich nach dem Schema anpassen möchte: Anrede;Titel;Titel;Nachname;Vorname;mit Die Liste ist so aufgebaut: Herr Mustermann mit Herr Mustermann, Max mit Herr Dr. Mustermann mit Herr Dr. Mustermann, Max mit Herr Prof. Dr. Mustermann mit Herr Prof. Dr. Mustermann, Max mit Das Semikolon nach Herr bekomme ich hin mit StringReplace. Nach Prof. wollte ich mit pos und insert das Semikolon einfügen. Funktioniert aber nicht. Was mache ich da falsch?
Code:
VG, Julia
var
s1, s2:string; i: integer; pos1: integer; begin for i := 0 to Memo1.Lines.Count - 1 do begin s1 := Memo1.lines[i]; pos1 := pos('Prof.', s1, pos1 + 1 ); if pos1 <> 0 then begin Insert(';' , s1 , pos1); end; |
AW: CSV anpassen
Möchtest du das Ergebnis im Memo speichern?
Ich frag deshalb, weil du das Ergebnis nur in einer Variable vorhältst und man nicht sehen kann wie du diese weiter verwendest. Wäre evtl. nicht das Ausführen von 2 StringRepace besser? Einmal mit ' ', ';' und einmal mit ', ', ';' Evtl. direkt auf Memo.Text angewendet, falls das Memo das Ergebnis bekommen soll:
Delphi-Quellcode:
Memo.Text := StringReplace( Memo.Text, ' ', ';', [rfReplaceAll] );
Memo.Text := StringReplace( Memo.Text, ',', ';', [rfReplaceAll] ); |
AW: CSV anpassen
.. wenn Du das als csv machen willst,
Dann sollten alles Zeilen die gleiche Anzahl von Elementen enthalten. Herr, , ,Mustermann, ,mit Herr, , ,Mustermann, Max, mit Herr,Dr., ,Mustermann, ,mit Herr,Dr., ,Mustermann, Max, mit Herr,Prof.,Dr.,Mustermann, ,mit Herr,Prof.,Dr., Mustermann, Max, mit Das automatisch hinzubekommenist nicht so einfach. Wie willst Du denn z.B. Namen und Vornamen unterscheiden? Oder ist es bei den Daten sicher, dass zumindest der Nachname aufgelistet ist? Die Titel, würde ich in ein Feld packen, also Prof, Prof. Dr., Prof. Dr. Dr., Grüße Klaus |
AW: CSV anpassen
Ich würde zunächst aufteilen in Nachname , Vorname (mit Pos(',')
anschliessend schauen welche Anreden und Titel noch vor dem Nachname stehen. Dafür brauchst Du ein Array mit allen möglichen Anreden und kannst über eine Schleife diese der Reihe nach im Nachnamen suchen. if Pos( a[i], Copy(nachname, 1, Length(a[i])))=1 then ... Am Ende kannst Du in einer StringList das CSV aufbauen. Es ist dort aber üblich, textelemente in "" zu stellen. |
AW: CSV anpassen
Zitat:
|
AW: CSV anpassen
Hallo und Danke für die bisherige Rückmeldung,
Die Daten sehen so aus, wie im Beispiel angeführt. Einen Nachnamen hat jeder Mitarbeiter. Ich kopiere die Liste in ein Memo. Die Anzahl der vorgegebenen Elemente, seien es Leerzeichen oder Kommas kann ich nicht beeinflussen. Nachname und Vorname sind immer durch ein Komma getrennt. Ich muss mal sehen, ob ich es heute noch schaffe, ein bisschen Code auszuprobieren. VG, Julia |
AW: CSV anpassen
Frage:
1) Kann man davon ausgehen, dass der String IMMER mit einer Anrede anfängt (also Herr, oder Frau)? 2) Kann man davon ausgehen, dass der String IMMER mit dem Wort "mit" endet? Oder kann die Anrede oder das Wort "mit" auch mal wegfallen? Entsprechend kurz oder länger wird der Code. ;-) |
AW: CSV anpassen
CSV geht aber anders. TStringlist... Add(string)... CommaText und schon ist eine Zeile fertig.
Speichern in einer zweiten TStringList. Die auslesen via Text oder SaveToFile. Dann hat man eine CSV Datei. |
AW: CSV anpassen
Zitat:
Es gibt immer ein mit. |
AW: CSV anpassen
Ich habe die Funktion CompareStrings gefunden.
Ich habe da den ganzen Morgen schon mit rumgespielt, aber es klappt nicht. Habe schon alle möglichen Kombinationen durch und komme nicht weiter. Wenn Herr kleiner als Prof ist, dann ein Semikolon, sonst zwei.
Code:
procedure TForm1.Button1Click(Sender: TObject);
var herr, prof: string; begin herr := 'Herr'; prof := 'Prof.'; CompareStrings(herr, prof); end; procedure TForm1.CompareStrings(const herr, prof: string); var result : Integer; i: Integer; begin begin for i := 0 to Memo1.Lines.Count - 1 do result := AnsiCompareText(herr , prof); if result < 0 then begin Memo1.Text := Stringreplace(Memo1.Text, herr, 'Herr;' , [rfReplaceAll]) end end; for i := 0 to Memo1.Lines.Count - 1 do result := AnsiCompareText('Herr;', prof); if result < 0 then begin Memo1.Text := Stringreplace(Memo1.Text, 'Herr' , 'Herr;;' , [rfReplaceAll]) end end; |
AW: CSV anpassen
.. CompareStrings vergleicht die Zeichen der Zeichenkette nicht deren Länge.
Da ist es egal ob am Ende ein Semikolon ist oder auch zwei. 'Herr' und 'Prof' unterscheiden sich schon beim ersten Zeichen. Grüße Klaus |
AW: CSV anpassen
Da Deine Titel immer eien Punkt beinhalten, kannst Du wohl mit einer Stringlist arbeiten
So mal aus dem Ärmel:
Code:
Hier gibt es keine Fehlerüberpüfung und sonstige Feinheiten und im Name darf auch kein Punkt vorkommen, aber grundsätzlich siehst Du hier einen gangbaren Weg.
procedure inputcsv;
var sl : TstringList; Anrede, Titel, Name, Vorname, Suffix : String; begin sl := TStringList.Create(); sl.Delimiter := ','; sl.StrictDelimiter := true; Try // Als Beispiel, später sollte das bei Dir eine übergeben Variable an ene Funktion sein, // die als Ausgabe dann Deinen Wunschstring enthält sl.DelimitedText := 'Herr,Prof., Mustermann, Max, mit'; Anrede := sl[0]; If Pos('.',sl[1]) > 0 Then // Titel vorhanden Begin Titel := sl[1]; Name := sl[2]; Vorname := sl[3]; Suffix := sl[4]; end else Begin Titel := ''; Name := sl[1]; Vorname := sl[2]; Suffix := sl[3]; End; Finally sl.free End; |
AW: CSV anpassen
Probier es mal damit. BtnStartClick muss du dir entsprechend anpassen:
Delphi-Quellcode:
Procedure SplitAtPosAndTrim(const aSource: String; const aPosOfRightPart: Integer; var aLeftPart: string; var aRightPart: String);
begin aRightPart := Trim(copy(aSource, aPosOfRightPart, length(aSource) - aPosOfRightPart+1)); aLeftPart := Trim(copy(aSource, 1, aPosOfRightPart-1)); end; Function KonvertToCsvString(aSourceString: String): String; const lTitelVorgaben: array [0 .. 2] of string = ('Dr.', 'Prof.', 'Dipl.-Ing.'); var lAnrede: String; lTitel1: String; lTitel2: String; lNachname: String; lVorname: String; lMit: string; var lpos: Integer; a: Integer; begin //************************************************************* // Vorsorglich Sonderzeichnen und Leerzeichen am Anfang und Ende ntfernen aSourceString := Trim(aSourceString); //************************************************************* // "mit" ist immer vorhanden und muss extrahiert werden SplitAtPosAndTrim(aSourceString, length(aSourceString) - 3, aSourceString, lMit); // Hier ggf kontrollieren, ob Source tatsächlich mit dem Wort "Mit" endete. > "if not SameText(lmit,'mit') then" //************************************************************* // Anrede ist immer als erstes vorhanden. Bis zum ersten Leerzeichen. lpos := PosEx(' ', aSourceString); SplitAtPosAndTrim(aSourceString, lpos, lAnrede, aSourceString); //************************************************************* // Anrede 1 filtern for a := low(lTitelVorgaben) to high(lTitelVorgaben) do if StartsText(lTitelVorgaben[a], aSourceString) then begin SplitAtPosAndTrim(aSourceString, length(lTitelVorgaben[a]) + 1, lTitel1, aSourceString); Break; end; //************************************************************* // Anrede 2 filtern for a := low(lTitelVorgaben) to high(lTitelVorgaben) do if StartsText(lTitelVorgaben[a], aSourceString) then begin SplitAtPosAndTrim(aSourceString, length(lTitelVorgaben[a]) + 1, lTitel2, aSourceString); Break; end; //*************************************************************************************** // Nachname und Vorname ermitteln lpos := pos(',', aSourceString); if lpos = 0 then lNachname := aSourceString else begin SplitAtPosAndTrim(aSourceString, lpos + 1, lNachname, lVorname); // abschliessendes Komma entfernen lNachname := copy(lNachname, 1, length(lNachname) - 1); end; Result := lAnrede + ';' + lTitel1 + ';' + lTitel2 + ';' + lNachname + ';' + lVorname + ';' + lMit; end; procedure TForm1.BtnStartClick(Sender: TObject); var a:Integer; begin for a:=0 to MemoSource.lines.count-1 do MemoDest.lines.add(KonvertToCsvString(MemoSource.Lines[a])); end; |
AW: CSV anpassen
Was ist Startstext?
Ich kann das nicht deklarieren. |
AW: CSV anpassen
|
AW: CSV anpassen
Das sieht schon gut aus.
Es gibt noch einen Fehler. Zwischen Dr. (ohne Prof.) und Nachname werden zwei Semikolons eingefügt. Dadurch verschiebt sich Dr. zu Prof. |
AW: CSV anpassen
Sicher führen viele Wege nach Rom. Hier ist einer davon:
Delphi-Quellcode:
procedure TSIPForm.Test;
var Line, aWord : String; A : Array [1..6] of String; I, K, L : Integer; function GetNextWord(var S:String):String; var P:Integer; begin Result:=''; P:=Pos(#32, S); if (P > 0) then begin Result:=Copy(S, 1, P - 1); Delete(S, 1, P); end; end; begin RichEdit.Clear; RichEdit.Lines.Add('Herr Mustermann mit'); RichEdit.Lines.Add('Herr Mustermann, Max mit'); RichEdit.Lines.Add('Herr Dr. Mustermann mit'); RichEdit.Lines.Add('Herr Dr. Mustermann, Max mit'); RichEdit.Lines.Add('Herr Prof. Dr. Mustermann mit'); RichEdit.Lines.Add('Herr Prof. Dr. Mustermann, Max mit'); RichEdit.Lines.Add(''); for L:=0 to RichEdit.Lines.Count - 1 do if (RichEdit.Lines[L] > '') then begin Line:=RichEdit.Lines[L]; for I:=1 to 6 do A[I]:=''; repeat aWord:=GetNextWord(Line); if (aWord > '') then begin if (A[1] = '') then A[1]:=aWord else begin if (aWord = 'Prof.') or (aWord = 'Dr.') then begin if (A[2] = '') then A[2]:=aWord else A[3]:=aWord; end else begin K:=Pos(',', aWord); if (K > 0) then Delete(aWord, K, 1); if (A[4] = '') then A[4]:=aWord else A[5]:=aWord; end; end; end; A[6]:='mit'; until (aWord = ''); Line:=''; for I:=1 to 6 do Line:=Line + A[I] + ';'; Delete(Line, Length(Line), 1); RichEdit.Lines.Add(Line); end; end; |
AW: CSV anpassen
Zitat:
a) CSV macht m.E. nur Sinn, wenn man einen Wert immer an der gleichen Stelle erwarten kann. b) In deinem eingangspost hast du geschrieben wie das Ergebnis aussehen soll Zitat:
2. Eintrag = Titel1 3. Eintrag = Titel2 4. Eintrag = Nachname 5. Eintrag = Vorname 6. Eintrag = mit Um es mal untereinander darzustellen (Mit dem Zeichen '>' aufgefüllt. Leerzeichen werden hier leider entfernt)
Code:
Herr;>>>>>;>>>;Mustermann;>>>;mit
Herr;>>>>>;>>>;Mustermann;Max;mit Herr;Dr.>>;>>>;Mustermann;>>>;mit Herr;Dr.>>;>>>;Mustermann;Max;mit Herr;Prof.;Dr.;Mustermann;>>>;mit Herr;Prof.;Dr.;Mustermann;Max;mit |
AW: CSV anpassen
.. wie schonmal angemerk, würde ich die Titel zusammenfassem.
Denn es gibt auch Menschen die mehr als zwei Titel haben. Prof. Dr. Dr. rer. Nat. Prof. Dr. Dipl.-Ing. usw. Grüße Klaus |
AW: CSV anpassen
Zitat:
|
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:
Dies kannst du dann entsprechend viel leichter behandeln und die Fehlerquote ist geringer.
Grid.LoadFromCSVFile('Dateiname')
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). |
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. |
AW: CSV anpassen
Zitat:
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; |
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 |
AW: CSV anpassen
Zitat:
Übung mach die Meisterin :-D |
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; |
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 :-( |
AW: CSV anpassen
Ich denke, mein obiges Codebeispiel kommt mit den Texten ganz gut klar.
|
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. |
AW: CSV anpassen
Zitat:
|
AW: CSV anpassen
Just for fun mal ein Pascalscript zum Thema:
Delphi-Quellcode:
Die Ausgabe dazu:
program JustForFun;
var i : Integer; sl : TStringList; sAnrede : String; sTitel : String; sNachname : String; sVorname : String; sABCD : String; sTermin : String; iPos : Integer; sTemp : String; begin sl := TStringList.Create; // Statt eine Datei zu lesen // sl.LoadFromFile('c:\temp\wie.auch.immer.txt'); sl.Add('Herr Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Dr. Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Dr. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Prof. Dr. Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Prof. Dr. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Prof. Dr. rer. nat. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Prof. Dr. Dipl.-Ing. Hummel, Johann-Nepomuk mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Frau Dr. Wespe, Natalie mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Frau Dr. med. Müller-Lüdenscheid, Cleopatra mit Julius Cäsar/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr van Gogh, Vincent Willem mit Gustav Klimt/00A (1): Terminplan(08:00 Uhr)'); sl.Add('Herr Wells, H. G. mit Böll, Heinrich/00A (1): Terminplan(08:00 Uhr)'); for i := 0 to sl.Count - 1 do begin sTemp := Trim(sl[i]); // Falls mal jemand 'ne Leerzeile einschmuggelt: if sTemp = '' then continue; WriteLn('Quelle: ' + sl[i]); // Ausgabe nur zum Testen // Zuerst den Termin holen: iPos := Pos('Terminplan',sTemp); sTermin := Copy(sl[i],iPos,Length(sTemp)); // Den Termin entfernen. sTemp := Copy(sTemp,1,iPos - 3); // Position von " mit " ermitteln iPos := Pos(' mit ',sTemp); // und alles hinter " mit " holen. sABCD := Copy(sTemp,iPos + 5,Length(sTemp)); // Alles, einschließlich " mit " entfernen. sTemp := Copy(sTemp,1,iPos - 1); // Gibt es ein Komma, dann gibt es auch einen Vornamen. iPos := Pos(', ',sTemp); sVorname := ''; if iPos > 0 then begin sVorname := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); sTemp := Copy(sTemp,1,iPos - 1); end; // Erstes Leerzeichen suchen, davor steht die Anrede. iPos := Pos(' ',sTemp); sAnrede := Copy(sTemp,1,iPos - 1); // Anrede entfernen. sTemp := Copy(sTemp,iPos + 1,Length(sTemp)); // Haben wir 'nen Punkt, so haben wir auch 'nen Titel: sTitel := ''; iPos := Pos('. ',sTemp); while iPos > 0 do begin sTitel := Format('%s %s',[sTitel,Copy(sTemp,1,iPos)]); sTemp := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); iPos := Pos('. ',sTemp); end; sTitel := Trim(sTitel); // Der verbliebene Rest entspricht dem Nachnamen: sNachname := sTemp; sl[i] := Format('%s;%s;%s;%s;mit %s: %s', [sAnrede, sTitel, sNachname, sVorname, sABCD, sTermin]); WriteLn('CSV : ' + sl[i]); // Ausgabe nur zum Testen end; // sl.SaveToFile('c:\temp\wie.auch.immer.csv'); sl.Free; end.
Code:
Quelle: Herr Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr)
CSV : Herr;;Mustermann;;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;;Mustermann;Max;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Dr. Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;Dr.;Mustermann;;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Dr. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;Dr.;Mustermann;Max;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Prof. Dr. Mustermann mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;Prof. Dr.;Mustermann;;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Prof. Dr. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;Prof. Dr.;Mustermann;Max;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Prof. Dr. rer. nat. Mustermann, Max mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;Prof. Dr. rer. nat.;Mustermann;Max;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Prof. Dr. Dipl.-Ing. Hummel, Johann-Nepomuk mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Herr;Prof. Dr. Dipl.-Ing.;Hummel;Johann-Nepomuk;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Frau Dr. Wespe, Natalie mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) CSV : Frau;Dr.;Wespe;Natalie;mit ABCDEFGHI/00A (1): Terminplan(08:00 Uhr) Quelle: Frau Dr. med. Müller-Lüdenscheid, Cleopatra mit Julius Cäsar/00A (1): Terminplan(08:00 Uhr) CSV : Frau;Dr. med.;Müller-Lüdenscheid;Cleopatra;mit Julius Cäsar/00A (1): Terminplan(08:00 Uhr) Quelle: Herr van Gogh, Vincent Willem mit Gustav Klimt/00A (1): Terminplan(08:00 Uhr) CSV : Herr;;van Gogh;Vincent Willem;mit Gustav Klimt/00A (1): Terminplan(08:00 Uhr) Quelle: Herr Wells, H. G. mit Böll, Heinrich/00A (1): Terminplan(08:00 Uhr) CSV : Herr;;Wells;H. G.;mit Böll, Heinrich/00A (1): Terminplan(08:00 Uhr) |
AW: CSV anpassen
Hallo,
warum funktioniert dein Code nicht? Was mache ich da falsch?
Code:
// === laden ==============================================
procedure TForm1.Button1Click(Sender: TObject); var str: TStringlist; begin str := Tstringlist.Create; try str.LoadFromFile('c:\users\Julia\documents\stringlist.txt'); Memo1.Lines.AddStrings(str); finally str.Free; end; end; // === verarbeitung ============================================== procedure TForm1.Button2Click(Sender: TObject); var i : Integer; sl : TStringList; sAnrede : String; sTitel : String; sNachname : String; sVorname : String; sABCD : String; sTermin : String; iPos : Integer; sTemp : String; begin sl := TStringList.Create; Memo1.Lines.AddStrings(sl); for i := 0 to sl.Count - 1 do begin sTemp := Trim(sl[i]); // Falls mal jemand 'ne Leerzeile einschmuggelt: if sTemp = '' then continue; WriteLn('Quelle: ' + sl[i]); // Ausgabe nur zum Testen // Zuerst den Termin holen: iPos := Pos('Terminplan',sTemp); sTermin := Copy(sl[i],iPos,Length(sTemp)); // Den Termin entfernen. sTemp := Copy(sTemp,1,iPos - 3); // Position von " mit " ermitteln iPos := Pos(' mit ',sTemp); // und alles hinter " mit " holen. sABCD := Copy(sTemp,iPos + 5,Length(sTemp)); // Alles, einschließlich " mit " entfernen. sTemp := Copy(sTemp,1,iPos - 1); // Gibt es ein Komma, dann gibt es auch einen Vornamen. iPos := Pos(', ',sTemp); sVorname := ''; if iPos > 0 then begin sVorname := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); sTemp := Copy(sTemp,1,iPos - 1); end; // Erstes Leerzeichen suchen, davor steht die Anrede. iPos := Pos(' ',sTemp); sAnrede := Copy(sTemp,1,iPos - 1); // Anrede entfernen. sTemp := Copy(sTemp,iPos + 1,Length(sTemp)); // Haben wir 'nen Punkt, so haben wir auch 'nen Titel: sTitel := ''; iPos := Pos('. ',sTemp); while iPos > 0 do begin sTitel := Format('%s %s',[sTitel,Copy(sTemp,1,iPos)]); sTemp := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); iPos := Pos('. ',sTemp); end; sTitel := Trim(sTitel); // Der verbliebene Rest entspricht dem Nachnamen: sNachname := sTemp; sl[i] := Format('%s;%s;%s;%s;mit %s: %s', [sAnrede, sTitel, sNachname, sVorname, sABCD, sTermin]); WriteLn('CSV : ' + sl[i]); // Ausgabe nur zum Testen end; sl.SaveToFile('c:\users\Julia\documents\stringlist.txt'); sl.Free; end; // === speichern ============================================== procedure TForm1.Button3Click(Sender: TObject); var str: TStringlist; i: integer; begin str := tstringlist.Create; try Memo1.Lines.SaveToFile('c:\users\Julia\documents\stringlist.txt'); finally str.Free; end; end; |
AW: CSV anpassen
Delphi-Quellcode:
// === verarbeitung ==============================================
procedure TForm1.Button2Click(Sender: TObject); var i : Integer; sl : TStringList; sAnrede : String; sTitel : String; sNachname : String; sVorname : String; sABCD : String; sTermin : String; iPos : Integer; sTemp : String; begin sl := TStringList.Create; // Was mag hier wohl in sl sein? // Ziemlich genau nichts. // In meinem Beispiel waren die Daten per .Add in die Stringliste eingefügt worden. // Hier müsstest Du sie daher aus dem Memo übernehmen. // statt // Memo1.Lines.AddStrings(sl); // eher sl.AddStrings(Memo1.Lines); for i := 0 to sl.Count - 1 do begin sTemp := Trim(sl[i]); // Falls mal jemand 'ne Leerzeile einschmuggelt: if sTemp = '' then continue; // WriteLn('Quelle: ' + sl[i]); // Ausgabe nur zum Testen // Zuerst den Termin holen: iPos := Pos('Terminplan',sTemp); sTermin := Copy(sl[i],iPos,Length(sTemp)); // Den Termin entfernen. sTemp := Copy(sTemp,1,iPos - 3); // Position von " mit " ermitteln iPos := Pos(' mit ',sTemp); // und alles hinter " mit " holen. sABCD := Copy(sTemp,iPos + 5,Length(sTemp)); // Alles, einschließlich " mit " entfernen. sTemp := Copy(sTemp,1,iPos - 1); // Gibt es ein Komma, dann gibt es auch einen Vornamen. iPos := Pos(', ',sTemp); sVorname := ''; if iPos > 0 then begin sVorname := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); sTemp := Copy(sTemp,1,iPos - 1); end; // Erstes Leerzeichen suchen, davor steht die Anrede. iPos := Pos(' ',sTemp); sAnrede := Copy(sTemp,1,iPos - 1); // Anrede entfernen. sTemp := Copy(sTemp,iPos + 1,Length(sTemp)); // Haben wir 'nen Punkt, so haben wir auch 'nen Titel: sTitel := ''; iPos := Pos('. ',sTemp); while iPos > 0 do begin sTitel := Format('%s %s',[sTitel,Copy(sTemp,1,iPos)]); sTemp := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); iPos := Pos('. ',sTemp); end; sTitel := Trim(sTitel); // Der verbliebene Rest entspricht dem Nachnamen: sNachname := sTemp; sl[i] := Format('%s;%s;%s;%s;mit %s: %s', [sAnrede, sTitel, sNachname, sVorname, sABCD, sTermin]); // WriteLn('CSV : ' + sl[i]); // Ausgabe nur zum Testen end; sl.SaveToFile('c:\users\Julia\documents\stringlist.txt'); sl.Free; end; |
AW: CSV anpassen
Hallo und guten Abend,
der Code/ die Codes funktionieren. Und auch noch, wenn ich dran rumgepfuscht habe. Das ist die gute Nachricht. Die schlechte Nachricht: Die Datei, aus der ich die Daten ziehe, enthält irgendwas an versteckten Zeichen. Da muss ich mal sehen, wo das Problem ist. Lade ich die Daten aus meiner Liste, bekomme ich als Ergebnis: ;;;;mit : Herr ... Schreibe ich den Text direkt ins Memo oder in eine saubere Text-Datei, läuft´s. Bis dahin und vielen, vielen Dank für alle Supporter, VG, Julia |
AW: CSV anpassen
Das müssen nicht unbedingt versteckten Zeichen (o. ä.) sein.
Ein marginal anderer Aufbau der Textdatei gegenüber Deinen Beispielen könnte schon derartige "Nebenfolgen" haben. Wäre es möglich, dass Du mal eine "Originaldatei" hier anhängst. Ohne konkrete Daten sehe ich momentan keine Chance, dem Problem auf die Spur zu kommen. Vermutlich ist der Inhalt der Datei etwas anders aufgebaut, als von Dir vermutet / erwartet. Ausgehend von meinem Script: Wenn die Zeichenfolge 'Terminplan' nicht enthalten ist, wäre das ';;;;mit : Herr ...' eine zu erwartende Folge. |
AW: CSV anpassen
Ich möchte nochmal die Frage aufwerfen @julchen, hast du nicht ggf. die Möglichkeit die Quelle zu ändern, das von vorneherein eine vernünftige CSV bei dir ankommt, mit der du auch arbeiten kannst?
|
AW: CSV anpassen
Hallo Narium,
ich habe es hinbekommen:
Code:
Vielen, vielen Dank an euch alle :love: und bis zum nächsten Problem :pale:
procedure TForm1.Button2Click(Sender: TObject);
var i : Integer; sl : TStringList; sAnrede : String; sTitel : String; sNachname : String; sVorname : String; sABCD : String; sTermin : String; iPos : Integer; sTemp : String; begin sl := TStringList.Create; sl.AddStrings(Memo1.Lines); try for i := 0 to sl.Count - 1 do begin sTemp := Trim(sl[i]); if sTemp = '' then continue; iPos := Pos('mit',sTemp); sABCD := Copy(sTemp,iPos + 5,Length(sTemp)); sTemp := Copy(sTemp,1,iPos - 1); iPos := Pos(', ',sTemp); sVorname := ''; if iPos > 0 then begin sVorname := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); sTemp := Copy(sTemp,1,iPos - 1); end; iPos := Pos(' ',sTemp); sAnrede := Copy(sTemp,1,iPos - 1); sTemp := Copy(sTemp,iPos + 1,Length(sTemp)); sTitel := ''; iPos := Pos('. ',sTemp); while iPos > 0 do begin sTitel := Format('%s %s',[sTitel,Copy(sTemp,1,iPos)]); sTemp := Trim(Copy(sTemp,iPos + 1,Length(sTemp))); iPos := Pos('. ',sTemp); end; sTitel := Trim(sTitel); sNachname := sTemp; sl[i] := Format('%s;%s;%s;%s;mit %s: %s', [sAnrede, sTitel, sNachname, sVorname, sABCD, sTermin]); end; Memo2.Lines.assign(sl); finally sl.Free; end; |
AW: CSV anpassen
Hallo Julchen, bitte ändere Deine Code noch ein bisserl:
Delphi-Quellcode:
Ansonsten kannst Du z. B. beim Namen Schmitt oder bei Schmitz auf ein unerwartetes Ergebnis stoßen. Bei denen kommt die Zeichenfolge mit halt schon vor der erwünschten Trennstelle mit : vor. In dem Fall würde das Ergebnis dann deutlich falsch ausfallen.
// Statt:
iPos := Pos('mit',sTemp); sABCD := Copy(sTemp,iPos + 5,Length(sTemp)); // lieber: iPos := Pos('mit :',sTemp); sABCD := Copy(sTemp,iPos + 5,Length(sTemp)); |
AW: CSV anpassen
Danke für den Tipp. :thumb:
An mit im Nachnamen habe ich nicht gedacht. "mit :" hat es wieder zerrissen, aber mit " mit" läuft bis jetzt. :-D VG und auf zum nächsten Problem ... |
AW: CSV anpassen
mittermeier :stupid:
Dann vielleicht mal an RegEx denken (ganzes Wort suchen) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 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