You've already forked lazarus-ccr
fpspreadsheet: Update cell flag cf3dFormula after parsing of a formula.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6424 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -617,7 +617,6 @@ type
|
||||
TsCellRangeExprNode = class(TsExprNode)
|
||||
private
|
||||
FWorksheet: TsWorksheet;
|
||||
// FWorksheet2: TsWorksheet;
|
||||
FRow: array[TsCellRangeIndex] of Cardinal;
|
||||
FCol: array[TsCellRangeIndex] of Cardinal;
|
||||
FSheetIndex: array[TsCellRangeIndex] of Integer;
|
||||
@ -719,6 +718,7 @@ type
|
||||
|
||||
protected
|
||||
FFormatSettings: TFormatSettings;
|
||||
FContains3DRef: Boolean;
|
||||
class function BuiltinExpressionManager: TsBuiltInExpressionManager;
|
||||
function BuildStringFormula(AFormatSettings: TFormatSettings): String;
|
||||
procedure ParserError(Msg: String);
|
||||
@ -771,9 +771,10 @@ type
|
||||
property RPNFormula: TsRPNFormula read GetRPNFormula write SetRPNFormula;
|
||||
property Identifiers: TsExprIdentifierDefs read FIdentifiers write SetIdentifiers;
|
||||
property BuiltIns: TsBuiltInExprCategories read FBuiltIns write SetBuiltIns;
|
||||
// property ActiveCell: PCell read FActiveCell write FActiveCell;
|
||||
property Worksheet: TsWorksheet read FWorksheet;
|
||||
property Dialect: TsFormulaDialect read FDialect write SetDialect;
|
||||
property Contains3DRef: boolean read FContains3DRef;
|
||||
|
||||
end;
|
||||
|
||||
TsSpreadsheetParser = class(TsExpressionParser)
|
||||
@ -3772,6 +3773,7 @@ begin
|
||||
FCol := ACol;
|
||||
FFlags := AFlags;
|
||||
FCell := GetSheet.FindCell(FRow, FCol);
|
||||
if Has3DLink then FParser.FContains3DRef := true;
|
||||
end;
|
||||
|
||||
function TsCellExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem;
|
||||
@ -3937,7 +3939,7 @@ begin
|
||||
|
||||
if ARange.Row2 = Cardinal(-1) then
|
||||
ARange.Row2 := ARange.Row1;
|
||||
if ARange.Row1 <= Arange.Row2 then
|
||||
if ARange.Row1 <= ARange.Row2 then
|
||||
begin
|
||||
FRow[1] := ARange.Row1;
|
||||
FRow[2] := ARange.Row2;
|
||||
@ -3967,6 +3969,8 @@ begin
|
||||
if (rfRelCol in AFlags) then Include(FFlags, rfRelCol2);
|
||||
if (rfRelCol2 in AFlags) then Include(FFlags, rfRelCol);
|
||||
end;
|
||||
|
||||
if Has3DLink then FParser.FContains3DRef := true;
|
||||
end;
|
||||
|
||||
function TsCellRangeExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem;
|
||||
|
@ -1286,6 +1286,7 @@ var
|
||||
link, txt: String;
|
||||
cell: PCell;
|
||||
formula: String;
|
||||
has3DLink: Boolean;
|
||||
begin
|
||||
if (boIgnoreFormulas in Workbook.Options) then
|
||||
exit;
|
||||
@ -1297,6 +1298,7 @@ begin
|
||||
try
|
||||
try
|
||||
parser.Expression := ACell^.FormulaValue;
|
||||
has3DLink := parser.Contains3DRef;
|
||||
res := parser.Evaluate;
|
||||
except
|
||||
on E:ECalcEngine do
|
||||
@ -1342,6 +1344,8 @@ begin
|
||||
WriteBlank(ACell);
|
||||
end;
|
||||
end;
|
||||
if has3DLink then Include(ACell^.Flags, cf3DFormula)
|
||||
else Exclude(ACell^.Flags, cf3DFormula);
|
||||
finally
|
||||
parser.Free;
|
||||
end;
|
||||
@ -5746,8 +5750,13 @@ begin
|
||||
if (AFormula <> '') and (AFormula[1] = '=') then
|
||||
AFormula := Copy(AFormula, 2, Length(AFormula));
|
||||
|
||||
parser := TsSpreadsheetParser.Create(self);
|
||||
try
|
||||
if ALocalized then begin
|
||||
// Convert "localized" formula to standard format
|
||||
parser := TsSpreadsheetParser.Create(self);
|
||||
try
|
||||
parser.LocalizedExpression[Workbook.FormatSettings] := AFormula;
|
||||
parser.Expression := AFormula;
|
||||
{
|
||||
if ALocalized then
|
||||
// Convert "localized" formula to standard format
|
||||
parser.LocalizedExpression[Workbook.FormatSettings] := AFormula
|
||||
@ -5757,8 +5766,10 @@ begin
|
||||
if parser.Has3DLinks
|
||||
then ACell.Flags := ACell.Flags + [cf3dFormula]
|
||||
else ACell.Flags := ACell.Flags - [cf3dFormula];
|
||||
finally
|
||||
parser.Free;
|
||||
}
|
||||
finally
|
||||
parser.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -2554,7 +2554,7 @@ procedure TsSpreadBIFF8Writer.CollectExternData;
|
||||
begin
|
||||
if not HasFormula(cell) then
|
||||
Continue;
|
||||
if not (cf3dFormula in cell^.Flags) then
|
||||
if (cell^.Flags * [cf3dFormula, cfCalculated] = [cfCalculated]) then
|
||||
Continue;
|
||||
|
||||
parser := TsSpreadsheetParser.Create(ASheet);
|
||||
|
@ -3416,13 +3416,13 @@ function TsSpreadBIFFWriter.CollectExternData(AWorksheet: TsWorksheet = nil): In
|
||||
begin
|
||||
if not HasFormula(cell) then
|
||||
Continue;
|
||||
if not (cf3dFormula in cell^.Flags) then
|
||||
if (cell^.Flags * [cf3dFormula, cfCalculated] = [cfCalculated]) then
|
||||
Continue;
|
||||
|
||||
if (pos('[', ASheet.Name) = 0) then
|
||||
kind := ebkInternal
|
||||
else
|
||||
kind := ebkExternal;
|
||||
kind := ebkExternal; // External refs: [filename]Sheet1!A1
|
||||
|
||||
parser := TsSpreadsheetParser.Create(ASheet);
|
||||
try
|
||||
|
@ -735,7 +735,7 @@ begin
|
||||
try
|
||||
workbook.Options := workbook.Options + [boReadFormulas];
|
||||
workbook.ReadFromFile(TempFile, AFormat);
|
||||
workbook.CalcFormulas;
|
||||
// workbook.CalcFormulas;
|
||||
|
||||
if AFormat = sfExcel2 then
|
||||
Fail('This test should not be executed')
|
||||
@ -770,7 +770,7 @@ begin
|
||||
if expected.ResultType = rtInteger then expected := FloatResult(expected.ResInteger);
|
||||
|
||||
{
|
||||
// The now function result is volatile, i.e. changes continuously. The
|
||||
// The NOW() function result is volatile, i.e. changes continuously. The
|
||||
// time for the soll value was created such that we can expect to have
|
||||
// the file value in the same second. Therefore we neglect the milliseconds.
|
||||
if formula = '=NOW()' then begin
|
||||
|
@ -55,9 +55,11 @@ type
|
||||
procedure SumMultiSheetRange_OOXML;
|
||||
procedure SumMultiSheetRange_ODS;
|
||||
|
||||
procedure SumMultiSheetRange_FlippedCells_BIFF8;
|
||||
procedure SumMultiSheetRange_FlippedCells_OOXML;
|
||||
procedure SumMultiSheetRange_FlippedSheets_OOXML;
|
||||
procedure SumMultiSheetRange_FlippedSheetsAndCells_OOXML;
|
||||
procedure SumMultiSheetRange_FlippedSheetsAndCells_ODS;
|
||||
|
||||
end;
|
||||
|
||||
@ -139,7 +141,7 @@ begin
|
||||
|
||||
// Read formula before saving
|
||||
actualFormula := cell^.Formulavalue;
|
||||
CheckEquals(AExpectedFormula, actualFormula, 'Unsaved formula text mismatch');
|
||||
CheckEquals(AFormula, actualFormula, 'Unsaved formula text mismatch');
|
||||
|
||||
// Read calculated value before saving
|
||||
actualvalue := worksheet.ReadAsNumber(TESTCELL_ROW, TESTCELL_COL);
|
||||
@ -164,6 +166,7 @@ begin
|
||||
|
||||
cell := worksheet.FindCell(TESTCELL_ROW, TESTCELL_COL);
|
||||
actualformula := cell^.FormulaValue;
|
||||
// When writing ranges are reconstructed in correct order.
|
||||
CheckEquals(AExpectedFormula, actualformula, 'Saved formula text mismatch.');
|
||||
finally
|
||||
workbook.Free;
|
||||
@ -301,19 +304,35 @@ end;
|
||||
|
||||
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheetsAndCells_OOXML;
|
||||
begin
|
||||
TestFloatFormula('SUM(Sheet3:Sheet2!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)');
|
||||
// In OOXML the range is written literally.
|
||||
TestFloatFormula('SUM(Sheet3:Sheet2!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOOXML);
|
||||
end;
|
||||
|
||||
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheetsAndCells_ODS;
|
||||
begin
|
||||
// ODS requires conversion of the formula which results in reordering of ranges.
|
||||
TestFloatFormula('SUM(Sheet3:Sheet2!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOpenDocument, 'SUM(Sheet2:Sheet3!C3:C5)');
|
||||
end;
|
||||
|
||||
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedCells_BIFF8;
|
||||
begin
|
||||
// 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)');
|
||||
end;
|
||||
|
||||
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedCells_OOXML;
|
||||
begin
|
||||
TestFloatFormula('SUM(Sheet2:Sheet3!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)');
|
||||
// In OOXML the range is written literally.
|
||||
TestFloatFormula('SUM(Sheet2:Sheet3!C5:C3)', 55.0, ftkCellRangeSheetRange, sfOOXML);
|
||||
end;
|
||||
|
||||
procedure TSpreadSingleFormulaTests.SumMultiSheetRange_FlippedSheets_OOXML;
|
||||
begin
|
||||
TestFloatFormula('SUM(Sheet3:Sheet2!C3:C5)', 55.0, ftkCellRangeSheetRange, sfOOXML, 'SUM(Sheet2:Sheet3!C3:C5)');
|
||||
// In OOXML the range is written literally.
|
||||
TestFloatFormula('SUM(Sheet3:Sheet2!C3:C5)', 55.0, ftkCellRangeSheetRange, sfOOXML);
|
||||
end;
|
||||
|
||||
|
||||
initialization
|
||||
// Register to include these tests in a full run
|
||||
RegisterTest(TSpreadSingleFormulaTests);
|
||||
|
Reference in New Issue
Block a user