Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - FindComponent für if-abfrage


JonesB - Mi 25.11.09 20:32
Titel: FindComponent für if-abfrage
hey,
hab folgendes problem, hoffe ist nicht zu schwer zu lösen

programmiere grad ein adressbuch, das nach unterschiedlichen spalten sortiert werden soll (Vorname, Nachname...usw.)
hab für jeden kontakt ein array of record gewählt.

Delphi-Quelltext
1:
2:
3:
Daten[i].Vorname
Daten[i].Nachname
Daten[i].Strasse usw.

wenn man nun auf die Spalte "Vornamen" klickt, wird der Variablen "Spalte" der wert "Vorname" zugewiesen. bei der spalte nachname der wert "nachname" usw...

möchte jetzt das bei dem vergleich von zwei werten

Delphi-Quelltext
1:
Daten[i].Vorname < Dateb[j].Vorname                    

der das Subitem "Vorname" durch den Wert der Variable "Spalte" ersetzt wird, damit ich nicht für jede spalte eine eigene prozedur schreiben muss.

also Daten[i].Spalte

hab schonmal was mit FindComponent versucht, hab aber ehrlich gesagt keine ahnung von FindComponent

Delphi-Quelltext
1:
if FindComponent('Daten[' + IntToStr(i) + '].' + Spalte) < FindComponent('Daten[' + IntToStr(j) + '].' + Spalte)                    


Hoffe ihr könnt mir helfen.

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


Georg08 - Mi 25.11.09 21:47

kannst du mal den quelltext posten, damit ich mir beser was runter vorstellen kann?


JonesB - Do 26.11.09 00:21


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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
unit Hauptfenster;

interface

uses
  Windows, Messages, SysUtils....

type
  TDatenRecord = Record
    Vorname, Vorname2, Nachname, Titel, Rufname, Straße, Ort, Bundesland, usw...
  End;

  Savedata = Array[0..100of TDatenRecord;

  TFHauptfenster = class(TForm)
    ...
    ...
    procedure LVUebersichtColumnClick(Sender: TObject; Column: TListColumn);
  private
    { Private-Deklarationen }
    procedure Speichern;
    procedure Laden;
  public
    { Public-Deklarationen }
    Daten : Savedata;
  end;

var
  FHauptfenster: TFHauptfenster;
  arr1: array[0..100]of TDatenRecord;
  arr2: array[0..100]of TDatenRecord;
  Spalte: String;

implementation

uses Startfenster, Kontofenster,...
{$R *.dfm}


procedure mergesort(l,r: integer);
var i,j,k,m: integer;
begin

if r-l>0 then
 begin
   m:=(r+l) div 2;  
   mergesort(l,m);  
   mergesort(m+1,r);

   for i:=m downto l do
   begin
    arr2[i]:=arr1[i]; 
   end;        

   for j:=m+1 to r do
   begin
    arr2[r+m+1-j]:=arr1[j];
   end;

   i:=l;
   j:=r;
   for k:=l to r do
   begin                          
     if arr2[i].Vorname < arr2[j].Vorname then 
  //hier soll für Vorname ein beliebiges Subitem des Record eingesetzt werden
  // if FindComponent('arr2[j].' + Spalte) < FindComponent('arr2[j].' + Spalte)  then
      begin
       arr1[k] :=arr2[i];
       inc(i);
      end
     else        //Falls i > j
        begin
        arr1[k]:=arr2[j];
         j:=j-1
        end;
   end;
 end;
end;


//wenn auf eine Spalte geklickt wird, soll der Index festgestellt werden und das Array of Record nach dem Wert sortiert werden
procedure TFHauptfenster.LVUebersichtColumnClick(Sender: TObject;
  Column: TListColumn);
  var
  Index, i : integer;
  begin
  Laden();             //läd alle Daten ins Prgramm
  Counter := Daten[0].Counter;    //ließt die Anzahl der Einträge im Array ein
  Index := Column.Index;

  if index = 1 then Spalte:= 'Vorname'
  else if index = 2 then Spalte:= 'Nachname'
  else if index = 3 then Spalte:= 'Straße'
  else if index = 4 then Spalte:= 'Ort'
  else if index = 5 then Spalte:= 'Postleitzahl';

  for i := 0 to Counter do
  begin
   arr1[i] := Daten[i];
  end;

  mergesort (0,counter-1);

  for i := 0 to Counter do
  begin
   Daten[i] := arr1[i];
  end;
end;


Martok - Do 26.11.09 09:50

Er meint das, wozu man in PHP $objekt->$eigenschaft = 42 schreiben könnte.

Kurz: sowas gibts nicht, du musst das von Hand unterscheiden. Am Einfachsten dürfte sein, du schreibst dir mehrere Vergleichsfunktionen (vgl. TList.Sort, TListSortCompare), von denen du je nach Sortierreihenfolge die passende auswählst.


jaenicke - Do 26.11.09 10:43

Naja, theoretisch könnte man so etwas in der Art mit Pointern relativ gut nachbauen. Allerdings verringert das die Lesbarkeit des Quelltextes drastisch, deshalb würde ich es nicht empfehlen...


JDF - Do 26.11.09 11:29

Hallo!

Du kannst ja mal etwas mit TVarRec probieren.
so etwa:


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:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
unit Records00F;

interface

uses
  Forms, SysUtils, Classes, Controls, StdCtrls;

type
  TDatenRecord = record case Byte of
    1: (
      Vorname,
      Vorname2,
      Nachname,
      Titel,
      Rufname,
      Strasse,
      Ort,
      Bundesland: TVarRec
    );
    2: (
      Items: array[0..7of TVarRec;
    );
  end;

type
  T_Records00F = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    Savedata: array[0..100of TDatenRecord;
  end;

var
  _Records00F: T_Records00F;

implementation

{$R *.dfm}

function ItemGet(Item: TVarRec): String;
begin
  Result := String(Item.VAnsiString);
end;

procedure ItemPut(var Item: TVarRec; const Value: String);
begin
  Item.VType := vtAnsiString;
  String(Item.VAnsiString) := Value;
end;

procedure T_Records00F.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to 99 do begin
    ItemPut( Savedata[i].Vorname, 'Vorname' + Format('%2.2d', [i]) );
    ItemPut( Savedata[i].Vorname2, 'Vorname2' + Format('%2.2d', [i]) );
    ItemPut( Savedata[i].Nachname, 'Nachname' + Format('%2.2d', [i]) );
    ItemPut( Savedata[i].Titel, 'Titel' + Format('%2.2d', [i]) );
  end;
end;

procedure T_Records00F.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  Memo1.Clear;
  for i := 0 to 99 do begin
    Memo1.Lines.Add( ItemGet(Savedata[i].Items[2]) )
  end;
end;

end.


Gruß
Jürgen


jaenicke - Do 26.11.09 12:15

Wenn ohnehin schon ein Array da ist, dann reicht auch ein Array mit Strings. ;-)
Mittels Konstanten kann man dann den entsprechenden Eintrag ansprechen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
const
  COL_NAME = 0;
  COL_STREET = 1;
  ...

type
  TMyRecord = record
    Columns: array[0..1of String;
    OtherData: ...
  end;

...

var
  test: TMyRecord;
begin
  test.Columns[COL_NAME] := ...

  ShowMessage(test.Columns[COL_NAME]);