Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte »    

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 Listbox nach Datum sortieren (https://www.delphipraxis.net/134814-listbox-nach-datum-sortieren.html)

Codix32 29. Mai 2009 14:23


Listbox nach Datum sortieren
 
Hi Leute,

ich raffs nicht. Habe ein Programm, das in einer Listbox Text mit vorgestelltem Datum ausgibt.

Meine Funktionen können die Listbox auch sortieren und das Ganze als Text Datei abspeichern.
Das Problem ist, daß ich das Programm jedesmal schliesen und neustarten muß, damit das Sortieren funktioniert. Wird nach dem Start in die Listbox mehr als ein Eintrag gemacht und mehr als einmal sortiert, steht der neue Item am Anfang der Liste.

Das Proggi sortiert das Datum ausgehend nach den vergangenen Tagen seit 1.01.1900 bis zum eingegebenen Datum. Die Tage stehen kurzfristig am Anfang des Items werden dann mit 'Listbox.sorted' sortiert, danach werden die Tage sofort entfernt, so daß das Datum am Anfang des Items steht:

Beispiel:

07334 31.01.1920 Blalbalbla...
14014 16.05.1938 Tusnelda Geburtstag

danach steht in der Liste:

31.01.1920 Blabalbla
16.05.1928 Tusnelda Geburtstag

Bei Übergabe der aktuellen Jahreszahl in die Funktion sortiert diese nach Monaten und Tagen.

Wo liegt der Fehler? Warum muß ich das Proggi vor dem Sortieren neu starten?

In 'onCreate' wird die Datei geladen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
BorderIcons := [biSystemmenu];
Form1.caption:='Zeitereignisse um den heutigen --> '+DatetoStr(Date);
Statusbar1.panels[0].text:='Datum: '+ DatetoStr(Date);
Statusbar1.panels[1].text:='Woche: '+ InttoStr(WeekOfYear(Date));
Statusbar1.panels[2].text:='Jahrestag: '+ TagdesJahres;
Listbox1.itemIndex:=0;
LADE;                  // <-Lade die Datei in Liste
aktuell;
end;
Hier wird ein neuer Item eingetragen, eigentlich schon sortiert und gespeichert:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var InputString:String;
    temp:String;
begin
  InputString:= InputBox('Eingabedialogfenster', 'Datum eingeben, dann 3 Leerzeichen, dann Text', '');
if (IstString_einDatum(DatetoStr(StrtoDate(copy(Inputstring,1,10))))) then
 begin
    temp:= DatetoStr(StrtoDate(copy(Inputstring,1,10)));
    Inputstring:=temp+copy(Inputstring,11,length(Inputstring));
    Listbox1.items.add(Inputstring);
//    Listbox1:=(sortiereListe(Listbox1));
aktuell;
    Listbox1.items.SaveToFile('Uebersicht.txt');
 end;
end;
Hier das Sortieren über einen Button:
Delphi-Quellcode:
procedure TForm1.Button3Click(Sender: TObject);
begin
    Listbox1:=(sortiereListe(Listbox1));
end;
Listbox.sorted wird in der 'function TForm1.sortiereListe(L:TListbox):TListbox;' auf 'True' gesetzt.

sx2008 29. Mai 2009 22:08

Re: Listbox nach Datum sortieren
 
Wenn du das Datum in der Form yyyy-mm-dd ausgibst, dann werden die Datumswerte richtig sortiert.
Delphi-Quellcode:
// hier die notwändige Änderung
temp:= FormatDateTime('yyyy-mm-dd', StrtoDate(copy(Inputstring,1,10)));
Wenn dir das Datumsformat nicht gefällt, musst du "schwerere Geschütze" auffahren.

Satty67 29. Mai 2009 22:40

Re: Listbox nach Datum sortieren
 
Du sortierst anhand der Tage seit 1.1.1990... ich nehme an, die Liste wird auch mit den Tagen am Anfang gespeichert oder in "Lade" davor eingefügt.

Wenn alles geladen und sortiert ist, entfernst Du die Tage, weil es doof aussieht. Wahrscheinlich in der Funktion "Lade" oder "aktuell", je nachdem... den Code hast Du nicht gezeigt.

Sooo.. die Liste ist geladen, sortiert und die Tage davor sind entfernt.

***

Jetzt kommt ein neuer Eintrag in die Liste, ohne die Tage davor. Die ganze Liste hat ja inzwischen keine Tage davor, weil Du die beim Laden entfernt hast, weil es doof aussieht.

Jetzt kommt Deine Sortier Routine, um wegen dem neuen Eintrag zu sortieren. Die Sortier-Routine funktioniert aber nur mit den Tagen davor, das weist Du.

***

Vor jedem Sortieren wieder die Tage vor die Einträge setzten oder anders sortieren (durch Auswerten des Datums), wäre jetzt eine Möglichkeit. Datumsanzeige ändern, wie sx2008 es vorgeschlagen hat, auch eine Möglichkeit (dann kannst Du Dir die Tage davor ganz sparen).

Ein "schwereres Geschütz" wäre, die Anzahl Tage im Object des Listeneintrages zu speichern und mit einer eigenen kleinen Routine nach Object sortieren.

;)

Codix32 30. Mai 2009 10:46

Re: Listbox nach Datum sortieren
 
Hallo Satty67

erstmal Danke für Deine Antwort :-)

Du schreibst:

Zitat:

Zitat von Satty67
Du sortierst anhand der Tage seit 1.1.1990... ich nehme an, die Liste wird auch mit den Tagen am Anfang gespeichert oder in "Lade" davor eingefügt.

Die Liste wird ohne Tage gespeichert, die Tage sind werden in der 'sortieren Funktion eingefügt und entfernt. Sie dienen nur dem Sortiervorgang und müssen danach entfernt werden, weil sonst das weitere Proggi nicht funktioniert - es muß für weitere Funktionen das Datum an erster Stelle stehen.

Zitat:

Zitat von Satty67
Wenn alles geladen und sortiert ist, entfernst Du die Tage, weil es doof aussieht. Wahrscheinlich in der Funktion "Lade" oder "aktuell", je nachdem... den Code hast Du nicht gezeigt.

Wie gesagt wird alles in der Func 'Sortiere' erledigt. Hier mal die Func:
Delphi-Quellcode:
function TForm1.sortiereListe(L:TListbox):TListbox;
var i: integer;
    Tage : string;
    Zeilendatum:String;
    Zeilenrest:string;
begin
for i := 0 to L.items.count-1 do
begin
ZeilenDatum:= copy(L.Items[i],1,10);
Zeilenrest:= copy(L.Items[i],11,length(L.Items[i]));
if IstString_einDatum(Zeilendatum) then
      {sortiert nach Monaten, Jahreszahl(2xxx muß aktuell sein}
//  Tage:= Datumsdiff_inTagen(strtodate('01.01.2009'),setEreignisDatuminZukunft(strtodate(Zeilendatum),strtodate('01.01.2009')));
      {sortiert nach Jahr und Tag, ab 1900}
Tage:= Datumsdiff_inTagen(strtodate('01.01.1900'),setEreignisDatuminZukunft(strtodate(Zeilendatum),strtodate('01.01.1900')));
if copy(Tage,1,1)='-' then Tage:=copy(Tage,2,length(Tage));
L.Items[i]:='';
if length(Tage)=1 then Tage:='0000'+Tage;
if length(Tage)=2 then Tage:='000'+Tage;
if length(Tage)=3 then Tage:='00'+Tage;
if length(Tage)=4 then Tage:='0'+Tage;
L.Items[i]:=Tage+' '+Zeilendatum +''+ Zeilenrest;
end;
L.Sorted := True;
for i := 0 to L.items.count-1 do L.Items[i]:=copy(L.Items[i],7,length(L.items[i]));  //Entfernt die Tage
Result:=L;
end;
Zitat:

Zitat von Satty67
Sooo.. die Liste ist geladen, sortiert und die Tage davor sind entfernt.

***

Jetzt kommt ein neuer Eintrag in die Liste, ohne die Tage davor. Die ganze Liste hat ja inzwischen keine Tage davor, weil Du die beim Laden entfernt hast, weil es doof aussieht.

Genau, hier die Proc:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var InputString:String;
    temp:String;
begin
  InputString:= InputBox('Eingabedialogfenster', 'Datum eingeben, dann 3 Leerzeichen, dann Text', '');
if (IstString_einDatum(DatetoStr(StrtoDate(copy(Inputstring,1,10))))) then
 begin
    temp:= DatetoStr(StrtoDate(copy(Inputstring,1,10)));
    Inputstring:=temp+copy(Inputstring,11,length(Inputstring));
    Listbox1.items.add(Inputstring);
    Listbox1:=(sortiereListe(Listbox1));
aktuell;
    Listbox1.items.SaveToFile('Uebersicht.txt');
 end;
end;
hier das Bild dazu:
http://www.siteupload.de/t961463-ProggiEingabe60jpg.jpg

Zitat:

Zitat von Satty67
Jetzt kommt Deine Sortier Routine, um wegen dem neuen Eintrag zu sortieren. Die Sortier-Routine funktioniert aber nur mit den Tagen davor, das weist Du.

***

Vor jedem Sortieren wieder die Tage vor die Einträge setzten oder anders sortieren (durch Auswerten des Datums), wäre jetzt eine Möglichkeit. Datumsanzeige ändern, wie sx2008 es vorgeschlagen hat, auch eine Möglichkeit (dann kannst Du Dir die Tage davor ganz sparen).

Ein "schwereres Geschütz" wäre, die Anzahl Tage im Object des Listeneintrages zu speichern und mit einer eigenen kleinen Routine nach Object sortieren.

;)

Siehe oben die Func 'sortieren' :-)

Also, woran könnte es liegen, daß ich nach dem Programmstart nur einmal sortieren kann?
Was ist da los mit der Komponente TListbox?

Luckie 30. Mai 2009 11:19

Re: Listbox nach Datum sortieren
 
Also, so sehen die Daten aus, die du bekommst:
Code:
31.01.1920 Blabalbla
16.05.1928 Tusnelda Geburtstag
Lass das Gefrickel mit den Tagen:
Delphi-Quellcode:
function ExtractDateFromString(s: String): TDateTime;
var
  DateStr: String;
  FormatSetting: TFormatSettings;
begin
  FormatSetting.DateSeparator := '.';
  FormatSetting.ShortDateFormat := 'dd.MM.yyyy';
  DateStr := Copy(s, 1, 10);
  Result := StrToDateTime(DateStr, FormatSetting);
end;

procedure BubbleSort(sl: TStrings);
var
  i, j: Integer;
  TempStr: String;
begin
  for i := sl.Count - 1 downto 1 do
  begin
    for j := 1 to i do
    begin
      if ExtractDateFromString(sl[j-1]) > ExtractDateFromString(sl[j]) then
      begin
        TempStr := sl[j];
        sl[j] := sl[j-1];
        sl[j-1] := TempStr;
      end;
    end;
  end;
end;


procedure TForm2.Button1Click(Sender: TObject);
begin
  BubbleSort(Listbox1.Items);
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Listbox1.Items.Add('31.01.1920 Blabalbla');
  Listbox1.Items.Add('16.05.1928 Tusnelda Geburtstag');
  Listbox1.Items.Add('31.08.1974 Michael');
  Listbox1.Items.Add('29.06.1949 Helmut');
  Listbox1.Items.Add('28.09.1948 Gitta');
  Listbox1.Items.Add('20.06.1972 Micky');
  Listbox1.Items.Add('29.06.1810 Bismarck');
  Listbox1.Items.Add('10.05.1905 Heinz');
end;

Codix32 30. Mai 2009 11:21

Re: Listbox nach Datum sortieren
 
Zitat:

Zitat von sx2008
Wenn du das Datum in der Form yyyy-mm-dd ausgibst, dann werden die Datumswerte richtig sortiert.
Delphi-Quellcode:
// hier die notwändige Änderung
temp:= FormatDateTime('yyyy-mm-dd', StrtoDate(copy(Inputstring,1,10)));
Wenn dir das Datumsformat nicht gefällt, musst du "schwerere Geschütze" auffahren.

Hallo sx2008,

das ist eine sehr einfache Lösung, aber:

Die Liste läßt sich nur einmal sortieren und dann kriege ich einen eConvert Error:

'1920-01-31' ist kein gültiges Datum.

Hier die Func:
Delphi-Quellcode:
function TForm1.sortListe2(L:TListbox):TListbox;
var i: integer;
    Zeilendatum:String;
    Zeilenrest:string;
    temp:string;
begin
for i := 0 to L.items.count-1 do
begin
temp:= FormatDateTime('yyyy-mm-dd', StrtoDate(copy(L.Items[i],1,10)));
ZeilenDatum:= temp;
Zeilenrest:= copy(L.Items[i],11,length(L.Items[i]));
L.Items[i]:='';
L.Items[i]:=Zeilendatum +'    '+ Zeilenrest;
end;
 L.sorted:=true;
end;

Luckie 30. Mai 2009 11:22

Re: Listbox nach Datum sortieren
 
Was ist mit miner Lösung?

Satty67 30. Mai 2009 11:27

Re: Listbox nach Datum sortieren
 
Okok... war gestern auch spät und ich war heiterer Stimmung (wie man an meinem Text sieht).

Probier mal, sortieren aus/ein...
Delphi-Quellcode:
L.Sorted := False;
L.Sorted := True;
for i := 0 to L.items.count-1 do L.Items[i]:=copy(L.Items[i],7,length(L.items[i]));  //Entfernt die Tage
Scheinbar wird nicht nochmal sortiert, wenn Sorted bereits True ist. Die Hilfe spricht zwar von sortiertem Einordnen, aber das war wohl anders gemeint.

Wobei Luckie's Code natürlich besser aussieht, zumindest anschauen solltest Du Dir den...

Codix32 30. Mai 2009 11:35

Re: Listbox nach Datum sortieren
 
Zitat:

Zitat von Luckie
Was ist mit miner Lösung?

Hallo Luckie .-)

Wenn Deine Lösung funzt, bin ich happy.

Ich habe früher schon mal versucht, mit Quick- und Bubble Sort was anzufangen und bin
gescheitert.

Ich danke Dir herzlich und werde die Routine gleich mal ausprobieren :thumb:

Codix32 30. Mai 2009 11:44

Re: Listbox nach Datum sortieren
 
Zitat:

Zitat von Satty67
Okok... war gestern auch spät und ich war heiterer Stimmung (wie man an meinem Text sieht).

Probier mal, sortieren aus/ein...
Delphi-Quellcode:
L.Sorted := False;
L.Sorted := True;
for i := 0 to L.items.count-1 do L.Items[i]:=copy(L.Items[i],7,length(L.items[i]));  //Entfernt die Tage
Scheinbar wird nicht nochmal sortiert, wenn Sorted bereits True ist. Die Hilfe spricht zwar von sortiertem Einordnen, aber das war wohl anders gemeint.

Wobei Luckie's Code natürlich besser aussieht, zumindest anschauen solltest Du Dir den...

Ok, das funzt nicht, Satty67. Wenn ich Sorted vorher auf False setze, ist alles durcheinander.

Ich versuchs mal mit Luckies Code.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:12 Uhr.
Seite 1 von 5  1 23     Letzte »    

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