You've already forked lazarus-ccr
fpspreadsheet: Fix absolute/relative cell reference issues when reading shared formulas. Update BIFFExplorer for shared formulas. Implement reading of shared formulas for biff5 (nothing to be done for biff2 which does not support shared formulas).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3490 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -1146,7 +1146,8 @@ type
|
||||
ANext: PRPNItem): PRPNItem; overload;
|
||||
function RPNCellRange(ARow, ACol, ARow2, ACol2: Integer; AFlags: TsRelFlags;
|
||||
ANext: PRPNItem): PRPNItem; overload;
|
||||
function RPNCellOffset(ARowOffset, AColOffset: Integer; ANext: PRPNItem): PRPNItem;
|
||||
function RPNCellOffset(ARowOffset, AColOffset: Integer; AFlags: TsRelFlags;
|
||||
ANext: PRPNItem): PRPNItem;
|
||||
function RPNErr(AErrCode: Byte; ANext: PRPNItem): PRPNItem;
|
||||
function RPNInteger(AValue: Word; ANext: PRPNItem): PRPNItem;
|
||||
function RPNMissingArg(ANext: PRPNItem): PRPNItem;
|
||||
@ -2707,6 +2708,7 @@ var
|
||||
ptr: Pointer;
|
||||
fek: TFEKind;
|
||||
formula: TsRPNFormula;
|
||||
r,c: Cardinal;
|
||||
begin
|
||||
Result := '';
|
||||
if ACell = nil then
|
||||
@ -2721,6 +2723,9 @@ begin
|
||||
else
|
||||
formula := ACell^.SharedFormulaBase^.RPNFormulaValue;
|
||||
|
||||
if Length(formula) = 0 then
|
||||
exit;
|
||||
|
||||
// We store the cell values and operation codes in a stringlist which serves
|
||||
// as kind of stack. Therefore, we do not destroy the original formula array.
|
||||
// We reverse the order of the items because in the next step stringlist
|
||||
@ -2744,7 +2749,15 @@ begin
|
||||
fekCellRange:
|
||||
L.AddObject(GetCellRangeString(elem.Row, elem.Col, elem.Row2, elem.Col2, elem.RelFlags), ptr);
|
||||
fekCellOffset:
|
||||
L.AddObject(GetCellString(ACell^.Row + SmallInt(elem.Row), ACell^.Col + SmallInt(elem.Col)), ptr);
|
||||
begin
|
||||
if rfRelRow in elem.RelFlags
|
||||
then r := ACell^.Row + SmallInt(elem.Row)
|
||||
else r := elem.Row;
|
||||
if rfRelCol in elem.RelFlags
|
||||
then c := ACell^.Col + SmallInt(elem.Col)
|
||||
else c := elem.Col;
|
||||
L.AddObject(GetCellString(r, c, elem.RelFlags), ptr);
|
||||
end
|
||||
// Operations:
|
||||
else
|
||||
L.AddObject(FEProps[elem.ElementKind].Symbol, ptr);
|
||||
@ -7195,15 +7208,17 @@ end;
|
||||
|
||||
@param ARowOffset Offset between current row and the row of a reference cell
|
||||
@param AColOffset Offset between current column and the column of a reference cell
|
||||
@param AFlags Flags specifying absolute or relative cell addresses
|
||||
@param ANext Pointer to the next RPN item in the list
|
||||
}
|
||||
function RPNCellOffset(ARowOffset, AColOffset: Integer; ANext: PRPNItem): PRPNItem;
|
||||
function RPNCellOffset(ARowOffset, AColOffset: Integer; AFlags: TsRelFlags;
|
||||
ANext: PRPNItem): PRPNItem;
|
||||
begin
|
||||
Result := NewRPNItem;
|
||||
Result^.FE.ElementKind := fekCellOffset;
|
||||
Result^.FE.Row := ARowOffset;
|
||||
Result^.FE.Col := AColOffset;
|
||||
Result^.FE.RelFlags := [rfRelRow, rfRelCol];
|
||||
Result^.FE.RelFlags := AFlags;
|
||||
Result^.Next := ANext;
|
||||
end;
|
||||
|
||||
|
@ -702,6 +702,8 @@ end;
|
||||
|
||||
|
||||
procedure TBIFFGrid.ShowCellAddress;
|
||||
{ Note: The bitmask assignment to relative column/row is reversed in relation
|
||||
to OpenOffice documentation in order to match with Excel files. }
|
||||
var
|
||||
numBytes: Word;
|
||||
b: Byte;
|
||||
@ -726,15 +728,16 @@ begin
|
||||
FDetails.Add('ColIndex information:'#13);
|
||||
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c and $3FFF, ABS_REL[c and $8000 <> 0]]));
|
||||
if c and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: absolute row index')
|
||||
else FDetails.Add('Bit 14=1: relative row index');
|
||||
then FDetails.Add('Bit 14=0: absolute column index')
|
||||
else FDetails.Add('Bit 14=1: relative column index');
|
||||
if c and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: absolute column index')
|
||||
else FDetails.Add('Bit 15=1: relative column index');
|
||||
then FDetails.Add('Bit 15=0: absolute row index')
|
||||
else FDetails.Add('Bit 15=1: relative row index');
|
||||
end;
|
||||
s := Format('%d ($%.4x)', [c, c]);
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Column index');
|
||||
end else begin
|
||||
end else
|
||||
begin
|
||||
numbytes := 1;
|
||||
Move(FBuffer[FBufferIndex+2], b, numBytes);
|
||||
c := b;
|
||||
@ -742,11 +745,11 @@ begin
|
||||
FDetails.Add('RowIndex information:'#13);
|
||||
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r and $3FFF, ABS_REL[r and $4000 <> 0]]));
|
||||
if r and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: absolute row index')
|
||||
else FDetails.Add('Bit 14=1: relative row index');
|
||||
then FDetails.Add('Bit 14=0: absolute column index')
|
||||
else FDetails.Add('Bit 14=1: relative column index');
|
||||
if r and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: absolute column index')
|
||||
else FDetails.Add('Bit 15=1: relative column index');
|
||||
then FDetails.Add('Bit 15=0: absolute row index')
|
||||
else FDetails.Add('Bit 15=1: relative row index');
|
||||
end;
|
||||
//s := Format('$%.4x (%d, %s)', [r, r and $3FFF, ABS_REL[r and $4000 <> 0]]);
|
||||
s := Format('%d ($%.4x)', [r, r]);
|
||||
@ -763,6 +766,8 @@ end;
|
||||
|
||||
|
||||
procedure TBIFFGrid.ShowCellAddressRange;
|
||||
{ Note: The bitmask assignment to relative column/row is reversed in relation
|
||||
to OpenOffice documentation in order to match with Excel files. }
|
||||
var
|
||||
numbytes: Word;
|
||||
b: Byte;
|
||||
@ -799,11 +804,11 @@ begin
|
||||
FDetails.Add('ColIndex information:'#13);
|
||||
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c and $3FFF, ABS_REL[c and $8000 <> 0]]));
|
||||
if c and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: absolute row index')
|
||||
else FDetails.Add('Bit 14=1: relative row index');
|
||||
then FDetails.Add('Bit 14=0: absolute column index')
|
||||
else FDetails.Add('Bit 14=1: relative column index');
|
||||
if c and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: absolute column index')
|
||||
else FDetails.Add('Bit 15=1: relative column index');
|
||||
then FDetails.Add('Bit 15=0: absolute row index')
|
||||
else FDetails.Add('Bit 15=1: relative row index');
|
||||
end;
|
||||
s := Format('%d ($%.4x)', [c, c]);
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'First column index');
|
||||
@ -813,11 +818,11 @@ begin
|
||||
FDetails.Add('ColIndex information:'#13);
|
||||
FDetails.Add(Format('Bits 0-13: ColIndex = %d (%s)', [c2 and $3FFF, ABS_REL[c2 and $8000 <> 0]]));
|
||||
if c2 and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: absolute row index')
|
||||
else FDetails.Add('Bit 14=1: relative row index');
|
||||
then FDetails.Add('Bit 14=0: absolute column index')
|
||||
else FDetails.Add('Bit 14=1: relative column index');
|
||||
if c2 and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: absolute column index')
|
||||
else FDetails.Add('Bit 15=1: relative column index');
|
||||
then FDetails.Add('Bit 15=0: absolute row index')
|
||||
else FDetails.Add('Bit 15=1: relative row index');
|
||||
end;
|
||||
s := Format('%d ($%.4x)', [c2, c2]);
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, s, 'Last column index');
|
||||
@ -839,11 +844,11 @@ begin
|
||||
FDetails.Add('RowIndex information:'#13);
|
||||
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r and $3FFF, ABS_REL[r and $4000 <> 0]]));
|
||||
if r and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: absolute row index')
|
||||
else FDetails.Add('Bit 14=1: relative row index');
|
||||
then FDetails.Add('Bit 14=0: absolute column index')
|
||||
else FDetails.Add('Bit 14=1: relative column index');
|
||||
if r and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: absolute column index')
|
||||
else FDetails.Add('Bit 15=1: relative column index');
|
||||
then FDetails.Add('Bit 15=0: absolute row index')
|
||||
else FDetails.Add('Bit 15=1: relative row index');
|
||||
end;
|
||||
s := Format('%d ($%.4x)', [r, r]);
|
||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'First row index');
|
||||
@ -853,11 +858,11 @@ begin
|
||||
FDetails.Add('RowIndex information:'#13);
|
||||
FDetails.Add(Format('Bits 0-13: RowIndex = %d (%s)', [r2 and $3FFF, ABS_REL[r2 and $4000 <> 0]]));
|
||||
if r2 and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: absolute row index')
|
||||
else FDetails.Add('Bit 14=1: relative row index');
|
||||
then FDetails.Add('Bit 14=0: absolute column index')
|
||||
else FDetails.Add('Bit 14=1: relative column index');
|
||||
if r2 and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: absolute column index')
|
||||
else FDetails.Add('Bit 15=1: relative column index');
|
||||
then FDetails.Add('Bit 15=0: absolute row index')
|
||||
else FDetails.Add('Bit 15=1: relative row index');
|
||||
end;
|
||||
s := Format('%d ($%.4x)', [r2, r2]);
|
||||
ShowInRow(FCurrRow, FBufferIndex, 2, s, 'Last row index');
|
||||
@ -2373,6 +2378,7 @@ var
|
||||
dbl: Double;
|
||||
firstTokenBufIndex: Integer;
|
||||
token: Byte;
|
||||
r, c: Word;
|
||||
begin
|
||||
// Tokens and parameters
|
||||
firstTokenBufIndex := FBufferIndex;
|
||||
@ -2599,52 +2605,96 @@ begin
|
||||
if FFormat = sfExcel8 then
|
||||
begin
|
||||
numBytes := 2;
|
||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||
w := WordLEToN(w);
|
||||
Move(FBuffer[FBufferIndex], w, numBytes); // row
|
||||
r := WordLEToN(w);
|
||||
Move(FBuffer[FBufferIndex+2], w, numBytes); // column with flags
|
||||
c := WordLEToN(w);
|
||||
|
||||
{ Note: The bitmask assignment to relative column/row is reversed in relation
|
||||
to OpenOffice documentation in order to match with Excel files. }
|
||||
if Row = FCurrRow then begin
|
||||
FDetails.Add('Encoded cell address (row):'#13);
|
||||
FDetails.Add('Relative row index: ' + IntToStr(Smallint(w)));
|
||||
if c and $8000 = 0 then
|
||||
begin
|
||||
FDetails.Add('Row index is ABSOLUTE (see Encoded column index)');
|
||||
FDetails.Add('Absolute row index: ' + IntToStr(r));
|
||||
end else
|
||||
begin
|
||||
FDetails.Add('Row index is RELATIVE (see Encoded column index)');
|
||||
FDetails.Add('Relative row index: ' + IntToStr(Smallint(r)));
|
||||
end;
|
||||
end;
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d', [SmallInt(w)]),
|
||||
'Relative row index');
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [r, r]),
|
||||
'Encoded row index');
|
||||
|
||||
numBytes := 2;
|
||||
Move(FBuffer[FBufferIndex], w, numbytes);
|
||||
w := WordLEToN(w);
|
||||
b := Lo(w);
|
||||
// Bit mask $4000 --> column
|
||||
// Bit mask $8000 --> row
|
||||
if Row = FCurrRow then
|
||||
begin
|
||||
FDetails.Add('Encoded cell address (column):'#13);
|
||||
FDetails.Add('Relative column index: ' + IntToStr(ShortInt(b)));
|
||||
if c and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: Column index is ABSOLUTE')
|
||||
else FDetails.Add('Bit 14=1: Column index is RELATIVE');
|
||||
if c and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: Row index is ABSOLUTE')
|
||||
else FDetails.Add('Bit 15=1: Row index is RELATIVE');
|
||||
FDetails.Add('');
|
||||
if c and $4000 = 0
|
||||
then FDetails.Add('Absolute column index: ' + IntToStr(Lo(c)))
|
||||
else FDetails.Add('Relative column index: ' + IntToStr(ShortInt(Lo(c))));
|
||||
end;
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d', [ShortInt(b)]),
|
||||
'Relative column index');
|
||||
end else
|
||||
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [c, c]),
|
||||
'Encoded column index');
|
||||
end
|
||||
else
|
||||
// Excel5 (Excel2 does not support shared formulas)
|
||||
begin
|
||||
numBytes := 2;
|
||||
Move(FBuffer[FBufferIndex], w, numBytes);
|
||||
w := WordLEToN(w) and $3FFF;
|
||||
w := WordLEToN(w);
|
||||
r := w and $3FFF;
|
||||
b := FBuffer[FBufferIndex+2];
|
||||
c := b;
|
||||
|
||||
// Bit mask $4000 --> column
|
||||
// Bit mask $8000 --> row
|
||||
if Row = FCurrRow then begin
|
||||
FDetails.Add('Encoded cell address (row):'#13);
|
||||
FDetails.Add('Relative row index: ' + IntToStr(Smallint(w)));
|
||||
if w and $4000 = 0
|
||||
then FDetails.Add('Bit 14=0: Column index is ABSOLUTE')
|
||||
else FDetails.Add('Bit 14=0: Column index is RELATIVE');
|
||||
if w and $8000 = 0
|
||||
then FDetails.Add('Bit 15=0: Row index is ABSOLUTE')
|
||||
else FDetails.Add('Bit 15=1: Row index is RELATIVE');
|
||||
FDetails.Add('');
|
||||
if w and $8000 = 0
|
||||
then FDetails.Add('Absolute row index: ' + IntToStr(r))
|
||||
else FDetails.Add('Relative row index: ' + IntToStr(Smallint(r)));
|
||||
end;
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d', [SmallInt(w)]),
|
||||
'Relative row index');
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.4x)', [w, w]),
|
||||
'Encoded row index');
|
||||
|
||||
numBytes := 1;
|
||||
b := FBuffer[FBufferIndex];
|
||||
if Row = FCurrRow then
|
||||
begin
|
||||
FDetails.Add('Encoded cell address (column):'#13);
|
||||
FDetails.Add('Relative column index: ' + IntToStr(ShortInt(b)));
|
||||
if w and $4000 = 0 then begin
|
||||
FDetails.Add('Column index is ABSOLUTE (see Encoded row index)');
|
||||
FDetails.Add('Absolute column index: ' + IntToStr(c));
|
||||
end else begin
|
||||
FDetails.Add('Column index is RELATIVE (see Encoded row index)');
|
||||
FDetails.Add('Relative column index: ' + IntToStr(ShortInt(c)));
|
||||
end;
|
||||
end;
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d', [ShortInt(b)]),
|
||||
'Relative column index');
|
||||
numBytes := 1;
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('%d ($%.2x)', [b, b]),
|
||||
'Encoded column index');
|
||||
end;
|
||||
end;
|
||||
|
||||
else
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||
'(unknown token)');
|
||||
ShowInRow(FCurrRow, FBufferIndex, numBytes, Format('$%.2x', [token]),
|
||||
'(unknown token)');
|
||||
|
||||
end; // case
|
||||
end; // while
|
||||
|
@ -1338,21 +1338,22 @@ begin
|
||||
|
||||
case RecordType of
|
||||
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_MULBLANK: ReadMulBlank(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_RSTRING : ReadRichString(AStream); //(RSTRING) This record stores a formatted text cell (Rich-Text). In BIFF8 it is usually replaced by the LABELSST record. Excel still uses this record, if it copies formatted text cells to the clipboard.
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream); //(RK) This record represents a cell that contains an RK value (encoded integer or floating-point value). If a floating-point value cannot be encoded to an RK value, a NUMBER record will be written. This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
|
||||
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||
INT_EXCEL_ID_BLANK : ReadBlank(AStream);
|
||||
INT_EXCEL_ID_MULBLANK : ReadMulBlank(AStream);
|
||||
INT_EXCEL_ID_NUMBER : ReadNumber(AStream);
|
||||
INT_EXCEL_ID_LABEL : ReadLabel(AStream);
|
||||
INT_EXCEL_ID_RSTRING : ReadRichString(AStream); //(RSTRING) This record stores a formatted text cell (Rich-Text). In BIFF8 it is usually replaced by the LABELSST record. Excel still uses this record, if it copies formatted text cells to the clipboard.
|
||||
INT_EXCEL_ID_RK : ReadRKValue(AStream); //(RK) This record represents a cell that contains an RK value (encoded integer or floating-point value). If a floating-point value cannot be encoded to an RK value, a NUMBER record will be written. This record replaces the record INTEGER written in BIFF2.
|
||||
INT_EXCEL_ID_MULRK : ReadMulRKValues(AStream);
|
||||
INT_EXCEL_ID_COLINFO : ReadColInfo(AStream);
|
||||
INT_EXCEL_ID_ROW : ReadRowInfo(AStream);
|
||||
INT_EXCEL_ID_FORMULA : ReadFormula(AStream);
|
||||
INT_EXCEL_ID_SHAREDFMLA: ReadSharedFormula(AStream);
|
||||
INT_EXCEL_ID_STRING : ReadStringRecord(AStream);
|
||||
INT_EXCEL_ID_WINDOW2 : ReadWindow2(AStream);
|
||||
INT_EXCEL_ID_PANE : ReadPane(AStream);
|
||||
INT_EXCEL_ID_BOF : ;
|
||||
INT_EXCEL_ID_EOF : SectionEOF := True;
|
||||
|
||||
{$IFDEF FPSPREADDEBUG} // Only write out if debugging
|
||||
else
|
||||
|
@ -88,7 +88,7 @@ type
|
||||
procedure ReadRPNCellAddress(AStream: TStream; out ARow, ACol: Cardinal;
|
||||
out AFlags: TsRelFlags); override;
|
||||
procedure ReadRPNCellAddressOffset(AStream: TStream;
|
||||
out ARowOffset, AColOffset: Integer); override;
|
||||
out ARowOffset, AColOffset: Integer; out AFlags: TsRelFlags); override;
|
||||
procedure ReadRPNCellRangeAddress(AStream: TStream;
|
||||
out ARow1, ACol1, ARow2, ACol2: Cardinal; out AFlags: TsRelFlags); override;
|
||||
procedure ReadSST(const AStream: TStream);
|
||||
@ -1710,18 +1710,25 @@ end;
|
||||
cell.
|
||||
Overriding the implementation in xlscommon. }
|
||||
procedure TsSpreadBIFF8Reader.ReadRPNCellAddressOffset(AStream: TStream;
|
||||
out ARowOffset, AColOffset: Integer);
|
||||
out ARowOffset, AColOffset: Integer; out AFlags: TsRelFlags);
|
||||
var
|
||||
dr: SmallInt;
|
||||
dc: ShortInt;
|
||||
c: Word;
|
||||
begin
|
||||
// 2 bytes for row offset
|
||||
dr := WordLEToN(AStream.ReadWord);
|
||||
ARowOffset := dr;
|
||||
|
||||
// 2 bytes for column offset
|
||||
dc := Lo(WordLEToN(AStream.ReadWord));
|
||||
c := WordLEToN(AStream.ReadWord);
|
||||
dc := Lo(c);
|
||||
AColOffset := dc;
|
||||
|
||||
// Extract info on absolute/relative addresses.
|
||||
AFlags := [];
|
||||
if (c and MASK_EXCEL_RELATIVE_COL <> 0) then Include(AFlags, rfRelCol);
|
||||
if (c and MASK_EXCEL_RELATIVE_ROW <> 0) then Include(AFlags, rfRelRow);
|
||||
end;
|
||||
|
||||
{ Reads a cell range address used in an RPN formula element.
|
||||
|
@ -439,7 +439,7 @@ type
|
||||
procedure ReadRPNCellAddress(AStream: TStream; out ARow, ACol: Cardinal;
|
||||
out AFlags: TsRelFlags); virtual;
|
||||
procedure ReadRPNCellAddressOffset(AStream: TStream;
|
||||
out ARowOffset, AColOffset: Integer); virtual;
|
||||
out ARowOffset, AColOffset: Integer; out AFlags: TsRelFlags); virtual;
|
||||
procedure ReadRPNCellRangeAddress(AStream: TStream;
|
||||
out ARow1, ACol1, ARow2, ACol2: Cardinal; out AFlags: TsRelFlags); virtual;
|
||||
function ReadRPNFunc(AStream: TStream): Word; virtual;
|
||||
@ -1548,18 +1548,25 @@ end;
|
||||
cell.
|
||||
Implemented here for BIFF5. BIFF8 must be overridden. Not used by BIFF2. }
|
||||
procedure TsSpreadBIFFReader.ReadRPNCellAddressOffset(AStream: TStream;
|
||||
out ARowOffset, AColOffset: Integer);
|
||||
out ARowOffset, AColOffset: Integer; out AFlags: TsRelFlags);
|
||||
var
|
||||
r: SmallInt;
|
||||
c: ShortInt;
|
||||
r: Word;
|
||||
dr: SmallInt;
|
||||
dc: ShortInt;
|
||||
begin
|
||||
// 2 bytes for row
|
||||
r := WordLEToN(AStream.ReadWord) and $3FFF;
|
||||
ARowOffset := r;
|
||||
r := WordLEToN(AStream.ReadWord);
|
||||
dr := SmallInt(r and $3FFF);
|
||||
ARowOffset := dr;
|
||||
|
||||
// 1 byte for column
|
||||
c := AStream.ReadByte;
|
||||
AColOffset := c;
|
||||
dc := AStream.ReadByte;
|
||||
AColOffset := dc;
|
||||
|
||||
// Extract absolute/relative flags
|
||||
AFlags := [];
|
||||
if (r and MASK_EXCEL_RELATIVE_COL <> 0) then Include(AFlags, rfRelCol);
|
||||
if (r and MASK_EXCEL_RELATIVE_ROW <> 0) then Include(AFlags, rfRelRow);
|
||||
end;
|
||||
|
||||
{ Reads the cell address used in an RPN formula element. Evaluates the corresponding
|
||||
@ -1649,8 +1656,8 @@ begin
|
||||
end;
|
||||
INT_EXCEL_TOKEN_TREFN_R, INT_EXCEL_TOKEN_TREFN_V:
|
||||
begin
|
||||
ReadRPNCellAddressOffset(AStream, dr, dc);
|
||||
rpnItem := RPNCellOffset(dr, dc, rpnItem);
|
||||
ReadRPNCellAddressOffset(AStream, dr, dc, flags);
|
||||
rpnItem := RPNCellOffset(dr, dc, flags, rpnItem);
|
||||
end;
|
||||
INT_EXCEL_TOKEN_TREFN_A:
|
||||
begin
|
||||
|
Reference in New Issue
Block a user