Author: Jorge Abel Ayala Marentes
How to insert, delete or sort columns in StringGrids
Answer:
Solve 1:
1
2 procedure GridRemoveColumn(StrGrid: TStringGrid; DelColumn: Integer);
3 var
4 Column: Integer;
5 begin
6 if DelColumn <= StrGrid.ColCount then
7 begin
8 for Column := DelColumn to StrGrid.ColCount - 1 do
9 StrGrid.Cols[Column - 1].Assign(StrGrid.Cols[Column]);
10 StrGrid.ColCount := StrGrid.ColCount - 1;
11 end;
12 end;
13
14 procedure GridAddColumn(StrGrid: TStringGrid; NewColumn: Integer);
15 var
16 Column: Integer;
17 begin
18 StrGrid.ColCount := StrGrid.ColCount + 1;
19 for Column := StrGrid.ColCount - 1 downto NewColumn do
20 StrGrid.Cols[Column].Assign(StrGrid.Cols[Column - 1]);
21 StrGrid.Cols[NewColumn - 1].Text := '';
22 end;
23
24 procedure GridSort(StrGrid: TStringGrid; NoColumn: Integer);
25 var
26 Line, PosActual: Integer;
27 Row: TStrings;
28 begin
29 Renglon := TStringList.Create;
30 for Line := 1 to StrGrid.RowCount - 1 do
31 begin
32 PosActual := Line;
33 Row.Assign(TStringlist(StrGrid.Rows[PosActual]));
34 while True do
35 begin
36 if (PosActual = 0) or (StrToInt(Row.Strings[NoColumn - 1]) >=
37 StrToInt(StrGrid.Cells[NoColumn - 1, PosActual - 1])) then
38 Break;
39 StrGrid.Rows[PosActual] := StrGrid.Rows[PosActual - 1];
40 Dec(PosActual);
41 end;
42 if StrToInt(Row.Strings[NoColumn - 1]) < StrToInt(StrGrid.Cells[NoColumn - 1,
43 PosActual]) then
44 StrGrid.Rows[PosActual] := Row;
45 end;
46 Renglon.Free;
47 end;
Solve 2:
Had a few problems with range errors with the algorythms. On Delete or Add columns
it is desirable to keep the widths of the columns as they are moved. Add column
could also take the width of the new column (or default to DefaultColWidth if
zero). I also had range errors in the Grid sort. On a large grid a Quicksort
routine would be more desirable.
The Quicksort routine could take various sort modes as a parameter eg.
Alpha,Double,Integer etc. (have supported only these 3 in demo, but it's easy to
see how to incorporate more). The quick sort should also take "from row - to row"
as parameters as we normally would not want to sort the header, or just a sub range
may be required to be
sorted.
All in all though, some nice ideas for an extended stringgrid class, couple with
DeleteRow, AddRow, LoadFromQuery etc.
48
49 procedure RemoveColumn(SG: TStringGrid; ColNumber: integer);
50 var
51 Column: integer;
52 begin
53 ColNumber := abs(ColNumber);
54
55 if ColNumber <= SG.ColCount then
56 begin
57 for Column := ColNumber to SG.ColCount - 2 do
58 begin
59 SG.Cols[Column].Assign(SG.Cols[Column + 1]);
60 SG.Colwidths[Column] := SG.Colwidths[Column + 1];
61 end;
62 SG.ColCount := SG.ColCount - 1;
63 end;
64 end;
65
66 procedure AddColumn(SG: TStringGrid; AtColNumber: integer;
67 ColWidth: integer = 0);
68 var
69 Column: integer;
70 Wdth: integer;
71 begin
72 AtColNumber := abs(AtColNumber);
73 SG.ColCount := SG.ColCount + 1;
74 if abs(ColWidth) = 0 then
75 Wdth := SG.DefaultColWidth
76 else
77 Wdth := ColWidth;
78
79 if AtColNumber <= SG.ColCount then
80 begin
81 for Column := SG.ColCount - 1 downto AtColNumber + 1 do
82 begin
83 SG.Cols[Column].Assign(SG.Cols[Column - 1]);
84 SG.Colwidths[Column] := SG.Colwidths[Column - 1];
85 end;
86
87 SG.Cols[AtColNumber].Text := '';
88 SG.Colwidths[AtColNumber] := Wdth;
89 end;
90 end;
Solve 3:
91 type
92 TStringGridExSortType = (srtAlpha, srtInteger, srtDouble);
93
94 procedure GridSort(SG: TStringGrid; ByColNumber, FromRow, ToRow: integer;
95 SortType: TStringGridExSortType = srtAlpha);
96 var
97 Temp: TStringList;
98
99 function SortStr(Line: string): string;
100 var
101 RetVar: string;
102 begin
103 case SortType of
104 srtAlpha: Retvar := Line;
105 srtInteger: Retvar := FormatFloat('000000000', StrToIntDef(trim(Line), 0));
106 srtDouble:
107 try
108 Retvar := FormatFloat('000000000.000000', StrToFloat(trim(Line)));
109 except
110 RetVar := '0.00';
111 end;
112 end;
113
114 Result := RetVar;
115 end;
116
117 // Recursive QuickSort
118 procedure QuickSort(Lo, Hi: integer; CC: TStrings);
119
120 procedure Sort(l, r: integer);
121 var
122 i, j: integer;
123 x: string;
124 begin
125 i := l;
126 j := r;
127 x := SortStr(CC[(l + r) div 2]);
128 repeat
129 while SortStr(CC[i]) < x do
130 inc(i);
131 while x < SortStr(CC[j]) do
132 dec(j);
133 if i <= j then
134 begin
135 Temp.Assign(SG.Rows[j]); // Swap the 2 rows
136 SG.Rows[j].Assign(SG.Rows[i]);
137 SG.Rows[i].Assign(Temp);
138 inc(i);
139 dec(j);
140 end;
141 until i > j;
142 if l < j then
143 sort(l, j);
144 if i < r then
145 sort(i, r);
146 end;
147
148 begin {quicksort}
149 Sort(Lo, Hi);
150 end;
151
152 begin
153 Temp := TStringList.Create;
154 QuickSort(FromRow, ToRow, SG.Cols[ByColNumber]);
155 Temp.Free;
156 end;
|