Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Duplikate mixen (https://www.delphipraxis.net/23389-duplikate-mixen.html)

se0man 2. Jun 2004 13:02


Duplikate mixen
 
Hallo,

also,
da funktioniert mal wieder etwas nicht wie ich es will. :wall:

Und zwar habe ich ein ClientDataSet mit 2 Spalten.
Meinetwegen:
Code:
Code:
ClientDataSet.FieldByName('Spalte1').AsString := '1,4'
ClientDataSet.FieldByName('Spalte2').AsString := '4,5,6'
Nun gebe ich in einer neuen Zeile folgende Werte ein:
Feld1: 1,2
Feld2: 5,6,7

Nun soll mein BeforePost-Ereignis erkennen,
dass das einige Werte schon vorhanden sind.
Als Trennzeichen dient jeweils das Komma.

Es soll mir die Zeilen mixen,
und als Ergebniszeile erwünsche ich mir dann:

Feld1: 1,2,4
Feld2: 4,5,6,7

Ich bin sicher,
ihr könnt mir da irgendwie weiterhelfen!!? :mrgreen:

thanxx
-seoman

se0man 8. Jun 2004 17:24

Re: Duplikate mixen
 
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...? :gruebel:

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 :mrgreen: !?

bis dann
-se0man


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:27 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