You've already forked lazarus-ccr
fpspreadsheet: Fix formula being affected when a row/column is inserted/deleted in another sheet which is not part of the formula.
See forum https://forum.lazarus.freepascal.org/index.php/topic,49005.0.html Add test case covering this situation. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7342 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -269,6 +269,8 @@ begin
|
||||
referencedSheet := TsCellExprNode(AExprNode).GetSheet;
|
||||
if TsCellExprNode(AExprNode).Has3dLink and (referencedSheet <> changedSheet) then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
if TsCellExprNode(AExprNode).Col > colIndex then begin
|
||||
TsCellExprNode(AExprNode).Col := TsCellExprNode(AExprNode).Col - 1;
|
||||
MustRebuildFormulas := true;
|
||||
@ -290,6 +292,8 @@ begin
|
||||
(referencedSheet2 <> changedSheet)
|
||||
then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
rng := TsCellRangeExprNode(AExprNode).Range;
|
||||
if (rng.Col1 = colIndex) and (rng.Col2 = colIndex) then begin
|
||||
TsCellRangeExprNode(AExprNode).Error := errIllegalRef;
|
||||
@ -326,6 +330,8 @@ begin
|
||||
referencedSheet := TsCellExprNode(AExprNode).GetSheet;
|
||||
if TsCellExprNode(AExprNode).Has3dLink and (referencedSheet <> changedSheet) then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
if TsCellExprNode(AExprNode).Row > rowIndex then begin
|
||||
TsCellExprNode(AExprNode).Row := TsCellExprNode(AExprNode).Row - 1;
|
||||
MustRebuildFormulas := true;
|
||||
@ -347,6 +353,10 @@ begin
|
||||
(referencedSheet2 <> changedSheet)
|
||||
then
|
||||
exit;
|
||||
|
||||
if (referencedSheet = nil) then
|
||||
exit;
|
||||
|
||||
rng := TsCellRangeExprNode(AExprNode).Range;
|
||||
if (rng.Row1 = rowIndex) and (rng.Row2 = rowIndex) then begin
|
||||
TsCellRangeExprNode(AExprNode).Error := errIllegalRef;
|
||||
@ -383,6 +393,8 @@ begin
|
||||
referencedSheet := TsCellExprNode(AExprNode).GetSheet;
|
||||
if TsCellExprNode(AExprNode).Has3dLink and (referencedSheet <> changedSheet) then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
if TsCellExprNode(AExprNode).Col >= colIndex then begin
|
||||
TsCellExprNode(AExprNode).Col := TsCellExprNode(AExprNode).Col + 1;
|
||||
MustRebuildFormulas := true;
|
||||
@ -399,6 +411,8 @@ begin
|
||||
(referencedSheet2 <> changedSheet)
|
||||
then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
rng := TsCellRangeExprNode(AExprNode).Range;
|
||||
if rng.Col1 >= colIndex then begin
|
||||
inc(rng.Col1);
|
||||
@ -429,6 +443,8 @@ begin
|
||||
referencedSheet := TsCellExprNode(AExprNode).GetSheet;
|
||||
if TsCellExprNode(AExprNode).Has3dLink and (referencedSheet <> changedSheet) then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
if TsCellExprNode(AExprNode).Row >= rowIndex then begin
|
||||
TsCellExprNode(AExprNode).Row := TsCellExprNode(AExprNode).Row + 1;
|
||||
MustRebuildFormulas := true;
|
||||
@ -445,6 +461,8 @@ begin
|
||||
(referencedSheet2 <> changedSheet)
|
||||
then
|
||||
exit;
|
||||
if referencedSheet = nil then
|
||||
exit;
|
||||
rng := TsCellRangeExprNode(AExprNode).Range;
|
||||
if rng.Row1 >= rowIndex then begin
|
||||
inc(rng.Row1);
|
||||
|
@ -55,6 +55,9 @@ type
|
||||
|
||||
procedure TestWriteRead_InsDelColRow(ATestIndex: Integer;
|
||||
AFormat: TsSpreadsheetFormat);
|
||||
|
||||
procedure TestWriteRead_InsDelColRow_FormulaOtherSheet(ATestIndex: Integer);
|
||||
|
||||
procedure TestWriteRead_HideShowColRow(IsCol: Boolean;
|
||||
IsHide: boolean; IsDefaultColRow: Boolean; AFormat: TsSpreadsheetFormat);
|
||||
|
||||
@ -339,6 +342,11 @@ type
|
||||
procedure TestWriteRead_RemovePageBreak_ColHidden_ODS;
|
||||
procedure TestWriteRead_RemovePageBreak_Row_ODS;
|
||||
procedure TestWriteRead_RemovePageBreak_RowHidden_ODS;
|
||||
|
||||
procedure TestWriteRead_InsCol_FormulaOtherSheet;
|
||||
procedure TestWriteRead_InsRow_FormulaOtherSheet;
|
||||
procedure TestWriteRead_DelCol_FormulaOtherSheet;
|
||||
procedure TestWriteRead_DelRow_FormulaOtherSheet;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -1869,6 +1877,73 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ Insert/Delete columns/rows in other sheet of formula }
|
||||
{------------------------------------------------------------------------------}
|
||||
procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_InsDelColRow_FormulaOtherSheet(
|
||||
ATestIndex: Integer);
|
||||
var
|
||||
workbook: TsWorkbook;
|
||||
worksheet1: TsWorksheet;
|
||||
worksheet2: TsWorksheet;
|
||||
expected: Double;
|
||||
actual: Double;
|
||||
begin
|
||||
workbook := TsWorkbook.Create;
|
||||
try
|
||||
workbook.Options := workbook.Options + [boAutoCalc];
|
||||
worksheet1 := workbook.AddWorksheet('Sheet 1');
|
||||
worksheet2 := workbook.AddWorksheet('Sheet 2');
|
||||
|
||||
case ATestIndex of
|
||||
0: begin // Insert a column in unaffected sheet. Formula must be unchanged.
|
||||
worksheet1.WriteNumber(0, 0, 1.0);
|
||||
worksheet1.WriteNumber(0, 1, 2.0);
|
||||
worksheet1.WriteNumber(0, 2, 4.0);
|
||||
worksheet1.WriteFormula(0, 3, 'SUM(A1:C1)');
|
||||
expected := worksheet1.ReadAsNumber(0, 3);
|
||||
worksheet2.InsertCol(1);
|
||||
actual := worksheet1.ReadAsNumber(0, 3);
|
||||
CheckEquals(expected, actual, 'Test 0: Inserting column in other sheet affects formula');
|
||||
end;
|
||||
1: begin // Delete a column from unaffected sheet. Formula must be unchanged.
|
||||
worksheet1.WriteNumber(0, 0, 1.0);
|
||||
worksheet1.WriteNumber(0, 1, 2.0);
|
||||
worksheet1.WriteNumber(0, 2, 4.0);
|
||||
worksheet1.WriteFormula(0, 3, 'SUM(A1:C1)');
|
||||
expected := worksheet1.ReadAsNumber(0, 3);
|
||||
worksheet2.DeleteCol(1);
|
||||
actual := worksheet1.ReadAsNumber(0, 3);
|
||||
CheckEquals(expected, actual, 'Test 1: Deleting column from other sheet affects formula');
|
||||
end;
|
||||
2: begin // Insert a row in unaffected sheet. Formula must be unchanged.
|
||||
worksheet1.WriteNumber(0, 0, 1.0);
|
||||
worksheet1.WriteNumber(1, 0, 2.0);
|
||||
worksheet1.WriteNumber(2, 0, 4.0);
|
||||
worksheet1.WriteFormula(3, 0, 'SUM(A1:A3)');
|
||||
expected := worksheet1.ReadAsNumber(3, 0);
|
||||
worksheet2.InsertRow(1);
|
||||
actual := worksheet1.ReadAsNumber(3, 0);
|
||||
CheckEquals(expected, actual, 'Test 2: Inserting row in other sheet affects formula');
|
||||
end;
|
||||
3: begin // Delete a row from unaffected sheet. Formula must be unchanged.
|
||||
worksheet1.WriteNumber(0, 0, 1.0);
|
||||
worksheet1.WriteNumber(1, 0, 2.0);
|
||||
worksheet1.WriteNumber(2, 0, 4.0);
|
||||
worksheet1.WriteFormula(3, 0, 'SUM(A1:A3)');
|
||||
expected := worksheet1.ReadAsNumber(3, 0);
|
||||
worksheet2.DeleteRow(1);
|
||||
actual := worksheet1.ReadAsNumber(3, 0);
|
||||
CheckEquals(expected, actual, 'Test 3: Deleting row from other sheet affects formula');
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
workbook.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ Hide/show columns/rows }
|
||||
{------------------------------------------------------------------------------}
|
||||
@ -2605,6 +2680,24 @@ begin
|
||||
TestWriteRead_RemovePageBreak_Row(true, sfOpenDocument);
|
||||
end;
|
||||
|
||||
|
||||
procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_InsCol_FormulaOtherSheet;
|
||||
begin
|
||||
TestWriteRead_InsDelColRow_FormulaOtherSheet(0);
|
||||
end;
|
||||
procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_InsRow_FormulaOtherSheet;
|
||||
begin
|
||||
TestWriteRead_InsDelColRow_FormulaOtherSheet(1);
|
||||
end;
|
||||
procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_DelCol_FormulaOtherSheet;
|
||||
begin
|
||||
TestWriteRead_InsDelColRow_FormulaOtherSheet(2);
|
||||
end;
|
||||
procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_DelRow_FormulaOtherSheet;
|
||||
begin
|
||||
TestWriteRead_InsDelColRow_FormulaOtherSheet(3);
|
||||
end;
|
||||
|
||||
initialization
|
||||
RegisterTest(TSpreadWriteRead_ColRow_Tests);
|
||||
InitTestData;
|
||||
|
Reference in New Issue
Block a user