You've already forked lazarus-ccr
fpspreadsheet: Reading and writing of shared formulas working for OOXML.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3523 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -1809,9 +1809,15 @@ begin
|
|||||||
parser := TsSpreadsheetParser.Create(self);
|
parser := TsSpreadsheetParser.Create(self);
|
||||||
try
|
try
|
||||||
if ACell^.SharedFormulaBase = nil then
|
if ACell^.SharedFormulaBase = nil then
|
||||||
formula := ACell^.FormulaValue
|
begin
|
||||||
|
formula := ACell^.FormulaValue;
|
||||||
|
parser.ActiveCell := nil;
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
begin
|
||||||
formula := ACell^.SharedFormulaBase^.FormulaValue;
|
formula := ACell^.SharedFormulaBase^.FormulaValue;
|
||||||
|
parser.ActiveCell := ACell;
|
||||||
|
end;
|
||||||
parser.Expression := formula;
|
parser.Expression := formula;
|
||||||
parser.EvaluateExpression(res);
|
parser.EvaluateExpression(res);
|
||||||
case res.ResultType of
|
case res.ResultType of
|
||||||
@ -2654,6 +2660,7 @@ end;
|
|||||||
|
|
||||||
{@@ If a cell contains a formula (string formula or RPN formula) the formula
|
{@@ If a cell contains a formula (string formula or RPN formula) the formula
|
||||||
is returned as a string in Excel syntax.
|
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 ACell Pointer to the cell considered
|
||||||
@param ALocalized If true, the formula is returned with decimal and list
|
@param ALocalized If true, the formula is returned with decimal and list
|
||||||
@ -2674,7 +2681,13 @@ begin
|
|||||||
begin
|
begin
|
||||||
parser := TsSpreadsheetParser.Create(self);
|
parser := TsSpreadsheetParser.Create(self);
|
||||||
try
|
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];
|
Result := parser.LocalizedExpression[Workbook.FormatSettings];
|
||||||
finally
|
finally
|
||||||
parser.Free;
|
parser.Free;
|
||||||
|
@ -652,30 +652,25 @@ begin
|
|||||||
begin
|
begin
|
||||||
// Formula to cell
|
// Formula to cell
|
||||||
formulaStr := GetNodeValue(datanode);
|
formulaStr := GetNodeValue(datanode);
|
||||||
if formulaStr <> '' then
|
|
||||||
|
s := GetAttrValue(datanode, 't');
|
||||||
|
if s = 'shared' then
|
||||||
begin
|
begin
|
||||||
s := GetAttrValue(datanode, 't');
|
s := GetAttrValue(datanode, 'ref');
|
||||||
if s = 'shared' then
|
if (s <>'') then
|
||||||
begin
|
begin
|
||||||
s := GetAttrValue(datanode, 'ref');
|
AWorksheet.WriteFormula(cell, formulaStr);
|
||||||
if (s <>'') then
|
// cell^.FormulaValue := formulaStr;
|
||||||
begin
|
FWorksheet.UseSharedFormula(s, cell);
|
||||||
cell^.FormulaValue := formulaStr;
|
end;
|
||||||
FWorksheet.UseSharedFormula(s, cell);
|
end
|
||||||
end;
|
else
|
||||||
end
|
AWorksheet.WriteFormula(cell, formulaStr);
|
||||||
else
|
// cell^.FormulaValue := formulaStr;
|
||||||
cell^.FormulaValue := formulaStr;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
datanode := datanode.NextSibling;
|
datanode := datanode.NextSibling;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ // formula to cell
|
|
||||||
if formulaStr <> '' then
|
|
||||||
cell^.FormulaValue.FormulaStr := '=' + formulaStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get data type
|
// get data type
|
||||||
s := GetAttrValue(ANode, 't'); // "t" = data type
|
s := GetAttrValue(ANode, 't'); // "t" = data type
|
||||||
if (s = '') and (dataStr = '') then
|
if (s = '') and (dataStr = '') then
|
||||||
@ -2533,7 +2528,8 @@ procedure TsSpreadOOXMLWriter.WriteFormula(AStream: TStream;
|
|||||||
var
|
var
|
||||||
cellPosText: String;
|
cellPosText: String;
|
||||||
lStyleIndex: Integer;
|
lStyleIndex: Integer;
|
||||||
r, c, r2, c2: Cardinal;
|
r, r1, r2: Cardinal;
|
||||||
|
c, c1, c2: Cardinal;
|
||||||
cell: PCell;
|
cell: PCell;
|
||||||
id: Cardinal;
|
id: Cardinal;
|
||||||
t, v: String;
|
t, v: String;
|
||||||
@ -2541,91 +2537,97 @@ begin
|
|||||||
cellPosText := TsWorksheet.CellPosToText(ARow, ACol);
|
cellPosText := TsWorksheet.CellPosToText(ARow, ACol);
|
||||||
lStyleIndex := GetStyleIndex(ACell);
|
lStyleIndex := GetStyleIndex(ACell);
|
||||||
|
|
||||||
|
case ACell^.ContentType of
|
||||||
|
cctFormula:
|
||||||
|
begin
|
||||||
|
t := '';
|
||||||
|
v := '';
|
||||||
|
end;
|
||||||
|
cctUTF8String:
|
||||||
|
begin
|
||||||
|
t := ' t="str"';
|
||||||
|
v := Format('<v>%s</v>', [UTF8TextToXMLText(ACell^.UTF8StringValue)]);
|
||||||
|
end;
|
||||||
|
cctNumber:
|
||||||
|
begin
|
||||||
|
t := '';
|
||||||
|
v := Format('<v>%g</v>', [ACell^.NumberValue], FPointSeparatorSettings);
|
||||||
|
end;
|
||||||
|
cctDateTime:
|
||||||
|
begin
|
||||||
|
t := '';
|
||||||
|
v := Format('<v>%g</v>', [ACell^.DateTimeValue], FPointSeparatorSettings);
|
||||||
|
end;
|
||||||
|
cctBool:
|
||||||
|
begin
|
||||||
|
t := ' t="b"';
|
||||||
|
if ACell^.BoolValue then
|
||||||
|
v := '<v>1</v>'
|
||||||
|
else
|
||||||
|
v := '<v>0</v>';
|
||||||
|
end;
|
||||||
|
cctError:
|
||||||
|
begin
|
||||||
|
t := ' t="e"';
|
||||||
|
v := Format('<v>%s</v>', [GetErrorValueStr(ACell^.ErrorValue)]);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// Cell uses a shared formula
|
// Cell uses a shared formula
|
||||||
if Assigned(ACell^.SharedFormulaBase) then begin
|
if Assigned(ACell^.SharedFormulaBase) then begin
|
||||||
// Cell is base of the shared formula, i.e. contains the shared formula
|
// Cell is base of the shared formula, i.e. contains the shared formula
|
||||||
if (ACell = ACell^.SharedFormulaBase) then
|
if (ACell = ACell^.SharedFormulaBase) then
|
||||||
begin
|
begin
|
||||||
// Find range of cells using this shared formula
|
// Find range of cells using this shared formula
|
||||||
r2 := ACell^.Row;
|
// The base of the shared formula is the left/top edge of the range
|
||||||
c2 := ACell^.Col;
|
r1 := ACell^.Row;
|
||||||
c := c2;
|
r2 := r1;
|
||||||
r := r2;
|
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
|
while c <= FWorksheet.GetLastColIndex do
|
||||||
begin
|
begin
|
||||||
cell := FWorksheet.FindCell(r, c);
|
cell := FWorksheet.FindCell(ACell^.Row, c);
|
||||||
if (cell <> nil) and (cell^.SharedFormulaBase = ACell^.SharedFormulaBase) then
|
if (cell <> nil) and (cell^.SharedFormulaBase = ACell^.SharedFormulaBase) then
|
||||||
c2 := c
|
c2 := c
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
inc(c);
|
inc(c);
|
||||||
end;
|
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(
|
AppendToStream(AStream, Format(
|
||||||
'<c r="%s" s="%d">' +
|
'<c r="%s" s="%d"%s>' +
|
||||||
'<f t="shared" ref="%s" si="%d">%s</f>' +
|
'<f t="shared" ref="%s" si="%d">%s</f>' +
|
||||||
|
'%s' +
|
||||||
'</c>', [
|
'</c>', [
|
||||||
CellPosText, lStyleIndex,
|
CellPosText, lStyleIndex, t,
|
||||||
GetCellRangeString(ACell^.Row, ACell^.Col, r2, c2),
|
GetCellRangeString(ACell^.Row, ACell^.Col, r2, c2),
|
||||||
PtrInt(ACell), // Use the cell pointer as ID of the shared formula
|
PtrInt(ACell), // Use the cell pointer as ID of the shared formula
|
||||||
PrepareFormula(ACell^.FormulaValue)
|
PrepareFormula(ACell^.FormulaValue),
|
||||||
|
v
|
||||||
]));
|
]));
|
||||||
end else
|
end else
|
||||||
// Cell uses the shared formula
|
// Cell uses the shared formula
|
||||||
AppendToStream(AStream, Format(
|
AppendToStream(AStream, Format(
|
||||||
'<c r="%s" s="%d">' +
|
'<c r="%s" s="%d"%s>' +
|
||||||
'<f t="shared" si="%d" />' +
|
'<f t="shared" si="%d" />' +
|
||||||
|
'%s' +
|
||||||
'</c>', [
|
'</c>', [
|
||||||
CellPosText, lStyleIndex,
|
CellPosText, lStyleIndex, t,
|
||||||
PtrInt(ACell^.SharedFormulaBase) // ID of the shared formula
|
PtrInt(ACell^.SharedFormulaBase), // ID of the shared formula
|
||||||
|
v
|
||||||
]));
|
]));
|
||||||
end else begin
|
end else begin
|
||||||
// "normal" formula
|
// "normal" formula
|
||||||
case ACell^.ContentType of
|
|
||||||
cctFormula:
|
|
||||||
begin
|
|
||||||
t := '';
|
|
||||||
v := '';
|
|
||||||
end;
|
|
||||||
cctUTF8String:
|
|
||||||
begin
|
|
||||||
t := ' t="str"';
|
|
||||||
v := Format('<v>%s</v>', [UTF8TextToXMLText(ACell^.UTF8StringValue)]);
|
|
||||||
end;
|
|
||||||
cctNumber:
|
|
||||||
begin
|
|
||||||
t := '';
|
|
||||||
v := Format('<v>%g</v>', [ACell^.NumberValue], FPointSeparatorSettings);
|
|
||||||
end;
|
|
||||||
cctDateTime:
|
|
||||||
begin
|
|
||||||
t := '';
|
|
||||||
v := Format('<v>%g</v>', [ACell^.DateTimeValue], FPointSeparatorSettings);
|
|
||||||
end;
|
|
||||||
cctBool:
|
|
||||||
begin
|
|
||||||
t := ' t="b"';
|
|
||||||
if ACell^.BoolValue then
|
|
||||||
v := '<v>1</v>'
|
|
||||||
else
|
|
||||||
v := '<v>0</v>';
|
|
||||||
end;
|
|
||||||
cctError:
|
|
||||||
begin
|
|
||||||
t := ' t="e"';
|
|
||||||
v := Format('<v>%s</v>', [GetErrorValueStr(ACell^.ErrorValue)]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
AppendToStream(AStream, Format(
|
AppendToStream(AStream, Format(
|
||||||
'<c r="%s" s="%d"%s>' +
|
'<c r="%s" s="%d"%s>' +
|
||||||
'<f>%s</f>' +
|
'<f>%s</f>' +
|
||||||
|
Reference in New Issue
Block a user