diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index a104ee11a..3ec0be55e 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -1074,7 +1074,7 @@ type procedure FixCellColors(ACell: PCell); function FixColor(AColor: TsColor): TsColor; virtual; procedure FixFormat(ACell: PCell); virtual; - procedure FixRelativeReferences(ACell: PCell; var AElement: TsFormulaElement); + procedure FixRelativeReferences(ACell: PCell; var AElement: TsFormulaElement); virtual; procedure GetSheetDimensions(AWorksheet: TsWorksheet; out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal); virtual; procedure ListAllFormattingStylesCallback(ACell: PCell; AStream: TStream); diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas index bd16f4e5b..ede57fdf9 100755 --- a/components/fpspreadsheet/xlsbiff2.pas +++ b/components/fpspreadsheet/xlsbiff2.pas @@ -112,6 +112,7 @@ type procedure WriteXFRecords(AStream: TStream); protected procedure CreateNumFormatList; override; + procedure FixRelativeReferences(ACell: PCell; var AElement: TsFormulaElement); override; procedure ListAllNumFormats; override; procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; ACell: PCell); override; procedure WriteFormat(AStream: TStream; AFormatData: TsNumFormatData; @@ -992,6 +993,26 @@ begin end; end; +{ Since BIFF2 does not support shared formulas it cannot handle the fekCellOffset + token. It is replaced by a fekCellValue token and correct relative references. } +procedure TsSpreadBIFF2Writer.FixRelativeReferences(ACell: PCell; + var AElement: TsFormulaElement); +begin + inherited FixRelativeReferences(ACell, AElement); + + if (ACell = nil) or (ACell^.SharedFormulaBase = nil) then + exit; + + if AElement.ElementKind = fekCellOffset then + begin + AElement.ElementKind := fekCell; + if (rfRelRow in AElement.RelFlags) then + AElement.Row := Integer(ACell^.Row) + Integer(AElement.Row); // AElement.Row means here: "RowOffsset" + if (rfRelCol in AElement.RelFlags) then + AElement.Col := Integer(ACell^.Col) + Integer(AElement.Col); // AElement.Col means here: "ColOffsset" + end; +end; + { Determines the cell attributes needed for writing a cell content record, such as WriteLabel, WriteNumber, etc. The cell attributes contain, in bit masks, xf record index, font index, borders, etc.} diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas index 56764960c..fd1b41cc2 100644 --- a/components/fpspreadsheet/xlscommon.pas +++ b/components/fpspreadsheet/xlscommon.pas @@ -1607,7 +1607,7 @@ begin end; { Reads the identifier for an RPN function with fixed argument count. - Valid for BIFF4-BIFF8. Override in BIFF2-BIFF3 } + Valid for BIFF4-BIFF8. Override in BIFF2-BIFF3 which read 1 byte only. } function TsSpreadBIFFReader.ReadRPNFunc(AStream: TStream): Word; begin Result := WordLEToN(AStream.ReadWord);