Thema: Delphi Duplikate mixen

Einzelnen Beitrag anzeigen

se0man

Registriert seit: 8. Mär 2004
51 Beiträge
 
#2

Re: Duplikate mixen

  Alt 8. Jun 2004, 18:24
Nun denn,
nachdem auf keiner von euch eine Idee gehabt zu haben scheint,
habe ich mir nun eine funktionierende Version gebastelt,
bei der ich irgendwie anzuzweifeln wage,
sie sei - zumindest in dieser Länge - nötig...?

Das ganze spricht, denke ich, für sich.

Delphi-Quellcode:
procedure Tform1.MixDuplicates;
var
  strlistNewWordsCol1,
  strlistNewWordsCol2,
  strlistOldWordsCol1,
  strlistOldWordsCol2
    : TStringList;
  intPosOfSeparator
    : Integer;
  boolCreateRow: Boolean;
  Bookmark: TBookmark;
begin
  try
  // *****************************************************
  // * Beladen der StringListen mit den neuen Wörtern *
  // *****************************************************

    // Neue StringListe für die Wörter des 1. Feldes beladen
    strlistNewWordsCol1 := TStringList.Create;
    strlistNewWordsCol1 := StrToStrList(ClientDataSet.FieldByName(ClientDataSet.FieldDefs[0].Name).AsString);


    // Neue StringListe für die Wörter des 2. Feldes beladen
    strlistNewWordsCol2 := TStringList.Create;
    strlistNewWordsCol2 := StrToStrList(ClientDataSet.FieldByName(ClientDataSet.FieldDefs[1].Name).AsString);


  // *****************************************************
  // * Suche nach den neuen Wörter im ClienDataSet *
  // *****************************************************

    ClientDataSet.DisableControls; // Verbindung zu DbGrid unterbrechen
    ClientDataSet.Delete; // löscht die neue Zeile -> nur noch in den beiden StringLists vorhanden ist
    ClientDataSet.First;

    boolCreateRow := True; // wenn Wort noch nirgends vorhanden, soll neue Zeile erstellt werden
    strlistOldWordsCol1 := TStringList.Create;
    strlistOldWordsCol2 := TStringList.Create;

    while not ClientDataSet.Eof
    do begin
      strlistOldWordsCol1 := StrToStrList(ClientDataSet.FieldByName(ClientDataSet.FieldDefs[0].Name).AsString);
      strlistOldWordsCol2 := StrToStrList(ClientDataSet.FieldByName(ClientDataSet.FieldDefs[1].Name).AsString);
      // wenn ein gleiches Wort in den StringListen alt und neu (egal in welcher Spalte)
      if CompareStrLists(strlistNewWordsCol1,strlistOldWordsCol1)
       or CompareStrLists(strlistNewWordsCol2,strlistOldWordsCol2)
      then begin
        // dann Wörter mixen
        ClientDataSet.Edit;
        boolAfterPostWorking := True; // Stack-Überlauf verhindern
        ClientDataSet.FieldByName(ClientDataSet.FieldDefs[0].Name).AsString :=
                                                                          StrListsToStr(strlistNewWordsCol1,strlistOldWordsCol1);
        ClientDataSet.FieldByName(ClientDataSet.FieldDefs[1].Name).AsString :=
                                                                          StrListsToStr(strlistNewWordsCol2,strlistOldWordsCol2);
        ClientDataSet.Post;
        boolAfterPostWorking := False;
        boolCreateRow := False; // da die neuen Wörter schon 'untergebracht' wurden, keine neue Zeile erstellen
        // Zeile bookmarken
        Bookmark := ClientDataSet.GetBookmark;
      end;
      ClientDataSet.Next;
    end;

    if boolCreateRow
    then begin
      ClientDataSet.Insert;
      boolAfterPostWorking := True;
      ClientDataSet.FieldByName(ClientDataSet.FieldDefs[0].Name).AsString :=
                                                                         StrListsToStr(strlistNewWordsCol1,strlistNewWordsCol1);
      ClientDataSet.FieldByName(ClientDataSet.FieldDefs[1].Name).AsString :=
                                                                         StrListsToStr(strlistNewWordsCol2,strlistNewWordsCol2);
      ClientDataSet.Post;
      boolAfterPostWorking := False;
    end
     else // ansonsten zur Zeile an der zuletzt ersetzt wurde gehen
      ClientDataSet.GotoBookmark(Bookmark);

    ClientDataSet.EnableControls; // Verbindung zu DbGrid reaktivieren
  finally
    strlistNewWordsCol1.Free;
    strlistNewWordsCol2.Free;
    strlistOldWordsCol1.Free;
    strlistOldWordsCol2.Free;
    ClientDataSet.FreeBookmark(Bookmark);
  end;
end;

function Tform1.StrToStrList(strWords: String): TStringList;
var
  intPosOfSeparator
    : Integer;
begin
  Result := TStringList.Create;
  while (strWords <> '')
  do begin
    intPosOfSeparator := Pos(form2.edtSeparator.Text,strWords);
    if (intPosOfSeparator <> 0)
    then begin // wenn noch nicht letztes Wort de Strings erreicht
      // einzelnes Wort ohne Trennzeichen der StringListe hinzufügen
      // (Trennzeichen kann variabel in form2 angegeben werden)
      Result.Add(Copy(strWords,1,intPosOfSeparator-1));
      Delete(strWords,1,intPosOfSeparator); // kopiertes Wort mit Trennzeichen löschen
    end
     else begin // wenn bereits letztes Wort der Zelle
      Result.Add(Copy(strWords,1,Length(strWords)));
      Delete(strWords,1,Length(strWords)); // kopiertes Wort mit Trennzeichen löschen
     end;
  end;
end;

function Tform1.StrListsToStr(strlist1, strlist2: TStringList): String;
var
  intWord
    : Integer;
begin
  // strlist2 in Ergebnisstring
  for intWord := 0 to strlist2.Count-1
  do Result := Result+strlist2[intWord]+form2.edtSeparator.Text;

  for intWord := 0 to strlist1.Count-1 do
    // wenn Eintrag noch nicht in strlist2, dann den aktuelles Wort dem ErgebnisString hinzufügen
    if (strlist2.IndexOf(strlist1[intWord]) = -1) then Result := Result+strlist1[intWord]+form2.edtSeparator.Text;

  // im Ergebnisstring das Trennzeichen am Schluss löschen
  Result := Copy(Result,1,Length(Result)-1)
end;

function Tform1.CompareStrLists(strlist1, strlist2: TStringList): Boolean;
var
  intWord
    : Integer;
begin
  Result := False;
  for intWord := 0 to strlist1.Count-1 do
    // wenn Eintrag noch nicht in strlist2, ist Ergebnis
    if (strlist2.IndexOf(strlist1[intWord]) <> -1) then Result := True;
end;
Nun hoffe ich auf ein wenig Kritik,
oder vielleicht sogar andere Versionen eurerseits !?

bis dann
-se0man
  Mit Zitat antworten Zitat