You've already forked lazarus-ccr
fpspreadsheet: Fix incorrect handling of cell reference by new forumula INDIRECT(). Add test cases for formula ADDRESS().
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7862 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -100,7 +100,8 @@ type
|
||||
rtFloat : (ResFloat : TsExprFloat);
|
||||
rtDateTime : (ResDateTime : TDatetime);
|
||||
rtCell : (ResRow, ResCol : Cardinal;
|
||||
ResSheetIndex : Integer);
|
||||
ResSheetIndex : Integer;
|
||||
ResSheetName : String[32]);
|
||||
rtCellRange : (ResCellRange : TsCellRange3D);
|
||||
rtHyperlink : ();
|
||||
rtString : ();
|
||||
@ -3936,7 +3937,8 @@ begin
|
||||
n := Length(FArgumentNodes);
|
||||
Result := ANext;
|
||||
for i:=0 to High(FArgumentNodes) do
|
||||
Result := FArgumentNodes[i].AsRPNItem(Result);
|
||||
if FArgumentNodes[i] <> nil then
|
||||
Result := FArgumentNodes[i].AsRPNItem(Result);
|
||||
Result := RPNFunc(FID.Name, n, Result);
|
||||
end;
|
||||
|
||||
@ -3962,7 +3964,8 @@ var
|
||||
i : Integer;
|
||||
begin
|
||||
for i := 0 to Length(FArgumentParams)-1 do
|
||||
FArgumentNodes[i].GetNodeValue(FArgumentParams[i]);
|
||||
if FArgumentNodes[i] <> nil then
|
||||
FArgumentNodes[i].GetNodeValue(FArgumentParams[i]);
|
||||
end;
|
||||
|
||||
procedure TsFunctionExprNode.Check;
|
||||
@ -4006,8 +4009,9 @@ function TsFunctionExprNode.Has3DLink: Boolean;
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
for i := 0 to Length(FArgumentParams)-1 do
|
||||
if FArgumentNodes[i].Has3DLink then exit(true);
|
||||
i := Length(FArgumentNodes);
|
||||
for i := 0 to High(FArgumentParams) do
|
||||
if (FArgumentNodes[i] <> nil) and FArgumentNodes[i].Has3DLink then exit(true);
|
||||
Result := false;
|
||||
end;
|
||||
|
||||
@ -4017,7 +4021,8 @@ var
|
||||
i: Integer;
|
||||
begin
|
||||
for i:=0 to High(FArgumentParams) do
|
||||
FArgumentNodes[i].IterateNodes(AProc, AData1, AData2, MustRebuildFormulas);
|
||||
if FArgumentNodes[i] <> nil then
|
||||
FArgumentNodes[i].IterateNodes(AProc, AData1, AData2, MustRebuildFormulas);
|
||||
end;
|
||||
|
||||
|
||||
@ -4205,7 +4210,18 @@ begin
|
||||
AResult.ResultType := rtCell;
|
||||
AResult.ResRow := GetRow;
|
||||
AResult.ResCol := GetCol;
|
||||
AResult.Worksheet := GetSheet;
|
||||
sheet := GetSheet as TsWorksheet;
|
||||
AResult.Worksheet := sheet;
|
||||
{
|
||||
if sheet = FWorksheet then
|
||||
begin
|
||||
AResult.ResSheetName := sheet.Name;
|
||||
AResult.ResSheetIndex := -1;
|
||||
end else
|
||||
begin}
|
||||
AResult.ResSheetname := sheet.Name;
|
||||
AResult.ResSheetIndex := sheet.Workbook.GetWorkSheetIndex(sheet);
|
||||
// end;
|
||||
end;
|
||||
|
||||
function TsCellExprNode.GetQuotedSheetName: String;
|
||||
@ -4795,9 +4811,21 @@ begin
|
||||
end;
|
||||
|
||||
function CellResult(AValue: String): TsExpressionResult;
|
||||
var
|
||||
p: Integer;
|
||||
begin
|
||||
Result.ResultType := rtCell;
|
||||
ParseCellString(AValue, Result.ResRow, Result.ResCol);
|
||||
p := pos('!', AValue);
|
||||
if p = 0 then
|
||||
begin
|
||||
ParseCellString(AValue, Result.ResRow, Result.ResCol);
|
||||
Result.ResSheetName := '';
|
||||
end else
|
||||
begin
|
||||
Result.ResSheetName := Copy(AValue, 1, p-1);
|
||||
ParseCellString(Copy(AValue, p+1, MaxInt), Result.ResRow, Result.ResCol);
|
||||
Result.Worksheet := nil; // this signals that the worksheet needs still to be determiend
|
||||
end;
|
||||
end;
|
||||
|
||||
function CellResult(ACellRow, ACellCol: Cardinal): TsExpressionResult;
|
||||
|
@ -2148,7 +2148,7 @@ begin
|
||||
end;
|
||||
|
||||
A1Dialect := true;
|
||||
if Length(Args) > 3 then
|
||||
if (Length(Args) > 3) and (Args[3].ResultType <> rtMissingArg) then
|
||||
A1Dialect := ArgToBoolean(Args[3]);
|
||||
|
||||
sheet := '';
|
||||
@ -2162,6 +2162,7 @@ begin
|
||||
|
||||
if sheet <> '' then resStr := sheet + '!' + resStr;
|
||||
|
||||
// Result := CellResult(resStr);
|
||||
Result := StringResult(resStr);
|
||||
end;
|
||||
|
||||
@ -2211,11 +2212,28 @@ procedure fpsINDIRECT(var Result: TsExpressionResult;
|
||||
interpreted as an R1C1-style reference.
|
||||
|
||||
NOTE: ref_style and mixing of A1 and R1C1 notation is not supported. }
|
||||
var
|
||||
sheet: TsWorksheet;
|
||||
book: TsWorkbook;
|
||||
addr: String;
|
||||
begin
|
||||
Result := ErrorResult(errArgError);
|
||||
if Length(Args) = 0 then
|
||||
exit;
|
||||
Result := Args[0];
|
||||
if (Args[0].ResultType = rtCell) then begin
|
||||
if Args[0].ResSheetIndex = -1 then
|
||||
sheet := TsWorksheet(Args[0].Worksheet)
|
||||
else
|
||||
begin
|
||||
book := TsWorksheet(Args[0].Worksheet).Workbook;
|
||||
sheet := book.GetWorksheetByIndex(Args[0].ResSheetIndex);
|
||||
end;
|
||||
addr := sheet.ReadAsText(Args[0].ResRow, Args[0].ResCol);
|
||||
Result := CellResult(addr);
|
||||
Result.Worksheet := sheet;
|
||||
end else
|
||||
if (Args[0].ResultType = rtString) then
|
||||
Result := CellResult(Args[0].ResString);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -1370,6 +1370,15 @@ begin
|
||||
end;
|
||||
rtBoolean : WriteBoolValue(lCell, res.ResBoolean);
|
||||
rtCell : begin
|
||||
if res.Worksheet = nil then
|
||||
begin
|
||||
if res.ResSheetName = '' then
|
||||
res.Worksheet := self
|
||||
else
|
||||
res.Worksheet := Workbook.GetWorksheetByName(res.ResSheetName);
|
||||
end else
|
||||
if res.ResSheetName <> '' then
|
||||
res.Worksheet := Workbook.GetWorksheetByName(res.ResSheetname);
|
||||
lCellRef := (res.Worksheet as TsWorksheet).FindCell(res.ResRow, res.ResCol);
|
||||
if lCellRef <> nil then
|
||||
case lCellRef^.ContentType of
|
||||
|
@ -1,13 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="12"/>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
<General>
|
||||
<Flags>
|
||||
<CompatibilityMode Value="True"/>
|
||||
</Flags>
|
||||
<SessionStorage Value="InProjectDir"/>
|
||||
<MainUnit Value="0"/>
|
||||
<Title Value="spreadtestgui"/>
|
||||
<ResourceType Value="res"/>
|
||||
</General>
|
||||
|
@ -3347,9 +3347,48 @@
|
||||
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ Lookup / reference functions }
|
||||
{ Lookup / reference functions }
|
||||
{------------------------------------------------------------------------------}
|
||||
{
|
||||
|
||||
// ADDRESS
|
||||
|
||||
inc(Row);
|
||||
formula := 'ADDRESS(1,1)';
|
||||
MyWorksheet.WriteText(Row, 0, formula);
|
||||
{
|
||||
if UseRPNFormula then
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
RPNInteger(1,
|
||||
RPNInteger(1,
|
||||
RPNFunc('ADDRESS', nil))))) // ---> does not work...
|
||||
else
|
||||
}
|
||||
MyWorksheet.WriteFormula(Row, 1, formula);
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := StringResult('$A$1');
|
||||
|
||||
inc(Row);
|
||||
formula := 'ADDRESS(1,1,4)';
|
||||
MyWorksheet.WriteText(Row, 0, formula);
|
||||
MyWorksheet.WriteFormula(Row, 1, formula);
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := StringResult('A1');
|
||||
|
||||
inc(Row);
|
||||
formula := 'ADDRESS(1,1,,,"Sheet2")';
|
||||
MyWorksheet.WriteText(Row, 0, formula);
|
||||
Myworksheet.WriteFormula(Row, 1, formula);
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := StringResult('Sheet2!$A$1');
|
||||
|
||||
inc(Row);
|
||||
formula := 'ADDRESS(1,1,,FALSE,"Sheet2")';
|
||||
MyWorksheet.WriteText(Row, 0, formula);
|
||||
Myworksheet.WriteFormula(Row, 1, formula);
|
||||
SetLength(sollValues, Row+1);
|
||||
sollValues[Row] := StringResult('Sheet2!R1C1');
|
||||
|
||||
{
|
||||
// COLUMN
|
||||
MyWorksheet.WriteText(Row, 0, 'COLUMN(A1)');
|
||||
MyWorksheet.WriteRPNFormula(Row, 1, CreateRPNFormula(
|
||||
|
Reference in New Issue
Block a user