fpspreadsheet: Fix copying of formulas with absolute cell references. (https://forum.lazarus.freepascal.org/index.php/topic,67763.0.html)

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9378 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2024-07-04 17:13:09 +00:00
parent e8c71cf0d3
commit 4fa643f210

View File

@ -1562,7 +1562,7 @@ end;
{ Signals that the parser is in "CopyMode", i.e. there is are source and { Signals that the parser is in "CopyMode", i.e. there is are source and
destination cells. All relative references in the formula of the source cell destination cells. All relative references in the formula of the source cell
habe to be adapted as seen from the destination cell. } have to be adapted as seen from the destination cell. }
function TsExpressionParser.CopyMode: Boolean; function TsExpressionParser.CopyMode: Boolean;
begin begin
Result := (FDestCell <> nil) and (FSourceCell <> nil); Result := (FDestCell <> nil) and (FSourceCell <> nil);
@ -4213,17 +4213,20 @@ end;
(1) Copy mode: (1) Copy mode:
The "DestCell" of the parser is the cell for which the formula is The "DestCell" of the parser is the cell for which the formula is
calculated. The "SourceCell" contains the formula. If the formula contains calculated. The "SourceCell" contains the formula. If the formula contains
a relative address in the cell node the function calculates the row a relative address in the cell node the function calculates the column
address of the cell represented by the node as seen from the DestCell. address of the cell represented by the node as seen from the DestCell.
If the formula contains an absolute address the function returns the row If the formula contains an absolute address the function returns the column
address of the SourceCell. address of the SourceCell.
(2) Normal mode: (2) Normal mode:
Returns the "true" row address of the cell assigned to the formula node. } Returns the "true" column address of the cell assigned to the formula node. }
function TsCellExprNode.GetCol: Cardinal; function TsCellExprNode.GetCol: Cardinal;
begin begin
Result := FCol; Result := FCol;
if FParser.CopyMode and (rfRelCol in FFlags) then if FParser.CopyMode then
Result := FCol - FParser.FSourceCell^.Col + FParser.FDestCell^.Col; begin
if (rfRelCol in FFlags) then
Result := FCol - FParser.FSourceCell^.Col + FParser.FDestCell^.Col;
end;
end; end;
procedure TsCellExprNode.GetNodeValue(out AResult: TsExpressionResult); procedure TsCellExprNode.GetNodeValue(out AResult: TsExpressionResult);
@ -4285,8 +4288,11 @@ end;
function TsCellExprNode.GetRow: Cardinal; function TsCellExprNode.GetRow: Cardinal;
begin begin
Result := FRow; Result := FRow;
if Parser.CopyMode and (rfRelRow in FFlags) then if Parser.CopyMode then
Result := FRow - FParser.FSourceCell^.Row + FParser.FDestCell^.Row; begin
if (rfRelRow in FFlags) then
Result := FRow - FParser.FSourceCell^.Row + FParser.FDestCell^.Row;
end;
end; end;
function TsCellExprNode.GetSheet: TsBasicWorksheet; function TsCellExprNode.GetSheet: TsBasicWorksheet;
@ -4497,14 +4503,23 @@ end;
a relative address in the cell node the function calculates the row a relative address in the cell node the function calculates the row
address of the cell represented by the node as seen from the DestCell. address of the cell represented by the node as seen from the DestCell.
If the formula contains an absolute address the function returns the row If the formula contains an absolute address the function returns the row
address of the SourceCell. address of the current cell.
(2) Normal mode: (2) Normal mode:
Returns the "true" row address of the cell assigned to the formula node. } Returns the "true" row address of the cell assigned to the formula node. }
function TsCellRangeExprNode.GetCol(AIndex: TsCellRangeIndex): Cardinal; function TsCellRangeExprNode.GetCol(AIndex: TsCellRangeIndex): Cardinal;
var
isRel: Boolean;
begin begin
Result := FCol[AIndex]; Result := FCol[AIndex];
if FParser.CopyMode and (rfRelCol in FFlags) then if FParser.CopyMode then
Result := FCol[AIndex] - FParser.FSourceCell^.Col + FParser.FDestCell^.Col; begin
case AIndex of
1: isRel := (rfRelCol in FFlags);
2: isRel := (rfRelCol2 in FFlags);
end;
if isRel then
Result := FCol[AIndex] - FParser.FSourceCell^.Col + FParser.FDestCell^.Col;
end;
end; end;
procedure TsCellRangeExprNode.GetNodeValue(out AResult: TsExpressionResult); procedure TsCellRangeExprNode.GetNodeValue(out AResult: TsExpressionResult);
@ -4571,10 +4586,19 @@ begin
end; end;
function TsCellRangeExprNode.GetRow(AIndex: TsCellRangeIndex): Cardinal; function TsCellRangeExprNode.GetRow(AIndex: TsCellRangeIndex): Cardinal;
var
isRel: Boolean;
begin begin
Result := FRow[AIndex]; Result := FRow[AIndex];
if FParser.CopyMode and (rfRelRow in FFlags) then if FParser.CopyMode then
Result := FRow[AIndex] - FParser.FSourceCell^.Row + FParser.FDestCell^.Row; begin
case AIndex of
1: isRel := (rfRelRow in FFlags);
2: isRel := (rfRelRow2 in FFlags);
end;
if isRel then
Result := FRow[AIndex] - FParser.FSourceCell^.Row + FParser.FDestCell^.Row;
end;
end; end;
function TsCellRangeExprNode.GetWorkbook: TsBasicWorkbook; function TsCellRangeExprNode.GetWorkbook: TsBasicWorkbook;