Autor Beitrag
Haraldo
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 11:53 
Hallo, ich hoffe mir kann jemand helfen. Folgendes Problem:

ich habe ein Datei die jeweils records in einer Zeile enthält. Beispiel:

ausblenden Quelltext
1:
2:
3:
Meier;Norbert;01.03.1967;2300;
Schulze;Detlev;12.4.1976;1856;
Querfrurt;Marina;12.6.1957;1234,50;


diese lese ich ein in ein wie folgt deklariertes array

ausblenden Delphi-Quelltext
1:
2:
3:
4:
var AName: Array of String;
    AVorname: Array of String;
    AGebdat: Array of tdate;
    AGehalt: Array of real;


das alles klappt sehr gut.
jetzt möchte ich aber das array sortieren können und zwar nach Gehalt (größte oben) oder nach Name (alphabetisch)

normale sortierungen nach zb. das gehalt, gibt mir aber dann die falschen Namen und Vornamen dazu aus.

kann mir jemand helfen. bitte

Moderiert von user profile iconKlabautermann: Delphi- & Code-Tags hinzugefügt.
Miri
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 657


Delphi 3 Prof., Delphi 2005 PE
BeitragVerfasst: Fr 11.05.07 11:55 
user profile iconHaraldo hat folgendes geschrieben:
kann mir jemand helfen. bitte


Klar, wenn du uns ein bisschen Code zeigst...
Blind losraten ist nicht so der Hit und führt meist auch nicht zum gewünschten Ergebnis...

_________________
Anonymes Eckenkind
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 11.05.07 11:58 
Dein Ansatz ist falsch. Organisiere deine Daten in einem Record-Array, was je ein Feld für name, Vorname, Geburtstag und Gehalt enthält. Nicht in mehreren Arrays unterschiedlichen Typs. Dieses Record-Array kannst du dann sortieren, und zusammenghörende Eigenschaften bleiben automatisch zusammen.

Woher soll denn dein Namen-Array wissen, wie ds Geburtstags-Array sortiert wurde?

_________________
We are, we were and will not be.
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 12:09 
Danke gausi,
wie deklariere ich das
so ?

ausblenden Delphi-Quelltext
1:
var meinArray: Array of array of array of array ofString;					


aber da haben ja alle den Typ string, ich brauche aber string, tdate und Real
kannst du mir aufs fahrrad helfen

Moderiert von user profile iconKlabautermann: Delphi-Tags hinzugefügt.
Miri
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 657


Delphi 3 Prof., Delphi 2005 PE
BeitragVerfasst: Fr 11.05.07 12:16 
Ohne Delphi vor mir zu haben:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
TMyRecord = record  
  meinString: string;
  meinInteger: integer;
  meinDatum: date;
end;  

TMyArray = array of TMyRecord;


So in etwa meinte Gausi das...

_________________
Anonymes Eckenkind
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 12:23 
super danke
ich habe es jetzt so gemacht
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type
 personal = record
 AName, AVorname :String;
 AGebdat :Tdate;
 AGehalt : real;
end;
var
 APersonal: array of Personal;


das geht, aber jetzt sortiert er nicht mehr mit bubblesort, ein prob gelöst kommt schon das zweite
gibt es für diese art von array andere sortierkriterien?

Moderiert von user profile iconKlabautermann: Delphi-Tags hinzugefügt.
Miri
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 657


Delphi 3 Prof., Delphi 2005 PE
BeitragVerfasst: Fr 11.05.07 12:25 
Wie schon gesagt... zeig uns den Code, wie du versuchst zu sortieren... sonst können wir ja nicht sagen, was daran falsch ist :-) (zumindest als Azubi wurde mir noch keine Glaskugel zur Verfügung gestellt)

_________________
Anonymes Eckenkind
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 12:30 
ok das habe ich bisher

ausblenden volle Höhe 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:
//********************************************************************************
procedure TFLabor1.EaendernClick(Sender: TObject);
//********************************************************************************
var f:textfile;                // Hilfsvariable deklarieren
var Quelldatei,zeile : string// Hilfsvariable deklarieren
var anzahl,lzeil,x,y,i :integer; // Hilfsvariable deklarieren
type
 personal = record
 AName, AVorname :String;
 AGebdat :Tdate;
 AGehalt : real;
end;
var
 APersonal: array of Personal;
begin
 Anzahl := 0;                 // Hilfsvariable für Anzahl der Records in der Datei / Array
 lzeil := 0;                  // Hilfsvariable für Zeilenzähler innerhalb der Datei / Array

 // Name und Speicherort der Quelldatei festlegen
 Quelldatei := ExtractFilePath(Application.ExeName)+'Personal.dat';
 if Quelldatei = 'Personal.dat' then  // wenn Quelldatei keine Pfadangaben hat dann
  begin
   MessageDlg('Die Datei Personal.dat ist nicht vorhanden.', mtInformation, [mbOk], 0);
   exit;                      // Procedure verlassen
  end;

 // Datei öffnen
 AssignFile(f,QuellDatei);    // File Personal.dat
 {$i-}
 Reset(f);                    // Datei aus der gelesen wird
 {$i+}
 if ioResult <> 0 then halt;  // wenn zu öffnen dann weiter

 // Anzahl der vorhandenen Datensätze ermitteln
 while not eof(f) do          // solange Datei nicht zu ende
  begin
   readln(f,Zeile);            // lese eine zeile
   inc(Anzahl);                // erhöhe anzahl
  end;
 closefile(f);                 // Quelldatei schliesen

 // array dimesionieren
 setlength(APersonal,Anzahl+1);
 // Anzahl der Datensätze auf Bildschirm ausgeben
 label5.Caption := 'Anzahl der vorhandenen Datensätze: '+ inttostr(anzahl-1);
 stringgrid1.RowCount := Anzahl;  //Anzahl der Zeilen im Stringgrid auf die Anzahl der Records festlegen

 // Datei zum auslesen öffnen
 AssignFile(f,QuellDatei);    // File Personal.dat
 {$i-}
 Reset(f);                    // Datei aus der gelesen wird
 {$i+}
 if ioResult <> 0 then halt;  // wenn zu öffnen dann weiter

 // Jetzt auslesen und die Werte in das Array schreiben
 while not eof(f) do          // solange Datei nicht zu ende
  begin
   readln(f,Zeile);            // lese eine zeile
   inc(lzeil);                 // Zählervariable erhöhen
   // Namen suchen und in das array einlesen
   x := WoistderString(';',zeile,1); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
<span style="color: red"><span style="font-size: 18px; line-height: normal">Hier tritt jetzt der erste Fehler auf da ich die zellen falsch anspreche</span></span> 
   APersonal.AName[lzeil] := copy(zeile,1,x-1);
   // Vornamen suchen und in das array einlesen
   x := WoistderString(';',zeile,1); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
   y := WoistderString(';',zeile,2); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
   AVorname[lzeil] := copy(zeile,x+1,y-x-1);
   // Geburtsdatum suchen und in das array einlesen
   x := WoistderString(';',zeile,2); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
   y := WoistderString(';',zeile,3); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
   AGebdat[lzeil] := strtodate(copy(zeile,x+1,y-x-1));
   // Gehalt suchen und in das array einlesen
   x := WoistderString(';',zeile,3); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
   y := WoistderString(';',zeile,4); // die xte Stelle des Vorkommens des Sonderzeichen ermitteln
   AGehalt[lzeil] := strtofloat(copy(zeile,x+1,y-x-1));

  end;
 closefile(f);  // Datei schliesen
 // Ausgabe des Array in ein Stringgrid
 For I := 1 to anzahl do
  begin
   StringGrid1.Cells[0,i] := Aname[i];
   StringGrid1.Cells[1,i] := AVorname[i];
   StringGrid1.Cells[2,i] := datetostr(AGebdat[i]);
   StringGrid1.Cells[3,i] := formatfloat('0.00,#,##',AGehalt[i]);
  end;
end;


mein prob ist jetzt das ansprechen der zellen, das es mit bubblesort jetzt nicht mehr geht habe ich gelesen noch nicht probiert.

Moderiert von user profile iconKlabautermann: Delphi-Tags hinzugefügt.
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 12:35 
sorry für die blöden fragen, aber ich arbeite schon lange mit delphi hatte selten probs, aber ich habe noch nie mit arrays gearbeitet, würde es für diese Aufgabe auch nicht tun, aber der prof. will unbedingt den weg. Textdatei-Array-sortieren-Stringgrid. Ich hätte es sonst ohne array schon lange gelöst.
Miri
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 657


Delphi 3 Prof., Delphi 2005 PE
BeitragVerfasst: Fr 11.05.07 12:38 
Bin mir nich sicher, aber versuchs mal so:

ausblenden Delphi-Quelltext
1:
APersonal[lzeil].AName := copy(zeile,1,x-1);					


Übrigens gibt es hier diese schönen Delphi-Tags: <span class="inlineSyntax"></span>
Pack die um deinen Code und der wird etwas leserlicher angezeigt...

_________________
Anonymes Eckenkind
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 12:49 
danke, miri das war richtig das einlesen aus datei und das übergeben an das array und das widerum an das stringgrid funktioniert, jetzt bleibt noch mein problem mit dem sortieren.
ich habe auf der form 4 buttons
1. sortieren nach name
2. sortieren nach vornamen
3. sortieren nach gebdat
4. sortieren nach gehalt

da habe ich jetzt gar keinen plan wie ich da vorgehen soll
Miri
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 657


Delphi 3 Prof., Delphi 2005 PE
BeitragVerfasst: Fr 11.05.07 12:57 
Okay, erstmal: was willst du nun sortieren? Die Daten in deinem Array oder die in dem String-Grid?

So wie die Procedure, die du eben gepostet hast, aussieht, hast du deinen Record und das dazugehörige Array in der Procedure lokal deklariert. Wenn du aber über die Procedure hinaus Freude daran haben willst, solltest du beides global deklarieren. (Den Record soweit ich weiß sowieso...)

Und dann würd ich nach wie vor gern sehen, wie du vorher sortiert hast (bzw. es versucht hast)...

_________________
Anonymes Eckenkind
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 13:43 
Danke miri, ich habe das Array nun global deklariert (war logisch)

das ist das was ich bisher habe

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
//********************************************************************************
procedure TFLabor1.Button4Click(Sender: TObject);
//********************************************************************************
var i,k,zwsp: integer;
begin
 // nach gehalt sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to 5 do
   begin
    if Apersonal[k].AGehalt > Apersonal[k+1].AGehalt then
     begin
      zwsp:= APersonal[k].AGehalt;
      APersonal[k]:= Apersonal[k+1].Agehalt;
      Apersonal[k+1].AGehalt:= zwsp;
     end;
   end;
end;


das funzt aber nicht
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 13:53 
jetzt funktioniert es so

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
//********************************************************************************
procedure TFLabor1.Button4Click(Sender: TObject);
//********************************************************************************
var i,k: integer;
var zwsp :real;
begin
 // nach gehalt sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to anzahl do
   begin
    if Apersonal[k].AGehalt > Apersonal[k+1].AGehalt then
     begin
      zwsp:= APersonal[k].AGehalt;
      APersonal[k].AGehalt:= Apersonal[k+1].AGehalt;
      Apersonal[k+1].AGehalt:= zwsp;
     end;
   end;
 instringgrid;
end;


ich habe aber den mit dem geringstem Gehalt oben, benötige aber dem mit dem höchsten Gehalt.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 11.05.07 13:59 
Nene, du musst schon die Records vertauschen, sonst bringst du die Gehälter durcheinander.

Es sollte also in etwa so gehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TFLabor1.Button4Click(Sender: TObject);
var i,k: integer;
    zwsp :personal;
begin
 // nach gehalt sortieren
 for i:= 1 to 10-1 do
   for k:= 1 to anzahl do
   begin
     if Apersonal[k].AGehalt > Apersonal[k+1].AGehalt then
     begin
       zwsp := APersonal[k];
       APersonal[k] := Apersonal[k+1];
       Apersonal[k+1] := zwsp;
     end;
   end;
 instringgrid;
end;
Wenn du die Reihenfolge umkehren willst, musst du das > durch ein < ersetzen.

_________________
We are, we were and will not be.
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 14:17 
Danke danke danke Gausi jetzt funzt es zumindestens beim Gehalt bei den Anderen Kriterien Name=string und GebDatum = Tdate da funzt es nicht

das habe ich:

ausblenden volle Höhe 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:
//********************************************************************************
procedure TFLabor1.Button4Click(Sender: TObject);
//********************************************************************************
var i,k: integer;
var zwsp :personal;
begin
 // nach gehalt sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to anzahl do
   begin
    if Apersonal[k].AGehalt < Apersonal[k+1].AGehalt then
     begin
      zwsp:= APersonal[k];
      APersonal[k]:= APersonal[k+1];
      Apersonal[k+1]:= zwsp;
     end;
   end;
 instringgrid;
end;

//********************************************************************************
procedure TFLabor1.Button3Click(Sender: TObject);
//********************************************************************************
var i,k: integer;
var zwsp :personal;
begin
 // nach Geburtsdatum sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to anzahl do
   begin
    if Apersonal[k].AGebdat > Apersonal[k+1].AGebdat then
     begin
      zwsp:= APersonal[k];
      APersonal[k]:= Apersonal[k+1];
      Apersonal[k+1]:= zwsp;
     end;
   end;
 instringgrid;
end;

//********************************************************************************
procedure TFLabor1.Button2Click(Sender: TObject);
//********************************************************************************
var i,k: integer;
var zwsp :personal;
begin
 // nach vornamen sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to anzahl do
   begin
    if Apersonal[k].AVorname > Apersonal[k+1].AVorname then
     begin
      zwsp:= APersonal[k];
      APersonal[k]:= Apersonal[k+1];
      Apersonal[k+1]:= zwsp;
     end;
   end;
 instringgrid;
end;

//********************************************************************************
procedure TFLabor1.Button1Click(Sender: TObject);
//********************************************************************************
var i,k: integer;
var zwsp :personal;
begin
 // nach Nachnamen sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to anzahl do
   begin
    if Apersonal[k].AName > Apersonal[k+1].AName then
     begin
      zwsp:= APersonal[k];
      APersonal[k]:= Apersonal[k+1];
      Apersonal[k+1]:= zwsp;
     end;
   end;
 instringgrid;
end;

//********************************************************************************
procedure TFLabor1.InStringgrid;
//********************************************************************************
var i :Integer;
begin
 // Ausgabe des Array in ein Stringgrid
 For I := 1 to anzahl do
  begin
   StringGrid1.Cells[0,i] := APersonal[i].Aname;
   StringGrid1.Cells[1,i] := APersonal[i].AVorname;
   StringGrid1.Cells[2,i] := datetostr(APersonal[i].AGebdat);
   StringGrid1.Cells[3,i] := formatfloat('0.00,#,##',APersonal[i].AGehalt);
  end;
end;
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 14:21 
sorry, ich habe gerade gemerkt das es doch nach allen kriterien funktioniert, aber allerdings immer nur einmal, wenn ich nach name sortiere geht es danach nach gehalt bekomme ich ein Acces violation, muss ich irgendetwas wieder freigeben?
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8554
Erhaltene Danke: 480

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Fr 11.05.07 14:36 
Die innere Sortier-Schleife (k) geht bis anzahl, du greifst aber auch auf das k+1.te Array-Element zu. Ist das denn vorhanden? Ich würde vermuten, dass es das nicht ist :nixweiss:.

Und warum läuft die äußere immer nur bis 10-1?

_________________
We are, we were and will not be.
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 14:47 
genau weil ich die routine nicht verstehe habe ich mir die gleichen fragen gestellt aber keine antwort gefunden

ich vermute die äußere schleife ist die anzahl der datensätze und die innere die anzahl der felder richtig? was die 10-1 bedeutet weis ich nicht habe ich übernommen
Haraldo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 38

XP Prof.
delphi6 und 7
BeitragVerfasst: Fr 11.05.07 15:02 
jetzt geht alles, aber ich weis nicht warum. kann mir jemand sagen was ist die äußere und was ist die innere schleife, ich würde es gerne verstehen
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
//********************************************************************************
procedure TFLabor1.Button4Click(Sender: TObject);
//********************************************************************************
var i,k: integer;
var zwsp :personal;
begin
 // nach gehalt sortieren
 for i:= 1 to 10-1 do
  for k:= 1 to anzahl-1 do
   begin
    if Apersonal[k].AGehalt < Apersonal[k+1].AGehalt then
     begin
      zwsp:= APersonal[k];
      APersonal[k]:= APersonal[k+1];
      Apersonal[k+1]:= zwsp;
     end;
   end;
 instringgrid;
end;