You've already forked lazarus-ccr
fpspreadsheet: Read non-contiguous shared formulas correctly from OOXLM (BIFF8 still faulty)
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3588 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -5113,7 +5113,7 @@ var
|
||||
cellnode: TAVLTreeNode;
|
||||
col: PCol;
|
||||
i: Integer;
|
||||
r, c, ic: Cardinal;
|
||||
r, c, cc: Cardinal;
|
||||
r1, c1, r2, c2: Cardinal;
|
||||
rLast, cLast: Cardinal;
|
||||
cell, nextcell, gapcell, oldbase, newbase: PCell;
|
||||
@ -5160,7 +5160,38 @@ begin
|
||||
gapcell := GetCell(r, ACol);
|
||||
gapcell^.Mergebase := cell^.MergeBase;
|
||||
end;
|
||||
end
|
||||
else
|
||||
// A shared formula block is found immediately to the left of the
|
||||
// inserted column. If it extends to the right we have to create a new
|
||||
// shared formula base in the upper left cell. Note: Excel does not
|
||||
// extend the shared formula to the inserted column.
|
||||
if cell^.SharedFormulaBase <> nil then begin
|
||||
oldbase := cell^.SharedFormulaBase;
|
||||
// Does it extend to the right of the new column?
|
||||
nextcell := FindCell(r, ACol+1);
|
||||
if Assigned(nextcell) and (nextcell^.SharedFormulaBase = oldbase) then
|
||||
begin
|
||||
// Yes.
|
||||
// It next cell is in the top row of the block we make it a shared formula base
|
||||
if r = oldbase^.Row then
|
||||
begin
|
||||
newbase := nextcell;
|
||||
nextcell^.SharedFormulaBase := nextcell;
|
||||
nextcell^.FormulaValue := InsertColToFormula(ACol, oldbase); // ??
|
||||
// Note: the references are not correct here - we fix that later!
|
||||
end;
|
||||
// Use the new shared formulabase in all cells of the old block at the right
|
||||
for cc := ACol+1 to cLast do
|
||||
begin
|
||||
cell := FindCell(r, cc);
|
||||
if (cell = nil) or (cell^.SharedFormulaBase <> oldbase) then
|
||||
break;
|
||||
cell^.SharedFormulaBase := newbase;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
(*
|
||||
else
|
||||
// A shared formula block is found immediately before the inserted column
|
||||
@ -5198,6 +5229,8 @@ begin
|
||||
*)
|
||||
end;
|
||||
|
||||
// Fix shared formulas:
|
||||
// A shared formula block may break into two pieces if cell references Cell references to the left and to the right of
|
||||
// Seek along the column immediately to the left of the inserted column
|
||||
c := ACol - 1;
|
||||
for r := 0 to rLast do
|
||||
@ -5228,9 +5261,9 @@ begin
|
||||
end;
|
||||
// Now link all cells to the right of the new column (which still
|
||||
// use the old base) to the new base
|
||||
for ic := ACol+1 to cLast do
|
||||
for cc := ACol+1 to cLast do
|
||||
begin
|
||||
cell := FindCell(r, ic);
|
||||
cell := FindCell(r, cc);
|
||||
if (cell = nil) or (cell^.SharedFormulaBase <> oldbase) then
|
||||
break;
|
||||
cell^.SharedFormulaBase := newbase;
|
||||
|
@ -65,6 +65,7 @@ type
|
||||
FFillList: TFPList;
|
||||
FBorderList: TFPList;
|
||||
FThemeColors: array of TsColorValue;
|
||||
FSharedFormulas: TStringList;
|
||||
FWrittenByFPS: Boolean;
|
||||
procedure ReadBorders(ANode: TDOMNode);
|
||||
procedure ReadCell(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
@ -395,6 +396,8 @@ begin
|
||||
// Set up the default palette in order to have the default color names correct.
|
||||
Workbook.UseDefaultPalette;
|
||||
|
||||
FSharedFormulas := TStringList.Create;
|
||||
|
||||
FSharedStrings := TStringList.Create;
|
||||
FFillList := TFPList.Create;
|
||||
FBorderList := TFPList.Create;
|
||||
@ -418,6 +421,7 @@ begin
|
||||
FBorderList.Free;
|
||||
|
||||
FSharedStrings.Free;
|
||||
FSharedFormulas.Free;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
@ -610,7 +614,7 @@ end;
|
||||
|
||||
procedure TsSpreadOOXMLReader.ReadCell(ANode: TDOMNode; AWorksheet: TsWorksheet);
|
||||
var
|
||||
s: String;
|
||||
addr, s: String;
|
||||
rowIndex, colIndex: Cardinal;
|
||||
cell: PCell;
|
||||
datanode: TDOMNode;
|
||||
@ -623,8 +627,8 @@ begin
|
||||
exit;
|
||||
|
||||
// get row and column address
|
||||
s := GetAttrValue(ANode, 'r'); // cell address, like 'A1'
|
||||
ParseCellString(s, rowIndex, colIndex);
|
||||
addr := GetAttrValue(ANode, 'r'); // cell address, like 'A1'
|
||||
ParseCellString(addr, rowIndex, colIndex);
|
||||
|
||||
// create cell
|
||||
if FIsVirtualMode then
|
||||
@ -656,11 +660,28 @@ begin
|
||||
s := GetAttrValue(datanode, 't');
|
||||
if s = 'shared' then
|
||||
begin
|
||||
// Shared formula
|
||||
s := GetAttrValue(datanode, 'ref');
|
||||
if (s <> '') then
|
||||
AWorksheet.WriteSharedFormula(s, formulaStr);
|
||||
if (s <> '') then // This is the shared formula base
|
||||
begin
|
||||
s := GetAttrValue(datanode, 'si');
|
||||
if s <> '' then
|
||||
FSharedFormulas.AddObject(addr, Pointer(PtrInt(StrToInt(s))));
|
||||
FWorksheet.WriteFormula(cell, formulaStr);
|
||||
cell^.SharedFormulaBase := cell;
|
||||
//AWorksheet.WriteSharedFormula(s, formulaStr);
|
||||
end else
|
||||
begin
|
||||
s := GetAttrValue(datanode, 'si');
|
||||
if s <> '' then
|
||||
begin
|
||||
s := FSharedFormulas[FSharedFormulas.IndexOfObject(Pointer(PtrInt(StrToInt(s))))];
|
||||
cell^.SharedFormulaBase := FWorksheet.FindCell(s);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
// "Normal" formula
|
||||
AWorksheet.WriteFormula(cell, formulaStr);
|
||||
end;
|
||||
datanode := datanode.NextSibling;
|
||||
|
Reference in New Issue
Block a user