Autor Beitrag
mauri260493
Hält's aus hier
Beiträge: 8

Windows 7
RAD Studio 2010
BeitragVerfasst: Fr 29.10.10 18:02 
Hi Leute,

ich möchte eine Fußball Tabelle in meinem Programme erstellen.
Die soll folgendermaßen aussehen:

Screenshot
( Platzierungen sollen erst nach dem sortieren eingefügt werden)

Die Daten speicher ich in einem Array und schreibe sie dann ins StringGrid.

Nun müssen die aber noch sortiert werden.

Nach einer Spalte zu sortieren macht überhaupt kein Problem, aber da bei Punktegleichheit die Tordifferenz bzw. geschossene Tore und kassierte Tore einbezogen werden müssen, gibts da ein Problem. -.-

Habe folgenden Code gefunden:
swissdelphicenter.ch.../showcode.php?id=449

Der funktioniert jedoch nicht. Ich schätze, dass es daran liegt, dass er versucht die Strings zu vergleichen, und nicht die Zahlen.

Wie ich den umschreiben soll, weiß ich aber nicht.

Kann jemand von euch mir helfen?

Danke schonmal. :)

Moderiert von user profile iconNarses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
Bergmann89
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1742
Erhaltene Danke: 72

Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
BeitragVerfasst: Fr 29.10.10 19:44 
Hey,

eigentlich ist es egal, ob den String oder die eigentliche Zahl zum Vergleichen nimmt, weil '0' auch als String kleiner ist als '2'.
Was genau geht denn nicht bei dem Code, den du gefunden hast?
Wie hast du das ganze bei dir eingebunden?

MfG Bergmann.

_________________
Ich weiß nicht viel, lern aber dafür umso schneller^^
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Fr 29.10.10 21:12 
kleine Einstriegshilfe, bitte selbst anpassen
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:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
unit StringridSort;

interface

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

type
  TMy2Compare=Function(Const R1c1,R2c1,R1c2,R2c2:String):Boolean;

  TStringGridX = class(TCustomGrid)
  public
  procedure MoveRow(FromIndex, ToIndex: Longint);
  procedure MoveColumn(FromIndex, ToIndex: Longint);
  procedure DeleteRow(ARow: Longint);
  procedure DeleteColumn(ACol: Longint);
  end;

  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TStringGridX }

procedure TStringGridX.DeleteColumn(ACol: Integer);
begin
inherited;
end;

procedure TStringGridX.DeleteRow(ARow: Integer);
begin
inherited;
end;

procedure TStringGridX.MoveColumn(FromIndex, ToIndex: Integer);
begin
inherited;
end;

procedure TStringGridX.MoveRow(FromIndex, ToIndex: Integer);
begin
inherited;
end;



Function Compare2RowsIamSureTheyAreNumericDesc(Const R1c1,R2c1,R1c2,R2c2:String):Boolean;
begin
  if StrToInt(R1c1)=StrToInt(R2c1) then Result := StrToInt(R1c2)<StrToInt(R2c2)

  else Result:=StrToInt(R1c1)<StrToInt(R2c1);
end;


Function Compare2RowsIamSureTheyAreNumericAsc(Const R1c1,R2c1,R1c2,R2c2:String):Boolean;
begin
  if StrToInt(R1c1)=StrToInt(R2c1) then Result := StrToInt(R1c2)>StrToInt(R2c2)

  else Result:=StrToInt(R1c1)>StrToInt(R2c1);
end;


procedure QuickSortSG2Rows(a:TStringGrid;Column1,Column2:Integer; lo, hi: integer;Compare:TMy2Compare);
var i, j, h: integer;
    s1,s2:String;
begin
  // lo ist der unterste Index, hi ist der oberste Index des
  // zu sortierenden (Teil-)Feldes a
  i:=lo;
  j:=hi;
  s1:=a.Cells[Column1,(lo+hi) div 2];
  s2:=a.Cells[Column2,(lo+hi) div 2];
  //Aufteilung
  while i<=j do
      begin
        While (i<=j) and Compare(s1,a.Cells[Column1,i],s2,a.Cells[Column2,i]) do inc(i);
        While (i<=j) and Compare(a.Cells[Column1,j],s1,a.Cells[Column2,j],s2) do dec(j);
        if (i<=j) then
        begin
          TStringGridX(a).MoveRow (i,j);
          if j-i>1 then TStringGridX(a).MoveRow (j-1,i);
          inc(i); dec(j);
        end;
      end;

  // Rekursion
  if lo<j then QuickSortSG2Rows(a, Column1,Column2, lo, j, Compare);
  if i<hi then QuickSortSG2Rows(a, Column1,Column2, i, hi, Compare);
end;



procedure TForm1.Button1Click(Sender: TObject);
begin
  QuickSortSG2Rows(StringGrid1,1,21, StringGrid1.RowCount - 1 ,Compare2RowsIamSureTheyAreNumericAsc)
end;

end.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 30.10.10 07:48 
Am besten mach es dir ganz einfach und benutze eine TListView. Da brauchst du nur OnCompare zu implementieren, das Sortieren geht komplett automatisch (einfach Sort aufrufen).

Außerdem siehts tausendmal besser aus.
toms
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1099
Erhaltene Danke: 2



BeitragVerfasst: Sa 30.10.10 08:40 
Ersetze AnsiCompareStr durch eine eigene Funktion:

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:
type
  TMoveSG = class(TCustomGrid);

// Zahlen vergleichen
function CompareInt(i1, i2: Integer): Integer;
// Result: -1 if i1 < i2, 1 if i1 > i2, 0 if i1 = i2
begin
  if i1 < i2 then
    Result := -1
  else if i1 > i2 then
    Result := 1
  else
    Result := 0;
end;

// Strings vergleichen
function CompareValues(const S1, S2 : String): Integer;
var
  V1, V2 : Integer;
  C1, C2 : Integer;
begin
  Val(S1, V1, C1);
  Val(S2, V2, C2);
  if (C1 = 0and (C2 = 0then  // Wenn beides Zahlen
     Result := CompareInt(V1, V2)
  else  // sonst wenn String/String od. String/Zahl
     Result := AnsiCompareStr(S1, S2);
end;

procedure SortGridByCols(Grid: TStringGrid; ColOrder: array of Integer; Fixed: Boolean);
var
  I, J, FirstRow: Integer;
  Sorted: Boolean;

  function Sort(Row1, Row2: Integer): Integer;
  var
    C: Integer;
  begin
    C := 0;
    Result := CompareValues(Grid.Cols[ColOrder[C]][Row1], Grid.Cols[ColOrder[C]][Row2]);
    if Result = 0 then
    begin
      Inc(C);
      while (C <= High(ColOrder)) and (Result = 0do
      begin
        Result := CompareValues(Grid.Cols[ColOrder[C]][Row1], Grid.Cols[ColOrder[C]][Row2]);
        Inc(C);
      end;
    end;
  end;

begin
  for I := 0 to High(ColOrder) do
    if (ColOrder[I] < 0or (ColOrder[I] >= Grid.ColCount) then
      Exit;

  if Fixed then
    FirstRow := 0
  else
    FirstRow := Grid.FixedRows;

  J := FirstRow;
  Sorted := True;
  repeat
    Inc(J);
    for I := FirstRow to Grid.RowCount - 2 do
      if Sort(I, I + 1) > 0 then
      begin
        TMoveSG(Grid).MoveRow(i + 1, i);
        Sorted := False;
      end;
  until Sorted or (J >= Grid.RowCount + 1000);
  Grid.Repaint;
end;
mauri260493 Threadstarter
Hält's aus hier
Beiträge: 8

Windows 7
RAD Studio 2010
BeitragVerfasst: Sa 30.10.10 12:29 
Erstmal Danke für eure Mühen :)

Toms Idee funktioniert auch soweit.

Ein Problem hab ich jedoch noch.

Alle Spalten werden aufwärts sortiert.
Eigentlich müsste ich die Punkte abwärts, dann die Tordifferenz abwärts, dann die Tore abwärts und dann die Gegentore aufwärts sortieren.

Kann man das so anpassen?
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Sa 30.10.10 12:47 
wenn Du statt ColOrder: array of Integer
ein Array übergibst vom Typ
TMySortInfo=record
Col:Integer;
asc:Boolean;
end;

kannst Du entweder verschiende Compareroutinen intern aufrufen oder der Compareroutine die Asc -Info durchreichen und intern gegf. mit vertauschten Vorzeichen arbeiten.
mauri260493 Threadstarter
Hält's aus hier
Beiträge: 8

Windows 7
RAD Studio 2010
BeitragVerfasst: Sa 30.10.10 13:45 
Klingt gut, aber ich weiß nicht wie ich die Routine ändern muss/kann :(
toms
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1099
Erhaltene Danke: 2



BeitragVerfasst: Sa 30.10.10 14:17 
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:
95:
96:
97:
98:
99:
100:
101:
102:
type
  TMoveSG = class(TCustomGrid);

type
  TSortInfo = record
    Col: Integer;
    asc: Boolean;
  end;

// Zahlen vergleichen

function CompareInt(i1, i2: Integer): Integer;
// Result: -1 if i1 < i2, 1 if i1 > i2, 0 if i1 = i2
begin
  if i1 < i2 then
    Result := -1
  else if i1 > i2 then
    Result := 1
  else
    Result := 0;
end;

// Werte vergleichen

function CompareValues(const S1, S2: string; Reverse: Boolean): Integer;
var
  V1, V2: Integer;
  C1, C2: Integer;
begin
  Val(S1, V1, C1);
  Val(S2, V2, C2);
  if (C1 = 0and (C2 = 0then // Wenn beides Zahlen
    Result := CompareInt(V1, V2)
  else // sonst wenn String/String od. String/Zahl
    Result := AnsiCompareStr(S1, S2);
  if not Reverse then
    Result := 0 - Result;
end;

procedure SortGridByCols(Grid: TStringGrid; SortInfo: array of TSortInfo;
  Fixed:
  Boolean);
var
  I, J, FirstRow: Integer;
  Sorted: Boolean;

  function Sort(Row1, Row2: Integer): Integer;
  var
    C: Integer;
  begin
    C := 0;
    Result := CompareValues(Grid.Cols[SortInfo[C].Col][Row1],
      Grid.Cols[SortInfo[C].Col][Row2], SortInfo[C].asc);
    if Result = 0 then
    begin
      Inc(C);
      while (C <= High(SortInfo)) and (Result = 0do
      begin
        Result := CompareValues(Grid.Cols[SortInfo[C].Col][Row1],
          Grid.Cols[SortInfo[C].Col][Row2], SortInfo[C].asc);
        Inc(C);
      end;
    end;
  end;

begin
  for I := 0 to High(SortInfo) do
    if (SortInfo[I].Col < 0or (SortInfo[I].Col >= Grid.ColCount) then
      Exit;

  if Fixed then
    FirstRow := 0
  else
    FirstRow := Grid.FixedRows;

  J := FirstRow;
  Sorted := True;
  repeat
    Inc(J);
    for I := FirstRow to Grid.RowCount - 2 do
      if Sort(I, I + 1) > 0 then
      begin
        TMoveSG(Grid).MoveRow(i + 1, i);
        Sorted := False;
      end;
  until Sorted or (J >= Grid.RowCount + 1000);
  Grid.Repaint;
end;



procedure TForm1.Button1Click(Sender: TObject);
const
  MySortInfo: array[0..3of TSortInfo =
    ((col: 1; asc: True),
    (col: 2; asc: True),
    (col: 3; asc: True),
    (col: 4; asc: False)
    );
begin
  SortGridByCols(StringGrid1, MySortInfo, true);
end;


Zuletzt bearbeitet von toms am Sa 30.10.10 14:35, insgesamt 1-mal bearbeitet
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Sa 30.10.10 14:24 
ich lehne mich mal an toms Code an

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:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
type
  TMoveSG = class(TCustomGrid);
  TSortInfo=Record
    col:Integer;
    asc:Boolean;
  End;

// Zahlen vergleichen
function CompareInt(i1, i2: Integer): Integer;
// Result: -1 if i1 < i2, 1 if i1 > i2, 0 if i1 = i2
begin
  if i1 < i2 then
    Result := -1
  else if i1 > i2 then
    Result := 1
  else
    Result := 0;
end;

// Strings vergleichen
function CompareValues(const S1, S2 : String;asc:Boolean): Integer;
var
  V1, V2 : Integer;
  C1, C2 : Integer;
begin
  Val(S1, V1, C1);
  Val(S2, V2, C2);
  if (C1 = 0and (C2 = 0then  // Wenn beides Zahlen
     Result := CompareInt(V1, V2)
  else  // sonst wenn String/String od. String/Zahl
     Result := AnsiCompareStr(S1, S2);
  if not Asc then Result := Result * -1;

end;

procedure SortGridByCols(Grid: TStringGrid; ColOrder: array of TSortInfo; Fixed: Boolean);
var
  I, J, FirstRow: Integer;
  Sorted: Boolean;

  function Sort(Row1, Row2: Integer): Integer;
  var
    C: Integer;
  begin
    C := 0;
    Result := CompareValues(Grid.Cols[ColOrder[C].col][Row1], Grid.Cols[ColOrder[C].col][Row2],ColOrder[C].asc);
    if Result = 0 then
    begin
      Inc(C);
      while (C <= High(ColOrder)) and (Result = 0do
      begin
        Result := CompareValues(Grid.Cols[ColOrder[C].col][Row1], Grid.Cols[ColOrder[C].col][Row2],ColOrder[C].asc);
        Inc(C);
      end;
    end;
  end;

begin
  for I := 0 to High(ColOrder) do
    if (ColOrder[I].col < 0or (ColOrder[I].col >= Grid.ColCount) then
      Exit;

  if Fixed then
    FirstRow := 0
  else
    FirstRow := Grid.FixedRows;

  J := FirstRow;
  Sorted := True;
  repeat
    Inc(J);
    for I := FirstRow to Grid.RowCount - 2 do
      if Sort(I, I + 1) > 0 then
      begin
        TMoveSG(Grid).MoveRow(i + 1, i);
        Sorted := False;
      end;
  until Sorted or (J >= Grid.RowCount + 1000);
  Grid.Repaint;
end;
procedure TForm1.Button1Click(Sender: TObject);
const
  MyArray: array[0..3of TSortInfo =
    ((col: 1; asc: true),
     (col: 2; asc: true),
     (col: 3; asc: true),
     (col: 4; asc: false)
     );
begin
  SortGridByCols(StringGrid1,MyArray,true);
end;

end.
mauri260493 Threadstarter
Hält's aus hier
Beiträge: 8

Windows 7
RAD Studio 2010
BeitragVerfasst: Sa 30.10.10 17:19 
Bummi, du bist meine Rettung.

Funktioniert einwandfrei :)

Vielen vielen Dank an euch alle ;)