diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas
index 1314385f6..0dfec3745 100755
--- a/components/fpspreadsheet/fpspreadsheet.pas
+++ b/components/fpspreadsheet/fpspreadsheet.pas
@@ -1809,9 +1809,15 @@ begin
parser := TsSpreadsheetParser.Create(self);
try
if ACell^.SharedFormulaBase = nil then
- formula := ACell^.FormulaValue
+ begin
+ formula := ACell^.FormulaValue;
+ parser.ActiveCell := nil;
+ end
else
+ begin
formula := ACell^.SharedFormulaBase^.FormulaValue;
+ parser.ActiveCell := ACell;
+ end;
parser.Expression := formula;
parser.EvaluateExpression(res);
case res.ResultType of
@@ -2654,6 +2660,7 @@ end;
{@@ If a cell contains a formula (string formula or RPN formula) the formula
is returned as a string in Excel syntax.
+ If the cell belongs to a shared formula the adapted shared formula is returned.
@param ACell Pointer to the cell considered
@param ALocalized If true, the formula is returned with decimal and list
@@ -2674,7 +2681,13 @@ begin
begin
parser := TsSpreadsheetParser.Create(self);
try
- parser.Expression := ACell^.FormulaValue;
+ if ACell^.SharedFormulaBase <> nil then begin
+ parser.ActiveCell := ACell;
+ parser.Expression := ACell^.SharedFormulaBase^.FormulaValue;
+ end else begin
+ parser.ActiveCell := nil;
+ parser.Expression := ACell^.FormulaValue;
+ end;
Result := parser.LocalizedExpression[Workbook.FormatSettings];
finally
parser.Free;
diff --git a/components/fpspreadsheet/xlsxooxml.pas b/components/fpspreadsheet/xlsxooxml.pas
index b18505353..512871b56 100755
--- a/components/fpspreadsheet/xlsxooxml.pas
+++ b/components/fpspreadsheet/xlsxooxml.pas
@@ -652,30 +652,25 @@ begin
begin
// Formula to cell
formulaStr := GetNodeValue(datanode);
- if formulaStr <> '' then
+
+ s := GetAttrValue(datanode, 't');
+ if s = 'shared' then
begin
- s := GetAttrValue(datanode, 't');
- if s = 'shared' then
+ s := GetAttrValue(datanode, 'ref');
+ if (s <>'') then
begin
- s := GetAttrValue(datanode, 'ref');
- if (s <>'') then
- begin
- cell^.FormulaValue := formulaStr;
- FWorksheet.UseSharedFormula(s, cell);
- end;
- end
- else
- cell^.FormulaValue := formulaStr;
- end;
+ AWorksheet.WriteFormula(cell, formulaStr);
+// cell^.FormulaValue := formulaStr;
+ FWorksheet.UseSharedFormula(s, cell);
+ end;
+ end
+ else
+ AWorksheet.WriteFormula(cell, formulaStr);
+// cell^.FormulaValue := formulaStr;
end;
datanode := datanode.NextSibling;
end;
-{ // formula to cell
- if formulaStr <> '' then
- cell^.FormulaValue.FormulaStr := '=' + formulaStr;
- }
-
// get data type
s := GetAttrValue(ANode, 't'); // "t" = data type
if (s = '') and (dataStr = '') then
@@ -2533,7 +2528,8 @@ procedure TsSpreadOOXMLWriter.WriteFormula(AStream: TStream;
var
cellPosText: String;
lStyleIndex: Integer;
- r, c, r2, c2: Cardinal;
+ r, r1, r2: Cardinal;
+ c, c1, c2: Cardinal;
cell: PCell;
id: Cardinal;
t, v: String;
@@ -2541,91 +2537,97 @@ begin
cellPosText := TsWorksheet.CellPosToText(ARow, ACol);
lStyleIndex := GetStyleIndex(ACell);
+ case ACell^.ContentType of
+ cctFormula:
+ begin
+ t := '';
+ v := '';
+ end;
+ cctUTF8String:
+ begin
+ t := ' t="str"';
+ v := Format('%s', [UTF8TextToXMLText(ACell^.UTF8StringValue)]);
+ end;
+ cctNumber:
+ begin
+ t := '';
+ v := Format('%g', [ACell^.NumberValue], FPointSeparatorSettings);
+ end;
+ cctDateTime:
+ begin
+ t := '';
+ v := Format('%g', [ACell^.DateTimeValue], FPointSeparatorSettings);
+ end;
+ cctBool:
+ begin
+ t := ' t="b"';
+ if ACell^.BoolValue then
+ v := '1'
+ else
+ v := '0';
+ end;
+ cctError:
+ begin
+ t := ' t="e"';
+ v := Format('%s', [GetErrorValueStr(ACell^.ErrorValue)]);
+ end;
+ end;
+
// Cell uses a shared formula
if Assigned(ACell^.SharedFormulaBase) then begin
// Cell is base of the shared formula, i.e. contains the shared formula
if (ACell = ACell^.SharedFormulaBase) then
begin
// Find range of cells using this shared formula
- r2 := ACell^.Row;
- c2 := ACell^.Col;
- c := c2;
- r := r2;
+ // The base of the shared formula is the left/top edge of the range
+ r1 := ACell^.Row;
+ r2 := r1;
+ r := r1 + 1;
+ while r <= FWorksheet.GetLastRowIndex do
+ begin
+ cell := FWorksheet.FindCell(r, ACell^.Col);
+ if (cell <> nil) and (cell^.SharedFormulaBase = ACell^.SharedFormulaBase) then
+ r2 := r
+ else
+ break;
+ inc(r);
+ end;
+ c1 := ACell^.Col;
+ c2 := c1;
+ c := c1 + 1;
while c <= FWorksheet.GetLastColIndex do
begin
- cell := FWorksheet.FindCell(r, c);
+ cell := FWorksheet.FindCell(ACell^.Row, c);
if (cell <> nil) and (cell^.SharedFormulaBase = ACell^.SharedFormulaBase) then
c2 := c
else
break;
inc(c);
end;
- c := ACell^.Col;
- while r <= FWorksheet.GetLastRowIndex do
- begin
- cell := FWorksheet.FindCell(r, c);
- if (cell <> nil) and (cell^.SharedFormulaBase <> ACell^.SharedFormulaBase) then
- r2 := r
- else
- break;
- inc(r);
- end;
-
AppendToStream(AStream, Format(
- '' +
+ '' +
'%s' +
+ '%s' +
'', [
- CellPosText, lStyleIndex,
+ CellPosText, lStyleIndex, t,
GetCellRangeString(ACell^.Row, ACell^.Col, r2, c2),
PtrInt(ACell), // Use the cell pointer as ID of the shared formula
- PrepareFormula(ACell^.FormulaValue)
+ PrepareFormula(ACell^.FormulaValue),
+ v
]));
end else
// Cell uses the shared formula
AppendToStream(AStream, Format(
- '' +
+ '' +
'' +
+ '%s' +
'', [
- CellPosText, lStyleIndex,
- PtrInt(ACell^.SharedFormulaBase) // ID of the shared formula
+ CellPosText, lStyleIndex, t,
+ PtrInt(ACell^.SharedFormulaBase), // ID of the shared formula
+ v
]));
end else begin
// "normal" formula
- case ACell^.ContentType of
- cctFormula:
- begin
- t := '';
- v := '';
- end;
- cctUTF8String:
- begin
- t := ' t="str"';
- v := Format('%s', [UTF8TextToXMLText(ACell^.UTF8StringValue)]);
- end;
- cctNumber:
- begin
- t := '';
- v := Format('%g', [ACell^.NumberValue], FPointSeparatorSettings);
- end;
- cctDateTime:
- begin
- t := '';
- v := Format('%g', [ACell^.DateTimeValue], FPointSeparatorSettings);
- end;
- cctBool:
- begin
- t := ' t="b"';
- if ACell^.BoolValue then
- v := '1'
- else
- v := '0';
- end;
- cctError:
- begin
- t := ' t="e"';
- v := Format('%s', [GetErrorValueStr(ACell^.ErrorValue)]);
- end;
- end;
AppendToStream(AStream, Format(
'' +
'%s' +