You've already forked lazarus-ccr
fpspreadsheet: Show message during writing when a formula is not supported by file format. Fix TsWorkbookSource ignoring its set options (i.e. ReadFormulas and AutoCalc working again).
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4480 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@@ -29,7 +29,7 @@ object MainForm: TMainForm
|
||||
Width = 707
|
||||
FrozenCols = 0
|
||||
FrozenRows = 0
|
||||
ReadFormulas = False
|
||||
ReadFormulas = True
|
||||
SelectionPen.JoinStyle = pjsMiter
|
||||
SelectionPen.Width = 3
|
||||
TextOverflow = True
|
||||
|
@@ -10,29 +10,29 @@ object Form1: TForm1
|
||||
ShowHint = True
|
||||
LCLVersion = '1.7'
|
||||
object Panel1: TPanel
|
||||
Left = 0
|
||||
Height = 41
|
||||
Top = 608
|
||||
Width = 894
|
||||
Align = alBottom
|
||||
Left = 776
|
||||
Height = 649
|
||||
Top = 0
|
||||
Width = 118
|
||||
Align = alRight
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 41
|
||||
ClientWidth = 894
|
||||
ClientHeight = 649
|
||||
ClientWidth = 118
|
||||
TabOrder = 0
|
||||
object BtnOpen: TButton
|
||||
Left = 96
|
||||
Left = 8
|
||||
Height = 25
|
||||
Top = 8
|
||||
Width = 75
|
||||
Top = 31
|
||||
Width = 99
|
||||
Caption = 'Open...'
|
||||
OnClick = BtnOpenClick
|
||||
TabOrder = 0
|
||||
end
|
||||
object BtnSave: TButton
|
||||
Left = 183
|
||||
Left = 8
|
||||
Height = 25
|
||||
Top = 8
|
||||
Width = 75
|
||||
Top = 58
|
||||
Width = 99
|
||||
Caption = 'Save...'
|
||||
OnClick = BtnSaveClick
|
||||
TabOrder = 1
|
||||
@@ -40,69 +40,99 @@ object Form1: TForm1
|
||||
object BtnNew: TButton
|
||||
Left = 8
|
||||
Height = 25
|
||||
Top = 8
|
||||
Width = 75
|
||||
Top = 4
|
||||
Width = 99
|
||||
Caption = 'New...'
|
||||
OnClick = BtnNewClick
|
||||
TabOrder = 2
|
||||
end
|
||||
end
|
||||
object WorksheetGrid: TsWorksheetGrid
|
||||
Left = 0
|
||||
Height = 576
|
||||
Top = 32
|
||||
Width = 894
|
||||
AutoCalc = True
|
||||
FrozenCols = 0
|
||||
FrozenRows = 0
|
||||
ReadFormulas = False
|
||||
SelectionPen.JoinStyle = pjsMiter
|
||||
SelectionPen.Width = 3
|
||||
WorkbookSource = WorksheetGrid.internal
|
||||
Align = alClient
|
||||
AutoAdvance = aaDown
|
||||
ColCount = 10
|
||||
DefaultColWidth = 64
|
||||
DefaultRowHeight = 22
|
||||
MouseWheelOption = mwGrid
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goEditing, goThumbTracking, goDblClickAutoSize, goSmoothScroll, goHeaderHotTracking, goHeaderPushedLook, goFixedColSizing, goCellHints]
|
||||
RowCount = 10
|
||||
TabOrder = 1
|
||||
TitleStyle = tsNative
|
||||
end
|
||||
object Panel2: TPanel
|
||||
Left = 0
|
||||
Height = 32
|
||||
Top = 0
|
||||
Width = 894
|
||||
Align = alTop
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 32
|
||||
ClientWidth = 894
|
||||
TabOrder = 2
|
||||
object Label1: TLabel
|
||||
object CbReadFormulas: TCheckBox
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 37
|
||||
Caption = 'Sheets:'
|
||||
ParentColor = False
|
||||
Height = 19
|
||||
Top = 96
|
||||
Width = 96
|
||||
Caption = 'Read formulas'
|
||||
OnChange = CbReadFormulasChange
|
||||
TabOrder = 3
|
||||
end
|
||||
object SheetsCombo: TComboBox
|
||||
Left = 72
|
||||
Height = 23
|
||||
Top = 4
|
||||
Width = 818
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'Sheet 1'
|
||||
)
|
||||
OnSelect = SheetsComboSelect
|
||||
Style = csDropDownList
|
||||
object CbAutoCalc: TCheckBox
|
||||
Left = 8
|
||||
Height = 19
|
||||
Top = 120
|
||||
Width = 70
|
||||
Caption = 'Auto calc'
|
||||
OnChange = CbAutoCalcChange
|
||||
TabOrder = 4
|
||||
end
|
||||
end
|
||||
object Panel3: TPanel
|
||||
Left = 0
|
||||
Height = 649
|
||||
Top = 0
|
||||
Width = 776
|
||||
Align = alClient
|
||||
BevelOuter = bvNone
|
||||
Caption = 'Panel3'
|
||||
ClientHeight = 649
|
||||
ClientWidth = 776
|
||||
TabOrder = 1
|
||||
object Panel2: TPanel
|
||||
Left = 0
|
||||
Height = 32
|
||||
Top = 0
|
||||
Width = 776
|
||||
Align = alTop
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 32
|
||||
ClientWidth = 776
|
||||
TabOrder = 0
|
||||
Text = 'Sheet 1'
|
||||
object Label1: TLabel
|
||||
Left = 8
|
||||
Height = 15
|
||||
Top = 8
|
||||
Width = 37
|
||||
Caption = 'Sheets:'
|
||||
ParentColor = False
|
||||
end
|
||||
object SheetsCombo: TComboBox
|
||||
Left = 72
|
||||
Height = 23
|
||||
Top = 4
|
||||
Width = 700
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
ItemHeight = 15
|
||||
ItemIndex = 0
|
||||
Items.Strings = (
|
||||
'Sheet 1'
|
||||
)
|
||||
OnSelect = SheetsComboSelect
|
||||
Style = csDropDownList
|
||||
TabOrder = 0
|
||||
Text = 'Sheet 1'
|
||||
end
|
||||
end
|
||||
object WorksheetGrid: TsWorksheetGrid
|
||||
Left = 0
|
||||
Height = 617
|
||||
Top = 32
|
||||
Width = 776
|
||||
AutoCalc = True
|
||||
FrozenCols = 0
|
||||
FrozenRows = 0
|
||||
ReadFormulas = True
|
||||
SelectionPen.JoinStyle = pjsMiter
|
||||
SelectionPen.Width = 3
|
||||
WorkbookSource = WorksheetGrid.internal
|
||||
Align = alClient
|
||||
AutoAdvance = aaDown
|
||||
ColCount = 10
|
||||
DefaultColWidth = 64
|
||||
DefaultRowHeight = 22
|
||||
MouseWheelOption = mwGrid
|
||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSizing, goColSizing, goEditing, goThumbTracking, goDblClickAutoSize, goSmoothScroll, goHeaderHotTracking, goHeaderPushedLook, goFixedColSizing, goCellHints]
|
||||
RowCount = 10
|
||||
TabOrder = 1
|
||||
TitleStyle = tsNative
|
||||
end
|
||||
end
|
||||
object OpenDialog: TOpenDialog
|
||||
|
@@ -17,6 +17,9 @@ type
|
||||
BtnOpen: TButton;
|
||||
BtnSave: TButton;
|
||||
BtnNew: TButton;
|
||||
CbReadFormulas: TCheckBox;
|
||||
CbAutoCalc: TCheckBox;
|
||||
Panel3: TPanel;
|
||||
SheetsCombo: TComboBox;
|
||||
Label1: TLabel;
|
||||
OpenDialog: TOpenDialog;
|
||||
@@ -27,6 +30,8 @@ type
|
||||
procedure BtnNewClick(Sender: TObject);
|
||||
procedure BtnOpenClick(Sender: TObject);
|
||||
procedure BtnSaveClick(Sender: TObject);
|
||||
procedure CbAutoCalcChange(Sender: TObject);
|
||||
procedure CbReadFormulasChange(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure SheetsComboSelect(Sender: TObject);
|
||||
private
|
||||
@@ -143,6 +148,16 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.CbAutoCalcChange(Sender: TObject);
|
||||
begin
|
||||
WorksheetGrid.AutoCalc := CbAutoCalc.Checked;
|
||||
end;
|
||||
|
||||
procedure TForm1.CbReadFormulasChange(Sender: TObject);
|
||||
begin
|
||||
WorksheetGrid.ReadFormulas := CbReadFormulas.Checked;
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
const
|
||||
THICK_BORDER: TsCellBorderStyle = (LineStyle: lsThick; Color: clNavy);
|
||||
@@ -195,6 +210,9 @@ begin
|
||||
WorksheetGrid.Cells[2,6] := '=B2^2*PI()';
|
||||
WorksheetGrid.CellComment[2,6] := 'Area of the circle with radius given in cell B2';
|
||||
WorksheetGrid.NumberFormat[2,6] := '0.000';
|
||||
|
||||
CbAutoCalc.Checked := WorksheetGrid.AutoCalc;
|
||||
CbReadFormulas.Checked := WorksheetGrid.ReadFormulas;
|
||||
end;
|
||||
|
||||
procedure TForm1.SheetsComboSelect(Sender: TObject);
|
||||
|
@@ -3405,7 +3405,6 @@ begin
|
||||
else
|
||||
n := Length(FArgumentNodes);
|
||||
Result := ANext;
|
||||
// for i:=Length(FArgumentNodes)-1 downto 0 do
|
||||
for i:=0 to High(FArgumentNodes) do
|
||||
Result := FArgumentNodes[i].AsRPNItem(Result);
|
||||
Result := RPNFunc(FID.Name, n, Result);
|
||||
|
@@ -880,7 +880,6 @@ begin
|
||||
FWorkbook.OnRemovingWorksheet := @WorksheetRemovingHandler;
|
||||
FWorkbook.OnRenameWorksheet := @WorksheetRenamedHandler;
|
||||
FWorkbook.OnSelectWorksheet := @WorksheetSelectedHandler;
|
||||
// FWorkbook.OnChangePalette := @WorkbookChangedPaletteHandler;
|
||||
// Pass options to workbook
|
||||
SetOptions(FOptions);
|
||||
end;
|
||||
@@ -945,6 +944,7 @@ var
|
||||
begin
|
||||
book := TsWorkbook.Create;
|
||||
try
|
||||
book.Options := FOptions;
|
||||
if AAutoDetect then
|
||||
book.ReadfromFile(AFileName)
|
||||
else
|
||||
|
@@ -1462,26 +1462,9 @@ procedure TsCustomWorksheetGrid.CreateNewWorkbook;
|
||||
begin
|
||||
GetWorkbookSource.CreateNewWorkbook;
|
||||
if FReadFormulas then
|
||||
Workbook.Options := Workbook.Options + [boReadFormulas] else
|
||||
Workbook.Options := Workbook.Options - [boReadFormulas];
|
||||
WorkbookSource.Options := WorkbookSource.Options + [boReadFormulas] else
|
||||
WorkbookSource.Options := Workbooksource.Options - [boReadFormulas];
|
||||
SetAutoCalc(FAutoCalc);
|
||||
{
|
||||
if FOwnsWorkbook then
|
||||
FreeAndNil(FOwnedWorkbook);
|
||||
|
||||
if FWorkbookSource <> nil then
|
||||
FWorkbookSource.CreateNewWorkbook
|
||||
else
|
||||
begin
|
||||
FOwnedWorkbook := TsWorkbook.Create;
|
||||
FOwnsWorkbook := true;
|
||||
if FReadFormulas then
|
||||
FOwnedWorkbook.Options := FOwnedWorkbook.Options + [boReadFormulas]
|
||||
else
|
||||
FOwnedWorkbook.Options := FOwnedWorkbook.Options - [boReadFormulas];
|
||||
SetAutoCalc(FAutoCalc);
|
||||
end;
|
||||
}
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
@@ -5132,23 +5115,20 @@ begin
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.SetAutoCalc(AValue: Boolean);
|
||||
var
|
||||
optns: TsWorkbookOptions;
|
||||
begin
|
||||
FAutoCalc := AValue;
|
||||
|
||||
if Assigned(FWorkbookSource) then
|
||||
if Assigned(WorkbookSource) then
|
||||
begin
|
||||
optns := WorkbookSource.Options;
|
||||
if FAutoCalc then
|
||||
FWorkbookSource.Options := FWorkbookSource.Options + [boAutoCalc]
|
||||
else
|
||||
FWorkbookSource.Options := FWorkbookSource.Options - [boAutoCalc];
|
||||
end;
|
||||
|
||||
if Assigned(Workbook) then
|
||||
begin
|
||||
if FAutoCalc then
|
||||
Workbook.Options := Workbook.Options + [boAutoCalc]
|
||||
else
|
||||
Workbook.Options := Workbook.Options - [boAutoCalc];
|
||||
Include(optns, boAutoCalc) else
|
||||
Exclude(optns, boAutoCalc);
|
||||
WorkbookSource.Options := optns;
|
||||
if FInternalWorkbookSource <> nil then
|
||||
FInternalWorkbookSource.Options := optns;
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -5643,23 +5623,20 @@ begin
|
||||
end;
|
||||
|
||||
procedure TsCustomWorksheetGrid.SetReadFormulas(AValue: Boolean);
|
||||
var
|
||||
optns: TsWorkbookOptions;
|
||||
begin
|
||||
FReadFormulas := AValue;
|
||||
|
||||
if Assigned(FWorkbookSource) then
|
||||
if Assigned(WorkbookSource) then
|
||||
begin
|
||||
optns := WorkbookSource.Options;
|
||||
if FReadFormulas then
|
||||
FWorkbookSource.Options := FWorkbookSource.Options + [boReadFormulas]
|
||||
Include(optns, boReadFormulas)
|
||||
else
|
||||
FWorkbookSource.Options := FWorkbookSource.Options - [boReadFormulas];
|
||||
end;
|
||||
|
||||
if Assigned(Workbook) then
|
||||
begin
|
||||
if FReadFormulas then
|
||||
Workbook.Options := Workbook.Options + [boReadFormulas]
|
||||
else
|
||||
Workbook.Options := Workbook.Options - [boReadFormulas];
|
||||
Exclude(optns, boReadFormulas);
|
||||
WorkbookSource.Options := optns;
|
||||
if FInternalWorkbookSource <> nil then
|
||||
FInternalWorkbookSource.Options := optns;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@@ -80,6 +80,7 @@ resourcestring
|
||||
rsIndexInSSTOutOfRange = 'Index %d in SST out of range (0-%d).';
|
||||
rsAmbiguousDecThouSeparator = 'Assuming usage of decimal separator in "%s".';
|
||||
rsCodePageNotSupported = 'Code page "%s" is not supported. Using "cp1252" (Latin 1) instead.';
|
||||
rsFormulaNotSupported = 'The formula in cell %s is not supported by this file format: %s';
|
||||
|
||||
rsNoValidHyperlinkInternal = 'The hyperlink "%s" is not a valid cell address.';
|
||||
rsNoValidHyperlinkURI = 'The hyperlink "%s" is not a valid URI.';
|
||||
|
@@ -20,15 +20,9 @@
|
||||
<VersionInfo>
|
||||
<StringTable ProductVersion=""/>
|
||||
</VersionInfo>
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="win32"/>
|
||||
</MacroValues>
|
||||
<BuildModes Count="3">
|
||||
<Item1 Name="Release" Default="True"/>
|
||||
<Item2 Name="Debug">
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="win32"/>
|
||||
</MacroValues>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
@@ -57,9 +51,6 @@
|
||||
</CompilerOptions>
|
||||
</Item2>
|
||||
<Item3 Name="Debug with heaptrace">
|
||||
<MacroValues Count="1">
|
||||
<Macro1 Name="LCLWidgetType" Value="win32"/>
|
||||
</MacroValues>
|
||||
<CompilerOptions>
|
||||
<Version Value="11"/>
|
||||
<PathDelim Value="\"/>
|
||||
@@ -134,6 +125,7 @@
|
||||
<ComponentName Value="AboutForm"/>
|
||||
<HasResources Value="True"/>
|
||||
<ResourceBaseClass Value="Form"/>
|
||||
<UnitName Value="beAbout"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="bebiffgrid.pas"/>
|
||||
|
@@ -98,6 +98,8 @@ type
|
||||
procedure WriteIXFE(AStream: TStream; XFIndex: Word);
|
||||
protected
|
||||
procedure AddBuiltinNumFormats; override;
|
||||
function FunctionSupported(AExcelCode: Integer;
|
||||
const AFuncName: String): Boolean; override;
|
||||
// procedure ListAllNumFormats; override;
|
||||
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
||||
ACell: PCell); override;
|
||||
@@ -1013,6 +1015,13 @@ begin
|
||||
InternalAddBuiltInNumFormats(FNumFormatList, Workbook.FormatSettings);
|
||||
end;
|
||||
|
||||
function TsSpreadBIFF2Writer.FunctionSupported(AExcelCode: Integer;
|
||||
const AFuncName: String): Boolean;
|
||||
begin
|
||||
Result := inherited and (AExcelCode < 200);
|
||||
end;
|
||||
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Determines the cell attributes needed for writing a cell content record, such
|
||||
as WriteLabel, WriteNumber, etc.
|
||||
@@ -1620,10 +1629,20 @@ var
|
||||
RPNLength: Word;
|
||||
RecordSizePos, FinalPos: Cardinal;
|
||||
xf: Word;
|
||||
isSupported: Boolean;
|
||||
unsupportedFormulas: String;
|
||||
begin
|
||||
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
|
||||
exit;
|
||||
|
||||
{ Check if formula is supported by this file format. If not, write only
|
||||
the result }
|
||||
isSupported := FormulaSupported(AFormula, unsupportedFormulas);
|
||||
if not IsSupported then
|
||||
Workbook.AddErrorMsg(rsFormulaNotSupported, [
|
||||
GetCellString(ARow, ACol), unsupportedformulas
|
||||
]);
|
||||
|
||||
RPNLength := 0;
|
||||
|
||||
xf := FindXFIndex(ACell);
|
||||
@@ -1650,11 +1669,7 @@ begin
|
||||
AStream.WriteByte(1);
|
||||
|
||||
{ Formula data (RPN token array) }
|
||||
{
|
||||
if ACell^.SharedFormulaBase <> nil then
|
||||
WriteRPNSharedFormulaLink(AStream, ACell, RPNLength)
|
||||
else}
|
||||
WriteRPNTokenArray(AStream, ACell, AFormula, false, RPNLength);
|
||||
WriteRPNTokenArray(AStream, ACell, AFormula, false, IsSupported, RPNLength);
|
||||
|
||||
{ Finally write sizes after we know them }
|
||||
FinalPos := AStream.Position;
|
||||
|
@@ -96,6 +96,7 @@ type
|
||||
|
||||
TsSpreadBIFF5Writer = class(TsSpreadBIFFWriter)
|
||||
protected
|
||||
function FunctionSupported(AExcelCode: Integer; const AFuncName: String): Boolean; override;
|
||||
procedure InternalWriteToStream(AStream: TStream);
|
||||
{ Record writing methods }
|
||||
procedure WriteBOF(AStream: TStream; ADataType: Word);
|
||||
@@ -214,7 +215,7 @@ implementation
|
||||
|
||||
uses
|
||||
Math,
|
||||
fpsStrings, fpsRegFileFormats, fpsStreams, fpsPalette, fpsNumFormat;
|
||||
fpsStrings, fpsRegFileFormats, fpsStreams, fpsPalette, fpsNumFormat, xlsconst;
|
||||
|
||||
const
|
||||
{ Excel record IDs }
|
||||
@@ -983,6 +984,12 @@ begin
|
||||
FCodePage := Excel5Settings.CodePage;
|
||||
end;
|
||||
|
||||
function TsSpreadBIFF5Writer.FunctionSupported(AExcelCode: Integer;
|
||||
const AFuncName: String): Boolean;
|
||||
begin
|
||||
Result := inherited and (AExcelCode <> INT_EXCEL_SHEET_FUNC_HYPERLINK);
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Writes an Excel BIFF5 record structure
|
||||
|
||||
|
@@ -468,6 +468,8 @@ type
|
||||
procedure AddBuiltinNumFormats; override;
|
||||
function FindXFIndex(ACell: PCell): Integer; virtual;
|
||||
function FixLineEnding(const AText: String): String;
|
||||
function FormulaSupported(ARPNFormula: TsRPNFormula; out AUnsupported: String): Boolean;
|
||||
function FunctionSupported(AExcelCode: Integer; const AFuncName: String): Boolean; virtual;
|
||||
function GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
||||
function GetLastColIndex(AWorksheet: TsWorksheet): Word;
|
||||
function GetPrintOptions: Word; virtual;
|
||||
@@ -544,7 +546,7 @@ type
|
||||
var RPNLength: Word); virtual;
|
||||
}
|
||||
procedure WriteRPNTokenArray(AStream: TStream; ACell: PCell;
|
||||
const AFormula: TsRPNFormula; UseRelAddr: Boolean; var RPNLength: Word);
|
||||
const AFormula: TsRPNFormula; UseRelAddr, IsSupported: Boolean; var RPNLength: Word);
|
||||
procedure WriteRPNTokenArraySize(AStream: TStream; ASize: Word); virtual;
|
||||
|
||||
// Writes out a SELECTION record
|
||||
@@ -2517,6 +2519,37 @@ begin
|
||||
Result[i] := #10;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Checks if the specified formula is supported by this file format.
|
||||
-------------------------------------------------------------------------------}
|
||||
function TsSpreadBIFFWriter.FormulaSupported(ARPNFormula: TsRPNFormula;
|
||||
out AUnsupported: String): Boolean;
|
||||
var
|
||||
exprDef: TsExprIdentifierDef;
|
||||
i: Integer;
|
||||
begin
|
||||
Result := true;
|
||||
AUnsupported := '';
|
||||
for i:=0 to Length(ARPNFormula)-1 do begin
|
||||
if ARPNFormula[i].ElementKind = fekFunc then begin
|
||||
exprDef := BuiltinIdentifiers.IdentifierByName(ARPNFormula[i].FuncName);
|
||||
if not FunctionSupported(exprDef.ExcelCode, exprDef.Name) then
|
||||
begin
|
||||
Result := false;
|
||||
AUnsupported := AUnsupported + ', ' + exprDef.Name + '()';
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if AUnsupported <> '' then Delete(AUnsupported, 1, 2);
|
||||
end;
|
||||
|
||||
function TsSpreadBIFFWriter.FunctionSupported(AExcelCode: Integer;
|
||||
const AFuncName: String): Boolean;
|
||||
begin
|
||||
Unused(AFuncName);
|
||||
Result := AExcelCode <> INT_EXCEL_SHEET_FUNC_NOT_BIFF;
|
||||
end;
|
||||
|
||||
function TsSpreadBIFFWriter.GetLastRowIndex(AWorksheet: TsWorksheet): Integer;
|
||||
begin
|
||||
Result := AWorksheet.GetLastRowIndex;
|
||||
@@ -3335,16 +3368,22 @@ procedure TsSpreadBIFFWriter.WriteRPNFormula(AStream: TStream;
|
||||
var
|
||||
RPNLength: Word = 0;
|
||||
RecordSizePos, StartPos, FinalPos: Int64;
|
||||
isSupported: Boolean;
|
||||
unsupportedFormulas: String;
|
||||
begin
|
||||
if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
|
||||
exit;
|
||||
|
||||
if Length(AFormula) = 0 then
|
||||
exit;
|
||||
{
|
||||
if not ((Length(AFormula) > 0) or (ACell^.SharedFormulaBase <> nil)) then
|
||||
exit;
|
||||
}
|
||||
|
||||
{ Check if formula is supported by this file format. If not, write only
|
||||
the result }
|
||||
isSupported := FormulaSupported(AFormula, unsupportedFormulas);
|
||||
if not IsSupported then
|
||||
Workbook.AddErrorMsg(rsFormulaNotSupported, [
|
||||
GetCellString(ARow, ACol), unsupportedformulas
|
||||
]);
|
||||
|
||||
{ BIFF Record header }
|
||||
AStream.WriteWord(WordToLE(INT_EXCEL_ID_FORMULA));
|
||||
@@ -3363,34 +3402,21 @@ begin
|
||||
WriteRPNResult(AStream, ACell);
|
||||
|
||||
{ Options flags }
|
||||
AStream.WriteWord(WordToLE(MASK_FORMULA_RECALCULATE_ALWAYS));
|
||||
if IsSupported then
|
||||
AStream.WriteWord(WordToLE(MASK_FORMULA_RECALCULATE_ALWAYS)) else
|
||||
AStream.WriteWord(0);
|
||||
|
||||
{ Not used }
|
||||
AStream.WriteDWord(0);
|
||||
|
||||
{ Formula data (RPN token array) }
|
||||
{
|
||||
if ACell^.SharedFormulaBase <> nil then
|
||||
WriteRPNSharedFormulaLink(AStream, ACell, RPNLength)
|
||||
else
|
||||
}
|
||||
WriteRPNTokenArray(AStream, ACell, AFormula, false, RPNLength);
|
||||
WriteRPNTokenArray(AStream, ACell, AFormula, false, IsSupported, RPNLength);
|
||||
|
||||
{ Write sizes in the end, after we known them }
|
||||
FinalPos := AStream.Position;
|
||||
AStream.Position := RecordSizePos;
|
||||
AStream.WriteWord(WordToLE(FinalPos - StartPos));
|
||||
AStream.Position := FinalPos;
|
||||
(*
|
||||
{ If the cell is the first cell of a range with a shared formula write the
|
||||
shared formula RECORD here. The shared formula RECORD must follow the
|
||||
first FORMULA record referring to the shared formula}
|
||||
if (ACell^.SharedFormulaBase <> nil) and
|
||||
(ARow = ACell^.SharedFormulaBase^.Row) and
|
||||
(ACol = ACell^.SharedFormulaBase^.Col)
|
||||
then
|
||||
WriteSharedFormula(AStream, ACell^.SharedFormulaBase);
|
||||
*)
|
||||
|
||||
{ Write following STRING record if formula result is a non-empty string. }
|
||||
if (ACell^.ContentType = cctUTF8String) and (ACell^.UTF8StringValue <> '') then
|
||||
@@ -3486,14 +3512,14 @@ end;
|
||||
Writes the token array of the given RPN formula and returns its size
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadBIFFWriter.WriteRPNTokenArray(AStream: TStream;
|
||||
ACell: PCell; const AFormula: TsRPNFormula; UseRelAddr: boolean;
|
||||
ACell: PCell; const AFormula: TsRPNFormula; UseRelAddr, IsSupported: boolean;
|
||||
var RPNLength: Word);
|
||||
var
|
||||
i: Integer;
|
||||
n: Word;
|
||||
dr, dc: Integer;
|
||||
TokenArraySizePos: Int64;
|
||||
FinalPos: Int64;
|
||||
finalPos: Int64;
|
||||
exprDef: TsExprIdentifierDef;
|
||||
primaryExcelCode, secondaryExcelCode: Word;
|
||||
begin
|
||||
@@ -3504,6 +3530,9 @@ begin
|
||||
TokenArraySizePos := AStream.Position;
|
||||
WriteRPNTokenArraySize(AStream, 0);
|
||||
|
||||
if not IsSupported then
|
||||
exit;
|
||||
|
||||
{ Formula data (RPN token array) }
|
||||
for i := 0 to Length(AFormula) - 1 do begin
|
||||
|
||||
|
Reference in New Issue
Block a user