Autor Beitrag
MILÖ
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: So 02.01.05 15:21 
Habe da noch mal eine Frage. Hat jemand eine Idee, wie man diese Problem löst?
Ich habe ein ListView in dem ein Dateidatum in dieser Form [20.12.04 17:45] angezeigt wird.
Jetzt möchte ich dieses sortieren.
Im Forum wird dieser Tipp gegeben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.ListView1ColumnClick(Sender: TObject;  
  Column: TListColumn);  

 
  function DateSortProc(Item1, Item2: TListItem;  
    ParamSort: Integer): Integer; stdcall;  
  begin  
      // Datum absteigend sortieren, falls aufsteigend erwünscht  
      // minus-Zeichen weglassen  
    Result := -CompareDate(StrToDate(Item1.Caption),  
      StrToDate(Item2.Caption));  
  end;  

 
begin  
   case Column.Index of  
     0: ListView1.CustomSort(@DateSortProc, 0);  
   end;  
end;

Da ich aber Delphi 3.0 benutze und das den Befehl „CompareDate“ nicht kennt, geht das leider nicht. Der Befehl „CompareText“ welchen es kennt, sortiert hier nicht richtig.
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 02.01.05 15:36 
comparedate brauchst du nicht. außerdem solltest du bei dem alphasort und oncompare bleiben, sonst fangen wir wieder von vorne an.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
Var z1,z2,code:integer;
begin
  case ColumnToSort of
    //1. Spalte nach namen
    0: Compare := CompareText(Item1.Caption, Item2.Caption);  
    //2. Spalte nach Zahlen
    1: begin  
         z1:=0;
         z2:=0;
         val(Item1.SubItems[0],z1,code);
         val(Item2.SubItems[0],z2,code);
         compare:=z1-z2; //einfach nur Differenz bilden
       end;
    //3. Spalte nach datum
    2: compare:=strtodate(item1.subitem[1])-strtodate(item2.subitem[1])
  end;
  //auf oder absteigend sortieren
  if accending then compare:=not compare;
end;

bei compare brauchst du nur <0, 0, oder >0 eintragen, deshalb langt ein einfaches subtrahieren

allerdings hat das auch so seine Problemchen: du muß sicherstellen, das auch ein gültiges Datum eingetragen ist, sonst gibts eine Exception, kannst du zwar mit einem try except abfangen, kostet aber auch zeit. Und wenn wir schon bei zeit sind: bei einer größeren Datenmenge in der Listview wirst du das deutlich merken, wenn du nach dem datum sortierst. Die Umrechnung von strtodate wird dich ewig zeit kosten. Ich würde in so einem Fall die Daten nicht direkt in Listview schreiben, sondern über ein reocrd gehen, wo ich name=string, dateigröße=integer und datum als Tdate ablegen würde und es dar data-erigenschaft zuweise. Beim sortieren greife ich dann auf die Dataeigenschaft zu und spare mir das umgerechne. Aber das führt zu weit und ist wahrscheinlich auch viel zu schwierig für dich, wollte es bloß mal erwähnen.

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)


Zuletzt bearbeitet von Keldorn am So 02.01.05 15:42, insgesamt 1-mal bearbeitet
Sprint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 849



BeitragVerfasst: So 02.01.05 15:38 
MILÖ hat folgendes geschrieben:
Da ich aber Delphi 3.0 benutze und das den Befehl „CompareDate“ nicht kennt, geht das leider nicht. Der Befehl „CompareText“ welchen es kennt, sortiert hier nicht richtig.

Du musst den String "20.12.04 17:45" (also Item1, Item2) in ein TDateTime umwandeln und vergleichen.

_________________
Ciao, Sprint.
MILÖ Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: So 02.01.05 15:55 
@ Keldorn
Guter Tipp, aber da gibt es Probleme. Inkompatible Typen "Integer und Real"
Will jetzt nicht klugscheißen, aber Du hast mich ja auch auf kleine Fehler hingewiesen:

Zitat:
2: compare:=strtodate(item1.subitem[1])-strtodate(item2.subitem[1])

Geht nicht...

ausblenden Delphi-Quelltext
1:
2: compare:=strtodate(item1.SubItems[1])-strtodate(item2.SubItems[1]);					

So sollte das heißen :wink:

Werde mal den Tipp von Sprint probieren.
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 02.01.05 16:01 
das kommt davon, wenn ma was direkt ins froum klimpert :mrgreen:
dann nutze round oder trunc
ausblenden Delphi-Quelltext
1:
2: compare:=trunc(strtodate(item1.subitems[1])-strtodate(item2.subitems[1]))					

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
MILÖ Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: So 02.01.05 16:20 
Dicht drann, aber noch nicht ganz.
user defined image
Erster Klick
user defined image
Zweiter Klick
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 02.01.05 16:42 
ausblenden Delphi-Quelltext
1:
2:compare:=trunc(strtodatetime(item1.subitems[1])-strtodatetime(item2.subitems[1]));					

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
MILÖ Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: So 02.01.05 17:00 
Nee, klapt auch nicht.
Aber vielleicht hilft die Zuweisung
ausblenden Delphi-Quelltext
1:
2:
DateTimeToString(DT,'dd.mm.yy  hh:mm',FileDateToDateTime(SearchRec.Time));
  NewItem.SubItems.Add(DT);
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: So 02.01.05 17:07 
ich habs in den code von gestern eingebaut und dort schon gesehen, das beim Listview hinzufügen "DateTimeToString" verwendet wird.
bei mir gehts wieder ;)

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)
MILÖ Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: So 02.01.05 17:19 
Heee? Bei Dir sortiert er richtig? Ich verstehe die Welt nicht mehr.... :cry:

Kannst Dir das Programm ja mal anschauen.
www.milo-soft.com/magazin/change15.exe
cybersoul
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: Mo 03.01.05 00:08 
Hi.
Ich habe mal zwei Funktionen zur Sortierung von Datum und Zeit geschrieben.
Wenn mann beide zu SortDateTime zusammenfügt, kann man das ganze einfach im
OnCompare-Ereignis aufrufen.

Aufwärts sortieren:
compare:=SortDateTime(DT1,DT2);

Abwärts sortieren:
compare:=-1*SortDateTime(DT1,DT2);

ausblenden volle Höhe Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
function SortDateTime(DT1,DT2:tdatetime):integer;
begin
  result:=SortDate(DT1,DT2);
  if result = 0 then
    result:=SortTime(DT1,DT2);
end;

function SortDate(D1,D2:tdatetime):integer;
var y1,m1,td1,y2,m2,td2:word;
begin
  DecodeDate(D1,y1,m1,td1);
  DecodeDate(D2,y2,m2,td2);
  if y1 < y2 then result:=-1
  else if y1 > y2 then result:=1
  else begin
    if m1 < m2 then result:=-1
    else if m1 > m2 then result:=1
    else begin
      if td1 < td2 then result:=-1
      else if td1 > td2 then result:=1
      else result:=0;
      end;
    end;
end;

function SortTime(T1,T2:tdatetime):integer;
var h1,m1,s1,ms1,h2,m2,s2,ms2:word;
begin
  DecodeTime(T1,h1,m1,s1,ms1);
  DecodeTime(T2,h2,m2,s2,ms2);
  if h1 < h2 then result:=-1
  else if h1 > h2 then result:=1
  else begin
    if m1 < m2 then result:=-1
    else if m1 > m2 then result:=1
    else begin
      if s1 < s2 then result:=-1
      else if s1 > s2 then result:=1
      else result:=0;
      end;
    end;
end;
MILÖ Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: Mo 03.01.05 11:57 
@ cybersoul
Danke für die Funktion. compare:=SortDateTime(StrToDateTime(item1.subitems[2]),StrToDateTime(item2.subitems[2]));
Ich habe sie eingebaut, doch leider funktioniert die Sortierung immer noch nicht richtig.

Hier kann man sich den kompletten original Quellcode downloaden....
www.milo-soft.com/magazin/sort.zip

user defined image
Aber auch Compare := CompareText(Item1.Caption, Item2.Caption);
funktioniert nicht richtig.
user defined image

Hier kann man sich den kompletten original Quellcode downloaden....
www.milo-soft.com/magazin/sort.zip
MILÖ Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 26

WIN 98 SE
Delphi 3.0
BeitragVerfasst: Di 04.01.05 16:01 
@ Keldorn

Habe die Procedure geändert

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
Var z1,z2,code:integer;
   
begin
  case ColumnToSort of
    0: Compare := CompareText(Item1.Caption, Item2.Caption);// Dateinamen z.B. Bild24.jpg
    1: begin   // Dateigröße z.B. 25478
         z1:=0;
         z2:=0;
         val(Item1.SubItems[0],z1,code);
         val(Item2.SubItems[0],z2,code);
         compare:=z1-z2; //einfach nur Differenz bilden
       end;
     2: begin  // Dateidatum z.B. 24.08.02 14:24
         z1:=0;
         z2:=0;
         val(IntToStr(trunc(StrToDateTime(Item1.SubItems[1]))),z1,code);
         val(IntToStr(trunc(StrToDateTime(Item1.SubItems[1]))),z2,code); 
         compare:=z1-z2; 
      end;
  end;
  //auf oder absteigend sortieren
  if accending then compare:=not compare;
end;


val(IntToStr(trunc(StrToDateTime(Item1.SubItems[1]))),z2,code);
So kann es natürlich auch nicht funktionieren....
Ich habe aus der 1 eine 2 gemacht und schon ist alles in Butter... :D