diff --git a/components/fpspreadsheet/examples/other/demo_sorting.pas b/components/fpspreadsheet/examples/other/demo_sorting.pas
new file mode 100644
index 000000000..1bc158ea4
--- /dev/null
+++ b/components/fpspreadsheet/examples/other/demo_sorting.pas
@@ -0,0 +1,416 @@
+program demo_sorting;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}{$IFDEF UseCThreads}
+ cthreads,
+ {$ENDIF}{$ENDIF}
+ SysUtils, Classes
+ { you can add units after this },
+ TypInfo, fpSpreadsheet, fpsutils;
+
+var
+ workbook: TsWorkbook;
+ worksheet: TsWorksheet;
+ s: String;
+ sortParams: TsSortParams;
+
+ procedure SortSingleColumn;
+ var
+ i: Integer;
+ n: Double;
+ begin
+ WriteLn('Sorting of a single column');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteNumber(0, 0, 10); // A1
+ worksheet.WriteNumber(1, 0, 2); // A2
+ worksheet.WriteNumber(2, 0, 5); // A3
+ worksheet.WriteNumber(3, 0, 1); // A4
+
+ sortParams := InitSortParams(true, 1);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 3, 0);
+
+ WriteLn(#9, 'A');
+ for i:=0 to 3 do
+ begin
+ n := worksheet.ReadAsNumber(i, 0);
+ WriteLn(i, #9, FloatToStr(n));
+ end;
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortSingleRow;
+ var
+ i: Integer;
+ n: Double;
+ begin
+ WriteLn('Sorting of a single row');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteNumber(0, 0, 10); // A1
+ worksheet.WriteNumber(0, 1, 2); // B1
+ worksheet.WriteNumber(0, 2, 5); // C1
+ worksheet.WriteNumber(0, 3, 1); // D1
+
+ sortParams := InitSortParams(false, 1);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 0, 3);
+
+ for i:=0 to 3 do
+ Write(char(ord('A')+i) + '1', #9);
+ WriteLn;
+
+ for i:=0 to 3 do
+ begin
+ n := worksheet.ReadAsNumber(0, i);
+ Write(FloatToStr(n), #9);
+ end;
+ WriteLn;
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortTwoColumns_OneKey;
+ var
+ i: Integer;
+ n1, n2: Double;
+ begin
+ WriteLn('Sorting of two columns using a single key column');
+ WriteLn('(The 2nd column must be the negative of the 1st one)');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteNumber(0, 0, 10); // A1
+ worksheet.WriteNumber(1, 0, 2); // A2
+ worksheet.WriteNumber(2, 0, 5); // A3
+ worksheet.WriteNumber(3, 0, 1); // A4
+
+ worksheet.WriteNumber(0, 1, -10); // B1
+ worksheet.WriteNumber(1, 1, -2); // B2
+ worksheet.WriteNumber(2, 1, -5); // B3
+ worksheet.WriteNumber(3, 1, -1); // B4
+
+ sortParams := InitSortParams(true, 1);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 3, 1);
+
+ WriteLn(#9, 'A', #9, 'B');
+ for i:=0 to 3 do
+ begin
+ n1 := worksheet.ReadAsNumber(i, 0);
+ n2 := worksheet.ReadAsNumber(i, 1);
+ WriteLn(i, #9, FloatToStr(n1), #9, FloatToStr(n2));
+ end;
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortTwoRows_OneKey;
+ var
+ i: Integer;
+ n1, n2: Double;
+ begin
+ WriteLn('Sorting of two rows using a single key column');
+ WriteLn('(The 2nd row must be the negative of 1st row)');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteNumber(0, 0, 10); // A1
+ worksheet.WriteNumber(0, 1, 2); // B1
+ worksheet.WriteNumber(0, 2, 5); // C1
+ worksheet.WriteNumber(0, 3, 1); // D1
+
+ worksheet.WriteNumber(1, 0, -10); // A2
+ worksheet.WriteNumber(1, 1, -2); // B2
+ worksheet.WriteNumber(1, 2, -5); // C2
+ worksheet.WriteNumber(1, 3, -1); // D2
+
+ sortParams := InitSortParams(false, 1);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 1, 3);
+
+ Write(#9);
+ for i:=0 to 3 do
+ Write(char(ord('A')+i) + '1', #9);
+ WriteLn;
+
+ Write('1', #9);
+ for i:=0 to 3 do begin
+ n1 := worksheet.ReadAsNumber(0, i);
+ Write(FloatToStr(n1), #9);
+ end;
+ WriteLn;
+
+ Write('2', #9);
+ for i:=0 to 3 do begin
+ n1 := worksheet.ReadAsNumber(1, i);
+ Write(FloatToStr(n1), #9);
+ end;
+ WriteLn;
+
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortTwoColumns_TwoKeys;
+ var
+ i: Integer;
+ n1, n2: Double;
+ begin
+ WriteLn('Sorting of two columns on column "A" and "B"');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteNumber(0, 0, 10); // A1
+ worksheet.WriteNumber(1, 0, 1); // A2
+ worksheet.WriteNumber(2, 0, 1); // A3
+ worksheet.WriteNumber(3, 0, 1); // A4
+
+ worksheet.WriteNumber(0, 1, -10); // B1
+ worksheet.WriteNumber(1, 1, -2); // B2
+ worksheet.WriteNumber(2, 1, -5); // B3
+ worksheet.WriteNumber(3, 1, -1); // B4
+
+ sortParams := InitSortParams(true, 2);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+ sortParams.Keys[1].ColRowIndex := 1;
+ sortParams.Keys[1].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 3, 1);
+
+ WriteLn(#9, 'A', #9, 'B');
+ for i:=0 to 3 do
+ begin
+ n1 := worksheet.ReadAsNumber(i, 0);
+ n2 := worksheet.ReadAsNumber(i, 1);
+ WriteLn(i, #9, FloatToStr(n1), #9, FloatToStr(n2));
+ end;
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortTwoRows_TwoKeys;
+ var
+ i: Integer;
+ n1, n2: Double;
+ begin
+ WriteLn('Sorting of two rows on row "1" and "2"');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteNumber(0, 0, 10); // A1
+ worksheet.WriteNumber(0, 1, 1); // B1
+ worksheet.WriteNumber(0, 2, 1); // C1
+ worksheet.WriteNumber(0, 3, 1); // D1
+
+ worksheet.WriteNumber(1, 0, -10); // A2
+ worksheet.WriteNumber(1, 1, -2); // B2
+ worksheet.WriteNumber(1, 2, -5); // C2
+ worksheet.WriteNumber(1, 3, -1); // D2
+
+ sortParams := InitSortParams(false, 2);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+ sortParams.Keys[1].ColRowIndex := 1;
+ sortParams.Keys[1].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 1, 3);
+
+ Write(#9);
+ for i:=0 to 3 do
+ Write(char(ord('A')+i) + '1', #9);
+ WriteLn;
+
+ Write('1', #9);
+ for i:=0 to 3 do begin
+ n1 := worksheet.ReadAsNumber(0, i);
+ Write(FloatToStr(n1), #9);
+ end;
+ WriteLn;
+
+ Write('2', #9);
+ for i:=0 to 3 do begin
+ n1 := worksheet.ReadAsNumber(1, i);
+ Write(FloatToStr(n1), #9);
+ end;
+ WriteLn;
+
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortTwoColumns_TwoKeys_1;
+ var
+ i: Integer;
+ n: Double;
+ s: String;
+ begin
+ WriteLn('Sorting of two columns on column "A" and "B"');
+ WriteLn('(Expecting an ascending columns of characters and numbers)');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteUTF8Text(0, 0, 'E');
+ worksheet.WriteUTF8Text(1, 0, 'E');
+ worksheet.WriteUTF8Text(2, 0, 'C');
+ worksheet.WriteUTF8Text(3, 0, 'B');
+ worksheet.WriteUTF8Text(4, 0, 'D');
+ worksheet.WriteUTF8Text(5, 0, 'D');
+ worksheet.WriteUTF8Text(6, 0, 'A');
+ worksheet.WriteUTF8Text(7, 0, 'B');
+ worksheet.WriteUTF8Text(8, 0, 'C');
+ worksheet.WriteUTF8Text(9, 0, 'A');
+
+ worksheet.WriteNumber(0, 1, 9); // A2 --> E
+ worksheet.WriteNumber(1, 1, 8); // B2 --> E
+ worksheet.WriteNumber(2, 1, 5); // C2 --> C
+ worksheet.WriteNumber(3, 1, 2); // D2 --> B
+ worksheet.WriteNumber(4, 1, 6); // E2 --> D
+ worksheet.WriteNumber(5, 1, 7); // F2 --> D
+ worksheet.WriteNumber(6, 1, 1); // G2 --> A
+ worksheet.WriteNumber(7, 1, 3); // H2 --> B
+ worksheet.WriteNumber(8, 1, 4); // I2 --> C
+ worksheet.WriteNumber(9, 1, 0); // J2 --> A
+
+ sortParams := InitSortParams(true, 2);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+ sortParams.Keys[1].ColRowIndex := 1;
+ sortParams.Keys[1].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 9, 1);
+
+ WriteLn(#9, 'A', #9, 'B');
+ for i:=0 to 9 do
+ begin
+ s := worksheet.ReadAsUTF8Text(i, 0);
+ n := worksheet.ReadAsNumber(i, 1);
+ WriteLn(i, #9, s, #9, FloatToStr(n));
+ end;
+
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+ procedure SortTwoRows_TwoKeys_1;
+ var
+ i: Integer;
+ n1, n2: Double;
+ begin
+ WriteLn('Sorting of two rows on row "1" and "2"');
+ WriteLn('(Expecting an ascending row of numbers)');
+ workbook := TsWorkbook.Create;
+ try
+ worksheet := workbook.AddWorksheet('Test');
+
+ worksheet.WriteUTF8Text(0, 0, 'E');
+ worksheet.WriteUTF8Text(0, 1, 'E');
+ worksheet.WriteUTF8Text(0, 2, 'C');
+ worksheet.WriteUTF8Text(0, 3, 'B');
+ worksheet.WriteUTF8Text(0, 4, 'D');
+ worksheet.WriteUTF8Text(0, 5, 'D');
+ worksheet.WriteUTF8Text(0, 6, 'A');
+ worksheet.WriteUTF8Text(0, 7, 'B');
+ worksheet.WriteUTF8Text(0, 8, 'C');
+ worksheet.WriteUTF8Text(0, 9, 'A');
+
+ worksheet.WriteNumber(1, 0, 9); // A2 --> E
+ worksheet.WriteNumber(1, 1, 8); // B2 --> E
+ worksheet.WriteNumber(1, 2, 5); // C2 --> C
+ worksheet.WriteNumber(1, 3, 2); // D2 --> B
+ worksheet.WriteNumber(1, 4, 6); // E2 --> D
+ worksheet.WriteNumber(1, 5, 7); // F2 --> D
+ worksheet.WriteNumber(1, 6, 1); // G2 --> A
+ worksheet.WriteNumber(1, 7, 3); // H2 --> B
+ worksheet.WriteNumber(1, 8, 4); // I2 --> C
+ worksheet.WriteNumber(1, 9, 0); // J2 --> A
+
+ sortParams := InitSortParams(false, 2);
+ sortParams.Keys[0].ColRowIndex := 0;
+ sortParams.Keys[0].Order := ssoAscending;
+ sortParams.Keys[1].ColRowIndex := 1;
+ sortParams.Keys[1].Order := ssoAscending;
+
+ worksheet.Sort(sortParams, 0, 0, 1, 9);
+
+ Write(#9);
+ for i:=0 to 9 do
+ Write(char(ord('A')+i) + '1', #9);
+ WriteLn;
+
+ Write('1', #9);
+ for i:=0 to 9 do
+ Write(worksheet.ReadAsUTF8Text(0, i), #9);
+ WriteLn;
+
+ Write('2', #9);
+ for i:=0 to 9 do begin
+ n1 := worksheet.ReadAsNumber(1, i);
+ Write(FloatToStr(n1), #9);
+ end;
+ WriteLn;
+
+ WriteLn;
+
+ finally
+ workbook.Free;
+ end;
+ end;
+
+begin
+ SortSingleColumn;
+ SortSingleRow;
+
+ SortTwoColumns_OneKey;
+ SortTwoRows_OneKey;
+
+ SortTwoColumns_TwoKeys;
+ SortTwoRows_TwoKeys;
+
+ SortTwoColumns_TwoKeys_1;
+ SortTwoRows_TwoKeys_1;
+end.
+
diff --git a/components/fpspreadsheet/fpsexprparser.pas b/components/fpspreadsheet/fpsexprparser.pas
index 5348c8bfa..2e5e8cddc 100644
--- a/components/fpspreadsheet/fpsexprparser.pas
+++ b/components/fpspreadsheet/fpsexprparser.pas
@@ -822,6 +822,9 @@ procedure RegisterFunction(const AName: ShortString; const AResultType: Char;
procedure RegisterFunction(const AName: ShortString; const AResultType: Char;
const AParamTypes: String; const AExcelCode: Integer; ACallBack: TsExprFunctionEvent); overload;
+var
+ ExprFormatSettings: TFormatSettings;
+
const
AllBuiltIns = [bcMath, bcStatistics, bcStrings, bcLogical, bcDateTime, bcLookup,
bcInfo, bcUser];
@@ -830,7 +833,7 @@ const
implementation
uses
- typinfo, math, lazutf8, dateutils, fpsutils, fpsfunc;
+ typinfo, math, lazutf8, dateutils, fpsutils; //, fpsfunc;
const
cNull = #0;
@@ -4255,7 +4258,7 @@ initialization
ExprFormatSettings.DecimalSeparator := '.';
ExprFormatSettings.ListSeparator := ',';
- RegisterStdBuiltins(BuiltinIdentifiers);
+// RegisterStdBuiltins(BuiltinIdentifiers);
finalization
FreeBuiltins;
diff --git a/components/fpspreadsheet/fpsfunc.pas b/components/fpspreadsheet/fpsfunc.pas
index 60aebdcfd..da74ddbe3 100644
--- a/components/fpspreadsheet/fpsfunc.pas
+++ b/components/fpspreadsheet/fpsfunc.pas
@@ -9,10 +9,7 @@ unit fpsfunc;
interface
uses
- Classes, SysUtils, fpspreadsheet, fpsExprParser;
-
-var
- ExprFormatSettings: TFormatSettings;
+ Classes, SysUtils, fpspreadsheet, fpsexprparser;
procedure RegisterStdBuiltins(AManager : TsBuiltInExpressionManager);
@@ -1895,5 +1892,6 @@ end;
*)
initialization
+ RegisterStdBuiltins(BuiltinIdentifiers);
end.
diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas
index 93d3bb8bd..38db9d5b2 100755
--- a/components/fpspreadsheet/fpspreadsheet.pas
+++ b/components/fpspreadsheet/fpspreadsheet.pas
@@ -3341,11 +3341,87 @@ procedure TsWorksheet.Sort(const ASortParams: TsSortParams;
repeat
I := L;
J := R;
- P := (L+R) div 2;
+ P := (L + R) div 2;
repeat
+ { original code from "grids.pas":
+
+ if ColSorting then begin
+ while DoCompareCells(index, P, index, I)>0 do I:=I+1;
+ while DoCompareCells(index, P, index, J)<0 do J:=J-1;
+ end else begin
+ while DoCompareCells(P, index, I, index)>0 do I:=I+1;
+ while DoCompareCells(P, index, J, index)<0 do J:=J-1;
+ end; }
+
if ASortParams.SortByCols then
begin
+ (*
// Sorting by columns
+ // The next "while" loop corresponds to grid's:
+ // while DoCompareCells(index, P, index, I) > 0 do I:=I+1;
+ while true do
+ begin
+ cell1 := FindCell(P, ASortParams.Keys[0].ColRowIndex);
+ cell2 := FindCell(I, ASortParams.Keys[0].ColRowIndex);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[0].Order);
+ if compareResult < 0 then
+ break
+ else
+ if compareResult > 0 then
+ inc(I)
+ else
+ begin
+ // equal --> check next condition
+ K := 1;
+ while (K <= High(ASortParams.Keys)) do
+ begin
+ cell1 := FindCell(P, ASortParams.Keys[K].ColRowIndex);
+ cell2 := FindCell(I, ASortParams.Keys[K].ColRowIndex);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[K].Order);
+ if compareResult < 0 then
+ break
+ else
+ if compareResult > 0 then begin
+ inc(I);
+ break;
+ end else
+ inc(K); // Still equal --> try next condition
+ end;
+ if compareResult <= 0 then
+ break;
+ end;
+ end;
+
+ // The next "while" loop corresponds to grid's:
+ // while DoCompareCells(index, P, index, J)<0 do J:=J-1;
+ while true do
+ begin
+ cell1 := FindCell(P, ASortParams.Keys[0].ColRowIndex);
+ cell2 := FindCell(J, ASortParams.Keys[0].ColRowIndex);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[0].Order);
+ if compareResult < 0 then
+ dec(J)
+ else
+ if compareResult > 0 then
+ break
+ else begin // equal --> check next condition
+ K := 1;
+ while (K <= High(ASortParams.Keys)) do
+ begin
+ cell1 := FindCell(P, ASortParams.Keys[K].ColRowIndex);
+ cell2 := FindCell(J, ASortParams.Keys[K].ColRowIndex);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[K].Order);
+ case abs(compareResult) of
+ -1: begin dec(J); break; end;
+ +1: break;
+ 0: inc(K);
+ end;
+ end;
+ if compareResult >= 0 then
+ break;
+ end;
+ end;
+ *)
K := 0;
while true do
begin
@@ -3355,9 +3431,10 @@ procedure TsWorksheet.Sort(const ASortParams: TsSortParams;
case sign(compareResult) of
-1: break;
0: if K <= High(ASortParams.Keys) then inc(K) else break;
- +1: inc(I);
+ +1: begin inc(I); K:= 0; end;
end;
end;
+
K := 0;
while true do
begin
@@ -3365,7 +3442,7 @@ procedure TsWorksheet.Sort(const ASortParams: TsSortParams;
cell2 := FindCell(J, ASortParams.Keys[K].ColRowIndex);
compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[K].Order);
case sign(compareResult) of
- -1: dec(J);
+ -1: begin dec(J); K := 0; end;
0: if K <= High(ASortParams.Keys) then inc(K) else break;
+1: break;
end;
@@ -3382,7 +3459,7 @@ procedure TsWorksheet.Sort(const ASortParams: TsSortParams;
case sign(compareResult) of
-1: break;
0: if K <= High(ASortParams.Keys) then inc(K) else break;
- +1: inc(I);
+ +1: begin inc(I); if K > 0 then K := 0; end;
end;
end;
K := 0;
@@ -3392,11 +3469,65 @@ procedure TsWorksheet.Sort(const ASortParams: TsSortParams;
cell2 := FindCell(ASortParams.Keys[K].ColRowIndex, J);
compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[K].Order);
case sign(compareResult) of
- -1: dec(J);
+ -1: begin dec(J); if K > 0 then K := 0; end;
0: if K <= High(ASortParams.Keys) then inc(K) else break;
+1: break;
end;
end;
+ (*
+ while true do
+ begin
+ cell1 := FindCell(ASortParams.Keys[0].ColRowIndex, P);
+ cell2 := FindCell(ASortParams.Keys[0].ColRowIndex, I);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[0].Order);
+ case sign(compareresult) of
+ -1: break;
+ +1: inc(I);
+ 0: begin
+ K := 1;
+ while (compareResult=0) and (K <= High(ASortParams.Keys)) do
+ begin
+ cell1 := FindCell(ASortParams.Keys[K].ColRowIndex, P);
+ cell2 := FindCell(ASortParams.Keys[K].ColRowIndex, I);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[K].Order);
+ if compareResult = 0 then
+ continue
+ else begin
+ if compareresult > 0 then inc(I);
+ break;
+ end;
+ end;
+ if compareResult < 0 then break;
+ end;
+ end;
+ end;
+ while true do
+ begin
+ cell1 := FindCell(ASortParams.Keys[0].ColRowIndex, P);
+ cell2 := FindCell(ASortParams.Keys[0].ColRowIndex, J);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[0].Order);
+ case sign(compareResult) of
+ -1: dec(J);
+ +1: break;
+ 0: begin
+ K := 1;
+ while (compareResult=0) and (K <= High(ASortParams.Keys)) do
+ begin
+ cell1 := FindCell(ASortParams.Keys[0].ColRowIndex, P);
+ cell2 := FindCell(ASortParams.Keys[0].ColRowIndex, J);
+ compareResult := DoCompareCells(cell1, cell2, ASortParams.Keys[K].Order);
+ if compareResult = 0 then
+ continue
+ else begin
+ if compareResult < 0 then dec(J);
+ break;
+ end;
+ end;
+ if compareResult > 0 then break;
+ end;
+ end;
+ end;
+ *)
end;
if I <= J then
diff --git a/components/fpspreadsheet/tests/sortingtests.pas b/components/fpspreadsheet/tests/sortingtests.pas
index e634649b9..c0b5219b2 100644
--- a/components/fpspreadsheet/tests/sortingtests.pas
+++ b/components/fpspreadsheet/tests/sortingtests.pas
@@ -272,8 +272,10 @@ var
begin
sortParams := InitSortParams(ASortByCols, 2);
- sortParams.Keys[0].ColRowIndex := 0;
- sortParams.Keys[1].ColRowIndex := 1;
+ sortParams.Keys[0].ColRowIndex := 0; // col/row 0 is primary key
+ sortParams.Keys[1].ColRowIndex := 1; // col/row 1 is second key
+
+ iLast := High(SollSortNumbers);
TempFile := GetTempFileName;
@@ -285,18 +287,22 @@ begin
row := 0;
if ASortByCols then
begin
- // Always 2 numbers in the first column are equal
- for i:=0 to High(SollSortNumbers) do
- MyWorksheet.WriteNumber(i, col, SollSortNumbers[(i mod 2)*2]);
- // All strings in the second column are distinct
- for i:=0 to High(SollSortStrings) do
- MyWorksheet.WriteUTF8Text(i, col+1, SollSortStrings[i]);
+ // Write all randomized numbers to column B
+ for i:=0 to iLast do
+ MyWorksheet.WriteNumber(i, col+1, SollSortNumbers[i]);
+ // divide each number by 2 and calculate the character assigned to it
+ // and write it to column A
+ // We will sort primarily according to column A, and seconarily according
+ // to B. The construction allows us to determine if the sorting is correct.
+ for i:=0 to iLast do
+ MyWorksheet.WriteUTF8Text(i, col, char(ord('A')+round(SollSortNumbers[i div 2])));
end else
begin
- for i:=0 to High(SollSortNumbers) do
- MyWorksheet.WriteNumber(row, i, SollSortNumbers[(i mod 2)*2]);
- for i:=0 to High(SollSortStrings) do
- MyWorksheet.WriteUTF8Text(row+1, i, SollSortStrings[i]);
+ // The same with the rows...
+ for i:=0 to iLast do
+ MyWorksheet.WriteNumber(row+1, i+1, SollSortNumbers[i]);
+ for i:=0 to iLast do
+ MyWorksheet.WriteUTF8Text(row, i, char(ord('A')+round(SollSortNumbers[i div 2])));
end;
MyWorkBook.WriteToFile(TempFile, AFormat, true);
@@ -319,7 +325,6 @@ begin
fail('Error in test code. Failed to get named worksheet');
// ... and sort it.
- iLast := High(SollSortNumbers); //must be the same as for SollSortStrings
r1 := 0; c1 := 0;
if ASortByCols then begin
c2 := 1;
@@ -338,31 +343,44 @@ begin
for i:=0 to iLast do
begin
- row := 0;
- col := 0;
if ASortByCols then
+ begin
+ // Read the number first, they must be in order 0...9 (if ascending).
+ col := 1;
case sortDir of
ssoAscending : row := i;
ssoDescending: row := iLast - i;
- end
- else
+ end;
+ actualNumber := MyWorksheet.ReadAsNumber(row, col); // col B is the number, must be 0...9 here
+ expectedNumber := i;
+ CheckEquals(expectednumber, actualnumber,
+ 'Sorted cell number mismatch, cell '+CellNotation(MyWorksheet, row, col));
+
+ // Now read the string. It must be the character corresponding to the
+ // half of the number
+ col := 0;
+ actualString := MyWorksheet.ReadAsUTF8Text(row, col);
+ expectedString := char(ord('A') + round(expectedNumber) div 2);
+ CheckEquals(expectedstring, actualstring,
+ 'Sorted cell string mismatch, cell '+CellNotation(MyWorksheet, row, col));
+ end else
+ begin
+ row := 1;
case sortDir of
ssoAscending : col := i;
ssoDescending: col := iLast - i;
end;
- actualNumber := MyWorksheet.ReadAsNumber(row, col);
- expectedNumber := (i mod 2) * 2;
- CheckEquals(expectednumber, actualnumber,
- 'Sorted cell number mismatch, cell '+CellNotation(MyWorksheet, row, col));
+ actualNumber := MyWorksheet.ReadAsNumber(row, col);
+ expectedNumber := i;
+ CheckEquals(expectednumber, actualnumber,
+ 'Sorted cell number mismatch, cell '+CellNotation(MyWorksheet, row, col));
- if ASortByCols then
- inc(col)
- else
- inc(row);
- actualString := MyWorksheet.ReadAsUTF8Text(row, col);
- expectedString := char(ord('A') + i);
- CheckEquals(expectedstring, actualstring,
- 'Sorted cell string mismatch, cell '+CellNotation(MyWorksheet, row, col));
+ row := 0;
+ actualstring := MyWorksheet.ReadAsUTF8Text(row, col);
+ expectedString := char(ord('A') + round(expectedNumber) div 2);
+ CheckEquals(expectedstring, actualstring,
+ 'Sorted cell string mismatch, cell '+CellNotation(MyWorksheet, row, col));
+ end;
end;
finally
MyWorkbook.Free;
diff --git a/components/fpspreadsheet/tests/spreadtestgui.lpi b/components/fpspreadsheet/tests/spreadtestgui.lpi
index fc62e2c66..fe7e6b7c0 100644
--- a/components/fpspreadsheet/tests/spreadtestgui.lpi
+++ b/components/fpspreadsheet/tests/spreadtestgui.lpi
@@ -48,7 +48,6 @@
-
@@ -76,6 +75,7 @@
+
@@ -84,6 +84,7 @@
+
@@ -96,6 +97,7 @@
+
@@ -105,6 +107,7 @@
+