fpspreadsheet: Remove TsNumberFormatDialect, not needed by number format parser any more. Fix some issues in visual demos related to number formats.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4089 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-04-19 22:03:33 +00:00
parent 3665dc7c3a
commit cd397b64d5
21 changed files with 300 additions and 445 deletions

View File

@ -254,11 +254,9 @@ begin
inc(r); inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0_);("$"#,##0)'); MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0_);("$"#,##0)');
MyWorksheet.WriteNumber(r, 1, number); MyWorksheet.WriteNumber(r, 1, number);
MyWorksheet.WriteFontColor(r, 1, NA_COLOR);
MyWorksheet.WriteNumberFormat(r, 1, nfCustom, '"$"#,##0_);("$"#,##0)'); MyWorksheet.WriteNumberFormat(r, 1, nfCustom, '"$"#,##0_);("$"#,##0)');
MyWorksheet.WriteNumber(r, 2, -number); MyWorksheet.WriteNumber(r, 2, -number);
MyWorksheet.WriteNumberFormat(r, 2, nfCustom, '"$"#,##0_);("$"#,##0)'); MyWorksheet.WriteNumberFormat(r, 2, nfCustom, '"$"#,##0_);("$"#,##0)');
MyWorksheet.WriteFontColor(r, 2, NA_COLOR);
inc(r); inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0.0_);[Red]("$"#,##0.0)'); MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0.0_);[Red]("$"#,##0.0)');
MyWorksheet.WriteNumber(r, 1, number); MyWorksheet.WriteNumber(r, 1, number);

View File

@ -127,9 +127,6 @@
<SmartLinkUnit Value="True"/> <SmartLinkUnit Value="True"/>
</CodeGeneration> </CodeGeneration>
<Linking> <Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
<Options> <Options>
<Win32> <Win32>
<GraphicApplication Value="True"/> <GraphicApplication Value="True"/>

View File

@ -105,7 +105,7 @@ object MainForm: TMainForm
'Font1=Arial; size 10; blue; underline' 'Font1=Arial; size 10; blue; underline'
'Font2=Arial; size 10; black; bold' 'Font2=Arial; size 10; black; bold'
'Font3=Arial; size 10; black; italic' 'Font3=Arial; size 10; black; italic'
'CellFormat0=' 'CellFormat0=nfGeneral'
) )
TitleCaptions.Strings = ( TitleCaptions.Strings = (
'Properties' 'Properties'
@ -820,6 +820,34 @@ object MainForm: TMainForm
Hint = 'Currency format (negative values in red)' Hint = 'Currency format (negative values in red)'
NumberFormat = nfCurrencyRed NumberFormat = nfCurrencyRed
end end
object AcNumFormatExp: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Exponential'
Hint = 'Exponential format'
NumberFormat = nfExp
end
object AcNumFormatFraction1: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Fraction (1 digit)'
NumberFormat = nfFraction
NumberFormatString = '# #/#'
end
object AcNumFormatFraction2: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Fraction (2 digits)'
NumberFormat = nfFraction
NumberFormatString = '# ##/##'
end
object AcNumFormatFraction3: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Fraction (3 digits)'
NumberFormat = nfFraction
NumberFormatString = '# ###/###'
end
object AcFileOpen: TFileOpen object AcFileOpen: TFileOpen
Category = 'File' Category = 'File'
Caption = '&Open ...' Caption = '&Open ...'
@ -874,6 +902,12 @@ object MainForm: TMainForm
ImageIndex = 49 ImageIndex = 49
OnExecute = AcColDeleteExecute OnExecute = AcColDeleteExecute
end end
object AcSettingsFormatSettings: TAction
Category = 'Settings'
Caption = 'Number format settings...'
Hint = 'Define number format settings'
OnExecute = AcSettingsFormatSettingsExecute
end
object AcSettingsCSVParams: TAction object AcSettingsCSVParams: TAction
Category = 'Settings' Category = 'Settings'
Caption = 'CSV parameters...' Caption = 'CSV parameters...'
@ -886,40 +920,6 @@ object MainForm: TMainForm
Hint = 'Define currency symbols' Hint = 'Define currency symbols'
OnExecute = AcSettingsCurrencyExecute OnExecute = AcSettingsCurrencyExecute
end end
object AcSettingsFormatSettings: TAction
Category = 'Settings'
Caption = 'Number format settings...'
Hint = 'Define number format settings'
OnExecute = AcSettingsFormatSettingsExecute
end
object AcNumFormatExp: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Exponential'
Hint = 'Exponential format'
NumberFormat = nfExp
end
object AcNumFormatFraction1: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Fraction (1 digit)'
NumberFormat = nfFraction
NumberFormatString = '# #/#'
end
object AcNumFormatFraction2: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Fraction (2 digits)'
NumberFormat = nfFraction
NumberFormatString = '# ##/##'
end
object AcNumFormatFraction3: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Fraction (3 digits)'
NumberFormat = nfFraction
NumberFormatString = '# ###/###'
end
object AcNumFormatDateTime: TsNumberFormatAction object AcNumFormatDateTime: TsNumberFormatAction
Category = 'FPSpreadsheet' Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource WorkbookSource = WorkbookSource
@ -941,6 +941,20 @@ object MainForm: TMainForm
Hint = 'Short date format' Hint = 'Short date format'
NumberFormat = nfShortDate NumberFormat = nfShortDate
end end
object AcNumFormatDayMonth: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Day and month'
Hint = 'Day and month only'
NumberFormat = nfDayMonth
end
object AcNumFormatMonthYear: TsNumberFormatAction
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
Caption = 'Month and year'
Hint = 'Month and year only'
NumberFormat = nfMonthYear
end
object AcNumFormatLongTime: TsNumberFormatAction object AcNumFormatLongTime: TsNumberFormatAction
Category = 'FPSpreadsheet' Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource WorkbookSource = WorkbookSource
@ -5057,6 +5071,17 @@ object MainForm: TMainForm
Action = AcNumFormatShortDate Action = AcNumFormatShortDate
AutoCheck = True AutoCheck = True
end end
object MenuItem118: TMenuItem
Caption = '-'
end
object MenuItem119: TMenuItem
Action = AcNumFormatDayMonth
AutoCheck = True
end
object MenuItem120: TMenuItem
Action = AcNumFormatMonthYear
AutoCheck = True
end
end end
object PuTimeFormat: TPopupMenu object PuTimeFormat: TPopupMenu
left = 504 left = 504

View File

@ -48,6 +48,9 @@ type
MenuItem115: TMenuItem; MenuItem115: TMenuItem;
MenuItem116: TMenuItem; MenuItem116: TMenuItem;
MenuItem117: TMenuItem; MenuItem117: TMenuItem;
MenuItem118: TMenuItem;
MenuItem119: TMenuItem;
MenuItem120: TMenuItem;
MnuSettings: TMenuItem; MnuSettings: TMenuItem;
MenuItem11: TMenuItem; MenuItem11: TMenuItem;
MenuItem12: TMenuItem; MenuItem12: TMenuItem;
@ -235,6 +238,8 @@ type
AcNumFormatFraction2: TsNumberFormatAction; AcNumFormatFraction2: TsNumberFormatAction;
AcNumFormatFraction1: TsNumberFormatAction; AcNumFormatFraction1: TsNumberFormatAction;
AcNumFormatFraction3: TsNumberFormatAction; AcNumFormatFraction3: TsNumberFormatAction;
AcNumFormatDayMonth: TsNumberFormatAction;
AcNumFormatMonthYear: TsNumberFormatAction;
Splitter2: TSplitter; Splitter2: TSplitter;
Splitter3: TSplitter; Splitter3: TSplitter;
ToolBar2: TToolBar; ToolBar2: TToolBar;

View File

@ -1303,11 +1303,11 @@ object MainFrm: TMainFrm
AutoCheck = True AutoCheck = True
end end
object MenuItem54: TMenuItem object MenuItem54: TMenuItem
Action = AcNFCustomDM Action = AcNFDayMonth
AutoCheck = True AutoCheck = True
end end
object MenuItem55: TMenuItem object MenuItem55: TMenuItem
Action = AcNFCustomMY Action = AcNFMonthDay
AutoCheck = True AutoCheck = True
end end
object MenuItem61: TMenuItem object MenuItem61: TMenuItem
@ -3077,98 +3077,98 @@ object MainFrm: TMainFrm
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFCurrency: TAction object AcNFCurrency: TAction
Tag = 1050 Tag = 1060
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Currency' Caption = 'Currency'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFCurrencyRed: TAction object AcNFCurrencyRed: TAction
Tag = 1060 Tag = 1070
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Currency (negative values in red)' Caption = 'Currency (negative values in red)'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFShortDateTime: TAction object AcNFShortDateTime: TAction
Tag = 1070 Tag = 1080
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Date + time' Caption = 'Date + time'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFShortDate: TAction object AcNFShortDate: TAction
Tag = 1080 Tag = 1090
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Short date' Caption = 'Short date'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFLongDate: TAction object AcNFLongDate: TAction
Tag = 1090 Tag = 1100
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Long date' Caption = 'Long date'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFCustomDM: TAction
Tag = 1151
Category = 'Format'
AutoCheck = True
Caption = 'Day + month'
OnExecute = AcNumFormatExecute
end
object AcNFCustomMY: TAction
Tag = 1152
Category = 'Format'
AutoCheck = True
Caption = 'Month + year'
OnExecute = AcNumFormatExecute
end
object AcNFShortTime: TAction object AcNFShortTime: TAction
Tag = 1100 Tag = 1110
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Short time' Caption = 'Short time'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFLongTime: TAction object AcNFLongTime: TAction
Tag = 1110 Tag = 1120
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Long time' Caption = 'Long time'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFShortTimeAM: TAction object AcNFShortTimeAM: TAction
Tag = 1120 Tag = 1130
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Short time AM/PM' Caption = 'Short time AM/PM'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFLongTimeAM: TAction object AcNFLongTimeAM: TAction
Tag = 1130 Tag = 1140
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Long time AM/PM' Caption = 'Long time AM/PM'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFDayMonth: TAction
Tag = 1150
Category = 'Format'
AutoCheck = True
Caption = 'Day + month'
OnExecute = AcNumFormatExecute
end
object AcNFMonthDay: TAction
Tag = 1160
Category = 'Format'
AutoCheck = True
Caption = 'Month + year'
OnExecute = AcNumFormatExecute
end
object AcNFCusstomMS: TAction object AcNFCusstomMS: TAction
Tag = 1153 Tag = 1181
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Minutes + seconds' Caption = 'Minutes + seconds'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFCustomMSZ: TAction object AcNFCustomMSZ: TAction
Tag = 1154 Tag = 1182
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Minutes + seconds + milliseconds' Caption = 'Minutes + seconds + milliseconds'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFTimeInterval: TAction object AcNFTimeInterval: TAction
Tag = 1140 Tag = 1170
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Time interval' Caption = 'Time interval'
@ -4001,11 +4001,11 @@ object MainFrm: TMainFrm
AutoCheck = True AutoCheck = True
end end
object MnuFmtDateTimeDM: TMenuItem object MnuFmtDateTimeDM: TMenuItem
Action = AcNFCustomDM Action = AcNFDayMonth
AutoCheck = True AutoCheck = True
end end
object MnuFmtDateTimeMY: TMenuItem object MnuFmtDateTimeMY: TMenuItem
Action = AcNFCustomMY Action = AcNFMonthDay
AutoCheck = True AutoCheck = True
end end
object MenuItem43: TMenuItem object MenuItem43: TMenuItem

View File

@ -66,8 +66,8 @@ type
AcNFShortTimeAM: TAction; AcNFShortTimeAM: TAction;
AcNFLongTimeAM: TAction; AcNFLongTimeAM: TAction;
AcNFTimeInterval: TAction; AcNFTimeInterval: TAction;
AcNFCustomDM: TAction; AcNFDayMonth: TAction;
AcNFCustomMY: TAction; AcNFMonthDay: TAction;
AcNFCusstomMS: TAction; AcNFCusstomMS: TAction;
AcNFCustomMSZ: TAction; AcNFCustomMSZ: TAction;
AcNew: TAction; AcNew: TAction;
@ -716,7 +716,7 @@ end;
procedure TMainFrm.AcNumFormatExecute(Sender: TObject); procedure TMainFrm.AcNumFormatExecute(Sender: TObject);
const const
DATETIME_CUSTOM: array[0..4] of string = ('', 'dd/mmm', 'mmm/yy', 'nn:ss', 'nn:ss.zzz'); DATETIME_CUSTOM: array[0..2] of string = ('', 'nn:ss', 'nn:ss.zzz');
var var
c, r: Cardinal; c, r: Cardinal;
cell: PCell; cell: PCell;
@ -1417,14 +1417,12 @@ begin
Worksheet.ReadNumFormat(cell, nf, nfs); Worksheet.ReadNumFormat(cell, nf, nfs);
for i:=0 to ActionList.ActionCount-1 do begin for i:=0 to ActionList.ActionCount-1 do begin
ac := TAction(ActionList.Actions[i]); ac := TAction(ActionList.Actions[i]);
if (ac.Tag >= NUMFMT_TAG) and (ac.Tag < NUMFMT_TAG + 200) then begin if (ac.Tag >= NUMFMT_TAG) and (ac.Tag < NUMFMT_TAG + 300) then begin
found := ((ac.Tag - NUMFMT_TAG) div 10 = ord(nf)); found := ((ac.Tag - NUMFMT_TAG) div 10 = ord(nf));
if nf = nfCustom then if nf = nfCustom then
case (ac.Tag - NUMFMT_TAG) mod 10 of case (ac.Tag - NUMFMT_TAG) mod 10 of
1: found := nfs = 'dd/mmm'; 1: found := nfs = 'nn:ss';
2: found := nfs = 'mmm/yy'; 2: found := nfs = 'nn:ss.z';
3: found := nfs = 'nn:ss';
4: found := nfs = 'nn:ss.z';
end; end;
ac.Checked := found; ac.Checked := found;
end; end;

View File

@ -26,7 +26,7 @@ type
constructor Create(AWorkbook: TsWorkbook; AOwnsData: Boolean); constructor Create(AWorkbook: TsWorkbook; AOwnsData: Boolean);
destructor Destroy; override; destructor Destroy; override;
function AddFormat(ASections: TsNumFormatSections): Integer; overload; function AddFormat(ASections: TsNumFormatSections): Integer; overload;
function AddFormat(AFormatStr: String; ADialect: TsNumFormatDialect): Integer; overload; function AddFormat(AFormatStr: String): Integer; overload;
procedure Clear; procedure Clear;
procedure Delete(AIndex: Integer); procedure Delete(AIndex: Integer);
function Find(ASections: TsNumFormatSections): Integer; function Find(ASections: TsNumFormatSections): Integer;
@ -214,14 +214,13 @@ begin
end; end;
end; end;
function TsNumFormatList.AddFormat(AFormatStr: String; function TsNumFormatList.AddFormat(AFormatStr: String): Integer;
ADialect: TsNumFormatDialect): Integer;
var var
parser: TsNumFormatParser; parser: TsNumFormatParser;
newSections: TsNumFormatSections; newSections: TsNumFormatSections;
i: Integer; i: Integer;
begin begin
parser := TsNumFormatParser.Create(FWorkbook, AFormatStr, ADialect); parser := TsNumFormatParser.Create(FWorkbook, AFormatStr);
try try
SetLength(newSections, parser.ParsedSectionCount); SetLength(newSections, parser.ParsedSectionCount);
for i:=0 to High(newSections) do for i:=0 to High(newSections) do

View File

@ -20,7 +20,10 @@ const
psErrNoValidNumberFormat = 6; psErrNoValidNumberFormat = 6;
psErrNoValidDateTimeFormat = 7; psErrNoValidDateTimeFormat = 7;
psErrQuoteExpected = 8; psErrQuoteExpected = 8;
psAmbiguousSymbol = 9; psErrMultipleCurrSymbols = 9;
psErrMultipleFracSymbols = 10;
psErrMultipleExpChars = 11;
psAmbiguousSymbol = 12;
type type
@ -35,13 +38,12 @@ type
FEnd: PChar; FEnd: PChar;
FCurrSection: Integer; FCurrSection: Integer;
FStatus: Integer; FStatus: Integer;
FDialect: TsNumFormatDialect;
function GetCurrencySymbol: String; function GetCurrencySymbol: String;
function GetDecimals: byte; function GetDecimals: byte;
function GetFracDenominator: Integer; function GetFracDenominator: Integer;
function GetFracInt: Integer; function GetFracInt: Integer;
function GetFracNumerator: Integer; function GetFracNumerator: Integer;
function GetFormatString(ADialect: TsNumFormatDialect): String; function GetFormatString: String;
function GetNumFormat: TsNumberFormat; function GetNumFormat: TsNumberFormat;
function GetParsedSectionCount: Integer; function GetParsedSectionCount: Integer;
function GetParsedSections(AIndex: Integer): TsNumFormatSection; function GetParsedSections(AIndex: Integer): TsNumFormatSection;
@ -86,7 +88,7 @@ type
procedure CheckSection(ASection: Integer); procedure CheckSection(ASection: Integer);
procedure FixMonthMinuteToken(ASection: Integer); procedure FixMonthMinuteToken(ASection: Integer);
// Format string // Format string
function BuildFormatString(ADialect: TsNumFormatDialect): String; virtual; function BuildFormatString: String; virtual;
// Token analysis // Token analysis
function GetTokenIntValueAt(AToken: TsNumFormatToken; function GetTokenIntValueAt(AToken: TsNumFormatToken;
ASection,AIndex: Integer): Integer; ASection,AIndex: Integer): Integer;
@ -96,8 +98,7 @@ type
function IsTokenAt(AToken: TsNumFormatToken; ASection,AIndex: Integer): Boolean; function IsTokenAt(AToken: TsNumFormatToken; ASection,AIndex: Integer): Boolean;
public public
constructor Create(AWorkbook: TsWorkbook; const AFormatString: String; constructor Create(AWorkbook: TsWorkbook; const AFormatString: String);
ADialect: TsNumFormatDialect = nfdDefault);
destructor Destroy; override; destructor Destroy; override;
procedure ClearAll; procedure ClearAll;
function GetDateTimeCode(ASection: Integer): String; function GetDateTimeCode(ASection: Integer): String;
@ -108,7 +109,7 @@ type
property CurrencySymbol: String read GetCurrencySymbol; property CurrencySymbol: String read GetCurrencySymbol;
property Decimals: Byte read GetDecimals write SetDecimals; property Decimals: Byte read GetDecimals write SetDecimals;
property FormatString[ADialect: TsNumFormatDialect]: String read GetFormatString; property FormatString: String read GetFormatString;
property FracDenominator: Integer read GetFracDenominator; property FracDenominator: Integer read GetFracDenominator;
property FracInt: Integer read GetFracInt; property FracInt: Integer read GetFracInt;
property FracNumerator: Integer read GetFracNumerator; property FracNumerator: Integer read GetFracNumerator;
@ -128,17 +129,13 @@ uses
{ TsNumFormatParser } { TsNumFormatParser }
{@@ Creates a number format parser for analyzing a formatstring that has been {@@ Creates a number format parser for analyzing a formatstring that has been
read from a spreadsheet file. read from a spreadsheet file. }
In case of "red" number formats we also have to specify the number format
because the format string might not contain the color information, and we
extract it from the NumFormat in this case. }
constructor TsNumFormatParser.Create(AWorkbook: TsWorkbook; constructor TsNumFormatParser.Create(AWorkbook: TsWorkbook;
const AFormatString: String; ADialect: TsNumFormatDialect = nfdDefault); const AFormatString: String);
begin begin
inherited Create; inherited Create;
FCreateMethod := 0; FCreateMethod := 0;
FWorkbook := AWorkbook; FWorkbook := AWorkbook;
FDialect := ADialect;
Parse(AFormatString); Parse(AFormatString);
CheckSections; CheckSections;
end; end;
@ -236,14 +233,14 @@ end;
{ Creates a formatstring for all sections. { Creates a formatstring for all sections.
Note: this implementation is only valid for the fpc and Excel dialects of Note: this implementation is only valid for the fpc and Excel dialects of
format string. } format string. }
function TsNumFormatParser.BuildFormatString(ADialect: TsNumFormatDialect): String; function TsNumFormatParser.BuildFormatString: String;
var var
i: Integer; i: Integer;
begin begin
if Length(FSections) > 0 then begin if Length(FSections) > 0 then begin
Result := BuildFormatStringFromSection(FSections[0], ADialect); Result := BuildFormatStringFromSection(FSections[0]);
for i:=1 to High(FSections) do for i:=1 to High(FSections) do
Result := Result + ';' + BuildFormatStringFromSection(FSections[i], ADialect); Result := Result + ';' + BuildFormatStringFromSection(FSections[i]);
end; end;
end; end;
@ -262,9 +259,9 @@ end;
procedure TsNumFormatParser.CheckSection(ASection: Integer); procedure TsNumFormatParser.CheckSection(ASection: Integer);
var var
el, next: Integer; el, next, i: Integer;
section: PsNumFormatSection; section: PsNumFormatSection;
nfs: String; nfs, nfsTest: String;
nf: TsNumberFormat; nf: TsNumberFormat;
datetimeFormats: set of TsNumberformat; datetimeFormats: set of TsNumberformat;
f1,f2: Integer; f1,f2: Integer;
@ -281,14 +278,24 @@ begin
nftPercent: nftPercent:
section^.Kind := section^.Kind + [nfkPercent]; section^.Kind := section^.Kind + [nfkPercent];
nftExpChar: nftExpChar:
if (nfkExp in section^.Kind) then
FStatus := psErrMultipleExpChars
else
section^.Kind := section^.Kind + [nfkExp]; section^.Kind := section^.Kind + [nfkExp];
nftFracSymbol: nftFracSymbol:
if (nfkFraction in section^.Kind) then
FStatus := psErrMultipleFracSymbols
else
section^.Kind := section^.Kind + [nfkFraction]; section^.Kind := section^.Kind + [nfkFraction];
nftCurrSymbol: nftCurrSymbol:
begin begin
if (nfkCurrency in section^.Kind) then
FStatus := psErrMultipleCurrSymbols
else begin
section^.Kind := section^.Kind + [nfkCurrency]; section^.Kind := section^.Kind + [nfkCurrency];
section^.CurrencySymbol := section^.Elements[el].TextValue; section^.CurrencySymbol := section^.Elements[el].TextValue;
end; end;
end;
nftYear, nftMonth, nftDay: nftYear, nftMonth, nftDay:
section^.Kind := section^.Kind + [nfkDate]; section^.Kind := section^.Kind + [nfkDate];
nftHour, nftMinute, nftSecond, nftMilliseconds: nftHour, nftMinute, nftSecond, nftMilliseconds:
@ -299,6 +306,9 @@ begin
end; end;
end; end;
if FStatus <> psOK then
exit;
if (section^.Kind * [nfkDate, nfkTime] <> []) and if (section^.Kind * [nfkDate, nfkTime] <> []) and
(section^.Kind * [nfkPercent, nfkExp, nfkCurrency, nfkFraction] <> []) then (section^.Kind * [nfkPercent, nfkExp, nfkCurrency, nfkFraction] <> []) then
begin begin
@ -311,7 +321,7 @@ begin
if (section^.Kind * [nfkDate, nfkTime] <> []) then if (section^.Kind * [nfkDate, nfkTime] <> []) then
begin begin
FixMonthMinuteToken(ASection); FixMonthMinuteToken(ASection);
nfs := FormatString[nfdDefault]; nfs := GetFormatString;
if (nfkTimeInterval in section^.Kind) then if (nfkTimeInterval in section^.Kind) then
section^.NumFormat := nfTimeInterval section^.NumFormat := nfTimeInterval
else else
@ -319,11 +329,31 @@ begin
datetimeFormats := [nfShortDateTime, nfLongDate, nfShortDate, nfLongTime, datetimeFormats := [nfShortDateTime, nfLongDate, nfShortDate, nfLongTime,
nfShortTime, nfLongTimeAM, nfShortTimeAM, nfDayMonth, nfMonthYear]; nfShortTime, nfLongTimeAM, nfShortTimeAM, nfDayMonth, nfMonthYear];
for nf in datetimeFormats do for nf in datetimeFormats do
begin
nfsTest := BuildDateTimeFormatString(nf, FWorkbook.FormatSettings);
if Length(nfsTest) = Length(nfs) then
begin
for i := 1 to Length(nfsTest) do
case nfsTest[i] of
'/': if not (nf in [nfLongTimeAM, nfShortTimeAM]) then
nfsTest[i] := FWorkbook.FormatSettings.DateSeparator;
':': nfsTest[i] := FWorkbook.FormatSettings.TimeSeparator;
'n': nfsTest[i] := 'm';
end;
if SameText(nfs, nfsTest) then
begin
section^.NumFormat := nf;
break;
end;
end;
{
if SameText(nfs, BuildDateTimeFormatString(nf, FWorkbook.FormatSettings)) then if SameText(nfs, BuildDateTimeFormatString(nf, FWorkbook.FormatSettings)) then
begin begin
section^.NumFormat := nf; section^.NumFormat := nf;
break; break;
end; end;
}
end;
end; end;
end else end else
begin begin
@ -535,9 +565,9 @@ begin
FSections[ASection].Elements[AIndex+1].FloatValue := AFloatValue; FSections[ASection].Elements[AIndex+1].FloatValue := AFloatValue;
end; end;
function TsNumFormatParser.GetFormatString(ADialect: TsNumFormatDialect): String; function TsNumFormatParser.GetFormatString: String;
begin begin
Result := BuildFormatString(ADialect); Result := BuildFormatString;
end; end;
{ Extracts the currency symbol form the formatting sections. It is assumed that { Extracts the currency symbol form the formatting sections. It is assumed that

View File

@ -150,7 +150,7 @@ type
procedure CreateStreams; procedure CreateStreams;
procedure DestroyStreams; procedure DestroyStreams;
procedure ListAllColumnStyles; procedure ListAllColumnStyles;
procedure ListAllNumFormats(ADialect: TsNumFormatDialect); override; procedure ListAllNumFormats; override;
procedure ListAllRowStyles; procedure ListAllRowStyles;
procedure ResetStreams; procedure ResetStreams;
@ -2562,7 +2562,7 @@ end;
{ Contains all number formats used in the workbook. Overrides the inherited { Contains all number formats used in the workbook. Overrides the inherited
method to assign a unique name according to the OpenDocument syntax ("N<number>" method to assign a unique name according to the OpenDocument syntax ("N<number>"
to the format items. } to the format items. }
procedure TsSpreadOpenDocWriter.ListAllNumFormats(ADialect: TsNumFormatDialect); procedure TsSpreadOpenDocWriter.ListAllNumFormats;
const const
FMT_BASE = 1000; // Format number to start with. Not clear if this is correct... FMT_BASE = 1000; // Format number to start with. Not clear if this is correct...
var var
@ -2573,21 +2573,9 @@ begin
for i:=0 to Workbook.GetNumberFormatCount - 1 do for i:=0 to Workbook.GetNumberFormatCount - 1 do
begin begin
nfParams := Workbook.GetNumberFormat(i); nfParams := Workbook.GetNumberFormat(i);
FNumFormatList.Add(Format('N%d:%s', [FMT_BASE+i, nfParams.NumFormatStr[ADialect]])); if nfParams <> nil then
FNumFormatList.Add(Format('N%d:%s', [FMT_BASE+i, nfParams.NumFormatStr]));
end; end;
{
var
n, i, j: Integer;
begin
n := NumFormatList.Count;
inherited ListAllNumFormats;
j := 0;
for i:=n to NumFormatList.Count-1 do
begin
NumFormatList.Items[i].Name := Format('N%d', [FMT_BASE + j]);
inc(j);
end;
}
end; end;
procedure TsSpreadOpenDocWriter.ListAllRowStyles; procedure TsSpreadOpenDocWriter.ListAllRowStyles;
@ -2917,7 +2905,7 @@ begin
nfParams := FWorkbook.GetNumberFormat(nfidx); nfParams := FWorkbook.GetNumberFormat(nfidx);
if nfParams <> nil then if nfParams <> nil then
begin begin
nfs := nfParams.NumFormatStr[nfdExcel]; nfs := nfParams.NumFormatStr;
for j:=0 to NumFormatList.Count-1 do for j:=0 to NumFormatList.Count-1 do
begin begin
s := NumFormatList[j]; s := NumFormatList[j];
@ -3408,7 +3396,7 @@ var
FZip: TZipper; FZip: TZipper;
begin begin
{ Analyze the workbook and collect all information needed } { Analyze the workbook and collect all information needed }
ListAllNumFormats(nfdExcel); ListAllNumFormats;
ListAllColumnStyles; ListAllColumnStyles;
ListAllRowStyles; ListAllRowStyles;

View File

@ -953,7 +953,7 @@ begin
numFmtParams := sourceSheet.Workbook.GetNumberFormat(fmt.NumberFormatIndex); numFmtParams := sourceSheet.Workbook.GetNumberFormat(fmt.NumberFormatIndex);
if numFmtParams <> nil then if numFmtParams <> nil then
begin begin
nfs := numFmtParams.NumFormatStr[nfdExcel]; nfs := numFmtParams.NumFormatStr;
fmt.NumberFormatIndex := destSheet.Workbook.AddNumberFormat(nfs); fmt.NumberFormatIndex := destSheet.Workbook.AddNumberFormat(nfs);
end; end;
end; end;
@ -2977,7 +2977,7 @@ begin
if numFmt <> nil then if numFmt <> nil then
begin begin
ANumFormat := numFmt.NumFormat; ANumFormat := numFmt.NumFormat;
ANumFormatStr := numFmt.NumFormatStr[nfdDefault]; ANumFormatStr := numFmt.NumFormatStr;
end else end else
begin begin
ANumFormat := nfGeneral; ANumFormat := nfGeneral;
@ -4108,7 +4108,6 @@ begin
RegisterCurrency(ACurrencySymbol); RegisterCurrency(ACurrencySymbol);
nfs := BuildCurrencyFormatString( nfs := BuildCurrencyFormatString(
nfdDefault,
ANumFormat, ANumFormat,
Workbook.FormatSettings, Workbook.FormatSettings,
ADecimals, ADecimals,
@ -4156,10 +4155,10 @@ procedure TsWorksheet.WriteCurrency(ACell: PCell; AValue: Double;
var var
fmt: TsCellFormat; fmt: TsCellFormat;
begin begin
if not (ANumFormat in [nfCurrency, nfCurrencyRed]) then if not IsCurrencyFormat(ANumFormat) then
raise Exception.Create('[TsWorksheet.WriteCurrency] ANumFormat can only be nfCurrency or nfCurrencyRed'); raise Exception.Create('[TsWorksheet.WriteCurrency] ANumFormat can only be nfCurrency or nfCurrencyRed');
if (ACell <> nil) and IsCurrencyFormat(ANumFormat) then begin if (ACell <> nil) then begin
ACell^.ContentType := cctNumber; ACell^.ContentType := cctNumber;
ACell^.NumberValue := AValue; ACell^.NumberValue := AValue;
@ -4364,6 +4363,7 @@ procedure TsWorksheet.WriteDateTimeFormat(ACell: PCell;
ANumFormat: TsNumberFormat; const ANumFormatString: String = ''); ANumFormat: TsNumberFormat; const ANumFormatString: String = '');
var var
fmt: TsCellFormat; fmt: TsCellFormat;
nfs: String;
begin begin
if ACell = nil then if ACell = nil then
exit; exit;
@ -4377,14 +4377,17 @@ begin
begin begin
Include(fmt.UsedFormattingFields, uffNumberFormat); Include(fmt.UsedFormattingFields, uffNumberFormat);
if (ANumFormatString = '') then if (ANumFormatString = '') then
fmt.NumberFormatStr := BuildDateTimeFormatString(ANumFormat, Workbook.FormatSettings) nfs := BuildDateTimeFormatString(ANumFormat, Workbook.FormatSettings)
else else
fmt.NumberFormatStr := ANumFormatString; nfs := ANumFormatString;
end else end else
begin begin
Exclude(fmt.UsedFormattingFields, uffNumberFormat); Exclude(fmt.UsedFormattingFields, uffNumberFormat);
fmt.NumberFormatStr := ''; fmt.NumberFormatStr := '';
end; end;
fmt.NumberFormat := ANumFormat;
fmt.NumberFormatStr := nfs;
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
ACell^.FormatIndex := FWorkbook.AddCellFormat(fmt); ACell^.FormatIndex := FWorkbook.AddCellFormat(fmt);
ChangedCell(ACell^.Row, ACell^.Col); ChangedCell(ACell^.Row, ACell^.Col);
@ -4426,11 +4429,11 @@ begin
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex); fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
numFmt := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex); numFmt := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
numFmtStr := numFmt.NumFormatStr[nfdDefault]; numFmtStr := numFmt.NumFormatStr;
parser := TsNumFormatParser.Create(Workbook, numFmtStr); parser := TsNumFormatParser.Create(Workbook, numFmtStr);
try try
parser.Decimals := ADecimals; parser.Decimals := ADecimals;
numFmtStr := parser.FormatString[nfdDefault]; numFmtStr := parser.FormatString;
fmt.NumberFormatIndex := Workbook.AddNumberFormat(numFmtStr); fmt.NumberFormatIndex := Workbook.AddNumberFormat(numFmtStr);
Include(fmt.UsedFormattingFields, uffNumberFormat); Include(fmt.UsedFormattingFields, uffNumberFormat);
ACell^.FormatIndex := Workbook.AddCellFormat(fmt); ACell^.FormatIndex := Workbook.AddCellFormat(fmt);
@ -4579,12 +4582,11 @@ begin
fmt.NumberFormat := ANumFormat; fmt.NumberFormat := ANumFormat;
if ANumFormat <> nfGeneral then begin if ANumFormat <> nfGeneral then begin
Include(fmt.UsedFormattingFields, uffNumberFormat); Include(fmt.UsedFormattingFields, uffNumberFormat);
if ANumFormat in [nfCurrency, nfCurrencyRed] then if IsCurrencyFormat(ANumFormat) then
begin begin
RegisterCurrency(ACurrencySymbol); RegisterCurrency(ACurrencySymbol);
fmtStr := BuildCurrencyFormatString(nfdDefault, ANumFormat, fmtStr := BuildCurrencyFormatString(ANumFormat, Workbook.FormatSettings,
Workbook.FormatSettings, ADecimals, ADecimals, APosCurrFormat, ANegCurrFormat, ACurrencySymbol);
APosCurrFormat, ANegCurrFormat, ACurrencySymbol);
end else end else
fmtStr := BuildNumberFormatString(ANumFormat, fmtStr := BuildNumberFormatString(ANumFormat,
Workbook.FormatSettings, ADecimals); Workbook.FormatSettings, ADecimals);
@ -7197,7 +7199,7 @@ begin
if numFmt <> nil then if numFmt <> nil then
Result := Format('%s; %s (%s)', [Result, Result := Format('%s; %s (%s)', [Result,
GetEnumName(TypeInfo(TsNumberFormat), ord(numFmt.NumFormat)), GetEnumName(TypeInfo(TsNumberFormat), ord(numFmt.NumFormat)),
numFmt.NumFormatStr[nfdDefault] numFmt.NumFormatStr
]) ])
else else
Result := Format('%s; %s', [Result, 'nfGeneral']); Result := Format('%s; %s', [Result, 'nfGeneral']);
@ -7487,7 +7489,7 @@ begin
if AFormatStr = '' then if AFormatStr = '' then
Result := -1 // General number format is not stored Result := -1 // General number format is not stored
else else
Result := TsNumFormatList(FNumFormatList).AddFormat(AFormatStr, nfdDefault); Result := TsNumFormatList(FNumFormatList).AddFormat(AFormatStr);
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------

View File

@ -1560,7 +1560,7 @@ var
begin begin
if Worksheet = nil then if Worksheet = nil then
exit; exit;
cell := Worksheet.FindCell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol); cell := Worksheet.GetCell(Worksheet.ActiveCellRow, Worksheet.ActiveCellCol);
if Worksheet.IsMerged(cell) then if Worksheet.IsMerged(cell) then
cell := Worksheet.FindMergeBase(cell); cell := Worksheet.FindMergeBase(cell);
s := Lines.Text; s := Lines.Text;
@ -1695,9 +1695,12 @@ begin
cctNumber: cctNumber:
Lines.Text := FloatToStr(ACell^.NumberValue); Lines.Text := FloatToStr(ACell^.NumberValue);
cctDateTime: cctDateTime:
if ACell^.DateTimeValue < 1.0 then if ACell^.DateTimeValue < 1.0 then // Time only
Lines.Text := FormatDateTime('tt', ACell^.DateTimeValue) Lines.Text := FormatDateTime('tt', ACell^.DateTimeValue)
else else
if frac(ACell^.DateTimeValue) = 0 then // Date only
Lines.Text := FormatDateTime('ddddd', ACell^.DateTimevalue)
else // both
Lines.Text := FormatDateTime('c', ACell^.DateTimeValue); Lines.Text := FormatDateTime('c', ACell^.DateTimeValue);
else else
Lines.Text := Worksheet.ReadAsUTF8Text(ACell); Lines.Text := Worksheet.ReadAsUTF8Text(ACell);
@ -2699,7 +2702,7 @@ begin
numFmt := Workbook.GetNumberFormat(fmt.NumberFormatIndex); numFmt := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
AStrings.Add(Format('NumberFormat=%s', [ AStrings.Add(Format('NumberFormat=%s', [
GetEnumName(TypeInfo(TsNumberFormat), ord(numFmt.NumFormat))])); GetEnumName(TypeInfo(TsNumberFormat), ord(numFmt.NumFormat))]));
AStrings.Add('NumberFormatStr=' + numFmt.NumFormatStr[nfdDefault]); AStrings.Add('NumberFormatStr=' + numFmt.NumFormatStr);
end; end;
if (Worksheet = nil) or not Worksheet.IsMerged(ACell) then if (Worksheet = nil) or not Worksheet.IsMerged(ACell) then

View File

@ -99,7 +99,7 @@ type
procedure FixFormat(ACell: PCell); virtual; procedure FixFormat(ACell: PCell); virtual;
procedure GetSheetDimensions(AWorksheet: TsWorksheet; procedure GetSheetDimensions(AWorksheet: TsWorksheet;
out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal); virtual; out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal); virtual;
procedure ListAllNumFormats(ADialect: TsNumFormatDialect); virtual; procedure ListAllNumFormats; virtual;
{ Helpers for writing } { Helpers for writing }
procedure WriteCellToStream(AStream: TStream; ACell: PCell); procedure WriteCellToStream(AStream: TStream; ACell: PCell);
@ -482,7 +482,7 @@ end;
Copies the format strings from the workbook's NumFormatList to the writer's Copies the format strings from the workbook's NumFormatList to the writer's
internal NumFormatList. internal NumFormatList.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsCustomSpreadWriter.ListAllNumFormats(ADialect: TsNumFormatDialect); procedure TsCustomSpreadWriter.ListAllNumFormats;
var var
i: Integer; i: Integer;
numFmt: TsNumFormatParams; numFmt: TsNumFormatParams;
@ -493,7 +493,7 @@ begin
numFmt := Workbook.GetNumberFormat(i); numFmt := Workbook.GetNumberFormat(i);
if numFmt <> nil then if numFmt <> nil then
begin begin
numFmtStr := numFmt.NumFormatStr[ADialect]; numFmtStr := numFmt.NumFormatStr;
if FindNumFormatInList(numFmtStr) = -1 then if FindNumFormatInList(numFmtStr) = -1 then
FNumFormatList.Add(numFmtStr); FNumFormatList.Add(numFmtStr);
end; end;

View File

@ -445,11 +445,7 @@ type
// other (format string goes directly into the file) // other (format string goes directly into the file)
nfCustom); nfCustom);
{@@ Identifies which "dialect" is used in the format strings: {@@ Tokens used by the elements of the number format parser }
nfdDefault is the dialect used by fpc
fndExcel is the dialect used by Excel }
TsNumFormatDialect = (nfdDefault, nfdExcel);
TsNumFormatToken = ( TsNumFormatToken = (
nftText, // must be quoted, stored in TextValue nftText, // must be quoted, stored in TextValue
nftThSep, // ',', replaced by FormatSettings.ThousandSeparator nftThSep, // ',', replaced by FormatSettings.ThousandSeparator
@ -525,12 +521,12 @@ type
TsNumFormatParams = class(TObject) TsNumFormatParams = class(TObject)
protected protected
function GetNumFormat: TsNumberFormat; virtual; function GetNumFormat: TsNumberFormat; virtual;
function GetNumFormatStr(ADialect: TsNumFormatDialect): String; virtual; function GetNumFormatStr: String; virtual;
public public
Sections: TsNumFormatSections; Sections: TsNumFormatSections;
function SectionsEqualTo(ASections: TsNumFormatSections): Boolean; function SectionsEqualTo(ASections: TsNumFormatSections): Boolean;
property NumFormat: TsNumberFormat read GetNumFormat; property NumFormat: TsNumberFormat read GetNumFormat;
property NumFormatStr[ADialect: TsNumFormatDialect]: String read GetNumFormatStr; property NumFormatStr: String read GetNumFormatStr;
end; end;
TsNumFormatParamsClass = class of TsNumFormatParams; TsNumFormatParamsClass = class of TsNumFormatParams;
@ -660,8 +656,7 @@ type
cctError : (ErrorValue: TsErrorValue); cctError : (ErrorValue: TsErrorValue);
end; end;
function BuildFormatStringFromSection(const ASection: TsNumFormatSection; function BuildFormatStringFromSection(const ASection: TsNumFormatSection): String;
ADialect: TsNumFormatDialect): String;
implementation implementation
@ -838,10 +833,10 @@ begin
end; end;
{ Creates a format string for the given section. This implementation covers { Creates a format string for the given number format section section.
the formatstring dialects of fpc (nfdDefault) and Excel (nfdExcel). } The format string is created according to Excel convention (which is used by
function BuildFormatStringFromSection(const ASection: TsNumFormatSection; ODS as well }
ADialect: TsNumFormatDialect): String; function BuildFormatStringFromSection(const ASection: TsNumFormatSection): String;
var var
element: TsNumFormatElement; element: TsNumFormatElement;
i: Integer; i: Integer;
@ -880,51 +875,39 @@ begin
nftText: nftText:
if element.TextValue <> '' then result := Result + '"' + element.TextValue + '"'; if element.TextValue <> '' then result := Result + '"' + element.TextValue + '"';
nftYear: nftYear:
Result := Result + DupeString(IfThen(ADialect = nfdExcel, 'Y', 'y'), element.IntValue); Result := Result + DupeString('Y', element.IntValue);
nftMonth: nftMonth:
Result := Result + DupeString(IfThen(ADialect = nfdExcel, 'M', 'm'), element.IntValue); Result := Result + DupeString('M', element.IntValue);
nftDay: nftDay:
Result := Result + DupeString(IfThen(ADialect = nfdExcel, 'D', 'd'), element.IntValue); Result := Result + DupeString('D', element.IntValue);
nftHour: nftHour:
if element.IntValue < 0 if element.IntValue < 0
then Result := Result + '[' + DupeString('h', -element.IntValue) + ']' then Result := Result + '[' + DupeString('h', -element.IntValue) + ']'
else Result := Result + DupeString('h', element.IntValue); else Result := Result + DupeString('h', element.IntValue);
nftMinute: nftMinute:
if element.IntValue < 0 if element.IntValue < 0
then Result := result + '[' + DupeString(IfThen(ADialect = nfdExcel, 'm', 'n'), -element.IntValue) + ']' then Result := result + '[' + DupeString('m', -element.IntValue) + ']'
else Result := Result + DupeString(IfThen(ADialect = nfdExcel, 'm', 'n'), element.IntValue); else Result := Result + DupeString('m', element.IntValue);
nftSecond: nftSecond:
if element.IntValue < 0 if element.IntValue < 0
then Result := Result + '[' + DupeString('s', -element.IntValue) + ']' then Result := Result + '[' + DupeString('s', -element.IntValue) + ']'
else Result := Result + DupeString('s', element.IntValue); else Result := Result + DupeString('s', element.IntValue);
nftMilliseconds: nftMilliseconds:
if ADialect = nfdExcel then Result := Result + DupeString('0', element.IntValue);
Result := Result + Dupestring('0', element.IntValue)
else
Result := Result + DupeString('z', element.IntValue);
nftSign, nftSignBracket, nftExpChar, nftExpSign, nftAMPM, nftDateTimeSep: nftSign, nftSignBracket, nftExpChar, nftExpSign, nftAMPM, nftDateTimeSep:
if element.TextValue <> '' then Result := Result + element.TextValue; if element.TextValue <> '' then Result := Result + element.TextValue;
nftCurrSymbol: nftCurrSymbol:
if element.TextValue <> '' then begin if element.TextValue <> '' then
if ADialect = nfdExcel then Result := Result + '[$' + element.TextValue + ']';
Result := Result + '[$' + element.TextValue + ']'
else
Result := Result + '"' + element.TextValue + '"';
end;
nftEscaped: nftEscaped:
if element.TextValue <> '' then begin if element.TextValue <> '' then
if ADialect = nfdExcel then Result := Result + '\' + element.TextValue;
Result := Result + '\' + element.TextValue
else
Result := Result + element.TextValue;
end;
nftTextFormat: nftTextFormat:
if element.TextValue <> '' then if element.TextValue <> '' then
if ADialect = nfdExcel then Result := Result + element.TextValue; Result := Result + element.TextValue;
nftRepeat: nftRepeat:
if element.TextValue <> '' then Result := Result + '*' + element.TextValue; if element.TextValue <> '' then Result := Result + '*' + element.TextValue;
nftColor: nftColor:
if ADialect = nfdExcel then begin
case element.IntValue of case element.IntValue of
scBlack : Result := '[black]'; scBlack : Result := '[black]';
scWhite : Result := '[white]'; scWhite : Result := '[white]';
@ -939,7 +922,6 @@ begin
end; end;
end; end;
end; end;
end;
{ TsNumFormatParams } { TsNumFormatParams }
@ -962,14 +944,14 @@ begin
end; end;
end; end;
function TsNumFormatParams.GetNumFormatStr(ADialect: TsNumFormatDialect): String; function TsNumFormatParams.GetNumFormatStr: String;
var var
i: Integer; i: Integer;
begin begin
if Length(Sections) > 0 then begin if Length(Sections) > 0 then begin
Result := BuildFormatStringFromSection(Sections[0], ADialect); Result := BuildFormatStringFromSection(Sections[0]);
for i := 1 to High(Sections) do for i := 1 to High(Sections) do
Result := Result + ';' + BuildFormatStringFromSection(Sections[i], ADialect); Result := Result + ';' + BuildFormatStringFromSection(Sections[i]);
end else end else
Result := ''; Result := '';
end; end;

View File

@ -96,9 +96,9 @@ function IfThen(ACondition: Boolean; AValue1,AValue2: TsNumberFormat): TsNumberF
procedure BuildCurrencyFormatList(AList: TStrings; procedure BuildCurrencyFormatList(AList: TStrings;
APositive: Boolean; AValue: Double; const ACurrencySymbol: String); APositive: Boolean; AValue: Double; const ACurrencySymbol: String);
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect; function BuildCurrencyFormatString(ANumberFormat: TsNumberFormat;
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings; const AFormatSettings: TFormatSettings; ADecimals, APosCurrFmt, ANegCurrFmt: Integer;
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String; ACurrencySymbol: String; Accounting: Boolean = false): String;
function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat; function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; AFormatString: String = ''): String; const AFormatSettings: TFormatSettings; AFormatString: String = ''): String;
function BuildFractionFormatString(AMixedFraction: Boolean; function BuildFractionFormatString(AMixedFraction: Boolean;
@ -119,9 +119,10 @@ function MonthNamesToString(const AMonthNames: TMonthNameArray;
const AEmptyStr: String): String; const AEmptyStr: String): String;
function SpecialDateTimeFormat(ACode: String; function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String; const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
{
procedure SplitFormatString(const AFormatString: String; out APositivePart, procedure SplitFormatString(const AFormatString: String; out APositivePart,
ANegativePart, AZeroPart: String); ANegativePart, AZeroPart: String);
}
procedure MakeTimeIntervalMask(Src: String; var Dest: String); procedure MakeTimeIntervalMask(Src: String; var Dest: String);
function ConvertFloatToStr(AValue: Double; AParams: TsNumFormatParams; function ConvertFloatToStr(AValue: Double; AParams: TsNumFormatParams;
@ -1062,30 +1063,30 @@ end;
or minus signs) is taken from the provided format settings. The format string or minus signs) is taken from the provided format settings. The format string
consists of three sections, separated by semicolons. consists of three sections, separated by semicolons.
@param ADialect Determines whether the format string is for use by
fpspreadsheet (nfdDefault) or by Excel (nfdExcel)
@param ANumberFormat Identifier of the built-in number format for which the @param ANumberFormat Identifier of the built-in number format for which the
format string is to be generated. format string is to be generated.
@param AFormatSettings FormatSettings to be applied (used to extract default @param AFormatSettings FormatSettings to be applied (used to extract default
values for the next parameters) values for the next parameters)
@param ADecimals number of decimal places. If < 0, the CurrencyDecimals @param ADecimals number of decimal places. If < 0, the CurrencyDecimals
of the FormatSettings is used. of the FormatSettings is used.
@param APosCurrFormat Identifier for the order of currency symbol, value and @param APosCurrFmt Identifier for the order of currency symbol, value and
spaces of positive values spaces of positive values
- see pcfXXXX constants in fpspreadsheet.pas. - see pcfXXXX constants in fpspreadsheet.pas.
If < 0, the CurrencyFormat of the FormatSettings is used. If < 0, the CurrencyFormat of the FormatSettings is used.
@param ANegCurrFormat Identifier for the order of currency symbol, value and @param ANegCurrFmt Identifier for the order of currency symbol, value and
spaces of negative values. Specifies also usage of (). spaces of negative values. Specifies also usage of ().
- see ncfXXXX constants in fpspreadsheet.pas. - see ncfXXXX constants in fpspreadsheet.pas.
If < 0, the NegCurrFormat of the FormatSettings is used. If < 0, the NegCurrFormat of the FormatSettings is used.
@param ACurrencySymbol Name of the currency, like $ or USD. @param ACurrencySymbol Name of the currency, like $ or USD.
If ? the CurrencyString of the FormatSettings is used. If ? the CurrencyString of the FormatSettings is used.
@param Accounting If true, adds spaces for alignment of decimals
@return String of formatting codes, such as '"$"#,##0.00;("$"#,##0.00);"$"0.00' @return String of formatting codes, such as '"$"#,##0.00;("$"#,##0.00);"$"0.00'
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect; function BuildCurrencyFormatString(ANumberFormat: TsNumberFormat;
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings; const AFormatSettings: TFormatSettings;
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String; ADecimals, APosCurrFmt, ANegCurrFmt: Integer; ACurrencySymbol: String;
Accounting: Boolean = false): String;
{ {
const const
POS_FMT: array[0..3] of string = ( POS_FMT: array[0..3] of string = (
@ -1120,8 +1121,8 @@ var
p, n: String; p, n: String;
negRed: Boolean; negRed: Boolean;
begin begin
pcf := IfThen(APosCurrFormat < 0, AFormatSettings.CurrencyFormat, APosCurrFormat); pcf := IfThen(APosCurrFmt < 0, AFormatSettings.CurrencyFormat, APosCurrFmt);
ncf := IfThen(ANegCurrFormat < 0, AFormatSettings.NegCurrFormat, ANegCurrFormat); ncf := IfThen(ANegCurrFmt < 0, AFormatSettings.NegCurrFormat, ANegCurrFmt);
if (ADecimals < 0) then if (ADecimals < 0) then
ADecimals := AFormatSettings.CurrencyDecimals; ADecimals := AFormatSettings.CurrencyDecimals;
if ACurrencySymbol = '?' then if ACurrencySymbol = '?' then
@ -1134,8 +1135,9 @@ begin
negRed := (ANumberFormat = nfCurrencyRed); negRed := (ANumberFormat = nfCurrencyRed);
p := POS_CURR_FMT[pcf]; // Format mask for positive values p := POS_CURR_FMT[pcf]; // Format mask for positive values
n := NEG_CURR_FMT[ncf]; // Format mask for negative values n := NEG_CURR_FMT[ncf]; // Format mask for negative values
// add extra space for the sign of the number for perfect alignment in Excel // add extra space for the sign of the number for perfect alignment in Excel
if ADialect = nfdExcel then if Accounting then
case ncf of case ncf of
0, 14: p := p + '_)'; 0, 14: p := p + '_)';
3, 11: p := p + '_-'; 3, 11: p := p + '_-';
@ -1146,13 +1148,12 @@ begin
if ACurrencySymbol <> '' then begin if ACurrencySymbol <> '' then begin
Result := Format(p, ['#,##0' + decs, ACurrencySymbol]) + ';' Result := Format(p, ['#,##0' + decs, ACurrencySymbol]) + ';'
+ IfThen(negRed, '[red]', '') + IfThen(negRed, '[red]', '')
// + IfThen(negRed and (ADialect = nfdExcel), '[red]', '')
+ Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';' + Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';'
+ Format(p, ['0'+decs, ACurrencySymbol]); + Format(p, ['0'+decs, ACurrencySymbol]);
end end
else begin else begin
Result := '#,##0' + decs; Result := '#,##0' + decs;
if negRed and (ADialect = nfdExcel) then if negRed then
Result := Result +';[red]' Result := Result +';[red]'
else else
Result := Result +';'; Result := Result +';';
@ -1216,14 +1217,20 @@ begin
Result := '0' + decs + 'E+00'; Result := '0' + decs + 'E+00';
nfPercentage: nfPercentage:
Result := '0' + decs + '%'; Result := '0' + decs + '%';
nfFraction:
if ADecimals = 0 then
Result := '# ??/??'
else
begin
decs := DupeString('?', ADecimals);
Result := '# ' + decs + '/' + decs;
end;
nfCurrency, nfCurrencyRed: nfCurrency, nfCurrencyRed:
Result := BuildCurrencyFormatString(nfdDefault, ANumberFormat, AFormatSettings, Result := BuildCurrencyFormatString(ANumberFormat, AFormatSettings,
ADecimals, AFormatSettings.CurrencyFormat, AFormatSettings.NegCurrFormat, ADecimals, AFormatSettings.CurrencyFormat, AFormatSettings.NegCurrFormat,
AFormatSettings.CurrencyString); AFormatSettings.CurrencyString);
// raise Exception.Create('BuildNumberFormatString: Use BuildCurrencyFormatString '+
// 'to create a format string for currency values.');
nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime, nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime,
nfShortTimeAM, nfLongTimeAM, nfTimeInterval: nfShortTimeAM, nfLongTimeAM, nfDayMonth, nfMonthYear, nfTimeInterval:
raise Exception.Create('BuildNumberFormatString: Use BuildDateTimeFormatSstring '+ raise Exception.Create('BuildNumberFormatString: Use BuildDateTimeFormatSstring '+
'to create a format string for date/time values.'); 'to create a format string for date/time values.');
end; end;
@ -1384,8 +1391,8 @@ const
MinInt64 = Low(Int64); MinInt64 = Low(Int64);
var var
H1, H2, K1, K2, A, NewA, tmp, prevH1, prevK1: Int64; H1, H2, K1, K2, A, NewA, tmp, prevH1, prevK1: Int64;
B, diff, test, eps: Double; B, diff, test: Double;
Found, PendingOverflow: Boolean; PendingOverflow: Boolean;
i: Integer = 0; i: Integer = 0;
begin begin
Assert((APrecision > 0) and (APrecision < 1)); Assert((APrecision > 0) and (APrecision < 1));
@ -1610,6 +1617,7 @@ end;
for negative numbers for negative numbers
@param AZeroPart Third section of the formatting string for zero. @param AZeroPart Third section of the formatting string for zero.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
(*
procedure SplitFormatString(const AFormatString: String; out APositivePart, procedure SplitFormatString(const AFormatString: String; out APositivePart,
ANegativePart, AZeroPart: String); ANegativePart, AZeroPart: String);
@ -1666,7 +1674,7 @@ begin
inc(P); inc(P);
end; end;
end; end;
*)
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
Creates a "time interval" format string having the first time code identifier Creates a "time interval" format string having the first time code identifier
in square brackets. in square brackets.
@ -2452,7 +2460,7 @@ var
if AddThousandSeparator then if AddThousandSeparator then
begin begin
j := Length(Result)-2; j := Length(Result)-2;
while (j > 0) do while (j > 1) do
begin begin
Insert(fs.ThousandSeparator, Result, j); Insert(fs.ThousandSeparator, Result, j);
dec(j, 3); dec(j, 3);
@ -2507,7 +2515,7 @@ var
var var
fmtStr: String; fmtStr: String;
begin begin
fmtStr := AParams.NumFormatStr[nfdExcel]; fmtStr := AParams.NumFormatStr;
raise Exception.CreateFmt(rsIsNoValidNumberFormatString, [fmtStr]); raise Exception.CreateFmt(rsIsNoValidNumberFormatString, [fmtStr]);
end; end;
@ -2583,7 +2591,7 @@ begin
(7) number w/o decimals --> exponent (7) number w/o decimals --> exponent
} }
// Integer only, followed by end-of-line (case 4) // Integer only, followed by end-of-line (case 4)
if (i = numEl) or (section.Elements[i].Token in (terminatingTokens - [nftSpace])) then if (i = numEl) or (section.Elements[i].Token in (terminatingTokens - [nftSpace, nftEmptyCharWidth])) then
begin begin
Result := Result + FixIntPart(AValue, false, digitsZero, digitsOpt, digitsSpace); Result := Result + FixIntPart(AValue, false, digitsZero, digitsOpt, digitsSpace);
el := i; el := i;
@ -2744,7 +2752,7 @@ begin
end; end;
// Simple decimal number (nfFixed), followed by terminating tokens (case 5) // Simple decimal number (nfFixed), followed by terminating tokens (case 5)
if (i < numEl) and (section.Elements[i].Token in terminatingTokens) then if (i < numEl) and (section.Elements[i].Token in terminatingTokens - [nftEmptyCharWidth]) then
begin begin
// Simple decimal number (nfFixed) (case 1) // Simple decimal number (nfFixed) (case 1)
Result := Result Result := Result
@ -2849,6 +2857,9 @@ begin
Result := Result + section.Elements[el].TextValue; Result := Result + section.Elements[el].TextValue;
end; end;
nftEmptyCharWidth:
Result := Result + ' ';
nftDateTimeSep: nftDateTimeSep:
case section.Elements[el].TextValue of case section.Elements[el].TextValue of
'/': Result := Result + fs.DateSeparator; '/': Result := Result + fs.DateSeparator;
@ -2955,159 +2966,6 @@ begin
end; end;
inc(el); inc(el);
end; end;
(*
section := AParams.Sections[sidx];
nf := section.NumFormat;
case nf of
nfFixed:
Result := FloatToStrF(AValue, ffFixed, 20, section.Decimals, fs);
nfFixedTh:
Result := FloatToStrF(AValue, ffNumber, 20, section.Decimals, fs);
nfPercentage:
Result := FloatToStrF(AValue*100.0, ffFixed, 20, section.Decimals, fs) + '%';
nfExp:
begin
elem := High(Section.Elements);
expDigits := 2;
if section.Elements[elem].Token = nftExpDigits then
expDigits := section.Elements[elem].IntValue;
Result := FloatToStrF(AValue, ffExponent, section.Decimals+1, expDigits, fs);
if (abs(AValue) >= 1.0) and (
((section.Elements[elem-1].Token <> nftExpSign) or (section.Elements[elem-1].TextValue = '-')) )
then
Delete(Result, pos('+', Result), 1);
end;
nfFraction:
begin
AValue := abs(AValue);
if section.FracInt = 0 then
frint := 0
else begin
frint := trunc(AValue);
AValue := frac(AValue);
end;
maxNum := Round(IntPower(10, section.FracNumerator));
maxDenom := Round(IntPower(10, section.FracDenominator));
FloatToFraction(AValue, maxnum, maxdenom, frnum, frdenom);
Result := IntToStr(frnum) + '/' + IntToStr(frdenom);
if frint <> 0 then
Result := IntToStr(frint) + ' ' + result;
if isNeg then Result := '-' + Result;
end;
nfCurrency,
nfCurrencyRed:
begin
valueDone := false;
for elem := 0 to High(section.Elements) do
case section.Elements[elem].Token of
nftSpace:
Result := Result + ' ';
nftText:
Result := Result + section.Elements[elem].TextValue;
nftCurrSymbol:
Result := Result + section.CurrencySymbol;
nftSign:
Result := Result + '-';
nftSignBracket:
Result := Result + section.Elements[elem].TextValue;
nftDigit, nftOptDigit:
if not ValueDone then
begin
Result := Result + FloatToStrF(AValue, ffNumber, 20, section.Decimals, fs);
valueDone := true;
end;
end;
end;
nfShortDate, nfLongDate, nfShortTime, nfLongTime, nfShortDateTime,
nfShortTimeAM, nfLongTimeAM:
begin
DecodeDate(trunc(AValue), yr, mon, day);
DecodeTime(frac(AValue), hr, min, sec, ms);
elem := 0;
while elem < Length(section.Elements) do
begin
case section.Elements[elem].Token of
nftSpace:
Result := Result + ' ';
nftText:
Result := Result + section.Elements[elem].TextValue;
nftYear:
case section.Elements[elem].IntValue of
1,
2: Result := Result + IfThen(yr < 10, '0'+IntToStr(yr), IntToStr(yr));
4: Result := Result + IntToStr(yr);
end;
nftMonth:
case section.Elements[elem].IntValue of
1: Result := Result + IntToStr(mon);
2: Result := Result + IfThen(mon < 10, '0'+IntToStr(mon), IntToStr(mon));
3: Result := Result + fs.ShortMonthNames[mon];
4: Result := Result + fs.LongMonthNames[mon];
end;
nftDay:
case section.Elements[elem].IntValue of
1: result := result + IntToStr(day);
2: result := Result + IfThen(day < 10, '0'+IntToStr(day), IntToStr(day));
3: Result := Result + fs.ShortDayNames[day];
4: Result := Result + fs.LongDayNames[day];
end;
nftHour:
begin
if section.Elements[elem].IntValue < 0 then
hr := hr + trunc(AValue) * 24;
case abs(section.Elements[elem].IntValue) of
1: Result := Result + IntToStr(hr);
2: Result := Result + IfThen(hr < 10, '0'+IntToStr(hr), IntToStr(hr));
end;
end;
nftMinute:
begin
if section.Elements[elem].IntValue < 0 then
min := min + trunc(AValue) * 24 * 60;
case abs(section.Elements[elem].IntValue) of
1: Result := Result + IntToStr(min);
2: Result := Result + IfThen(min < 10, '0'+IntToStr(min), IntToStr(min));
end;
end;
nftSecond:
begin
if section.Elements[elem].IntValue < 0 then
sec := sec + trunc(AValue) * 24 * 60 * 60;
case abs(section.Elements[elem].IntValue) of
1: Result := Result + IntToStr(sec);
2: Result := Result + IfThen(sec < 10, '0'+IntToStr(sec), IntToStr(sec));
end;
end;
nftDecSep:
Result := Result + fs.DecimalSeparator;
nftMilliseconds:
case section.Elements[elem].IntValue of
1: Result := Result + IntToStr(ms div 100);
2: Result := Result + Format('%02d', [ms div 10]);
3: Result := Result + Format('%03d', [ms]);
end;
nftDateTimeSep:
case section.Elements[elem].TextValue of
'/': Result := Result + fs.DateSeparator;
':': Result := Result + fs.TimeSeparator;
else Result := Result + section.Elements[elem].TextValue;
end;
nftAMPM:
if frac(AValue) <= 0.5 then
Result := Result + fs.TimeAMString
else
Result := Result + fs.TimePMString;
nftEscaped:
begin
inc(elem);
Result := Result + section.Elements[elem].TextValue;
end;
end;
inc(elem);
end;
end;
end;*)
end; end;

View File

@ -84,7 +84,7 @@ begin
end; end;
with ParserTestData[4] do begin with ParserTestData[4] do begin
FormatString := 'hh:mm:ss'; FormatString := 'hh:mm:ss';
SollFormatString := 'hh:nn:ss'; SollFormatString := 'hh:mm:ss';
SollNumFormat := nfLongTime; SollNumFormat := nfLongTime;
SollSectionCount := 1; SollSectionCount := 1;
SollDecimals := 0; SollDecimals := 0;
@ -92,7 +92,7 @@ begin
end; end;
with ParserTestData[5] do begin with ParserTestData[5] do begin
FormatString := 'hh:mm:ss AM/PM'; FormatString := 'hh:mm:ss AM/PM';
SollFormatString := 'hh:nn:ss AM/PM'; SollFormatString := 'hh:mm:ss AM/PM';
SollNumFormat := nfLongTimeAM; SollNumFormat := nfLongTimeAM;
SollSectionCount := 1; SollSectionCount := 1;
SollDecimals := 0; SollDecimals := 0;
@ -100,7 +100,7 @@ begin
end; end;
with ParserTestData[6] do begin with ParserTestData[6] do begin
FormatString := '[$-409]hh:mm:ss\ AM/PM;@'; FormatString := '[$-409]hh:mm:ss\ AM/PM;@';
SollFormatString := 'hh:nn:ss AM/PM'; SollFormatString := 'hh:mm:ss AM/PM';
SollNumFormat := nfLongTimeAM; SollNumFormat := nfLongTimeAM;
SollSectionCount := 2; SollSectionCount := 2;
SollDecimals := 0; SollDecimals := 0;
@ -108,7 +108,7 @@ begin
end; end;
with ParserTestData[7] do begin with ParserTestData[7] do begin
FormatString := '[$-F400]dd.mm.yy\ hh:mm'; FormatString := '[$-F400]dd.mm.yy\ hh:mm';
SollFormatString := 'dd.mm.yy hh:nn'; SollFormatString := 'dd.mm.yy hh:mm';
SollNumFormat := nfShortDateTime; SollNumFormat := nfShortDateTime;
SollSectionCount := 1; SollSectionCount := 1;
SollDecimals := 0; SollDecimals := 0;
@ -170,7 +170,7 @@ begin
for i:=0 to 5 do begin for i:=0 to 5 do begin
parser := TsNumFormatParser.Create(MyWorkbook, ParserTestData[i].FormatString); parser := TsNumFormatParser.Create(MyWorkbook, ParserTestData[i].FormatString);
try try
actual := parser.FormatString[nfdDefault]; actual := parser.FormatString;
CheckEquals(ParserTestData[i].SollFormatString, actual, CheckEquals(ParserTestData[i].SollFormatString, actual,
'Test format string ' + ParserTestData[i].SollFormatString + ' construction mismatch'); 'Test format string ' + ParserTestData[i].SollFormatString + ' construction mismatch');
CheckEquals(ord(ParserTestData[i].SollNumFormat), ord(parser.ParsedSections[0].NumFormat), CheckEquals(ord(ParserTestData[i].SollNumFormat), ord(parser.ParsedSections[0].NumFormat),

View File

@ -164,11 +164,6 @@
<OtherUnitFiles Value=".."/> <OtherUnitFiles Value=".."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths> </SearchPaths>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2Set"/>
</Debugging>
</Linking>
</CompilerOptions> </CompilerOptions>
<Debugging> <Debugging>
<Exceptions Count="6"> <Exceptions Count="6">

View File

@ -97,7 +97,7 @@ type
procedure WriteIXFE(AStream: TStream; XFIndex: Word); procedure WriteIXFE(AStream: TStream; XFIndex: Word);
protected protected
procedure AddBuiltinNumFormats; override; procedure AddBuiltinNumFormats; override;
procedure ListAllNumFormats(ADialect: TsNumFormatDialect); override; procedure ListAllNumFormats; override;
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
ACell: PCell); override; ACell: PCell); override;
procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal; procedure WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
@ -251,8 +251,7 @@ type
end; end;
procedure InternalAddBuiltinNumFormats(AList: TStringList; procedure InternalAddBuiltinNumFormats(AList: TStringList; AFormatSettings: TFormatSettings);
AFormatSettings: TFormatSettings; ADialect: TsNumFormatDialect);
var var
fs: TFormatSettings absolute AFormatSettings; fs: TFormatSettings absolute AFormatSettings;
cs: String; cs: String;
@ -266,10 +265,10 @@ begin
Add('0.00'); // 2 Add('0.00'); // 2
Add('#,##0'); // 3 Add('#,##0'); // 3
Add('#,##0.00'); // 4 Add('#,##0.00'); // 4
Add(BuildCurrencyFormatString(ADialect, nfCurrency, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 5 Add(BuildCurrencyFormatString(nfCurrency, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 5
Add(BuildCurrencyFormatString(ADialect, nfCurrencyRed, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 6 Add(BuildCurrencyFormatString(nfCurrencyRed, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 6
Add(BuildCurrencyFormatString(ADialect, nfCurrency, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 7 Add(BuildCurrencyFormatString(nfCurrency, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 7
Add(BuildCurrencyFormatString(ADialect, nfCurrencyRed, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 8 Add(BuildCurrencyFormatString(nfCurrencyRed, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 8
Add('0%'); // 9 Add('0%'); // 9
Add('0.00%'); // 10 Add('0.00%'); // 10
Add('0.00E+00'); // 11 Add('0.00E+00'); // 11
@ -299,7 +298,7 @@ end;
procedure TsSpreadBIFF2Reader.AddBuiltInNumFormats; procedure TsSpreadBIFF2Reader.AddBuiltInNumFormats;
begin begin
FFirstNumFormatIndexInFile := 0; FFirstNumFormatIndexInFile := 0;
InternalAddBuiltInNumFormats(FNumFormatList, Workbook.FormatSettings, nfdDefault); InternalAddBuiltInNumFormats(FNumFormatList, Workbook.FormatSettings);
end; end;
procedure TsSpreadBIFF2Reader.ReadBlank(AStream: TStream); procedure TsSpreadBIFF2Reader.ReadBlank(AStream: TStream);
@ -905,7 +904,7 @@ begin
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs); fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
nf := Workbook.GetNumberFormat(fmt.NumberFormatIndex); nf := Workbook.GetNumberFormat(fmt.NumberFormatIndex);
fmt.NumberFormat := nf.NumFormat; fmt.NumberFormat := nf.NumFormat;
fmt.NumberFormatStr := nf.NumFormatStr[nfdDefault]; fmt.NumberFormatStr := nf.NumFormatStr;
Include(fmt.UsedFormattingFields, uffNumberFormat); Include(fmt.UsedFormattingFields, uffNumberFormat);
end; end;
@ -974,7 +973,7 @@ end;
procedure TsSpreadBIFF2Writer.AddBuiltInNumFormats; procedure TsSpreadBIFF2Writer.AddBuiltInNumFormats;
begin begin
FFirstNumFormatIndexInFile := 0; FFirstNumFormatIndexInFile := 0;
InternalAddBuiltInNumFormats(FNumFormatList, Workbook.FormatSettings, nfdExcel); InternalAddBuiltInNumFormats(FNumFormatList, Workbook.FormatSettings);
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@ -1034,9 +1033,8 @@ end;
standard formats; these formats have been added by AddBuiltInFormats. standard formats; these formats have been added by AddBuiltInFormats.
Nothing to do here. Nothing to do here.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsSpreadBIFF2Writer.ListAllNumFormats(ADialect: TsNumFormatDialect); procedure TsSpreadBIFF2Writer.ListAllNumFormats;
begin begin
Unused(ADialect);
// Nothing to do here. // Nothing to do here.
end; end;
@ -1234,7 +1232,7 @@ begin
WriteFonts(AStream); WriteFonts(AStream);
WriteCodePage(AStream, FCodePage); WriteCodePage(AStream, FCodePage);
WriteFormatCount(AStream); WriteFormatCount(AStream);
WriteNumFormats(AStream, nfdExcel); WriteNumFormats(AStream);
WriteXFRecords(AStream); WriteXFRecords(AStream);
WriteColWidths(AStream); WriteColWidths(AStream);
WriteDimensions(AStream, FWorksheet); WriteDimensions(AStream, FWorksheet);

View File

@ -1004,7 +1004,7 @@ begin
WriteCodepage(AStream, FCodePage); WriteCodepage(AStream, FCodePage);
WriteWindow1(AStream); WriteWindow1(AStream);
WriteFonts(AStream); WriteFonts(AStream);
WriteNumFormats(AStream, nfdExcel); WriteNumFormats(AStream);
WritePalette(AStream); WritePalette(AStream);
WriteXFRecords(AStream); WriteXFRecords(AStream);
WriteStyle(AStream); WriteStyle(AStream);
@ -1497,20 +1497,12 @@ begin
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields) if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields)
then begin then begin
nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex); nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex);
nfs := nfParams.NumFormatStr[nfdExcel]; nfs := nfParams.NumFormatStr;
j := NumFormatList.IndexOf(nfs); j := NumFormatList.IndexOf(nfs);
if j = -1 then j := 0; if j = -1 then j := 0;
end; end;
rec.NumFormatIndex := WordToLE(j); rec.NumFormatIndex := WordToLE(j);
{
// The number formats in the FormatList are still in fpc dialect
// They will be converted to Excel syntax immediately before writing.
j := NumFormatList.Find(AFormatRecord^.NumberFormat, AFormatRecord^.NumberFormatStr);
if j > -1 then
rec.NumFormatIndex := NumFormatList[j].Index;
end;
rec.NumFormatIndex := WordToLE(rec.NumFormatIndex);
}
{ XF type, cell protection and parent style XF } { XF type, cell protection and parent style XF }
rec.XFType_Prot_ParentXF := XFType_Prot and MASK_XF_TYPE_PROT; rec.XFType_Prot_ParentXF := XFType_Prot and MASK_XF_TYPE_PROT;
if XFType_Prot and MASK_XF_TYPE_PROT_STYLE_XF <> 0 then if XFType_Prot and MASK_XF_TYPE_PROT_STYLE_XF <> 0 then

View File

@ -1669,7 +1669,7 @@ begin
WriteCodePage(AStream, 'ucs2le'); // = utf8 WriteCodePage(AStream, 'ucs2le'); // = utf8
WriteWindow1(AStream); WriteWindow1(AStream);
WriteFonts(AStream); WriteFonts(AStream);
WriteNumFormats(AStream, nfdExcel); WriteNumFormats(AStream);
WritePalette(AStream); WritePalette(AStream);
WriteXFRecords(AStream); WriteXFRecords(AStream);
WriteStyle(AStream); WriteStyle(AStream);
@ -2831,7 +2831,7 @@ begin
nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex); nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex);
if nfParams <> nil then if nfParams <> nil then
begin begin
nfs := nfParams.NumFormatStr[nfdExcel]; nfs := nfParams.NumFormatStr;
j := NumFormatList.IndexOf(nfs); j := NumFormatList.IndexOf(nfs);
if j = -1 then j := 0; if j = -1 then j := 0;
end; end;

View File

@ -369,7 +369,7 @@ type
procedure WriteNumFormat(AStream: TStream; ANumFormatStr: String; procedure WriteNumFormat(AStream: TStream; ANumFormatStr: String;
ANumFormatIndex: Integer); virtual; ANumFormatIndex: Integer); virtual;
// Writes out all FORMAT records // Writes out all FORMAT records
procedure WriteNumFormats(AStream: TStream; ADialect: TsNumFormatDialect); procedure WriteNumFormats(AStream: TStream);
// Writes out a floating point NUMBER record // Writes out a floating point NUMBER record
procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
const AValue: Double; ACell: PCell); override; const AValue: Double; ACell: PCell); override;
@ -429,8 +429,7 @@ type
end; end;
procedure AddBuiltinBiffFormats(AList: TStringList; procedure AddBuiltinBiffFormats(AList: TStringList;
AFormatSettings: TFormatSettings; ALastIndex: Integer; AFormatSettings: TFormatSettings; ALastIndex: Integer);
ADialect: TsNumFormatDialect);
implementation implementation
@ -594,8 +593,7 @@ end;
number format that Excel used. number format that Excel used.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure AddBuiltinBiffFormats(AList: TStringList; procedure AddBuiltinBiffFormats(AList: TStringList;
AFormatSettings: TFormatSettings; ALastIndex: Integer; AFormatSettings: TFormatSettings; ALastIndex: Integer);
ADialect: TsNumFormatDialect);
var var
fs: TFormatSettings absolute AFormatSettings; fs: TFormatSettings absolute AFormatSettings;
cs: String; cs: String;
@ -608,10 +606,10 @@ begin
AList.Add('0.00'); // 2 AList.Add('0.00'); // 2
AList.Add('#,##0'); // 3 AList.Add('#,##0'); // 3
AList.Add('#,##0.00'); // 4 AList.Add('#,##0.00'); // 4
AList.Add(BuildCurrencyFormatString(ADialect, nfCurrency, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 5 AList.Add(BuildCurrencyFormatString(nfCurrency, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 5
AList.Add(BuildCurrencyFormatString(ADialect, nfCurrencyRed, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 6 AList.Add(BuildCurrencyFormatString(nfCurrencyRed, fs, 0, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 6
AList.Add(BuildCurrencyFormatString(ADialect, nfCurrency, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 7 AList.Add(BuildCurrencyFormatString(nfCurrency, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 7
AList.Add(BuildCurrencyFormatString(ADialect, nfCurrencyRed, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 8 AList.Add(BuildCurrencyFormatString(nfCurrencyRed, fs, 2, fs.CurrencyFormat, fs.NegCurrFormat, cs)); // 8
AList.Add('0%'); // 9 AList.Add('0%'); // 9
AList.Add('0.00%'); // 10 AList.Add('0.00%'); // 10
AList.Add('0.00E+00'); // 11 AList.Add('0.00E+00'); // 11
@ -670,7 +668,7 @@ procedure TsSpreadBIFFReader.AddBuiltinNumFormats;
begin begin
FFirstNumFormatIndexInFile := 164; FFirstNumFormatIndexInFile := 164;
AddBuiltInBiffFormats( AddBuiltInBiffFormats(
FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1, nfdDefault FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1
); );
end; end;
@ -1861,7 +1859,7 @@ procedure TsSpreadBIFFWriter.AddBuiltinNumFormats;
begin begin
FFirstNumFormatIndexInFile := 164; FFirstNumFormatIndexInFile := 164;
AddBuiltInBiffFormats( AddBuiltInBiffFormats(
FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1, nfdExcel FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1
); );
end; end;
@ -2211,37 +2209,24 @@ end;
Writes all number formats to the stream. Saving starts at the item with the Writes all number formats to the stream. Saving starts at the item with the
FirstFormatIndexInFile. FirstFormatIndexInFile.
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsSpreadBIFFWriter.WriteNumFormats(AStream: TStream; procedure TsSpreadBIFFWriter.WriteNumFormats(AStream: TStream);
ADialect: TsNumFormatDialect);
var var
i: Integer; i: Integer;
parser: TsNumFormatParser; parser: TsNumFormatParser;
fmtStr: String; fmtStr: String;
begin begin
ListAllNumFormats(ADialect); ListAllNumFormats;
for i:= FFirstNumFormatIndexInFile to NumFormatList.Count-1 do for i:= FFirstNumFormatIndexInFile to NumFormatList.Count-1 do
begin begin
fmtStr := NumFormatList[i]; fmtStr := NumFormatList[i];
parser := TsNumFormatParser.Create(Workbook, fmtStr); parser := TsNumFormatParser.Create(Workbook, fmtStr);
try try
fmtStr := parser.FormatString[ADialect];; fmtStr := parser.FormatString;
WriteNumFormat(AStream, fmtStr, i); WriteNumFormat(AStream, fmtStr, i);
finally finally
parser.Free; parser.Free;
end; end;
end; end;
{
i := NumFormatList.FindByIndex(FFirstNumFormatIndexInFile);
if i > -1 then
while i < NumFormatList.Count do
begin
item := NumFormatList[i];
if item <> nil then
WriteNumFormat(AStream, item, i);
inc(i);
end;
}
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------

View File

@ -417,7 +417,7 @@ procedure TsSpreadOOXMLReader.AddBuiltinNumFormats;
begin begin
FFirstNumFormatIndexInFile := 164; FFirstNumFormatIndexInFile := 164;
AddBuiltInBiffFormats( AddBuiltInBiffFormats(
FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1, nfdDefault FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1
); );
end; end;
@ -2222,7 +2222,7 @@ begin
numFmtStr := NumFormatList[i]; numFmtStr := NumFormatList[i];
parser := TsNumFormatParser.Create(Workbook, numFmtStr); parser := TsNumFormatParser.Create(Workbook, numFmtStr);
try try
numFmtStr := UTF8TextToXMLText(parser.FormatString[nfdExcel]); numFmtStr := UTF8TextToXMLText(parser.FormatString);
xmlStr := xmlStr + Format('<numFmt numFmtId="%d" formatCode="%s" />', xmlStr := xmlStr + Format('<numFmt numFmtId="%d" formatCode="%s" />',
[i, numFmtStr]); [i, numFmtStr]);
inc(n); inc(n);
@ -2475,7 +2475,7 @@ begin
numFmtParams := Workbook.GetNumberFormat(fmt^.NumberFormatIndex); numFmtParams := Workbook.GetNumberFormat(fmt^.NumberFormatIndex);
if numFmtParams <> nil then if numFmtParams <> nil then
begin begin
numFmtStr := numFmtParams.NumFormatStr[nfdExcel]; numFmtStr := numFmtParams.NumFormatStr;
idx := NumFormatList.IndexOf(numFmtStr); idx := NumFormatList.IndexOf(numFmtStr);
end else end else
idx := 0; // "General" format is at index 0 idx := 0; // "General" format is at index 0
@ -2905,7 +2905,7 @@ procedure TsSpreadOOXMLWriter.AddBuiltinNumFormats;
begin begin
FFirstNumFormatIndexInFile := 164; FFirstNumFormatIndexInFile := 164;
AddBuiltInBiffFormats( AddBuiltInBiffFormats(
FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1, nfdExcel FNumFormatList, Workbook.FormatSettings, FFirstNumFormatIndexInFile-1
); );
end; end;
@ -3048,7 +3048,7 @@ var
i: Integer; i: Integer;
begin begin
{ Analyze the workbook and collect all information needed } { Analyze the workbook and collect all information needed }
ListAllNumFormats(nfdExcel); ListAllNumFormats;
ListAllFills; ListAllFills;
ListAllBorders; ListAllBorders;