You've already forked lazarus-ccr
fpspreadsheet: Functional writing support for shared formulas in BIFF5 and BIFF8.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3492 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -164,7 +164,6 @@
|
||||
<Unit7>
|
||||
<Filename Value="mrumanager.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="mrumanager"/>
|
||||
</Unit7>
|
||||
<Unit8>
|
||||
<Filename Value="bemain.lfm"/>
|
||||
|
@ -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! }
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user