Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Memo lässt Zeilen verschwinden (https://www.delphipraxis.net/159382-memo-laesst-zeilen-verschwinden.html)

aphexx 25. Mär 2011 14:08

Delphi-Version: 2009

Memo lässt Zeilen verschwinden
 
Hallo!

Ich bin gerade dabei ein Chat-Programm für Dropbox zu entwickeln.
Nix großes und manche Stimmen halten es für überflüssig, aber ich finds toll :wink:

Hintergrund: Ich arbeite mit einem Verzeichnis in dem x txt-Dateien liegen.
Diese lade ich bei einer Aktualisierung in ein array (da das integrierte Datum zum sortieren beutzt wird) vom typ record
(Username, Datum/Zeit, Nachricht). Danach wird alles in einem Memo angezeigt.

Das Problem ist, dass immer der vorletzte Eintrag (von beispielseise 3 txt-Dateien) nur mit Username und Datum angezigt wird.
Die Nachricht ist nicht zu sehen. Das Array läuft sauber, die Daten exisiteren, nur die Darstellung nicht :?

Vielleicht hilft es, wenn ich zusätzlich die EXE bereitstelle?

Hier ist der Code. Unwichtige Funktionen/Prozeduren habe ich ausgeklammert.

Delphi-Quellcode:
unit main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, ImgList;

function RandomString(const len: Integer = 30; const CharSet: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'): string;overload;

type
  TEntry = record
    User: String[25];
    Msg: TStringList;
    DatumZeit: String;
  end;
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    BSend: TButton;
    MOutput: TMemo;
    MMessage: TMemo;
    EUser: TEdit;
    Label1: TLabel;
    EDiv: TEdit;
    Label2: TLabel;
    BSort: TButton;
    Icons: TImageList;
    BRefresh: TButton;
    procedure FormCreate(Sender: TObject);
    procedure BSendClick(Sender: TObject);
    procedure BSortClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BRefreshClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Entry: TEntry;
  Entries: Array of TEntry;
  AufAb: Boolean;

implementation

{$R *.dfm}

procedure GetFilesInDirectory(Directory: string; const Mask: string;
                              List: TStrings;
                              WithSubDirs, ClearList: Boolean);
[...]
end;

procedure Sortieren(Aufsteigend: Boolean);
var
  E: TEntry;
  i, j, max: Integer;
  x, y: TDateTime;
begin
  E.Msg := TStringlist.Create;
  max := Length(Entries);
  for i:=0 to max-1 do
  for j:=0 to max-1 do
  begin
     DateSeparator := '.';
     ShortDateFormat := 'dd.mm.yyyy';
     LongTimeFormat := 'hh:nn:ss.zzz';

     if Aufsteigend = True
     then
     begin
       x := StrToDateTime(Entries[i].DatumZeit);
       y := StrToDateTime(Entries[j].DatumZeit);
     end
     else
     begin
       x := StrToDateTime(Entries[j].DatumZeit);
       y := StrToDateTime(Entries[i].DatumZeit);
     end;

     if x > y then
      begin
       E := Entries[i];
       Entries[i] := Entries[j];
       Entries[j] := E;
     end;
  end;
  E.Msg.Clear;
end;

procedure InitFillEntries(Liste: TStringList);
var
  i, zeilen, j: Integer;
  Inhalt: TStringlist;
begin
  Inhalt := TStringlist.Create;

  if Length(Entries) > Liste.Count then
  begin
    for i := 0 to Length(Entries) - 1 do
    begin
      Entries[i].Msg.Clear;
      Entries[i].User := '';
      Entries[i].DatumZeit := '';
    end;
  end;

  SetLength(Entries, Liste.Count);

  for i := 0 to Length(Entries) - 1 do
  begin
    if FileExists(Liste[i]) then Inhalt.LoadFromFile(Liste[i])
    else
    begin
      ShowMessage(Liste[i] + #13 + 'does not exist.');
      Exit;
    end;

    Entries[i].User := Inhalt.Strings[0];
    Entries[i].DatumZeit := Inhalt.Strings[1];

    Entries[i].Msg := TSTringlist.Create;
    Entries[i].Msg.BeginUpdate;
    Entries[i].Msg.LoadFromFile(Liste[i]);
    Entries[i].Msg.Delete(0);
    Entries[i].Msg.Delete(0);

    Entries[i].Msg.EndUpdate;
  end;
  Sortieren(AufAb);
  Inhalt.Free;
end;


procedure PassEntries;
var
  i, c, j: Integer;
  L, laden: TStringlist;
  Liste: TStringlist;
  s, dir: String;
begin
  L := TStringlist.Create;
  Liste := TStringlist.Create;
  Laden := TStringlist.Create;

  dir := ExtractFilePath(ParamStr( 0 ))+'dbchat\';

  GetFilesInDirectory(dir, '*.txt', Liste, False, True);

  L.BeginUpdate;

  InitFillEntries(Liste);              //Array Füllen

  for i := 0 to Length(Entries) - 1 do
  begin
    L.BeginUpdate;
    L.Add(Entries[i].User);
    L.Add(Entries[i].DatumZeit);
    L.Add('');
    L.Add(Trim(Entries[i].Msg.Text));

    for c := 0 to 19 do s := s + Form1.EDiv.Text;
    L.Add(s);
    s := '';
  end;
  L.EndUpdate;

  Form1.MOutput.Lines.Clear;

  Form1.MOutput.Lines.Assign(L);

  Liste.Free;
  laden.Free;
  L.Free;
end;

function RandomString(const len: Integer; const CharSet: string): string;
[...]
end;

procedure TForm1.BSendClick(Sender: TObject);
[...]
end;

procedure TForm1.BSortClick(Sender: TObject);
begin
[...]
end;

procedure TForm1.BRefreshClick(Sender: TObject);
begin
  PassEntries;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  dir : string;
begin
  Randomize;
  // Get the current directory
  dir := GetCurrentDir;
  if DirectoryExists('dbchat') = True
  then
    begin
      AufAb := True;
      PassEntries;
    end
  else
  begin
   CreateDir('dbchat');
   ShowMessage('Directory created:' + #13 + dir + 'dbchat');
  end;
  MMessage.Lines.Clear;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  //Leeren
  for i := 0 to Length(Entries) - 1 do
  begin
    Entries[i].Msg.Clear;
    Entries[i].User := '';
    Entries[i].DatumZeit := '';
  end;
  SetLength(Entries, 0);
end;

end.

p80286 25. Mär 2011 15:07

AW: Memo lässt Zeilen verschwinden
 
Delphi-Quellcode:
  ....
  InitFillEntries(Liste); //Array Füllen

  for i := 0 to Length(Entries) - 1 do
  begin
    L.BeginUpdate;
    L.Add(Entries[i].User);
    L.Add(Entries[i].DatumZeit);
    L.Add('');
    L.Add(Trim(Entries[i].Msg.Text));

    for c := 0 to 19 do s := s + Form1.EDiv.Text;
    L.Add(s);
    s := '';
  end;
  L.EndUpdate;

  Form1.MOutput.Lines.Clear;

  Form1.MOutput.Lines.Assign(L);
  ....
Das ist ja der Teil um den es geht, und abgesen von s='' (das sollte vor for c:=0... stehen) sehe ich da nichts erwähnenswertes.
Zitat:

Zitat von aphexx (Beitrag 1090953)
Die Nachricht ist nicht zu sehen. Das Array läuft sauber, die Daten exisiteren, nur die Darstellung nicht :?

Da bist Du Dir sicher?

Gruß
K-H

Luckie 25. Mär 2011 16:39

AW: Memo lässt Zeilen verschwinden
 
Wie kommen die Daten in die Dateien? Kann es sein, dass da noch irgendwelche Steuerzeichen von der Übertragung drin stehen?

aphexx 25. Mär 2011 18:39

AW: Memo lässt Zeilen verschwinden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von p80286 (Beitrag 1090982)
Delphi-Quellcode:
  ....
  InitFillEntries(Liste); //Array Füllen

  for i := 0 to Length(Entries) - 1 do
  begin
    L.BeginUpdate;
    L.Add(Entries[i].User);
    L.Add(Entries[i].DatumZeit);
    L.Add('');
    L.Add(Trim(Entries[i].Msg.Text));

    for c := 0 to 19 do s := s + Form1.EDiv.Text;
    L.Add(s);
    s := '';
  end;
  L.EndUpdate;

  Form1.MOutput.Lines.Clear;

  Form1.MOutput.Lines.Assign(L);
  ....
Das ist ja der Teil um den es geht, und abgesen von s='' (das sollte vor for c:=0... stehen) sehe ich da nichts erwähnenswertes.
Zitat:

Zitat von aphexx (Beitrag 1090953)
Die Nachricht ist nicht zu sehen. Das Array läuft sauber, die Daten exisiteren, nur die Darstellung nicht :?

Da bist Du Dir sicher?

Gruß
K-H

s bringt uns nur eine improvisierte Trennlinie von 20 Zeichen. In PassEntries hole ich die Daten aus dem Array und setze sie ins Memo, in InitFillEntries fülle ich das Array wiederum. Ich werde mal die EXE uppen, dann sieht man den Murks mal in action ;)

@Luckie: Sorry, da war Zensursula etwas übereifrig. Beim Speichern kann eigentlich auch nix schief laufen, da die txt-Dateien alle vollständig sind.

Hier die OnClick vom Senden-Button:
Delphi-Quellcode:
procedure TForm1.BSendClick(Sender: TObject);
var
  L: TStringList;
  s1, s2, p: String;
begin
  if EUser.Text = '' then
  begin
    ShowMessage('Chatting without a name sucks.');
    EUser.SetFocus;
    Exit;
  end;
  if MMessage.Lines.Count = 0 then
  begin
    ShowMessage('Chatting without writing something sucks.');
    MMessage.SetFocus;
    Exit;
  end;
  L := TStringList.Create;
  L.BeginUpdate;
  L.Clear;
  L.Add(EUser.Text);
  L.Add(FormatDateTime('dd.mm.yyyy hh:nn:ss.zzz', now));
  L.AddStrings(MMessage.Lines);
  if DirectoryExists('dbchat') then
  begin
    s1 := RandomString;
    p := ExtractFilePath(ParamStr( 0 ))+'\dbchat\' + s1 + '.txt';
    while FileExists(p) = True do
    begin
      ShowMessage('FileExists');
      s1 := RandomString;
      p := ExtractFilePath(ParamStr( 0 ))+'\dbchat\' + s1 + '.txt';
    end;
    L.SaveToFile(p);
  end;
  L.EndUpdate;
  L.Free;
  PassEntries;
  MMessage.Lines.Clear;
  MMessage.SetFocus;
end;

Die EXE habe ich beigelegt, bitte versucht mal 3 oder 4 Einträge anzulegen und danach die Sortierung nach Datum umzukehren; ihr werdet sehen, dass nur bei einem Eintrag was faul ist. DANKE!

aphexx 25. Mär 2011 19:18

AW: Memo lässt Zeilen verschwinden
 
Eilmeldung: Ich habe gerade beschlossen keine einzelnen Dateien mehr zu erstellen, sondern pro user genau eine Datei anzulegen, dann stresst Dropbox nicht so oft rum. Verstehen würde ich das Problem von weiter oben trotzdem gern, also wenn jemand eine spontane Eingebung wär ich sehr dankbar =)

aphexx 27. Mär 2011 14:53

AW: Memo lässt Zeilen verschwinden
 
Liste der Anhänge anzeigen (Anzahl: 3)
Ok, wie es ausschaut, habe ich doch irgendeinen Denkfehler gemacht, denn auch in der neuen Version, bei der pro Chat-User immer nur eine txt angelegt wird, wird die Nachricht des vorletzten Eintrags ausgelassen.
Und weil das nicht schon nervig genug ist, wird auch nur die letzte Zeile einer Nachricht angezeigt.

Bitte bitte helft mir, ich stehe so kurz vorm Ziel und Verzweifeln.

Zur Veranschaulichung habe ich die Prozeduren zum Füllen des Arrays und Darstellung im Memo etwas kommentiert, hoffentlich hilft's.
Delphi-Quellcode:
//################################################### Deklaration
type
  TEntry = record
    User: String[25];
    Msg: TStringList;
    DatumZeit: String;
  end;
  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    BSend: TButton;
    MOutput: TMemo;
    MMessage: TMemo;
    EUser: TEdit;
    Label1: TLabel;
    EDiv: TEdit;
    Label2: TLabel;
    BSort: TButton;
    Icons: TImageList;
    BRefresh: TButton;
    procedure FormCreate(Sender: TObject);
    procedure BSendClick(Sender: TObject);
    procedure BSortClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BRefreshClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  Entry: TEntry;
  Entries: Array of TEntry;
  AufAb: Boolean;

//################################################### Deklaration Ende

{...verschiedene Funktionen...}

//################################################### Sortieren
procedure Sortieren(Aufsteigend: Boolean);
var
  E: TEntry;
  i, j, max: Integer;
  x, y: TDateTime;
begin
  E.Msg := TStringlist.Create;
  max := Length(Entries);
  for i:=0 to max-1 do
  for j:=0 to max-1 do
  begin
     DateSeparator := '.';
     ShortDateFormat := 'dd.mm.yyyy';
     LongTimeFormat := 'hh:nn:ss.zzz';

     if Aufsteigend = True
     then
     begin
       x := StrToDateTime(Entries[i].DatumZeit);
       y := StrToDateTime(Entries[j].DatumZeit);
     end
     else
     begin
       x := StrToDateTime(Entries[j].DatumZeit);
       y := StrToDateTime(Entries[i].DatumZeit);
     end;

     if x > y then
      begin
       E := Entries[i];
       Entries[i] := Entries[j];
       Entries[j] := E;
     end;
  end;
  E.Msg.Clear;
end;


//################################################### Array füllen

procedure InitFillEntries(Liste: TStringList);
var
  i, eintrAuf, c: Integer;
  Inhalt, temp: TStringlist;
  PosisAuf, PosisZu: Array of Integer;
  f: String;
begin
  Inhalt := TStringlist.Create;
  temp := TStringlist.Create;

  //Array leeren
  for i := 0 to Length(Entries) - 1 do
    begin
      Entries[i].Msg.Clear;
      Entries[i].User := '';
      Entries[i].DatumZeit := '';
    end;
  SetLength(Entries,0);
  //Array leeren Ende

  //Alle TXT-Dateien in "temp" reinladen | "Liste" enthält die Filenames
  for i := 0 to Liste.Count - 1 do
  begin
    f := Liste[i];
    if FileExists(f) then Inhalt.LoadFromFile(f);
    temp.BeginUpdate;
    temp.AddStrings(Inhalt);
    temp.EndUpdate;
  end;
  //TXT-Dateien Ende

  eintrAuf := 0;            //Nachrichtenzähler nullen
  SetLength(PosisAuf, 0);   //Start-Merker nullen
  SetLength(PosisZu, 0);    //Ende-Merker nullen

  //"temp" scannen
  for i := 0 to temp.Count - 1 do
  begin
    if temp.Strings[i] = '{{' then               //Start eines Beitrags | Start-Merker
    begin
      Inc(eintrAuf);
      SetLength(PosisAuf, Length(PosisAuf)+1);
      PosisAuf[High(PosisAuf)] := i;
    end;

    if temp.Strings[i] = '}}' then              //Ende eines Beitrags | Ende-Merker
    begin
      SetLength(PosisZu, Length(PosisZu)+1);
      PosisZu[High(PosisZu)] := i;
    end;
  end;

  SetLength(Entries, eintrAuf);                //Array auf die Anzahl der Einträge setzen


  for i := 0 to eintrAuf-1 do                        //Array durchlaufen
  begin
      Entries[i].User := temp[PosisAuf[i]+1];        //Übergabe aus "temp" --> User-Name
      Entries[i].DatumZeit := temp[PosisAuf[i]+2];   //Übergabe aus "temp" --> Datum/Zeit
      for c := PosisAuf[i]+1 to PosisZu[i] - 1 do    //Zeilenweise Übergabe aus "temp" --> Nachricht
      begin
        Entries[i].Msg := TStringList.Create;
        Entries[i].Msg.Add(temp.Strings[c]);
      end;
  end;

  //Leichen begraben
  SetLength(PosisAuf, 0);
  SetLength(PosisZu, 0);
  Inhalt.Clear;
  temp.Clear;
end;


//################################################### An Memo Übergeben

procedure PassEntries;
var
  i, c: Integer;
  L: TStringlist;
  Liste: TStringlist;
  s, dir: String;
begin
  L := TStringlist.Create;              //Zukünftiger Inhalt vom Memo
  Liste := TStringlist.Create;          //Liste der TXT-Dateien

  dir := ExtractFilePath(ParamStr( 0 ))+'dbchat\';

  GetFilesInDirectory(dir, '*.txt', Liste, False, True);      //Alle TXT-Dateien in Verz. "dbchat" einlesen

  L.BeginUpdate;
  L.Clear;

  InitFillEntries(Liste);              //Array Füllen
  Sortieren(AufAb);                    //Array nach Datum/Zeit sortieren

  for i := 0 to Length(Entries) - 1 do                //"L" befüllen
  begin
    L.BeginUpdate;
    L.Add(Entries[i].User);
    L.Add(Entries[i].DatumZeit);
    L.Add('');

    for c := 0 to Entries[i].Msg.Count - 1 do        //Zeilen aus der Nachricht holen
    begin
      L.Add(Entries[i].Msg[c]);
    end;

    for c := 0 to 19 do s := s + Form1.EDiv.Text;    //20 Zeichen als Trennlinie
    L.Add(s);
    s := '';
  end;
  L.EndUpdate;

  Form1.MOutput.Lines.Clear;                        // "L" an Memo übergeben
  Form1.MOutput.Lines.Assign(L);

  Liste.Free; //Freigeben
  L.Free;

  //Scrollen
  if AufAb = True then Form1.MOutput.Perform(EM_LineScroll, 0 , Form1.MOutput.Lines.Count-1);
end;
EDIT:
Ich habe den Anhang um den Screenshot "debugger.png" erweitert. Dieser zeigt, was sich tatsächlich im Array verbirgt.
Username ist ok, Datum/Zeit ist ok. Aber warum steht unter Msg (TStringlist) nicht der Text? Das macht mich echt mürbe -.-

EDIT2:
Delphi-Quellcode:
  for i := 0 to eintrAuf-1 do                        //Array durchlaufen
  begin
      Entries[i].User := temp[PosisAuf[i]+1];        //Übergabe aus "temp" --> User-Name
      Entries[i].DatumZeit := temp[PosisAuf[i]+2];   //Übergabe aus "temp" --> Datum/Zeit
      Entries[i].Msg := TStringList.Create;
      for c := PosisAuf[i]+3 to PosisZu[i] - 1 do    //Zeilenweise Übergabe aus "temp" --> Nachricht
      begin
        Entries[i].Msg.Add(temp.Strings[c]);
      end;
  end;
Ich hatte die Stringlist an der falschen Stelle created. Nun funzen zumindest alle Einträge bis auf den vorletzten. Sry für den monolog, aber vllt. sieht es sich ja trotzdem noch einer an ;)

aphexx 27. Mär 2011 20:56

AW: Memo lässt Zeilen verschwinden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hier ist der letzte Stand der EXE.
Würde mich freuen, wenn Ihr eine Idee bzgl. des Bugs habt.

p80286 28. Mär 2011 11:25

AW: Memo lässt Zeilen verschwinden
 
Was ist denn eigentlich jetzt der Stand der Dinge?
Versuch doch bitte noch einmal das Problem, genau zu beschreiben!

Gruß
K-H

P.S.
Ich schlage mich im allg. nicht darum, fremde Sourcen zu lesen, um mögliche Fehler zu finden.

aphexx 28. Mär 2011 13:31

AW: Memo lässt Zeilen verschwinden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von p80286 (Beitrag 1091504)
Was ist denn eigentlich jetzt der Stand der Dinge?
Versuch doch bitte noch einmal das Problem, genau zu beschreiben!

Gruß
K-H

P.S.
Ich schlage mich im allg. nicht darum, fremde Sourcen zu lesen, um mögliche Fehler zu finden.

Danke erstmal, dass Du Dich überhaupt mit meinem Problem befassen magst.
Der Chat funktioniert mittlerweile fast einwandfrei. Das einzige Problem ist leider immer noch das vom Anfang,
dass das Memo, welches den gesamten Chatlog anzeigt, bei der vorletzten Nachricht nur den User und das Datum mit Zeit anzeigt.
Die Daten kommen aus einem Array of TEntry, welcher ein Record aus 2 Strings und einer Stringlist ist. Die Vermutung liegt nahe,
dass die Übergabe ans Memo fehlerhaft ist (PassEntries). Diese Schlussfolgerung kommt daher, dass dieses Array vor der Darstellung
analysiert und sortiert wird (also Datum/Zeit) und allein vom Datensatz her richtig befüllt ist. Das erkennt man daran,
dass sowohl in der aufsteigenden als auch absteigenden Sortieung der vorletzte Message-Eintrag des Chat-Logs fehlt.
Vielleicht ist es irgendein dubioser Zahlendreher, den ich einfach nicht sehe.

Ich werde nochmal die aktuellste main.pas anhängen. Die Übergabe vom Array zum Memo passiert in "PassEntries".

p80286 28. Mär 2011 14:42

AW: Memo lässt Zeilen verschwinden
 
Viel wichtiger,
wie sieht der Eintrag für den Text in deinem array aus?
"vorletzter" scheint mir sehr unwahrscheinlich, es sei denn Du fügst noch einen Standardsatz am Ende ein.

Gruß
K-H

aphexx 28. Mär 2011 15:11

AW: Memo lässt Zeilen verschwinden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von p80286 (Beitrag 1091563)
Viel wichtiger,
wie sieht der Eintrag für den Text in deinem array aus?
"vorletzter" scheint mir sehr unwahrscheinlich, es sei denn Du fügst noch einen Standardsatz am Ende ein.

Gruß
K-H

Das Array spiegelt genau den Inhalt aller TXTs pro user wider, mit der Ausnahme, dass in den Textdateien {{ und }} zum Trennen der Beiträge vorhanden sind. Das Array wird nimmt die Daten dazwischen auf.
EDIT: User/Datum = String und Nachricht TStringlist.

Ich habe die Problematik kurz skizziert (s. Anhang).

Danke und viele Grüße,
aphexx

p80286 28. Mär 2011 16:17

AW: Memo lässt Zeilen verschwinden
 
das war ein Mißverständnis,
Sind die Daten im Array vorhanden?
Wenn ich Deinen anhang richtig verstehe, dann fehlen die Daten in der Anzeige und sind in der/den Datei(en) vorhanden.

Gruß
K-H

aphexx 28. Mär 2011 17:35

AW: Memo lässt Zeilen verschwinden
 
Jo, alle Daten sind im Array und die Anzeige im Memo ist fehlerhaft.

Jumpy 29. Mär 2011 07:25

AW: Memo lässt Zeilen verschwinden
 
Hat wahrsch. nix mit dem Problem zu tun aber du machst vor der For-Schleife L.BeginUpdate, in der For-Schleife bei jedem Durchlauf L.BeginUpdate aber nur einmal nach der Schleife L.EndUpdate.
Ist das in der Schleife nicht überflüssig?

Zum Problem, kannst du dir nicht in einer weiteren For-Schleife mal den Inhalt von L ausgeben lassen?
Wenn da schon was fehlt liegts nicht am Memo sondern am füllen von L.

Ich würde mir vllt. einfach mal an versch. Stellen im Code den Stand der Dinge anzeigen lassen. Hat mit öfters schon geholfen, wenn ich einen gut versteckten logischen Fehler eingebaut hatte (soll jetzt nicht heißen, dass du einen solchen drin hast, kann gut auch was anderes sein).

P.S.: Hast du mal größere Beispiele durchgespielt? Ist wirklich immer nur der Vorletzte problematisch?

aphexx 29. Mär 2011 22:37

AW: Memo lässt Zeilen verschwinden
 
Zitat:

Zitat von Jumpy (Beitrag 1091668)
Hat wahrsch. nix mit dem Problem zu tun aber du machst vor der For-Schleife L.BeginUpdate, in der For-Schleife bei jedem Durchlauf L.BeginUpdate aber nur einmal nach der Schleife L.EndUpdate.
Ist das in der Schleife nicht überflüssig?

Zum Problem, kannst du dir nicht in einer weiteren For-Schleife mal den Inhalt von L ausgeben lassen?
Wenn da schon was fehlt liegts nicht am Memo sondern am füllen von L.

Ich würde mir vllt. einfach mal an versch. Stellen im Code den Stand der Dinge anzeigen lassen. Hat mit öfters schon geholfen, wenn ich einen gut versteckten logischen Fehler eingebaut hatte (soll jetzt nicht heißen, dass du einen solchen drin hast, kann gut auch was anderes sein).

P.S.: Hast du mal größere Beispiele durchgespielt? Ist wirklich immer nur der Vorletzte problematisch?

Danke, das mit dem BeginUpdate für L habe ich korrigiert.

Dein Hinweis mit der Anzeige von L und der Überprüfung im Allgemeinen war sehr gut, denn das Ergebnis ist, tadaa, dass das Array falsch sortiert wurde.
L ist nicht schuld, das Memo auch nicht ;)

Soweit so schlecht, denn dieser Sortieralgo ist doch eigentlich richtig, oder?
Ich versteh' dann trotzdem nicht, warum er ausgerechnet eine Stinglist aus dem Array haut.
Vor dem Sortieren war der vorletzte Array-Eintrag (inkl. StringList) vorhanden, danach nicht mehr.

EDIT: PS: bei größeren txt-Sammlungen ist es das selbe Ergebnis :/

Delphi-Quellcode:
procedure Sortieren(Aufsteigend: Boolean);
var
  E: TEntry;
  i, j, max: Integer;
  x, y: TDateTime;
begin
  E.Msg := TStringlist.Create;
  max := Length(Entries);
  for i:=0 to max-1 do
  for j:=0 to max-1 do
  begin
     DateSeparator := '.';
     ShortDateFormat := 'dd.mm.yyyy';
     LongTimeFormat := 'hh:nn:ss.zzz';

     if Aufsteigend = True
     then
     begin
       x := StrToDateTime(Entries[i].DatumZeit);
       y := StrToDateTime(Entries[j].DatumZeit);
     end
     else
     begin
       x := StrToDateTime(Entries[j].DatumZeit);
       y := StrToDateTime(Entries[i].DatumZeit);
     end;

     if x > y then
      begin
       E := Entries[i];
       Entries[i] := Entries[j];
       Entries[j] := E;
     end;
  end;
  E.Msg.Clear;
end;

Satty67 30. Mär 2011 02:15

AW: Memo lässt Zeilen verschwinden
 
BubbleSort? Die äußere Schleife High-1 oder in Deinem Fall
Delphi-Quellcode:
for i:=0 to max-2 do
.
oder war es die innere?

Für TStringList würde ich aber ganz klar die Methode CustomSort verwenden. Delphi-Referenz durchsuchenTStringList.CustomSort

aphexx 30. Mär 2011 14:07

AW: Memo lässt Zeilen verschwinden
 
Zitat:

Zitat von Satty67 (Beitrag 1091886)
BubbleSort? Die äußere Schleife High-1 oder in Deinem Fall
Delphi-Quellcode:
for i:=0 to max-2 do
.
oder war es die innere?

Für TStringList würde ich aber ganz klar die Methode CustomSort verwenden. Delphi-Referenz durchsuchenTStringList.CustomSort

OK, ich habe den Bubblesort nun umgeschrieben, doch das Problem besteht weiterhin, nur in anderem Gewand. Es wird bei aufsteigender Sortierung die 5. Nachricht nicht angezeigt und bei absteigender Sortierung die 2. Nachricht. Dein Tipp mit CustomSort ist etwas hanebüchen, da ich die einzelnen Text-Nachrichten ja nicht sortiere, sondern das Array of TEntry, welches aus 2 Strings und einmal TStringlist besteht.
Delphi-Quellcode:
procedure Sortieren(Aufsteigend: Boolean);
var
  E: TEntry;
  i, j, max: Integer;
  x, y: TDateTime;
begin
  E.Msg := TStringlist.Create;
  max := Length(Entries);
  for i:=Low(Entries) to High(Entries) do
  for j:=Low(Entries) to High(Entries)-1 do
  begin
     DateSeparator := '.';
     ShortDateFormat := 'dd.mm.yyyy';
     LongTimeFormat := 'hh:nn:ss.zzz';

     if Aufsteigend = True
     then
     begin
       x := StrToDateTime(Entries[j].DatumZeit);
       y := StrToDateTime(Entries[j+1].DatumZeit);
     end
     else
     begin
       x := StrToDateTime(Entries[j+1].DatumZeit);
       y := StrToDateTime(Entries[j].DatumZeit);
     end;

     if x > y then
      begin
       E := Entries[j];
       Entries[j] := Entries[j+1];
       Entries[j+1] := E;
     end;
  end;
  E.Msg.Clear;
end;

Jumpy 30. Mär 2011 15:17

AW: Memo lässt Zeilen verschwinden
 
Weiß den Fehler auch nicht, möchte aber mal wieder bei dir Aufräumen: ;-)

Zitat:

Zitat von aphexx (Beitrag 1091992)
Delphi-Quellcode:
     DateSeparator := '.';
     ShortDateFormat := 'dd.mm.yyyy';
     LongTimeFormat := 'hh:nn:ss.zzz';

1. Muss das in der Schleife stehen? Reicht das nicht, das einmalig festzulegen?

2. Irgendwie sieht mir der Sortieralgorhytmus noch komisch aus. Setzt doch einfach mal einen anderen um, z.B. SelectionSort, oder so.

Just my 2 ct.

p80286 30. Mär 2011 17:02

AW: Memo lässt Zeilen verschwinden
 
wie wäre es statt des Arrays eine Tlist zu verwenden?
Da gibt es eine funktionierende Sortierung.

Gruß
K-H

aphexx 30. Mär 2011 21:28

AW: Memo lässt Zeilen verschwinden
 
Zitat:

Zitat von p80286 (Beitrag 1092074)
wie wäre es statt des Arrays eine Tlist zu verwenden?
Da gibt es eine funktionierende Sortierung.

Gruß
K-H

Ich hab' nun das Array in eine funktionierende TList umgewandelt. Die Datenübergabe funzt perfekt, allerdings habe ich jetzt noch ein kleines Problem mit der Sortierung. Die Reihenfolge ist überhaupt nicht korrekt und sieht nur 'etwas' sortiert aus. Außerdem wird die Reihenfolge jedes mal geändert, wenn ich die Liste sortiere. Klar ist das erwünscht, wenn ich meine Boolean-Variable mit ins Spiel bringe, aber ohne Variable muss das Ergebnis doch immer gleich aussehen. Für eine absteigende Sortierung (siehe Code-Block) würde ich in der if-Klausel X > Y schreiben. Wäre das korrekt?


Nach ein wenig Recherche sieht meine TListSortCompare so aus:
Delphi-Quellcode:
function Dh_CompareDateB(Item1, Item2: pointer):integer;
var
  X, Y: TDateTime;
begin
  x := StrToDateTime(PEntry(Item1).DatumZeit);
  y := StrToDateTime(PEntry(Item2).DatumZeit);
  if (X < Y)
  then Result := 1
  else if (X = Y) then Result := 0
                    else Result := -1;
end;
@Jumpy: Danke für's aufräumen, ich habs umgesetzt. :-D

Satty67 30. Mär 2011 21:41

AW: Memo lässt Zeilen verschwinden
 
Wenn Item1 < Item2 dann Result < 0, also müsste x < y = -1 sein. (Aber das kann man ja am Ergebnis schnell testen)

Für absteigend, die Rückgabe negieren, also
Delphi-Quellcode:
Result := -Result;
Sehr problematisch ist x = y! Flieskommazahlen (was TDateTime ist) kann man nur schwer sicher auf Gleichheit testen. Deshalb vieleicht eher das "gleich" im letzten else:
Delphi-Quellcode:
if (X < Y) then
  Result := -1
else if (X > Y) then
  Result := 1
else
  Result := 0;

if Absteigend then
  Result := -Result;

aphexx 31. Mär 2011 17:51

AW: Memo lässt Zeilen verschwinden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Perfekt!!1 So klappt es wunderbar! :thumb:
Vielen vielen Dank!

EDIT:
für eure Mühe gibt's jetzt auch das Programm :-D


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