You've already forked lazarus-ccr
fpspreadsheet: Add test cases for insert/delete rows into worksheets containing formulas. Issues remaining when cells referred to by the formula are deleted. Add detection of error values to the formula scanner.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3581 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -41,7 +41,8 @@ begin
|
||||
//cell := Worksheet.WriteFormula(1, 0, 'Day(Date(2014, 1, 12))');
|
||||
//cell := Worksheet.WriteFormula(1, 0, 'SUM(1,2,3)');
|
||||
//cell := Worksheet.WriteFormula(1, 0, 'CELL("address",A1)');
|
||||
cell := Worksheet.WriteFormula(1, 0, 'REPT("Hallo", 3)');
|
||||
// cell := Worksheet.WriteFormula(1, 0, 'REPT("Hallo", 3)');
|
||||
cell := Worksheet.WriteFormula(1, 0, '#REF!');
|
||||
|
||||
WriteLn('A1: ', worksheet.ReadAsUTF8Text(0, 0));
|
||||
WriteLn('B1: ', worksheet.ReadAsUTF8Text(0, 1));
|
||||
@ -76,6 +77,7 @@ begin
|
||||
fekInteger : Write(' / integer value: ', IntToStr(formula[i].IntValue));
|
||||
fekString : Write(' / string value: "', formula[i].StringValue, '"');
|
||||
fekBool : Write(' / boolean value: ', BoolToStr(formula[i].DoubleValue <> 0, true));
|
||||
fekErr : Write(' / error value: ', GetErrorValueStr(TsErrorValue(formula[i].IntValue)));
|
||||
end;
|
||||
WriteLn;
|
||||
end;
|
||||
|
@ -57,20 +57,11 @@ uses
|
||||
type
|
||||
{ Tokens }
|
||||
|
||||
(* { Basic operands }
|
||||
fekCell, fekCellRef, fekCellRange, fekCellOffset, fekNum, fekInteger,
|
||||
fekString, fekBool, fekErr, fekMissingArg,
|
||||
{ Basic operations }
|
||||
fekAdd, fekSub, fekMul, fekDiv, fekPercent, fekPower, fekUMinus, fekUPlus,
|
||||
fekConcat, // string concatenation
|
||||
fekEqual, fekGreater, fekGreaterEqual, fekLess, fekLessEqual, fekNotEqual,
|
||||
fekParen,
|
||||
*)
|
||||
TsTokenType = (
|
||||
ttCell, ttCellRange, ttNumber, ttString, ttIdentifier,
|
||||
ttPlus, ttMinus, ttMul, ttDiv, ttConcat, ttPercent, ttPower, ttLeft, ttRight,
|
||||
ttLessThan, ttLargerThan, ttEqual, ttNotEqual, ttLessThanEqual, ttLargerThanEqual,
|
||||
ttListSep, ttTrue, ttFalse, ttEOF
|
||||
ttListSep, ttTrue, ttFalse, ttError, ttEOF
|
||||
);
|
||||
|
||||
TsExprFloat = Double;
|
||||
@ -409,7 +400,8 @@ type
|
||||
constructor CreateDateTime(AParser: TsExpressionParser; AValue: TDateTime);
|
||||
constructor CreateFloat(AParser: TsExpressionParser; AValue: TsExprFloat);
|
||||
constructor CreateBoolean(AParser: TsExpressionParser; AValue: Boolean);
|
||||
constructor CreateError(AParser: TsExpressionParser; AValue: TsErrorValue);
|
||||
constructor CreateError(AParser: TsExpressionParser; AValue: TsErrorValue); overload;
|
||||
constructor CreateError(AParser: TsExpressionParser; AValue: String); overload;
|
||||
function AsString: string; override;
|
||||
function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
|
||||
function NodeType : TsResultType; override;
|
||||
@ -653,6 +645,7 @@ type
|
||||
procedure ScanError(Msg: String);
|
||||
protected
|
||||
procedure SetSource(const AValue: String); virtual;
|
||||
function DoError: TsTokenType;
|
||||
function DoIdentifier: TsTokenType;
|
||||
function DoNumber: TsTokenType;
|
||||
function DoDelimiter: TsTokenType;
|
||||
@ -842,6 +835,7 @@ uses
|
||||
const
|
||||
cNull = #0;
|
||||
cDoubleQuote = '"';
|
||||
cError = '#';
|
||||
|
||||
Digits = ['0'..'9']; // + decimalseparator
|
||||
WhiteSpace = [' ', #13, #10, #9];
|
||||
@ -998,6 +992,21 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TsExpressionScanner.DoError: TsTokenType;
|
||||
var
|
||||
C: Char;
|
||||
s: String;
|
||||
begin
|
||||
C := CurrentChar;
|
||||
while (not IsWordDelim(C)) and (C <> cNull) do
|
||||
begin
|
||||
FToken := FToken + C;
|
||||
C := NextPos;
|
||||
end;
|
||||
S := UpperCase(Token);
|
||||
Result := ttError;
|
||||
end;
|
||||
|
||||
function TsExpressionScanner.DoIdentifier: TsTokenType;
|
||||
var
|
||||
C: Char;
|
||||
@ -1137,6 +1146,8 @@ begin
|
||||
Result := DoString
|
||||
else if IsDigit(C) then
|
||||
Result := DoNumber
|
||||
else if (C = cError) then
|
||||
Result := DoError
|
||||
else if IsAlpha(C) or (C = '$') then
|
||||
Result := DoIdentifier
|
||||
else
|
||||
@ -1662,6 +1673,8 @@ begin
|
||||
Result := TsCellExprNode.Create(self, FWorksheet, CurrentToken)
|
||||
else if (TokenType = ttCellRange) then
|
||||
Result := TsCellRangeExprNode.Create(self, FWorksheet, CurrentToken)
|
||||
else if (TokenType = ttError) then
|
||||
Result := tsConstExprNode.CreateError(self, CurrentToken)
|
||||
else if not (TokenType in [ttIdentifier]) then
|
||||
ParserError(Format(SerrUnknownTokenAtPos, [Scanner.Pos, CurrentToken]))
|
||||
else
|
||||
@ -2648,6 +2661,28 @@ begin
|
||||
FValue.ResError := AValue;
|
||||
end;
|
||||
|
||||
constructor TsConstExprNode.CreateError(AParser: TsExpressionParser;
|
||||
AValue: String);
|
||||
var
|
||||
err: TsErrorValue;
|
||||
begin
|
||||
if AValue = '#NULL!' then
|
||||
err := errEmptyIntersection
|
||||
else if AValue = '#DIV/0!' then
|
||||
err := errDivideByZero
|
||||
else if AValue = '#VALUE!' then
|
||||
err := errWrongType
|
||||
else if AVAlue = '#REF!' then
|
||||
err := errIllegalRef
|
||||
else if AVAlue = '#NAME?' then
|
||||
err := errWrongName
|
||||
else if AValue = '#FORMULA?' then
|
||||
err := errFormulaNotSupported
|
||||
else
|
||||
AParser.ParserError('Unknown error type.');
|
||||
CreateError(AParser, err);
|
||||
end;
|
||||
|
||||
procedure TsConstExprNode.Check;
|
||||
begin
|
||||
// Nothing to check;
|
||||
@ -2671,6 +2706,7 @@ begin
|
||||
rtDateTime : Result := '''' + FormatDateTime('cccc', FValue.ResDateTime, Parser.FFormatSettings) + ''''; // Probably wrong !!!
|
||||
rtBoolean : if FValue.ResBoolean then Result := 'TRUE' else Result := 'FALSE';
|
||||
rtFloat : Result := FloatToStr(FValue.ResFloat, Parser.FFormatSettings);
|
||||
rtError : Result := GetErrorValueStr(FValue.ResError);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -2682,6 +2718,7 @@ begin
|
||||
rtDateTime : Result := RPNNumber(FValue.ResDateTime, ANext);
|
||||
rtBoolean : Result := RPNBool(FValue.ResBoolean, ANext);
|
||||
rtFloat : Result := RPNNumber(FValue.ResFloat, ANext);
|
||||
rtError : Result := RPNErr(ord(FValue.ResError), ANext);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -5068,9 +5068,13 @@ var
|
||||
r, c, rr, cc: Cardinal;
|
||||
r1, c1, r2, c2: Cardinal;
|
||||
cell, nextcell, basecell: PCell;
|
||||
lastCol, lastRow: Cardinal;
|
||||
begin
|
||||
lastCol := GetLastColIndex;
|
||||
lastRow := GetLastOccupiedRowIndex;
|
||||
|
||||
// Loop along the column to be deleted and fix merged cells and shared formulas
|
||||
for r := 0 to GetLastRowIndex do
|
||||
for r := 0 to lastRow do
|
||||
begin
|
||||
cell := FindCell(r, ACol);
|
||||
|
||||
@ -5099,8 +5103,8 @@ begin
|
||||
// Write adapted formula to the cell below.
|
||||
WriteFormula(nextcell, basecell^.Formulavalue); //ReadFormulaAsString(nextcell));
|
||||
// Have all cells sharing the formula use the new formula base
|
||||
for rr := r to GetLastOccupiedRowIndex do
|
||||
for cc := ACol+1 to GetLastOccupiedColIndex do
|
||||
for rr := r to lastRow do
|
||||
for cc := ACol+1 to lastCol do
|
||||
begin
|
||||
cell := FindCell(rr, cc);
|
||||
if (cell <> nil) and (cell^.SharedFormulaBase = basecell) then
|
||||
@ -5112,7 +5116,7 @@ begin
|
||||
end;
|
||||
|
||||
// Delete cells
|
||||
for r := GetLastRowIndex downto 0 do
|
||||
for r := lastRow downto 0 do
|
||||
RemoveCell(r, ACol);
|
||||
|
||||
// Update column index of cell records
|
||||
|
@ -23,6 +23,7 @@ type
|
||||
DeleteCol: Integer;
|
||||
DeleteRow: Integer;
|
||||
Formula: String;
|
||||
SollFormula: String;
|
||||
SharedFormulaRowCount: Integer;
|
||||
SharedFormulaColCount: Integer;
|
||||
MergedColCount: Integer;
|
||||
@ -31,7 +32,7 @@ type
|
||||
end;
|
||||
|
||||
var
|
||||
InsDelTestData: array[0..5] of TInsDelTestDataItem;
|
||||
InsDelTestData: array[0..21] of TInsDelTestDataItem;
|
||||
|
||||
procedure InitTestData;
|
||||
|
||||
@ -54,6 +55,30 @@ type
|
||||
procedure TestWriteRead_InsDelColRow_3; // first
|
||||
procedure TestWriteRead_InsDelColRow_4; // middle
|
||||
procedure TestWriteRead_InsDelColRow_5; // last
|
||||
// Writes out simple cell layout and inserts rows
|
||||
procedure TestWriteRead_InsDelColRow_6; // before first
|
||||
procedure TestWriteRead_InsDelColRow_7; // middle
|
||||
procedure TestWriteRead_InsDelColRow_8; // before last
|
||||
// Writes out simple cell layout and deletes rows
|
||||
procedure TestWriteRead_InsDelColRow_9; // first
|
||||
procedure TestWriteRead_InsDelColRow_10; // middle
|
||||
procedure TestWriteRead_InsDelColRow_11; // last
|
||||
|
||||
// Writes out cell layout with formula and inserts columns
|
||||
procedure TestWriteRead_InsDelColRow_12; // before formula cell
|
||||
procedure TestWriteRead_InsDelColRow_13; // after formula cell
|
||||
// Writes out cell layout with formula and inserts rows
|
||||
procedure TestWriteRead_InsDelColRow_14; // before formula cell
|
||||
procedure TestWriteRead_InsDelColRow_15; // after formula cell
|
||||
// Writes out cell layout with formula and deletes columns
|
||||
procedure TestWriteRead_InsDelColRow_16; // before formula cell
|
||||
procedure TestWriteRead_InsDelColRow_17; // after formula cell
|
||||
procedure TestWriteRead_InsDelColRow_18; // cell in formula
|
||||
// Writes out cell layout with formula and deletes rows
|
||||
procedure TestWriteRead_InsDelColRow_19; // before formula cell
|
||||
procedure TestWriteRead_InsDelColRow_20; // after formula cell
|
||||
procedure TestWriteRead_InsDelColRow_21; // cell in formula
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -77,12 +102,17 @@ begin
|
||||
DeleteCol := -1;
|
||||
DeleteRow := -1;
|
||||
Formula := '';
|
||||
SollFormula := '';
|
||||
SharedFormulaColCount := 0;
|
||||
SharedFormulaRowCount := 0;
|
||||
MergedColCount := 0;
|
||||
MergedRowCount := 0;
|
||||
end;
|
||||
|
||||
{ ---------------------------------------------------------------------------}
|
||||
{ Simple layouts }
|
||||
{ ---------------------------------------------------------------------------}
|
||||
|
||||
// Insert a column before col 0
|
||||
with InsDelTestData[0] do begin
|
||||
Layout := '12345678|'+
|
||||
@ -160,6 +190,305 @@ begin
|
||||
'3456789|'+
|
||||
'4567890';
|
||||
end;
|
||||
|
||||
// Insert a ROW before row 0
|
||||
with InsDelTestData[6] do begin
|
||||
Layout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
InsertRow := 0;
|
||||
SollLayout := ' |'+
|
||||
'12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
end;
|
||||
|
||||
// Insert a ROW before row 2
|
||||
with InsDelTestData[7] do begin
|
||||
Layout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
InsertRow := 2;
|
||||
SollLayout := '12345|'+
|
||||
'23456|'+
|
||||
' |'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
end;
|
||||
|
||||
// Insert a ROW before last row
|
||||
with InsDelTestData[8] do begin
|
||||
Layout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
InsertRow := 5;
|
||||
SollLayout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
' |'+
|
||||
'67890|';
|
||||
end;
|
||||
|
||||
// Delete the first row
|
||||
with InsDelTestData[9] do begin
|
||||
Layout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
DeleteRow := 0;
|
||||
SollLayout := '23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
end;
|
||||
|
||||
// Delete row #2
|
||||
with InsDelTestData[10] do begin
|
||||
Layout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
DeleteRow := 2;
|
||||
SollLayout := '12345|'+
|
||||
'23456|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
end;
|
||||
|
||||
// Delete last row
|
||||
with InsDelTestData[11] do begin
|
||||
Layout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789|'+
|
||||
'67890|';
|
||||
DeleteRow := 5;
|
||||
SollLayout := '12345|'+
|
||||
'23456|'+
|
||||
'34567|'+
|
||||
'45678|'+
|
||||
'56789';
|
||||
end;
|
||||
|
||||
{ ---------------------------------------------------------------------------}
|
||||
{ Layouts with formula }
|
||||
{ ---------------------------------------------------------------------------}
|
||||
|
||||
// Insert a column before #1, i.e. before formula cell
|
||||
with InsDelTestData[12] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
InsertCol := 1;
|
||||
Formula := 'C3';
|
||||
SollFormula := 'D3'; // col index increases due to inserted col
|
||||
SollLayout := '1 2345678|'+
|
||||
'2 3456789|'+
|
||||
'3 4565890|'+
|
||||
'4 5678901|'+
|
||||
'5 6789012|'+
|
||||
'6 7890123';
|
||||
end;
|
||||
|
||||
// Insert a column before #3, i.e. after formula cell
|
||||
with InsDelTestData[13] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
InsertCol := 3;
|
||||
Formula := 'C3';
|
||||
SollFormula := 'C3'; // no change of cell because insertion is behind
|
||||
SollLayout := '123 45678|'+
|
||||
'234 56789|'+
|
||||
'345 65890|'+
|
||||
'456 78901|'+
|
||||
'567 89012|'+
|
||||
'678 90123';
|
||||
end;
|
||||
|
||||
// Insert a row before #1, i.e. before formula cell
|
||||
with InsDelTestData[14] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
InsertRow := 1;
|
||||
Formula := 'E4';
|
||||
SollFormula := 'E5'; // row index increaes due to inserted row
|
||||
SollLayout := '12345678|'+
|
||||
' |'+
|
||||
'23456789|'+
|
||||
'34568890|'+
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
end;
|
||||
|
||||
// Insert a row before #4, i.e. after formula cell
|
||||
with InsDelTestData[15] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
InsertRow := 5;
|
||||
Formula := 'E4';
|
||||
SollFormula := 'E4'; // row index not changed dur to insert after cell
|
||||
SollLayout := '12345678|'+
|
||||
'23456789|'+
|
||||
'34568890|'+
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
' |'+
|
||||
'67890123';
|
||||
end;
|
||||
|
||||
// Deletes column #1, i.e. before formula cell
|
||||
with InsDelTestData[16] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
DeleteCol := 1;
|
||||
Formula := 'C3';
|
||||
SollFormula := 'B3'; // col index decreases due to delete before cell
|
||||
SollLayout := '1345678|'+
|
||||
'2456789|'+
|
||||
'3565890|'+
|
||||
'4678901|'+
|
||||
'5789012|'+
|
||||
'6890123';
|
||||
end;
|
||||
|
||||
// Deletes column #5, i.e. after formula cell
|
||||
with InsDelTestData[17] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
DeleteCol := 5;
|
||||
Formula := 'C3';
|
||||
SollFormula := 'C3'; // col index unchanged due to deleted after cell
|
||||
SollLayout := '1234578|'+
|
||||
'2345689|'+
|
||||
'3456590|'+
|
||||
'4567801|'+
|
||||
'5678912|'+
|
||||
'6789023';
|
||||
end;
|
||||
|
||||
// Deletes column #2, i.e. cell appearing in formula is gone --> #REF! error
|
||||
with InsDelTestData[18] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
DeleteCol := 2;
|
||||
Formula := 'C3';
|
||||
SollFormula := '#REF!'; // col index unchanged due to deletion after cell
|
||||
SollLayout := '1245678|'+
|
||||
'2356789|'+
|
||||
'346E890|'+ // "E" = error
|
||||
'4578901|'+
|
||||
'5689012|'+
|
||||
'6790123';
|
||||
end;
|
||||
|
||||
// Deletes row #1, i.e. before formula cell
|
||||
with InsDelTestData[19] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
DeleteRow := 1;
|
||||
Formula := 'E4';
|
||||
SollFormula := 'E3'; // row index decreases due to delete before cell
|
||||
SollLayout := '12345678|'+
|
||||
// '23456789|'+
|
||||
'34568890|'+
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
end;
|
||||
|
||||
// Deletes row #4, i.e. after formula cell
|
||||
with InsDelTestData[20] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
DeleteRow := 4;
|
||||
Formula := 'E4';
|
||||
SollFormula := 'E4'; // row index unchanged (delete is after cell)
|
||||
SollLayout := '12345678|'+
|
||||
'23456789|'+
|
||||
'34568890|'+
|
||||
'45678901|'+
|
||||
// '56789012|'+
|
||||
'67890123';
|
||||
end;
|
||||
|
||||
// Deletes row #2, i.e. row containing cell used in formula --> #REF! error!
|
||||
with InsDelTestData[21] do begin
|
||||
Layout := '12345678|'+
|
||||
'23456789|'+
|
||||
'3456F890|'+ // "F" = Formula in row 2, col 4
|
||||
'45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
DeleteRow := 3;
|
||||
Formula := 'E4';
|
||||
SollFormula := '#REF!';
|
||||
SollLayout := '12345678|'+
|
||||
'23456789|'+
|
||||
'34568890|'+
|
||||
// '45678901|'+
|
||||
'56789012|'+
|
||||
'67890123';
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
@ -211,6 +540,7 @@ begin
|
||||
for col := 0 to Length(s)-1 do
|
||||
case s[col+1] of
|
||||
'0'..'9': MyWorksheet.WriteNumber(row, col, StrToInt(s[col+1]));
|
||||
'F' : MyWorksheet.WriteFormula(row, col, InsDelTestData[ATestIndex].Formula);
|
||||
' ' : ;
|
||||
end;
|
||||
end;
|
||||
@ -237,7 +567,9 @@ begin
|
||||
// Open the spreadsheet
|
||||
MyWorkbook := TsWorkbook.Create;
|
||||
try
|
||||
MyWorkbook.Options := MyWorkbook.Options + [boReadFormulas, boAutoCalc];
|
||||
MyWorkbook.ReadFromFile(TempFile, AFormat);
|
||||
|
||||
if AFormat = sfExcel2 then
|
||||
MyWorksheet := MyWorkbook.GetFirstWorksheet
|
||||
else
|
||||
@ -253,10 +585,19 @@ begin
|
||||
MyCell := MyWorksheet.FindCell(row, col);
|
||||
if MyCell = nil then
|
||||
actual := actual + ' '
|
||||
else
|
||||
else begin
|
||||
case MyCell^.ContentType of
|
||||
cctEmpty : actual := actual + ' ';
|
||||
cctNumber: actual := actual + IntToStr(Round(Mycell^.NumberValue));
|
||||
cctError : actual := actual + 'E';
|
||||
end;
|
||||
if HasFormula(MyCell) then begin
|
||||
CheckEquals(
|
||||
MyWorksheet.ReadFormulaAsString(MyCell),
|
||||
InsDelTestData[ATestIndex].SollFormula,
|
||||
'Formula mismatch, cell '+CellNotation(MyWorksheet, Row, Col)
|
||||
);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CheckEquals(actual, expected,
|
||||
@ -309,6 +650,101 @@ begin
|
||||
TestWriteRead_InsDelColRow(5);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_6;
|
||||
// insert row before first one
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(6);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_7;
|
||||
// insert row before #2
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(7);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_8;
|
||||
// insert row before last one
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(8);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_9;
|
||||
// delete first row
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(9);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_10;
|
||||
// delete row #2
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(10);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_11;
|
||||
// delete last row
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(11);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_12;
|
||||
// insert column before formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(12);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_13;
|
||||
// insert column after formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(13);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_14;
|
||||
// insert row before formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(14);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_15;
|
||||
// insert row after formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(15);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_16;
|
||||
// delete column before formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(16);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_17;
|
||||
// delete column after formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(17);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_18;
|
||||
// delete column containing a cell used in formula
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(18);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_19;
|
||||
// delete row before formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(19);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_20;
|
||||
// delete row after formula cell
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(20);
|
||||
end;
|
||||
|
||||
procedure TSpreadWriteRead_InsDelColRow_Tests.TestWriteRead_InsDelColRow_21;
|
||||
// delete row containing a cell used in formula
|
||||
begin
|
||||
TestWriteRead_InsDelColRow(21);
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TSpreadWriteRead_InsDelColRow_Tests);
|
||||
|
@ -48,6 +48,7 @@
|
||||
<Unit1>
|
||||
<Filename Value="datetests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="datetests"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="stringtests.pas"/>
|
||||
@ -56,7 +57,6 @@
|
||||
<Unit3>
|
||||
<Filename Value="numberstests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="numberstests"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="manualtests.pas"/>
|
||||
@ -66,20 +66,20 @@
|
||||
<Unit5>
|
||||
<Filename Value="testsutility.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="testsutility"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="internaltests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="internaltests"/>
|
||||
</Unit6>
|
||||
<Unit7>
|
||||
<Filename Value="formattests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="formattests"/>
|
||||
</Unit7>
|
||||
<Unit8>
|
||||
<Filename Value="colortests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="colortests"/>
|
||||
</Unit8>
|
||||
<Unit9>
|
||||
<Filename Value="fonttests.pas"/>
|
||||
@ -106,15 +106,16 @@
|
||||
<Unit14>
|
||||
<Filename Value="emptycelltests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="emptycelltests"/>
|
||||
</Unit14>
|
||||
<Unit15>
|
||||
<Filename Value="errortests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="errortests"/>
|
||||
</Unit15>
|
||||
<Unit16>
|
||||
<Filename Value="virtualmodetests.pas"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="virtualmodetests"/>
|
||||
</Unit16>
|
||||
<Unit17>
|
||||
<Filename Value="insertdeletetests.pas"/>
|
||||
|
Reference in New Issue
Block a user