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);
MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0_);("$"#,##0)');
MyWorksheet.WriteNumber(r, 1, number);
MyWorksheet.WriteFontColor(r, 1, NA_COLOR);
MyWorksheet.WriteNumberFormat(r, 1, nfCustom, '"$"#,##0_);("$"#,##0)');
MyWorksheet.WriteNumber(r, 2, -number);
MyWorksheet.WriteNumberFormat(r, 2, nfCustom, '"$"#,##0_);("$"#,##0)');
MyWorksheet.WriteFontColor(r, 2, NA_COLOR);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0.0_);[Red]("$"#,##0.0)');
MyWorksheet.WriteNumber(r, 1, number);

View File

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

View File

@ -105,7 +105,7 @@ object MainForm: TMainForm
'Font1=Arial; size 10; blue; underline'
'Font2=Arial; size 10; black; bold'
'Font3=Arial; size 10; black; italic'
'CellFormat0='
'CellFormat0=nfGeneral'
)
TitleCaptions.Strings = (
'Properties'
@ -820,6 +820,34 @@ object MainForm: TMainForm
Hint = 'Currency format (negative values in red)'
NumberFormat = nfCurrencyRed
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
Category = 'File'
Caption = '&Open ...'
@ -874,6 +902,12 @@ object MainForm: TMainForm
ImageIndex = 49
OnExecute = AcColDeleteExecute
end
object AcSettingsFormatSettings: TAction
Category = 'Settings'
Caption = 'Number format settings...'
Hint = 'Define number format settings'
OnExecute = AcSettingsFormatSettingsExecute
end
object AcSettingsCSVParams: TAction
Category = 'Settings'
Caption = 'CSV parameters...'
@ -886,40 +920,6 @@ object MainForm: TMainForm
Hint = 'Define currency symbols'
OnExecute = AcSettingsCurrencyExecute
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
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
@ -941,6 +941,20 @@ object MainForm: TMainForm
Hint = 'Short date format'
NumberFormat = nfShortDate
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
Category = 'FPSpreadsheet'
WorkbookSource = WorkbookSource
@ -5057,6 +5071,17 @@ object MainForm: TMainForm
Action = AcNumFormatShortDate
AutoCheck = True
end
object MenuItem118: TMenuItem
Caption = '-'
end
object MenuItem119: TMenuItem
Action = AcNumFormatDayMonth
AutoCheck = True
end
object MenuItem120: TMenuItem
Action = AcNumFormatMonthYear
AutoCheck = True
end
end
object PuTimeFormat: TPopupMenu
left = 504

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -96,9 +96,9 @@ function IfThen(ACondition: Boolean; AValue1,AValue2: TsNumberFormat): TsNumberF
procedure BuildCurrencyFormatList(AList: TStrings;
APositive: Boolean; AValue: Double; const ACurrencySymbol: String);
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect;
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings;
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String;
function BuildCurrencyFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; ADecimals, APosCurrFmt, ANegCurrFmt: Integer;
ACurrencySymbol: String; Accounting: Boolean = false): String;
function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; AFormatString: String = ''): String;
function BuildFractionFormatString(AMixedFraction: Boolean;
@ -119,9 +119,10 @@ function MonthNamesToString(const AMonthNames: TMonthNameArray;
const AEmptyStr: String): String;
function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
{
procedure SplitFormatString(const AFormatString: String; out APositivePart,
ANegativePart, AZeroPart: String);
}
procedure MakeTimeIntervalMask(Src: String; var Dest: String);
function ConvertFloatToStr(AValue: Double; AParams: TsNumFormatParams;
@ -1062,30 +1063,30 @@ end;
or minus signs) is taken from the provided format settings. The format string
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
format string is to be generated.
@param AFormatSettings FormatSettings to be applied (used to extract default
values for the next parameters)
@param ADecimals number of decimal places. If < 0, the CurrencyDecimals
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
- see pcfXXXX constants in fpspreadsheet.pas.
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 ().
- see ncfXXXX constants in fpspreadsheet.pas.
If < 0, the NegCurrFormat of the FormatSettings is used.
@param ACurrencySymbol Name of the currency, like $ or USD.
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'
-------------------------------------------------------------------------------}
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect;
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings;
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String;
function BuildCurrencyFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings;
ADecimals, APosCurrFmt, ANegCurrFmt: Integer; ACurrencySymbol: String;
Accounting: Boolean = false): String;
{
const
POS_FMT: array[0..3] of string = (
@ -1120,8 +1121,8 @@ var
p, n: String;
negRed: Boolean;
begin
pcf := IfThen(APosCurrFormat < 0, AFormatSettings.CurrencyFormat, APosCurrFormat);
ncf := IfThen(ANegCurrFormat < 0, AFormatSettings.NegCurrFormat, ANegCurrFormat);
pcf := IfThen(APosCurrFmt < 0, AFormatSettings.CurrencyFormat, APosCurrFmt);
ncf := IfThen(ANegCurrFmt < 0, AFormatSettings.NegCurrFormat, ANegCurrFmt);
if (ADecimals < 0) then
ADecimals := AFormatSettings.CurrencyDecimals;
if ACurrencySymbol = '?' then
@ -1134,25 +1135,25 @@ begin
negRed := (ANumberFormat = nfCurrencyRed);
p := POS_CURR_FMT[pcf]; // Format mask for positive 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
if ADialect = nfdExcel then
if Accounting then
case ncf of
0, 14: p := p + '_)';
3, 11: p := p + '_-';
4, 15: p := '_(' + p;
4, 15: p := '_(' + p;
5, 8 : p := '_-' + p;
end;
if ACurrencySymbol <> '' then begin
Result := Format(p, ['#,##0' + decs, ACurrencySymbol]) + ';'
+ IfThen(negRed, '[red]', '')
// + IfThen(negRed and (ADialect = nfdExcel), '[red]', '')
+ Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';'
+ Format(p, ['0'+decs, ACurrencySymbol]);
end
else begin
Result := '#,##0' + decs;
if negRed and (ADialect = nfdExcel) then
if negRed then
Result := Result +';[red]'
else
Result := Result +';';
@ -1216,14 +1217,20 @@ begin
Result := '0' + decs + 'E+00';
nfPercentage:
Result := '0' + decs + '%';
nfFraction:
if ADecimals = 0 then
Result := '# ??/??'
else
begin
decs := DupeString('?', ADecimals);
Result := '# ' + decs + '/' + decs;
end;
nfCurrency, nfCurrencyRed:
Result := BuildCurrencyFormatString(nfdDefault, ANumberFormat, AFormatSettings,
Result := BuildCurrencyFormatString(ANumberFormat, AFormatSettings,
ADecimals, AFormatSettings.CurrencyFormat, AFormatSettings.NegCurrFormat,
AFormatSettings.CurrencyString);
// raise Exception.Create('BuildNumberFormatString: Use BuildCurrencyFormatString '+
// 'to create a format string for currency values.');
nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime,
nfShortTimeAM, nfLongTimeAM, nfTimeInterval:
nfShortTimeAM, nfLongTimeAM, nfDayMonth, nfMonthYear, nfTimeInterval:
raise Exception.Create('BuildNumberFormatString: Use BuildDateTimeFormatSstring '+
'to create a format string for date/time values.');
end;
@ -1384,8 +1391,8 @@ const
MinInt64 = Low(Int64);
var
H1, H2, K1, K2, A, NewA, tmp, prevH1, prevK1: Int64;
B, diff, test, eps: Double;
Found, PendingOverflow: Boolean;
B, diff, test: Double;
PendingOverflow: Boolean;
i: Integer = 0;
begin
Assert((APrecision > 0) and (APrecision < 1));
@ -1610,6 +1617,7 @@ end;
for negative numbers
@param AZeroPart Third section of the formatting string for zero.
-------------------------------------------------------------------------------}
(*
procedure SplitFormatString(const AFormatString: String; out APositivePart,
ANegativePart, AZeroPart: String);
@ -1666,7 +1674,7 @@ begin
inc(P);
end;
end;
*)
{@@ ----------------------------------------------------------------------------
Creates a "time interval" format string having the first time code identifier
in square brackets.
@ -2452,7 +2460,7 @@ var
if AddThousandSeparator then
begin
j := Length(Result)-2;
while (j > 0) do
while (j > 1) do
begin
Insert(fs.ThousandSeparator, Result, j);
dec(j, 3);
@ -2507,7 +2515,7 @@ var
var
fmtStr: String;
begin
fmtStr := AParams.NumFormatStr[nfdExcel];
fmtStr := AParams.NumFormatStr;
raise Exception.CreateFmt(rsIsNoValidNumberFormatString, [fmtStr]);
end;
@ -2583,7 +2591,7 @@ begin
(7) number w/o decimals --> exponent
}
// 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
Result := Result + FixIntPart(AValue, false, digitsZero, digitsOpt, digitsSpace);
el := i;
@ -2744,7 +2752,7 @@ begin
end;
// 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
// Simple decimal number (nfFixed) (case 1)
Result := Result
@ -2849,6 +2857,9 @@ begin
Result := Result + section.Elements[el].TextValue;
end;
nftEmptyCharWidth:
Result := Result + ' ';
nftDateTimeSep:
case section.Elements[el].TextValue of
'/': Result := Result + fs.DateSeparator;
@ -2955,159 +2966,6 @@ begin
end;
inc(el);
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;

View File

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

View File

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

View File

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

View File

@ -1004,7 +1004,7 @@ begin
WriteCodepage(AStream, FCodePage);
WriteWindow1(AStream);
WriteFonts(AStream);
WriteNumFormats(AStream, nfdExcel);
WriteNumFormats(AStream);
WritePalette(AStream);
WriteXFRecords(AStream);
WriteStyle(AStream);
@ -1497,20 +1497,12 @@ begin
if (AFormatRecord <> nil) and (uffNumberFormat in AFormatRecord^.UsedFormattingFields)
then begin
nfParams := Workbook.GetNumberFormat(AFormatRecord^.NumberFormatIndex);
nfs := nfParams.NumFormatStr[nfdExcel];
nfs := nfParams.NumFormatStr;
j := NumFormatList.IndexOf(nfs);
if j = -1 then j := 0;
end;
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 }
rec.XFType_Prot_ParentXF := XFType_Prot and MASK_XF_TYPE_PROT;
if XFType_Prot and MASK_XF_TYPE_PROT_STYLE_XF <> 0 then

View File

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

View File

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

View File

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