fpspreadsheet: Fix crash when referenced worksheet does not exist.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6453 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-06-03 11:07:42 +00:00
parent 115a423be5
commit 6c19ca21cb
4 changed files with 124 additions and 104 deletions

View File

@ -606,6 +606,7 @@ type
FCell: PCell; // cell which contains the formula FCell: PCell; // cell which contains the formula
// FSheetName: String; // referenced other sheet // FSheetName: String; // referenced other sheet
FSheetIndex: Integer; // index of referenced other sheet FSheetIndex: Integer; // index of referenced other sheet
FHas3DLink: Boolean;
FIsRef: Boolean; FIsRef: Boolean;
FError: TsErrorValue; FError: TsErrorValue;
protected protected
@ -3845,18 +3846,23 @@ constructor TsCellExprNode.Create(AParser: TsExpressionParser;
AWorksheet: TsBasicWorksheet; ASheetName: String; ARow, ACol: Cardinal; AWorksheet: TsBasicWorksheet; ASheetName: String; ARow, ACol: Cardinal;
AFlags: TsRelFlags); AFlags: TsRelFlags);
begin begin
FError := errOK;
FParser := AParser; FParser := AParser;
FWorksheet := AWorksheet; FWorksheet := AWorksheet;
if (ASheetName = '') then if (ASheetName = '') then begin
FSheetIndex := -1 FSheetIndex := -1;
else FHas3DLink := false;
end else begin
FSheetIndex := TsWorkbook(GetWorkbook).GetWorksheetIndex(ASheetName); FSheetIndex := TsWorkbook(GetWorkbook).GetWorksheetIndex(ASheetName);
if FSheetIndex = -1 then
FError := errIllegalRef;
FHas3DLink := true;
end;
FRow := ARow; FRow := ARow;
FCol := ACol; FCol := ACol;
FFlags := AFlags; FFlags := AFlags;
FError := errOK; FCell := TsWorksheet(FWorksheet).FindCell(FRow, FCol);
FCell := (GetSheet as TsWorksheet).FindCell(FRow, FCol); // FCell := (GetSheet as TsWorksheet).FindCell(FRow, FCol);
if Has3DLink then FParser.FContains3DRef := true;
end; end;
function TsCellExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem; function TsCellExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem;
@ -4041,7 +4047,7 @@ end;
function TsCellExprNode.Has3DLink: Boolean; function TsCellExprNode.Has3DLink: Boolean;
begin begin
Result := FSheetIndex <> -1; Result := FHas3dLink;
end; end;
function TsCellExprNode.NodeType: TsResultType; function TsCellExprNode.NodeType: TsResultType;
@ -4082,17 +4088,13 @@ begin
((ASheet1 <> '') and (ASheet2 = '')); ((ASheet1 <> '') and (ASheet2 = ''));
FSheetIndex[1] := book.GetWorksheetIndex(ASheet1); FSheetIndex[1] := book.GetWorksheetIndex(ASheet1);
{ if (FSheetIndex[1] = -1) and (ASheet1 <> '') then
if FSheetIndex[1] = -1 then
FError := errIllegalREF FError := errIllegalREF
else else
}
if ASheet2 <> '' then begin if ASheet2 <> '' then begin
FSheetIndex[2] := book.GetWorksheetIndex(ASheet2); FSheetIndex[2] := book.GetWorksheetIndex(ASheet2);
{ if (FSheetIndex[2] = -1) and (ASheet2 <> '') then
if FSheetIndex[2] = -1 then
FError := errIllegalREF; FError := errIllegalREF;
}
end else end else
FSheetIndex[2] := FSheetIndex[1]; FSheetIndex[2] := FSheetIndex[1];
EnsureOrder(FSheetIndex[1], FSheetIndex[2]); EnsureOrder(FSheetIndex[1], FSheetIndex[2]);
@ -4249,6 +4251,10 @@ begin
for ss := s[1] to s[2] do begin for ss := s[1] to s[2] do begin
sheet := (Workbook as TsWorkbook).GetWorksheetByIndex(ss); sheet := (Workbook as TsWorkbook).GetWorksheetByIndex(ss);
if sheet = nil then begin
AResult := ErrorResult(errIllegalRef);
exit;
end;
for formula in sheet.Formulas do for formula in sheet.Formulas do
if (formula^.Row >= r[1]) and (formula^.Row <= r[2]) and if (formula^.Row >= r[1]) and (formula^.Row <= r[2]) and
(formula^.Col >= c[1]) and (formula^.Col <= c[2]) (formula^.Col >= c[1]) and (formula^.Col <= c[2])

View File

@ -2808,15 +2808,15 @@ end;
If the cell contains a text value it is attempted to convert it to a number. If the cell contains a text value it is attempted to convert it to a number.
If the cell is empty or its contents cannot be represented as a number the If the cell is empty or its contents cannot be represented as a number the
value 0.0 is returned. value NaN is returned.
@param ACell Pointer to the cell @param ACell Pointer to the cell
@return Floating-point value representing the cell contents, or 0.0 if cell @return Floating-point value representing the cell contents, or NaN if cell
does not exist or its contents cannot be converted to a number. does not exist or its contents cannot be converted to a number.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function TsWorksheet.ReadAsNumber(ACell: PCell): Double; function TsWorksheet.ReadAsNumber(ACell: PCell): Double;
begin begin
Result := 0.0; Result := NaN;
if ACell = nil then if ACell = nil then
exit; exit;
@ -2827,7 +2827,7 @@ begin
Result := ACell^.NumberValue; Result := ACell^.NumberValue;
cctUTF8String: cctUTF8String:
if not TryStrToFloat(ACell^.UTF8StringValue, Result, FWorkbook.FormatSettings) if not TryStrToFloat(ACell^.UTF8StringValue, Result, FWorkbook.FormatSettings)
then Result := 0.0; then Result := NaN;
cctBool: cctBool:
if ACell^.BoolValue then Result := 1.0 else Result := 0.0; if ACell^.BoolValue then Result := 1.0 else Result := 0.0;
end; end;

View File

@ -3469,14 +3469,21 @@ var
sheetlist: TsBIFFExternSheetList; sheetlist: TsBIFFExternSheetList;
sheetIdx, sheetIdx1, sheetIdx2: Integer; sheetIdx, sheetIdx1, sheetIdx2: Integer;
workbook: TsWorkbook; workbook: TsWorkbook;
sheetName: String;
begin begin
Unused(MustRebuildFormulas); Unused(MustRebuildFormulas);
sheetlist := TsBIFFExternSheetList(AData); sheetlist := TsBIFFExternSheetList(AData);
if (ANode is TsCellExprNode) and TsCellExprNode(ANode).Has3DLink then if (ANode is TsCellExprNode) and TsCellExprNode(ANode).Has3DLink then
sheetList.AddSheet(TsCellExprNode(ANode).GetSheetName, ebkInternal) begin
else if (ANode as TsCellExprNode).Error <> errOK then
exit;
sheetName := TsCellExprNode(ANode).GetSheetName;
sheetList.AddSheet(sheetName, ebkInternal)
end else
if (ANode is TsCellRangeExprNode) and TsCellRangeExprNode(ANode).Has3DLink then if (ANode is TsCellRangeExprNode) and TsCellRangeExprNode(ANode).Has3DLink then
begin begin
if (ANode as TsCellRangeExprNode).Error <> errOK then
exit;
workbook := TsCellRangeExprNode(ANode).Workbook as TsWorkbook; workbook := TsCellRangeExprNode(ANode).Workbook as TsWorkbook;
sheetIdx1 := TsCellRangeExprNode(ANode).GetSheetIndex(1); sheetIdx1 := TsCellRangeExprNode(ANode).GetSheetIndex(1);
sheetIdx2 := TsCellRangeExprNode(ANode).GetSheetIndex(2); sheetIdx2 := TsCellRangeExprNode(ANode).GetSheetIndex(2);
@ -3500,54 +3507,6 @@ function TsSpreadBIFFWriter.CollectExternData(AWorksheet: TsBasicWorksheet = nil
for formula in ASheet.Formulas do for formula in ASheet.Formulas do
formula^.Parser.IterateNodes(@DoCollectSheetsWith3dRefs, ASheetList); formula^.Parser.IterateNodes(@DoCollectSheetsWith3dRefs, ASheetList);
end; end;
{
var
cell: PCell;
workbook: TsWorkbook;
parser: TsExpressionParser;
rpn: TsRPNFormula;
fe: TsFormulaElement;
i, j: Integer;
kind: TsBIFFExternKind;
begin
workbook := ASheet.Workbook;
for cell in ASheet.Cells do
begin
if not HasFormula(cell) then
Continue;
if (cell^.Flags * [cf3dFormula, cfCalculated] = [cfCalculated]) then
Continue;
if (pos('[', ASheet.Name) = 0) then
kind := ebkInternal
else
kind := ebkExternal; // External refs: [filename]Sheet1!A1
parser := TsSpreadsheetParser.Create(ASheet);
try
parser.Expression := cell^.FormulaValue;
rpn := parser.RPNFormula;
for i:=0 to High(rpn) do
begin
fe := rpn[i];
if fe.ElementKind in [fekCell3d, fekCellRef3d, fekCellRange3d] then begin
if fe.Sheet = -1 then
ASheetList.AddSheet(ASheet.Name, kind)
else
if fe.Sheet2 = -1 then
ASheetList.AddSheet(workbook.GetWorksheetByIndex(fe.Sheet).Name, kind)
else
for j :=fe.Sheet to fe.Sheet2 do
ASheetList.AddSheet(workbook.GetWorksheetbyIndex(j).Name, kind);
end;
end;
finally
parser.Free;
rpn := nil;
end;
end;
end;
}
var var
sheet: TsWorksheet; sheet: TsWorksheet;

View File

@ -23,7 +23,7 @@ type
protected protected
procedure SetUp; override; procedure SetUp; override;
procedure TearDown; override; procedure TearDown; override;
procedure TestFloatFormula(AFormula: String; AExpected: Double; procedure TestFormula(AFormula: String; AExpected: String;
ATestKind: TFormulaTestKind; AFormat: TsSpreadsheetFormat; ATestKind: TFormulaTestKind; AFormat: TsSpreadsheetFormat;
AExpectedFormula: String = ''); AExpectedFormula: String = '');
procedure TestWorksheet(ATestKind: TWorksheetTestKind; ATestCase: Integer); procedure TestWorksheet(ATestKind: TWorksheetTestKind; ATestCase: Integer);
@ -63,6 +63,16 @@ type
procedure SumMultiSheetRange_FlippedSheetsAndCells_OOXML; procedure SumMultiSheetRange_FlippedSheetsAndCells_OOXML;
procedure SumMultiSheetRange_FlippedSheetsAndCells_ODS; procedure SumMultiSheetRange_FlippedSheetsAndCells_ODS;
procedure NonExistantSheet_BIFF5;
procedure NonExistantSheet_BIFF8;
procedure NonExistantSheet_OOXML;
procedure NonExistantSheet_ODS;
procedure NonExistantSheetRange_BIFF5;
procedure NonExistantSheetRange_BIFF8;
procedure NonExistantSheetRange_OOXML;
procedure NonExistantSheetRange_ODS;
procedure RenameWorksheet_Single; procedure RenameWorksheet_Single;
procedure RenameWorksheet_Multi_First; procedure RenameWorksheet_Multi_First;
procedure RenameWorksheet_Multi_Inner; procedure RenameWorksheet_Multi_Inner;
@ -87,7 +97,7 @@ uses
{$IFDEF FORMULADEBUG} {$IFDEF FORMULADEBUG}
LazLogger, LazLogger,
{$ENDIF} {$ENDIF}
typinfo, lazUTF8, fpsUtils; Math, typinfo, lazUTF8, fpsUtils;
{ TSpreadExtendedFormulaTests } { TSpreadExtendedFormulaTests }
@ -102,8 +112,8 @@ begin
inherited TearDown; inherited TearDown;
end; end;
procedure TSpreadSingleFormulaTests.TestFloatFormula(AFormula: String; procedure TSpreadSingleFormulaTests.TestFormula(AFormula: String;
AExpected: Double; ATestKind: TFormulaTestKind; AFormat: TsSpreadsheetFormat; AExpected: String; ATestKind: TFormulaTestKind; AFormat: TsSpreadsheetFormat;
AExpectedFormula: String = ''); AExpectedFormula: String = '');
const const
SHEET1 = 'Sheet1'; SHEET1 = 'Sheet1';
@ -118,7 +128,7 @@ var
TempFile: string; //write xls/xml to this file and read back from it TempFile: string; //write xls/xml to this file and read back from it
cell: PCell; cell: PCell;
actualformula: String; actualformula: String;
actualValue: Double; actualValue: String;
begin begin
TempFile := GetTempFileName; TempFile := GetTempFileName;
if AExpectedFormula = '' then AExpectedFormula := AFormula; if AExpectedFormula = '' then AExpectedFormula := AFormula;
@ -127,6 +137,7 @@ begin
// Create test workbook and write test formula and needed cells // Create test workbook and write test formula and needed cells
workbook := TsWorkbook.Create; workbook := TsWorkbook.Create;
try try
workbook.FormatSettings.DecimalSeparator := '.';
workbook.Options := workbook.Options + [boCalcBeforeSaving, boAutoCalc]; workbook.Options := workbook.Options + [boCalcBeforeSaving, boAutoCalc];
workSheet:= workBook.AddWorksheet(SHEET1); workSheet:= workBook.AddWorksheet(SHEET1);
@ -162,7 +173,7 @@ begin
CheckEquals(AExpectedFormula, actualFormula, 'Unsaved formula text mismatch'); CheckEquals(AExpectedFormula, actualFormula, 'Unsaved formula text mismatch');
// Read calculated value before saving // Read calculated value before saving
actualvalue := worksheet.ReadAsNumber(TESTCELL_ROW, TESTCELL_COL); actualValue := worksheet.ReadAsText(TESTCELL_ROW, TESTCELL_COL);
CheckEquals(AExpected, actualvalue, 'Unsaved calculated value mismatch'); CheckEquals(AExpected, actualvalue, 'Unsaved calculated value mismatch');
// Save // Save
@ -174,18 +185,18 @@ begin
// Read file // Read file
workbook := TsWorkbook.Create; workbook := TsWorkbook.Create;
try try
workbook.FormatSettings.DecimalSeparator := '.';
workbook.Options := workbook.Options + [boReadFormulas, boAutoCalc]; workbook.Options := workbook.Options + [boReadFormulas, boAutoCalc];
workbook.ReadFromFile(TempFile, AFormat); workbook.ReadFromFile(TempFile, AFormat);
worksheet := workbook.GetFirstWorksheet; worksheet := workbook.GetFirstWorksheet;
// Read calculated formula value // Read calculated formula value
actualvalue := worksheet.ReadAsNumber(TESTCELL_ROW, TESTCELL_COL); actualValue := worksheet.ReadAsText(TESTCELL_ROW, TESTCELL_COL);
CheckEquals(AExpected, actualValue, 'Saved calculated value mismatch'); CheckEquals(AExpected, actualValue, 'Saved calculated value mismatch');
cell := worksheet.FindCell(TESTCELL_ROW, TESTCELL_COL); cell := worksheet.FindCell(TESTCELL_ROW, TESTCELL_COL);
actualformula := worksheet.Formulas.FindFormula(cell)^.Text; actualformula := worksheet.Formulas.FindFormula(cell)^.Text;
// actualformula := cell^.FormulaValue; // When writing ranges are reconstructed in correct order -> compare against AExpectedFormula
// When writing ranges are reconstructed in correct order.
CheckEquals(AExpectedFormula, actualformula, 'Saved formula text mismatch.'); CheckEquals(AExpectedFormula, actualformula, 'Saved formula text mismatch.');
finally finally
workbook.Free; workbook.Free;
@ -198,125 +209,125 @@ end;
procedure TSpreadSingleFormulaTests.AddConst_BIFF2; procedure TSpreadSingleFormulaTests.AddConst_BIFF2;
begin begin
TestFloatFormula('1+1', 2, ftkConstants, sfExcel2); TestFormula('1+1', '2', ftkConstants, sfExcel2);
end; end;
procedure TSpreadSingleFormulaTests.AddConst_BIFF5; procedure TSpreadSingleFormulaTests.AddConst_BIFF5;
begin begin
TestFloatFormula('1+1', 2, ftkConstants, sfExcel5); TestFormula('1+1', '2', ftkConstants, sfExcel5);
end; end;
procedure TSpreadSingleFormulaTests.AddConst_BIFF8; procedure TSpreadSingleFormulaTests.AddConst_BIFF8;
begin begin
TestFloatFormula('1+1', 2, ftkConstants, sfExcel8); TestFormula('1+1', '2', ftkConstants, sfExcel8);
end; end;
procedure TSpreadSingleFormulaTests.AddConst_OOXML; procedure TSpreadSingleFormulaTests.AddConst_OOXML;
begin begin
TestFloatFormula('1+1', 2, ftkConstants, sfOOXML); TestFormula('1+1', '2', ftkConstants, sfOOXML);
end; end;
procedure TSpreadSingleFormulaTests.AddConst_ODS; procedure TSpreadSingleFormulaTests.AddConst_ODS;
begin begin
TestFloatFormula('1+1', 2, ftkConstants, sfOpenDocument); TestFormula('1+1', '2', ftkConstants, sfOpenDocument);
end; end;
{---------------} {---------------}
procedure TSpreadSingleFormulaTests.AddCells_BIFF2; procedure TSpreadSingleFormulaTests.AddCells_BIFF2;
begin begin
TestFloatFormula('C3+C4', -1.0, ftkCells, sfExcel2); TestFormula('C3+C4', '-1', ftkCells, sfExcel2);
end; end;
procedure TSpreadSingleFormulaTests.AddCells_BIFF5; procedure TSpreadSingleFormulaTests.AddCells_BIFF5;
begin begin
TestFloatFormula('C3+C4', -1.0, ftkCells, sfExcel5); TestFormula('C3+C4', '-1', ftkCells, sfExcel5);
end; end;
procedure TSpreadSingleFormulaTests.AddCells_BIFF8; procedure TSpreadSingleFormulaTests.AddCells_BIFF8;
begin begin
TestFloatFormula('C3+C4', -1.0, ftkCells, sfExcel8); TestFormula('C3+C4', '-1', ftkCells, sfExcel8);
end; end;
procedure TSpreadSingleFormulaTests.AddCells_OOXML; procedure TSpreadSingleFormulaTests.AddCells_OOXML;
begin begin
TestFloatFormula('C3+C4', -1.0, ftkCells, sfOOXML); TestFormula('C3+C4', '-1', ftkCells, sfOOXML);
end; end;
procedure TSpreadSingleFormulaTests.AddCells_ODS; procedure TSpreadSingleFormulaTests.AddCells_ODS;
begin begin
TestFloatFormula('C3+C4', -1.0, ftkCells, sfOpenDocument); TestFormula('C3+C4', '-1', ftkCells, sfOpenDocument);
end; end;
{ ------ } { ------ }
procedure TSpreadSingleFormulaTests.SumRange_BIFF2; procedure TSpreadSingleFormulaTests.SumRange_BIFF2;
begin begin
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfExcel2); TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfExcel2);
end; end;
procedure TSpreadSingleFormulaTests.SumRange_BIFF5; procedure TSpreadSingleFormulaTests.SumRange_BIFF5;
begin begin
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfExcel5); TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfExcel5);
end; end;
procedure TSpreadSingleFormulaTests.SumRange_BIFF8; procedure TSpreadSingleFormulaTests.SumRange_BIFF8;
begin begin
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfExcel8); TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfExcel8);
end; end;
procedure TSpreadSingleFormulaTests.SumRange_OOXML; procedure TSpreadSingleFormulaTests.SumRange_OOXML;
begin begin
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfOOXML); TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfOOXML);
end; end;
procedure TSpreadSingleFormulaTests.SumRange_ODS; procedure TSpreadSingleFormulaTests.SumRange_ODS;
begin begin
TestFloatFormula('SUM(C3:C5)', 0.5, ftkCellRange, sfOpenDocument); TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfOpenDocument);
end; end;
{ ---- } { ---- }
procedure TSpreadSingleFormulaTests.SumSheetRange_BIFF5; procedure TSpreadSingleFormulaTests.SumSheetRange_BIFF5;
begin begin
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfExcel5); TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfExcel5);
end; end;
procedure TSpreadSingleFormulaTests.SumSheetRange_BIFF8; procedure TSpreadSingleFormulaTests.SumSheetRange_BIFF8;
begin begin
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfExcel8); TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfExcel8);
end; end;
procedure TSpreadSingleFormulaTests.SumSheetRange_OOXML; procedure TSpreadSingleFormulaTests.SumSheetRange_OOXML;
begin begin
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfOOXML); TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfOOXML);
end; end;
procedure TSpreadSingleFormulaTests.SumSheetRange_ODS; procedure TSpreadSingleFormulaTests.SumSheetRange_ODS;
begin begin
TestFloatFormula('SUM(Sheet2!C3:C5)', 5.0, ftkCellRangeSheet, sfOpenDocument); TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfOpenDocument);
end; end;
{ ---- } { ---- }
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_BIFF5; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_BIFF5;
begin begin
TestFloatFormula('SUM(Sheet2:Sheet3!C3:C5)', 55.0, ftkCellRangeSheetRange, sfExcel5); TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfExcel5);
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_BIFF8; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_BIFF8;
begin begin
TestFloatFormula('SUM(Sheet2:Sheet3!C3:C5)', 55.0, ftkCellRangeSheetRange, sfExcel8); TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfExcel8);
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_OOXML; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_OOXML;
begin begin
TestFloatFormula('SUM(Sheet2:Sheet3!C3:C5)', 55.0, ftkCellRangeSheetRange, sfOOXML); TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfOOXML);
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_ODS; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_ODS;
begin begin
TestFloatFormula('SUM(Sheet2:Sheet3!C3:C5)', 55.0, ftkCellRangeSheetRange, sfOpenDocument); TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfOpenDocument);
end; end;
{ --- } { --- }
@ -326,28 +337,72 @@ end;
expected range must be in correct order. } expected range must be in correct order. }
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheetsAndCells_OOXML; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheetsAndCells_OOXML;
begin begin
TestFloatFormula('SUM(Sheet3:Sheet2!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)'); TestFormula('SUM(Sheet3:Sheet2!C5:C3)', '55', ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)');
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheetsAndCells_ODS; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheetsAndCells_ODS;
begin begin
TestFloatFormula('SUM(Sheet3:Sheet2!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOpenDocument, 'SUM(Sheet2:Sheet3!C3:C5)'); TestFormula('SUM(Sheet3:Sheet2!C5:C3)', '55', ftkCellRangeSheetRange, sfOpenDocument, 'SUM(Sheet2:Sheet3!C3:C5)');
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedCells_BIFF8; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedCells_BIFF8;
begin begin
// Upon writing the ranges are reconstructed for BIFF in correct order. // Upon writing the ranges are reconstructed for BIFF in correct order.
TestFloatFormula('SUM(Sheet2:Sheet3!C5:C3)', 55.0, ftkCellRangeSheetRange, sfExcel8, 'SUM(Sheet2:Sheet3!C3:C5)'); TestFormula('SUM(Sheet2:Sheet3!C5:C3)', '55', ftkCellRangeSheetRange, sfExcel8, 'SUM(Sheet2:Sheet3!C3:C5)');
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedCells_OOXML; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedCells_OOXML;
begin begin
TestFloatFormula('SUM(Sheet2:Sheet3!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)'); TestFormula('SUM(Sheet2:Sheet3!C5:C3)', '55', ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)');
end; end;
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheets_OOXML; procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheets_OOXML;
begin begin
TestFloatFormula('SUM(Sheet3:Sheet2!C3:C5)', 55.0, ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)'); TestFormula('SUM(Sheet3:Sheet2!C3:C5)', '55', ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)');
end;
{ --- }
procedure TSpreadSingleFormulaTests.NonExistantSheet_BIFF5;
begin
TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfExcel5, '#REF!');
end;
procedure TSpreadSingleFormulaTests.NonExistantSheet_BIFF8;
begin
TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfExcel8, '#REF!');
end;
procedure TSpreadSingleFormulaTests.NonExistantSheet_OOXML;
begin
TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfOOXML, '#REF!');
end;
procedure TSpreadSingleFormulaTests.NonExistantSheet_ODS;
begin
TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfOpenDocument, '#REF!');
end;
{ --- }
procedure TSpreadSingleFormulaTests.NonExistantSheetRange_BIFF5;
begin
TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfExcel5, 'SUM(#REF!)');
end;
procedure TSpreadSingleFormulaTests.NonExistantSheetRange_BIFF8;
begin
TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfExcel8, 'SUM(#REF!)');
end;
procedure TSpreadSingleFormulaTests.NonExistantSheetRange_OOXML;
begin
TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfOOXML, 'SUM(#REF!)');
end;
procedure TSpreadSingleFormulaTests.NonExistantSheetRange_ODS;
begin
TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfOpenDocument, 'SUM(#REF!)');
end; end;