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);
|
||||
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;
|
||||
|
@ -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('<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
|
||||
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(
|
||||
'<c r="%s" s="%d">' +
|
||||
'<c r="%s" s="%d"%s>' +
|
||||
'<f t="shared" ref="%s" si="%d">%s</f>' +
|
||||
'%s' +
|
||||
'</c>', [
|
||||
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(
|
||||
'<c r="%s" s="%d">' +
|
||||
'<c r="%s" s="%d"%s>' +
|
||||
'<f t="shared" si="%d" />' +
|
||||
'%s' +
|
||||
'</c>', [
|
||||
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('<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(
|
||||
'<c r="%s" s="%d"%s>' +
|
||||
'<f>%s</f>' +
|
||||
|
Reference in New Issue
Block a user