diff --git a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi b/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi
index 011054dc2..ae8bd0e7a 100644
--- a/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi
+++ b/components/fpspreadsheet/reference/BIFFExplorer/BIFFExplorer.lpi
@@ -164,7 +164,6 @@
-
diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas
index d58ad14e9..df0f19238 100755
--- a/components/fpspreadsheet/xlsbiff5.pas
+++ b/components/fpspreadsheet/xlsbiff5.pas
@@ -119,7 +119,6 @@ type
procedure WriteIndex(AStream: TStream);
procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal;
const AValue: string; ACell: PCell); override;
- procedure WriteSharedFormulaRange(AStream: TStream; const ARange: TRect); override;
procedure WriteStringRecord(AStream: TStream; AString: String); override;
procedure WriteStyle(AStream: TStream);
procedure WriteWindow2(AStream: TStream; ASheet: TsWorksheet);
@@ -380,7 +379,6 @@ var
CurrentPos: Int64;
Boundsheets: array of Int64;
i, len: Integer;
- sheet : TsWorksheet;
pane: Byte;
begin
{ Store some data about the workbook that other routines need }
@@ -414,7 +412,7 @@ begin
for i := 0 to Workbook.GetWorksheetCount - 1 do
begin
- sheet := Workbook.GetWorksheetByIndex(i);
+ FWorksheet := Workbook.GetWorksheetByIndex(i);
{ First goes back and writes the position of the BOF of the
sheet on the respective BOUNDSHEET record }
@@ -427,18 +425,18 @@ begin
WriteIndex(AStream);
// WritePageSetup(AStream);
- WriteColInfos(AStream, sheet);
- WriteDimensions(AStream, sheet);
- WriteWindow2(AStream, sheet);
- WritePane(AStream, sheet, true, pane); // true for "is BIFF5 or BIFF8"
- WriteSelection(AStream, sheet, pane);
+ WriteColInfos(AStream, FWorksheet);
+ WriteDimensions(AStream, FWorksheet);
+ WriteWindow2(AStream, FWorksheet);
+ WritePane(AStream, FWorksheet, true, pane); // true for "is BIFF5 or BIFF8"
+ WriteSelection(AStream, FWorksheet, pane);
//WriteRows(AStream, sheet);
if (boVirtualMode in Workbook.Options) then
WriteVirtualCells(AStream)
else begin
- WriteRows(AStream, sheet);
- WriteCellsToStream(AStream, sheet.Cells);
+ WriteRows(AStream, FWorksheet);
+ WriteCellsToStream(AStream, FWorksheet.Cells);
end;
WriteEOF(AStream);
@@ -838,18 +836,6 @@ begin
SetLength(buf, 0);
end;
-{ Writes the borders of the cell range covered by a shared formula.
- Needs to be overridden to write the column data (2 bytes in case of BIFF8). }
-procedure TsSpreadBIFF5Writer.WriteSharedFormulaRange(AStream: TStream;
- const ARange: TRect);
-begin
- inherited WriteSharedFormulaRange(AStream, ARange);
- // Index to first column
- AStream.WriteByte(ARange.Left);
- // Index to last rcolumn
- AStream.WriteByte(ARange.Right);
-end;
-
{ Writes an Excel 5 STRING record which immediately follows a FORMULA record
when the formula result is a string.
BIFF5 writes a byte-string, but uses a 16-bit length here! }
diff --git a/components/fpspreadsheet/xlsbiff8.pas b/components/fpspreadsheet/xlsbiff8.pas
index d28ba11f9..37f640c62 100755
--- a/components/fpspreadsheet/xlsbiff8.pas
+++ b/components/fpspreadsheet/xlsbiff8.pas
@@ -127,7 +127,7 @@ type
AFlags: TsRelFlags): Word; override;
function WriteRPNCellRangeAddress(AStream: TStream; ARow1, ACol1, ARow2, ACol2: Cardinal;
AFlags: TsRelFlags): Word; override;
- procedure WriteSharedFormulaRange(AStream: TStream; const ARange: TRect); override;
+// procedure WriteSharedFormulaRange(AStream: TStream; const ARange: TRect); override;
function WriteString_8bitLen(AStream: TStream; AString: String): Integer; override;
procedure WriteStringRecord(AStream: TStream; AString: string); override;
procedure WriteStyle(AStream: TStream);
@@ -435,7 +435,6 @@ const
var
CurrentPos: Int64;
Boundsheets: array of Int64;
- sheet: TsWorksheet;
i, len: Integer;
pane: Byte;
begin
@@ -465,8 +464,7 @@ begin
for i := 0 to Workbook.GetWorksheetCount - 1 do
begin
- sheet := Workbook.GetWorksheetByIndex(i);
- FWorksheet := sheet;
+ FWorksheet := Workbook.GetWorksheetByIndex(i);
{ First goes back and writes the position of the BOF of the
sheet on the respective BOUNDSHEET record }
@@ -479,20 +477,20 @@ begin
WriteIndex(AStream);
//WriteSheetPR(AStream);
// WritePageSetup(AStream);
- WriteColInfos(AStream, sheet);
- WriteDimensions(AStream, sheet);
+ WriteColInfos(AStream, FWorksheet);
+ WriteDimensions(AStream, FWorksheet);
//WriteRowAndCellBlock(AStream, sheet);
if (boVirtualMode in Workbook.Options) then
WriteVirtualCells(AStream)
else begin
- WriteRows(AStream, sheet);
- WriteCellsToStream(AStream, sheet.Cells);
+ WriteRows(AStream, FWorksheet);
+ WriteCellsToStream(AStream, FWorksheet.Cells);
end;
- WriteWindow2(AStream, sheet);
- WritePane(AStream, sheet, isBIFF8, pane);
- WriteSelection(AStream, sheet, pane);
+ WriteWindow2(AStream, FWorksheet);
+ WritePane(AStream, FWorksheet, isBIFF8, pane);
+ WriteSelection(AStream, FWorksheet, pane);
WriteEOF(AStream);
end;
@@ -800,13 +798,15 @@ end;
function TsSpreadBIFF8Writer.WriteRPNCellOffset(AStream: TStream;
ARowOffset, AColOffset: Integer; AFlags: TsRelFlags): Word;
var
- c: Word;
+ c: word;
+ r: SmallInt;
begin
// row address
- AStream.WriteWord(WordToLE(Word(Lo(ARowOffset))));
+ r := SmallInt(ARowOffset);
+ AStream.WriteWord(WordToLE(Word(r)));
// Encoded column address
- c := word(Lo(AColOffset)) and MASK_EXCEL_COL_BITS_BIFF8;
+ c := word(SmallInt(AColOffset)) and MASK_EXCEL_COL_BITS_BIFF8;
if (rfRelRow in AFlags) then c := c or MASK_EXCEL_RELATIVE_ROW_BIFF8;
if (rfRelCol in AFlags) then c := c or MASK_EXCEL_RELATIVE_COL_BIFF8;
AStream.WriteWord(WordToLE(c));
@@ -836,18 +836,21 @@ begin
Result := 8;
end;
-
+ (*
{ Writes the borders of the cell range covered by a shared formula.
Needs to be overridden to write the column data (2 bytes in case of BIFF8). }
procedure TsSpreadBIFF8Writer.WriteSharedFormulaRange(AStream: TStream;
const ARange: TRect);
begin
inherited WriteSharedFormulaRange(AStream, ARange);
+ {
// Index to first column
AStream.WriteWord(WordToLE(ARange.Left));
// Index to last rcolumn
AStream.WriteWord(WordToLE(ARange.Right));
+ }
end;
+*)
{ Helper function for writing a string with 8-bit length. Overridden version
for BIFF8. Called for writing rpn formula string tokens.
diff --git a/components/fpspreadsheet/xlscommon.pas b/components/fpspreadsheet/xlscommon.pas
index e8ec2c955..e35f62069 100644
--- a/components/fpspreadsheet/xlscommon.pas
+++ b/components/fpspreadsheet/xlscommon.pas
@@ -2555,13 +2555,13 @@ end;
{ Is called from WriteRPNFormula in the case that the cell uses a shared
formula and writes the token "array" pointing to the shared formula base.
- This implementation is valid for BIFF5 and BIFF8. BIFF2 does not support
- shared formulas; the BIFF2 writer must copy the formula found in the
+ This implementation is valid for BIFF3-BIFF8. BIFF2 is different, but does not
+ support shared formulas; the BIFF2 writer must copy the formula found in the
SharedFormulaBase field of the cell and adjust the relative references. }
procedure TsSpreadBIFFWriter.WriteRPNSharedFormulaLink(AStream: TStream;
ACell: PCell; var RPNLength: Word);
type
- TSharedFormulaLinkRecord = record
+ TSharedFormulaLinkRecord = packed record
FormulaSize: Word; // Size of token array
Token: Byte; // 1st (and only) token of the rpn formula array
Row: Word; // row of cell containing the shared formula
@@ -2570,6 +2570,7 @@ type
var
rec: TSharedFormulaLinkRecord;
begin
+ FillChar(rec, SizeOf(rec), 0);
rec.FormulaSize := WordToLE(5);
rec.Token := INT_EXCEL_TOKEN_TEXP; // Marks the cell for using a shared formula
rec.Row := WordToLE(ACell^.SharedFormulaBase.Row);
@@ -2636,7 +2637,7 @@ begin
begin
n := WriteRPNCellOffset(
AStream,
- AFormula[i].Row, AFormula[i].Col,
+ integer(AFormula[i].Row), integer(AFormula[i].Col),
AFormula[i].RelFlags
);
inc(RPNLength, n);
@@ -2928,6 +2929,12 @@ begin
// Write borders of cell range covered by the formula
WriteSharedFormulaRange(AStream, range);
+ // Not used
+ AStream.WriteByte(0);
+
+ // Number of existing formula records
+ AStream.WriteByte((range.Right-range.Left+1)*(range.Bottom-range.Top+1));
+
// Copy the formula (we don't want to overwrite the cell formulas)
// and adjust relative references
SetLength(formula, Length(ACell^.SharedFormulaBase^.RPNFormulaValue));
@@ -2936,7 +2943,7 @@ begin
FixRelativeReferences(ACell, formula[i]);
end;
// Writes the (copied) rpn token array
- WriteRPNTokenArray(AStream, formula, false, RPNLength);
+ WriteRPNTokenArray(AStream, formula, true, RPNLength);
{ Write record size at the end after we known it }
finalPos := AStream.Position;
@@ -2946,9 +2953,8 @@ begin
end;
{ Writes the borders of the cell range covered by a shared formula.
- Needs to be overridden by BIFF5 and BIFF8 to write the column data
- (1 byte in BIFF5, 2 bytes in BIFF8). No need for BIFF2 which does not
- support shared formulas. }
+ Valid for BIFF5 and BIFF8 - BIFF8 writes 8-bit column index as well.
+ No need for BIFF2 which does not support shared formulas. }
procedure TsSpreadBIFFWriter.WriteSharedFormulaRange(AStream: TStream;
const ARange: TRect);
begin
@@ -2956,8 +2962,10 @@ begin
AStream.WriteWord(WordToLE(ARange.Top));
// Index to last row
AStream.WriteWord(WordToLE(ARange.Bottom));
-
- // column indexes follow in overridden procedure!
+ // Index to first column
+ AStream.WriteByte(Lo(ARange.Left));
+ // Index to last rcolumn
+ AStream.WriteByte(Lo(ARange.Right));
end;