fpspreadsheet: Remove built-in number formats nfSci (not suppored by ods and fpc) and nfAccounting/nfAccountingRed (too much display-oriented, too cumbersome to implement for reading and displaying in the grid). If needed in Excel they can still be written using nfCustom. Update all files and tests for these now no longer existing formats.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3222 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-06-23 09:15:56 +00:00
parent be203a87e5
commit 13a9fb2603
20 changed files with 291 additions and 701 deletions

View File

@ -212,36 +212,6 @@ begin
MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3); MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3);
MyWorksheet.WriteFontColor(r, 2, scGray); MyWorksheet.WriteFontColor(r, 2, scGray);
inc(r); inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 1 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 1);
MyWorksheet.WriteFontColor(r, 1, scGray);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 1);
MyWorksheet.WriteFontColor(r, 2, scGray);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 1);
MyWorksheet.WriteFontColor(r, 3, scGray);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 1);
MyWorksheet.WriteFontColor(r, 4, scGray);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 2 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 2);
MyWorksheet.WriteFontColor(r, 1, scGray);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 2);
MyWorksheet.WriteFontColor(r, 2, scGray);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 2);
MyWorksheet.WriteFontColor(r, 3, scGray);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 2);
MyWorksheet.WriteFontColor(r, 4, scGray);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 3 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 3);
MyWorksheet.WriteFontColor(r, 1, scGray);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 3);
MyWorksheet.WriteFontColor(r, 2, scGray);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 3);
MyWorksheet.WriteFontColor(r, 3, scGray);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 3);
MyWorksheet.WriteFontColor(r, 4, scGray);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 1 dec'); MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 1 dec');
MyWorksheet.WriteNumber(r, 1, number, nfExp, 1); MyWorksheet.WriteNumber(r, 1, number, nfExp, 1);
MyWorksheet.WriteFontColor(r, 1, scGray); MyWorksheet.WriteFontColor(r, 1, scGray);
@ -278,16 +248,6 @@ begin
MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD');
inc(r); inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfAccounting, 0 decs');
MyWorksheet.WriteCurrency(r, 1, number, nfAccounting, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfAccounting, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfAccounting, 0, 'USD');
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfAccountingRed, 0 decs');
MyWorksheet.WriteCurrency(r, 1, number, nfAccountingRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfAccountingRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfAccountingRed, 0, 'USD');
inc(r, 2);
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, scGray); MyWorksheet.WriteFontColor(r, 1, scGray);

View File

@ -238,24 +238,6 @@ begin
MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 3); MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 3);
MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3); MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3);
inc(r); inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 1 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 1);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 1);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 1);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 1);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 2 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 2);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 2);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 2);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 2);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 3 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 3);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 3);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 3);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 3);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 1 dec'); MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 1 dec');
MyWorksheet.WriteNumber(r, 1, number, nfExp, 1); MyWorksheet.WriteNumber(r, 1, number, nfExp, 1);
MyWorksheet.WriteNumber(r, 2, -number, nfExp, 1); MyWorksheet.WriteNumber(r, 2, -number, nfExp, 1);
@ -284,16 +266,6 @@ begin
MyWorksheet.WriteCurrency(r, 1, number, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 1, number, nfCurrencyRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD');
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfAccounting, 0 decs');
MyWorksheet.WriteCurrency(r, 1, number, nfAccounting, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfAccounting, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfAccounting, 0, 'USD');
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfAccountingRed, 0 decs');
MyWorksheet.WriteCurrency(r, 1, number, nfAccountingRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfAccountingRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfAccountingRed, 0, 'USD');
inc(r, 2); inc(r, 2);
MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0_);("$"#,##0)'); MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0_);("$"#,##0)');

View File

@ -256,30 +256,7 @@ begin
MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 3); MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 3);
MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3); MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3);
inc(r,2); inc(r,2);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 0 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 0);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 0);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 0);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 0);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 1 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 1);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 1);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 1);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 1);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 2 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 2);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 2);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 2);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 2);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfSci, 3 dec');
MyWorksheet.WriteNumber(r, 1, number, nfSci, 3);
MyWorksheet.WriteNumber(r, 2, -number, nfSci, 3);
MyWorksheet.WriteNumber(r, 3, 1.0/number, nfSci, 3);
MyWorksheet.WriteNumber(r, 4, -1.0/number, nfSci, 3);
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 0 dec'); MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 0 dec');
MyWorksheet.WriteNumber(r, 1, number, nfExp, 0); MyWorksheet.WriteNumber(r, 1, number, nfExp, 0);
MyWorksheet.WriteNumber(r, 2, -number, nfExp, 0); MyWorksheet.WriteNumber(r, 2, -number, nfExp, 0);
@ -314,18 +291,8 @@ begin
MyWorksheet.WriteCurrency(r, 1, number, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 1, number, nfCurrencyRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD'); MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD');
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfAccounting, 0 decs');
MyWorksheet.WriteCurrency(r, 1, number, nfAccounting, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, -number, nfAccounting, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfAccounting, 0, 'USD');
inc(r);
MyWorksheet.WriteUTF8Text(r, 0, 'nfAccountingRed, 0 decs');
MyWorksheet.WriteCurrency(r, 1, -number, nfAccountingRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 2, number, nfAccountingRed, 0, 'USD');
MyWorksheet.WriteCurrency(r, 3, 0.0, nfAccountingRed, 0, 'USD');
{ {
inc(r,2); inc(r,2);
MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "EUR "#,##0_);("EUR "#,##0)'); MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "EUR "#,##0_);("EUR "#,##0)');
MyWorksheet.WriteNumber(r, 1, number); MyWorksheet.WriteNumber(r, 1, number);

View File

@ -184,16 +184,6 @@ begin
MyWorksheet.WriteNumber(row, 7, number7, nfExp, 3); MyWorksheet.WriteNumber(row, 7, number7, nfExp, 3);
MyWorksheet.WriteNumber(row, 8, number8, nfExp, 3); MyWorksheet.WriteNumber(row, 8, number8, nfExp, 3);
inc(row); inc(row);
MyWorksheet.WriteUTF8Text(row, 0, 'nfSci, 2 decimals');
MyWorksheet.WriteNumber(row, 1, number1, nfSci, 2);
MyWorksheet.WriteNumber(row, 2, number2, nfSci, 2);
MyWorksheet.WriteNumber(row, 3, number3, nfSci, 2);
MyWorksheet.WriteNumber(row, 4, number4, nfSci, 2);
MyWorksheet.WriteNumber(row, 5, number5, nfSci, 2);
MyWorksheet.WriteNumber(row, 6, number6, nfSci, 2);
MyWorksheet.WriteNumber(row, 7, number7, nfSci, 2);
MyWorksheet.WriteNumber(row, 8, number8, nfSci, 2);
inc(row);
MyWorksheet.WriteUTF8Text(row, 0, 'nfCurrency, 2 decimals'); MyWorksheet.WriteUTF8Text(row, 0, 'nfCurrency, 2 decimals');
MyWorksheet.WriteCurrency(row, 1, number1, nfCurrency, 2, '$'); MyWorksheet.WriteCurrency(row, 1, number1, nfCurrency, 2, '$');
MyWorksheet.WriteCurrency(row, 2, number2, nfCurrency, 2, '$'); MyWorksheet.WriteCurrency(row, 2, number2, nfCurrency, 2, '$');
@ -213,28 +203,8 @@ begin
MyWorksheet.WriteCurrency(row, 6, number6, nfCurrencyRed, 2, '$', pcfCSV, ncfBCSVB); MyWorksheet.WriteCurrency(row, 6, number6, nfCurrencyRed, 2, '$', pcfCSV, ncfBCSVB);
MyWorksheet.WriteCurrency(row, 7, number7, nfCurrencyRed, 2, '$', pcfCSV, ncfBCSVB); MyWorksheet.WriteCurrency(row, 7, number7, nfCurrencyRed, 2, '$', pcfCSV, ncfBCSVB);
MyWorksheet.WriteCurrency(row, 8, number8, nfCurrencyRed, 2, '$', pcfCSV, ncfBCSVB); MyWorksheet.WriteCurrency(row, 8, number8, nfCurrencyRed, 2, '$', pcfCSV, ncfBCSVB);
inc(row);
// Note: nfAccounting's not supported by ods, will be replaced by nfCurrency's
MyWorksheet.WriteUTF8Text(row, 0, 'nfAccounting, 2 decimals');
MyWorksheet.WriteCurrency(row, 1, number1, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 2, number2, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 3, number3, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 4, number4, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 5, number5, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 6, number6, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 7, number7, nfAccounting, 2, '$');
MyWorksheet.WriteCurrency(row, 8, number8, nfAccounting, 2, '$');
inc(row);
MyWorksheet.WriteUTF8Text(row, 0, 'nfAccountingRed, 2 decimals, >0: EUR 1000, <0: -EUR 1000)');
MyWorksheet.WriteCurrency(row, 1, number1, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 2, number2, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 3, number3, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 4, number4, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 5, number5, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 6, number6, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 7, number7, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
MyWorksheet.WriteCurrency(row, 8, number8, nfAccountingRed, 2, 'EUR', pcfCSV, ncfMCSV);
inc(row,2); inc(row,2);
MyWorksheet.WriteUTF8Text(row, 0, 'Some date/time values in various formats:'); MyWorksheet.WriteUTF8Text(row, 0, 'Some date/time values in various formats:');
inc(row); inc(row);
MyWorksheet.WriteUTF8Text(row, 0, 'nfShortDateTime'); MyWorksheet.WriteUTF8Text(row, 0, 'nfShortDateTime');
@ -264,6 +234,9 @@ begin
MyWorksheet.WriteUTF8Text(row, 0, 'nfLongTimeAM'); MyWorksheet.WriteUTF8Text(row, 0, 'nfLongTimeAM');
MyWorksheet.WriteDateTime(row, 1, dt1, nfLongTimeAM); MyWorksheet.WriteDateTime(row, 1, dt1, nfLongTimeAM);
MyWorksheet.WriteDateTime(row, 2, dt2, nfLongTimeAM); MyWorksheet.WriteDateTime(row, 2, dt2, nfLongTimeAM);
inc(row,2);
MyWorksheet.WriteUTF8Text(row, 0, 'Some custom formats');
inc(row); inc(row);
// In order to use a semicolon as a date-time separator it must be escaped either by // In order to use a semicolon as a date-time separator it must be escaped either by
// using the backslash or quotes (because the semicolon is the separator between sections) // using the backslash or quotes (because the semicolon is the separator between sections)

View File

@ -4,7 +4,7 @@ object Form1: TForm1
Top = 248 Top = 248
Width = 884 Width = 884
Caption = 'spready' Caption = 'spready'
ClientHeight = 629 ClientHeight = 624
ClientWidth = 884 ClientWidth = 884
Menu = MainMenu Menu = MainMenu
OnActivate = FormActivate OnActivate = FormActivate
@ -14,7 +14,7 @@ object Form1: TForm1
object Panel1: TPanel object Panel1: TPanel
Left = 0 Left = 0
Height = 85 Height = 85
Top = 544 Top = 539
Width = 884 Width = 884
Align = alBottom Align = alBottom
BevelOuter = bvNone BevelOuter = bvNone
@ -23,9 +23,9 @@ object Form1: TForm1
TabOrder = 0 TabOrder = 0
object CbShowHeaders: TCheckBox object CbShowHeaders: TCheckBox
Left = 8 Left = 8
Height = 19 Height = 24
Top = 8 Top = 8
Width = 93 Width = 116
Caption = 'Show headers' Caption = 'Show headers'
Checked = True Checked = True
OnClick = CbShowHeadersClick OnClick = CbShowHeadersClick
@ -34,9 +34,9 @@ object Form1: TForm1
end end
object CbShowGridLines: TCheckBox object CbShowGridLines: TCheckBox
Left = 8 Left = 8
Height = 19 Height = 24
Top = 32 Top = 32
Width = 100 Width = 125
Caption = 'Show grid lines' Caption = 'Show grid lines'
Checked = True Checked = True
OnClick = CbShowGridLinesClick OnClick = CbShowGridLinesClick
@ -45,7 +45,7 @@ object Form1: TForm1
end end
object EdFrozenCols: TSpinEdit object EdFrozenCols: TSpinEdit
Left = 389 Left = 389
Height = 23 Height = 28
Top = 8 Top = 8
Width = 52 Width = 52
OnChange = EdFrozenColsChange OnChange = EdFrozenColsChange
@ -53,7 +53,7 @@ object Form1: TForm1
end end
object EdFrozenRows: TSpinEdit object EdFrozenRows: TSpinEdit
Left = 389 Left = 389
Height = 23 Height = 28
Top = 39 Top = 39
Width = 52 Width = 52
OnChange = EdFrozenRowsChange OnChange = EdFrozenRowsChange
@ -61,37 +61,37 @@ object Form1: TForm1
end end
object Label1: TLabel object Label1: TLabel
Left = 304 Left = 304
Height = 15 Height = 20
Top = 13 Top = 13
Width = 62 Width = 77
Caption = 'Frozen cols:' Caption = 'Frozen cols:'
FocusControl = EdFrozenCols FocusControl = EdFrozenCols
ParentColor = False ParentColor = False
end end
object Label2: TLabel object Label2: TLabel
Left = 304 Left = 304
Height = 15 Height = 20
Top = 40 Top = 40
Width = 66 Width = 82
Caption = 'Frozen rows:' Caption = 'Frozen rows:'
FocusControl = EdFrozenRows FocusControl = EdFrozenRows
ParentColor = False ParentColor = False
end end
object CbReadFormulas: TCheckBox object CbReadFormulas: TCheckBox
Left = 8 Left = 8
Height = 19 Height = 24
Top = 56 Top = 56
Width = 96 Width = 120
Caption = 'Read formulas' Caption = 'Read formulas'
OnChange = CbReadFormulasChange OnChange = CbReadFormulasChange
TabOrder = 4 TabOrder = 4
end end
object CbHeaderStyle: TComboBox object CbHeaderStyle: TComboBox
Left = 152 Left = 152
Height = 23 Height = 28
Top = 8 Top = 8
Width = 116 Width = 116
ItemHeight = 15 ItemHeight = 20
ItemIndex = 2 ItemIndex = 2
Items.Strings = ( Items.Strings = (
'Lazarus' 'Lazarus'
@ -106,7 +106,7 @@ object Form1: TForm1
end end
object PageControl1: TPageControl object PageControl1: TPageControl
Left = 0 Left = 0
Height = 465 Height = 460
Top = 79 Top = 79
Width = 884 Width = 884
ActivePage = TabSheet1 ActivePage = TabSheet1
@ -116,11 +116,11 @@ object Form1: TForm1
OnChange = PageControl1Change OnChange = PageControl1Change
object TabSheet1: TTabSheet object TabSheet1: TTabSheet
Caption = 'Sheet1' Caption = 'Sheet1'
ClientHeight = 437 ClientHeight = 427
ClientWidth = 876 ClientWidth = 876
object WorksheetGrid: TsWorksheetGrid object WorksheetGrid: TsWorksheetGrid
Left = 0 Left = 0
Height = 437 Height = 427
Top = 0 Top = 0
Width = 876 Width = 876
FrozenCols = 0 FrozenCols = 0
@ -136,7 +136,7 @@ object Form1: TForm1
TitleStyle = tsNative TitleStyle = tsNative
OnSelection = WorksheetGridSelection OnSelection = WorksheetGridSelection
ColWidths = ( ColWidths = (
42 56
64 64
64 64
64 64
@ -244,19 +244,19 @@ object Form1: TForm1
end end
object FontComboBox: TComboBox object FontComboBox: TComboBox
Left = 52 Left = 52
Height = 23 Height = 28
Top = 2 Top = 2
Width = 127 Width = 127
ItemHeight = 15 ItemHeight = 20
OnSelect = FontComboBoxSelect OnSelect = FontComboBoxSelect
TabOrder = 0 TabOrder = 0
end end
object FontSizeComboBox: TComboBox object FontSizeComboBox: TComboBox
Left = 179 Left = 179
Height = 23 Height = 28
Top = 2 Top = 2
Width = 48 Width = 48
ItemHeight = 15 ItemHeight = 20
Items.Strings = ( Items.Strings = (
'8' '8'
'9' '9'
@ -977,6 +977,9 @@ object Form1: TForm1
Action = AcNFGeneral Action = AcNFGeneral
AutoCheck = True AutoCheck = True
end end
object MenuItem38: TMenuItem
Caption = '-'
end
object MenuItem34: TMenuItem object MenuItem34: TMenuItem
Action = AcNFFixed Action = AcNFFixed
AutoCheck = True AutoCheck = True
@ -993,8 +996,54 @@ object Form1: TForm1
Action = AcNFExp Action = AcNFExp
AutoCheck = True AutoCheck = True
end end
object MenuItem38: TMenuItem object MenuItem47: TMenuItem
Action = AcNFSci Caption = '-'
end
object MenuItem48: TMenuItem
Action = AcNFCurrency
AutoCheck = True
end
object MenuItem49: TMenuItem
Action = AcNFCurrencyRed
AutoCheck = True
end
object MenuItem50: TMenuItem
Caption = '-'
end
object MenuItem51: TMenuItem
Action = AcNFShortDateTime
AutoCheck = True
end
object MenuItem52: TMenuItem
Action = AcNFShortDate
AutoCheck = True
end
object MenuItem53: TMenuItem
Action = AcNFLongDate
AutoCheck = True
end
object MenuItem54: TMenuItem
Action = AcNFCustomDM
AutoCheck = True
end
object MenuItem55: TMenuItem
Action = AcNFCustomMY
AutoCheck = True
end
object MenuItem56: TMenuItem
Action = AcNFShortTime
AutoCheck = True
end
object MenuItem57: TMenuItem
Action = AcNFLongTime
AutoCheck = True
end
object MenuItem58: TMenuItem
Action = AcNFShortTimeAM
AutoCheck = True
end
object MenuItem59: TMenuItem
Action = AcNFLongTimeAM
AutoCheck = True AutoCheck = True
end end
end end
@ -2398,127 +2447,106 @@ object Form1: TForm1
Caption = 'Exponential' Caption = 'Exponential'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFSci: TAction
Tag = 1040
Category = 'Format'
AutoCheck = True
Caption = 'Scientific'
OnExecute = AcNumFormatExecute
end
object AcNFPercentage: TAction object AcNFPercentage: TAction
Tag = 1050 Tag = 1040
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Percentage' Caption = 'Percentage'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFCurrency: TAction object AcNFCurrency: TAction
Tag = 1060 Tag = 1050
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 = 1070 Tag = 1060
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 AcNFAccounting: TAction
Tag = 1080
Category = 'Format'
AutoCheck = True
Caption = 'Accounting'
OnExecute = AcNumFormatExecute
end
object AcNFAccountingRed: TAction
Tag = 1090
Category = 'Format'
AutoCheck = True
Caption = 'Accounting (negative values in red)'
OnExecute = AcNumFormatExecute
end
object AcNFShortDateTime: TAction object AcNFShortDateTime: TAction
Tag = 1100 Tag = 1070
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 = 1110 Tag = 1080
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Short date' Caption = 'Short date'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFFmtDateTimeDM: TAction
Tag = 1181
Category = 'Format'
AutoCheck = True
Caption = 'Day + month'
OnExecute = AcNumFormatExecute
end
object AcNFFmtDateTimeMY: TAction
Tag = 1182
Category = 'Format'
AutoCheck = True
Caption = 'Month + year'
OnExecute = AcNumFormatExecute
end
object AcNFLongDate: TAction object AcNFLongDate: TAction
Tag = 1120 Tag = 1090
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 = 1130 Tag = 1100
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 = 1140 Tag = 1110
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 = 1150 Tag = 1120
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 = 1160 Tag = 1130
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 AcNFFmtDateTimeMS: TAction object AcNFCusstomMS: TAction
Tag = 1183 Tag = 1153
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Minutes + seconds' Caption = 'Minutes + seconds'
OnExecute = AcNumFormatExecute OnExecute = AcNumFormatExecute
end end
object AcNFFmtDateTimeMSZ: TAction object AcNFCustomMSZ: TAction
Tag = 1184 Tag = 1154
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 = 1170 Tag = 1140
Category = 'Format' Category = 'Format'
AutoCheck = True AutoCheck = True
Caption = 'Time interval' Caption = 'Time interval'
@ -3218,10 +3246,6 @@ object Form1: TForm1
Action = AcNFExp Action = AcNFExp
AutoCheck = True AutoCheck = True
end end
object MnuNFSci: TMenuItem
Action = AcNFSci
AutoCheck = True
end
object MenuItem39: TMenuItem object MenuItem39: TMenuItem
Caption = '-' Caption = '-'
end end
@ -3233,14 +3257,6 @@ object Form1: TForm1
Action = AcNFCurrencyRed Action = AcNFCurrencyRed
AutoCheck = True AutoCheck = True
end end
object MnuAccounting: TMenuItem
Action = AcNFAccounting
AutoCheck = True
end
object MnuAccountingRed: TMenuItem
Action = AcNFAccountingRed
AutoCheck = True
end
object MenuItem40: TMenuItem object MenuItem40: TMenuItem
Caption = '-' Caption = '-'
end end
@ -3260,11 +3276,11 @@ object Form1: TForm1
AutoCheck = True AutoCheck = True
end end
object MnuFmtDateTimeDM: TMenuItem object MnuFmtDateTimeDM: TMenuItem
Action = AcNFFmtDateTimeDM Action = AcNFCustomDM
AutoCheck = True AutoCheck = True
end end
object MnuFmtDateTimeMY: TMenuItem object MnuFmtDateTimeMY: TMenuItem
Action = AcNFFmtDateTimeMY Action = AcNFCustomMY
AutoCheck = True AutoCheck = True
end end
object MenuItem43: TMenuItem object MenuItem43: TMenuItem
@ -3287,11 +3303,11 @@ object Form1: TForm1
AutoCheck = True AutoCheck = True
end end
object MenuItem45: TMenuItem object MenuItem45: TMenuItem
Action = AcNFFmtDateTimeMS Action = AcNFCusstomMS
AutoCheck = True AutoCheck = True
end end
object MnuFmtDateTimeMSZ: TMenuItem object MnuFmtDateTimeMSZ: TMenuItem
Action = AcNFFmtDateTimeMSZ Action = AcNFCustomMSZ
AutoCheck = True AutoCheck = True
end end
object MenuItem44: TMenuItem object MenuItem44: TMenuItem

View File

@ -53,12 +53,9 @@ type
AcDecDecimals: TAction; AcDecDecimals: TAction;
AcNFGeneral: TAction; AcNFGeneral: TAction;
AcNFExp: TAction; AcNFExp: TAction;
AcNFSci: TAction;
AcCopyFormat: TAction; AcCopyFormat: TAction;
AcNFCurrency: TAction; AcNFCurrency: TAction;
AcNFCurrencyRed: TAction; AcNFCurrencyRed: TAction;
AcNFAccounting: TAction;
AcNFAccountingRed: TAction;
AcNFShortDateTime: TAction; AcNFShortDateTime: TAction;
AcNFShortDate: TAction; AcNFShortDate: TAction;
AcNFLongDate: TAction; AcNFLongDate: TAction;
@ -67,10 +64,10 @@ type
AcNFShortTimeAM: TAction; AcNFShortTimeAM: TAction;
AcNFLongTimeAM: TAction; AcNFLongTimeAM: TAction;
AcNFTimeInterval: TAction; AcNFTimeInterval: TAction;
AcNFFmtDateTimeDM: TAction; AcNFCustomDM: TAction;
AcNFFmtDateTimeMY: TAction; AcNFCustomMY: TAction;
AcNFFmtDateTimeMS: TAction; AcNFCusstomMS: TAction;
AcNFFmtDateTimeMSZ: TAction; AcNFCustomMSZ: TAction;
AcNew: TAction; AcNew: TAction;
AcWordwrap: TAction; AcWordwrap: TAction;
AcVAlignDefault: TAction; AcVAlignDefault: TAction;
@ -132,6 +129,19 @@ type
MenuItem44: TMenuItem; MenuItem44: TMenuItem;
MenuItem45: TMenuItem; MenuItem45: TMenuItem;
MenuItem46: TMenuItem; MenuItem46: TMenuItem;
MenuItem47: TMenuItem;
MenuItem48: TMenuItem;
MenuItem49: TMenuItem;
MenuItem50: TMenuItem;
MenuItem51: TMenuItem;
MenuItem52: TMenuItem;
MenuItem53: TMenuItem;
MenuItem54: TMenuItem;
MenuItem55: TMenuItem;
MenuItem56: TMenuItem;
MenuItem57: TMenuItem;
MenuItem58: TMenuItem;
MenuItem59: TMenuItem;
MnuFmtDateTimeMSZ: TMenuItem; MnuFmtDateTimeMSZ: TMenuItem;
MnuTimeInterval: TMenuItem; MnuTimeInterval: TMenuItem;
MnuShortTimeAM: TMenuItem; MnuShortTimeAM: TMenuItem;
@ -143,8 +153,6 @@ type
MnuLongTime: TMenuItem; MnuLongTime: TMenuItem;
MnuLongDate: TMenuItem; MnuLongDate: TMenuItem;
MnuShortDateTime: TMenuItem; MnuShortDateTime: TMenuItem;
MnuAccountingRed: TMenuItem;
MnuAccounting: TMenuItem;
MnuCurrencyRed: TMenuItem; MnuCurrencyRed: TMenuItem;
MnuCurrency: TMenuItem; MnuCurrency: TMenuItem;
MnuNumberFormat: TMenuItem; MnuNumberFormat: TMenuItem;
@ -152,7 +160,6 @@ type
MnuNFFixedTh: TMenuItem; MnuNFFixedTh: TMenuItem;
MnuNFPercentage: TMenuItem; MnuNFPercentage: TMenuItem;
MnuNFExp: TMenuItem; MnuNFExp: TMenuItem;
MnuNFSci: TMenuItem;
MnuNFGeneral: TMenuItem; MnuNFGeneral: TMenuItem;
MnuTextRotation: TMenuItem; MnuTextRotation: TMenuItem;
MenuItem3: TMenuItem; MenuItem3: TMenuItem;

View File

@ -133,8 +133,6 @@ type
var ANextIndex: Integer): Boolean; var ANextIndex: Integer): Boolean;
function IsNumberAt(ASection,AIndex: Integer; out ANumberFormat: TsNumberFormat; function IsNumberAt(ASection,AIndex: Integer; out ANumberFormat: TsNumberFormat;
out ADecimals: Byte; out ANextIndex: Integer): Boolean; out ADecimals: Byte; out ANextIndex: Integer): Boolean;
function IsSciAt(ASection, AIndex: Integer; out ANumberFormat: TsNumberFormat;
out ADecimals: Byte; out ANextIndex: Integer): Boolean;
function IsTextAt(AText: string; ASection, AIndex: Integer): Boolean; function IsTextAt(AText: string; ASection, AIndex: Integer): Boolean;
function IsTimeAt(ASection,AIndex: Integer; out ANumberFormat: TsNumberFormat; function IsTimeAt(ASection,AIndex: Integer; out ANumberFormat: TsNumberFormat;
out ANextIndex: Integer): Boolean; out ANextIndex: Integer): Boolean;
@ -179,7 +177,7 @@ begin
inherited Create; inherited Create;
FCreateMethod := 0; FCreateMethod := 0;
FWorkbook := AWorkbook; FWorkbook := AWorkbook;
FHasRedSection := (ANumFormat in [nfCurrencyRed, nfAccountingRed]); FHasRedSection := (ANumFormat = nfCurrencyRed);
Parse(AFormatString); Parse(AFormatString);
end; end;
@ -584,10 +582,6 @@ begin
end; end;
end; end;
// Look for scientific format
if IsSciAt(ASection, 0, ANumFormat, ADecimals, next) then
exit;
// Currency? // Currency?
if IsCurrencyAt(ASection, ANumFormat, ADecimals, ACurrencySymbol, AColor) if IsCurrencyAt(ASection, ANumFormat, ADecimals, ACurrencySymbol, AColor)
then exit; then exit;
@ -677,7 +671,7 @@ begin
result := nfGeneral result := nfGeneral
else begin else begin
Result := FSections[0].NumFormat; Result := FSections[0].NumFormat;
if (Result in [nfCurrency, nfAccounting]) then begin if (Result = nfCurrency) then begin
if Length(FSections) = 2 then begin if Length(FSections) = 2 then begin
Result := FSections[1].NumFormat; Result := FSections[1].NumFormat;
if FSections[1].CurrencySymbol <> FSections[0].CurrencySymbol then begin if FSections[1].CurrencySymbol <> FSections[0].CurrencySymbol then begin
@ -688,10 +682,6 @@ begin
(FSections[1].NumFormat in [nfCurrency, nfCurrencyRed]) (FSections[1].NumFormat in [nfCurrency, nfCurrencyRed])
then then
exit; exit;
if FSections[1].NumFormat = nfAccounting then begin
Result := nfAccounting;
exit;
end;
end else end else
if Length(FSections) = 3 then begin if Length(FSections) = 3 then begin
Result := FSections[1].NumFormat; Result := FSections[1].NumFormat;
@ -706,12 +696,6 @@ begin
(FSections[2].NumFormat in [nfCurrency, nfCurrencyRed]) (FSections[2].NumFormat in [nfCurrency, nfCurrencyRed])
then then
exit; exit;
if (FSections[1].NumFormat = nfAccounting) and
(FSections[2].NumFormat in [nfCurrency, nfAccounting])
then begin
Result := nfAccounting;
exit;
end;
end; end;
Result := nfCustom; Result := nfCustom;
exit; exit;
@ -739,7 +723,6 @@ function TsNumFormatParser.IsCurrencyAt(ASection: Integer;
out ANumFormat: TsNumberFormat; out ADecimals: byte; out ANumFormat: TsNumberFormat; out ADecimals: byte;
out ACurrencySymbol: String; out AColor: TsColor): Boolean; out ACurrencySymbol: String; out AColor: TsColor): Boolean;
var var
isAccounting : Boolean;
hasCurrSymbol: Boolean; hasCurrSymbol: Boolean;
hasColor: Boolean; hasColor: Boolean;
el: Integer; el: Integer;
@ -750,7 +733,6 @@ begin
ACurrencySymbol := ''; ACurrencySymbol := '';
ADecimals := 0; ADecimals := 0;
AColor := scNotDefined; AColor := scNotDefined;
isAccounting := false;
hasColor := false; hasColor := false;
hasCurrSymbol := false; hasCurrSymbol := false;
@ -783,7 +765,7 @@ begin
hasColor := true; hasColor := true;
end; end;
nftRepeat: nftRepeat:
isAccounting := true; ;
nftCurrSymbol: nftCurrSymbol:
begin begin
ACurrencySymbol := FSections[ASection].Elements[el].TextValue; ACurrencySymbol := FSections[ASection].Elements[el].TextValue;
@ -812,13 +794,8 @@ begin
Result := hasCurrSymbol and ((ANumFormat = nfFixedTh) or (ASection = 2)); Result := hasCurrSymbol and ((ANumFormat = nfFixedTh) or (ASection = 2));
if Result then begin if Result then begin
if isAccounting then begin if AColor = scNotDefined then ANumFormat := nfCurrency else
if AColor = scNotDefined then ANumFormat := nfAccounting else if AColor = scRed then ANumFormat := nfCurrencyRed;
if AColor = scRed then ANumFormat := nfAccountingRed;
end else begin
if AColor = scNotDefined then ANumFormat := nfCurrency else
if AColor = scRed then ANumFormat := nfCurrencyRed;
end;
end else end else
ANumFormat := nfCustom; ANumFormat := nfCustom;
end; end;
@ -974,26 +951,6 @@ begin
end; end;
end; end;
function TsNumFormatParser.IsSciAt(ASection, AIndex: Integer;
out ANumberFormat: TsNumberFormat; out ADecimals: Byte; out ANextIndex: Integer): Boolean;
begin
if IsTokenAt(nftOptDigit, ASection, AIndex) and // '#'
IsTokenAt(nftOptDigit, ASection, Aindex+1) and // '#'
IsTokenAt(nftDigit, ASection, AIndex+2) and // '0'
IsTokenAt(nftDecSep, ASection, AIndex+3) and // '.'
IsTokenAt(nftDecs, ASection, AIndex+4) and // count of decimals
IsTokenAt(nftExpChar, ASection, AIndex+5) and // E
IsTokenAt(nftExpSign, ASection, AIndex+6) and // +/-
IsTokenAt(nftExpDigits, ASection, AIndex+7)
then begin
Result := true;
ANumberFormat := nfSci;
ADecimals := FSections[ASection].Elements[AIndex+4].IntValue;
ANextIndex := AIndex + 8;
end else
Result := false;
end;
function TsNumFormatParser.IsTextAt(AText: String; ASection, AIndex: Integer): Boolean; function TsNumFormatParser.IsTextAt(AText: String; ASection, AIndex: Integer): Boolean;
begin begin
Result := IsTokenAt(nftText, ASection, AIndex) and Result := IsTokenAt(nftText, ASection, AIndex) and

View File

@ -183,9 +183,9 @@ type
// general-purpose for all numbers // general-purpose for all numbers
nfGeneral, nfGeneral,
// numbers // numbers
nfFixed, nfFixedTh, nfExp, nfSci, nfPercentage, nfFixed, nfFixedTh, nfExp, nfPercentage,
// currency // currency
nfCurrency, nfCurrencyRed, nfAccounting, nfAccountingRed, nfCurrency, nfCurrencyRed,
// dates and times // dates and times
nfShortDateTime, {nfFmtDateTime, }nfShortDate, nfLongDate, nfShortTime, nfLongTime, nfShortDateTime, {nfFmtDateTime, }nfShortDate, nfLongDate, nfShortTime, nfLongTime,
nfShortTimeAM, nfLongTimeAM, nfTimeInterval, nfShortTimeAM, nfLongTimeAM, nfTimeInterval,
@ -1779,18 +1779,8 @@ function TsWorksheet.ReadAsUTF8Text(ACell: PCell): ansistring;
if (ANumberFormat = nfGeneral) or (ANumberFormatStr = '') then if (ANumberFormat = nfGeneral) or (ANumberFormatStr = '') then
Result := FloatToStr(Value, fs) Result := FloatToStr(Value, fs)
else else
if ANumberFormat = nfSci then
Result := SciFloat(Value, CountDecs(ANumberFormatStr, ['0']), fs)
else
if (ANumberFormat = nfPercentage) then if (ANumberFormat = nfPercentage) then
Result := FormatFloat(ANumberFormatStr, Value*100, fs) Result := FormatFloat(ANumberFormatStr, Value*100, fs)
else
if (ANumberFormat in [nfAccounting, nfAccountingRed]) then
case SplitAccountingFormatString(ANumberFormatStr, Sign(Value), left, right) of
0: Result := FormatFloat(ANumberFormatStr, Value, fs);
1: Result := FormatFloat(left, abs(Value), fs) + ' ' + Right;
2: Result := Left + ' ' + FormatFloat(right, abs(Value), fs);
end
else else
Result := FormatFloat(ANumberFormatStr, Value, fs) Result := FormatFloat(ANumberFormatStr, Value, fs)
end; end;
@ -2203,15 +2193,14 @@ begin
if ACell <> nil then begin if ACell <> nil then begin
ACell^.ContentType := cctNumber; ACell^.ContentType := cctNumber;
ACell^.NumberValue := ANumber; ACell^.NumberValue := ANumber;
ACell^.NumberFormat := AFormat;
if AFormat <> nfGeneral then begin if AFormat <> nfGeneral then begin
Include(ACell^.UsedFormattingFields, uffNumberFormat); Include(ACell^.UsedFormattingFields, uffNumberFormat);
ACell^.NumberFormat := AFormat;
ACell^.NumberFormatStr := BuildNumberFormatString(ACell^.NumberFormat, ACell^.NumberFormatStr := BuildNumberFormatString(ACell^.NumberFormat,
Workbook.FormatSettings, ADecimals); Workbook.FormatSettings, ADecimals);
end else begin end else begin
Exclude(ACell^.UsedFormattingFields, uffNumberFormat); Exclude(ACell^.UsedFormattingFields, uffNumberFormat);
ACell^.NumberFormat := nfGeneral;
ACell^.NumberFormatStr := ''; ACell^.NumberFormatStr := '';
end; end;
@ -2268,11 +2257,16 @@ begin
parser.Free; parser.Free;
end; end;
Include(ACell^.UsedFormattingFields, uffNumberFormat);
ACell^.ContentType := cctNumber; ACell^.ContentType := cctNumber;
ACell^.NumberValue := ANumber; ACell^.NumberValue := ANumber;
ACell^.NumberFormat := AFormat; //nfCustom; ACell^.NumberFormat := AFormat;
ACell^.NumberFormatStr := AFormatString; if AFormat <> nfGeneral then begin
Include(ACell^.UsedFormattingFields, uffNumberFormat);
ACell^.NumberFormatStr := AFormatString;
end else begin
Exclude(ACell^.UsedFormattingFields, uffNumberFormat);
ACell^.NumberFormatStr := '';
end;
ChangedCell(ACell^.Row, ACell^.Col); ChangedCell(ACell^.Row, ACell^.Col);
end; end;
@ -2381,8 +2375,7 @@ end;
@param ARow Cell row index @param ARow Cell row index
@param ACol Cell column index @param ACol Cell column index
@param AValue Number value to be written @param AValue Number value to be written
@param AFormat Format identifier, must be nfCurrency, nfCurrencyRed, @param AFormat Format identifier, must be nfCurrency, or nfCurrencyRed.
nfAccounting, or nfAccountingRed
@param ADecimals Number of decimal places @param ADecimals Number of decimal places
@param APosCurrFormat Code specifying the order of value, currency symbol @param APosCurrFormat Code specifying the order of value, currency symbol
and spaces (see pcfXXXX constants) and spaces (see pcfXXXX constants)
@ -2408,8 +2401,7 @@ end;
@param ACell Pointer to the cell considered @param ACell Pointer to the cell considered
@param AValue Number value to be written @param AValue Number value to be written
@param AFormat Format identifier, must be nfCurrency, nfCurrencyRed, @param AFormat Format identifier, must be nfCurrency or nfCurrencyRed.
nfAccounting, or nfAccountingRed
@param ADecimals Number of decimal places @param ADecimals Number of decimal places
@param APosCurrFormat Code specifying the order of value, currency symbol @param APosCurrFormat Code specifying the order of value, currency symbol
and spaces (see pcfXXXX constants) and spaces (see pcfXXXX constants)
@ -2454,8 +2446,7 @@ end;
@param ARow Cell row index @param ARow Cell row index
@param ACol Cell column index @param ACol Cell column index
@param AValue Number value to be written @param AValue Number value to be written
@param AFormat Format identifier, must be nfCurrency, nfCurrencyRed, @param AFormat Format identifier, must be nfCurrency or nfCurrencyRed.
nfAccounting, or nfAccountingRed
@param AFormatString String of formatting codes, including currency symbol. @param AFormatString String of formatting codes, including currency symbol.
Can contain sections for different formatting of positive Can contain sections for different formatting of positive
and negative number. Example: '"EUR" #,##0.00;("EUR" #,##0.00)' and negative number. Example: '"EUR" #,##0.00;("EUR" #,##0.00)'
@ -2472,8 +2463,7 @@ end;
@param ACell Pointer to the cell considered @param ACell Pointer to the cell considered
@param AValue Number value to be written @param AValue Number value to be written
@param AFormat Format identifier, must be nfCurrency, nfCurrencyRed, @param AFormat Format identifier, must be nfCurrency or nfCurrencyRed.
nfAccounting, or nfAccountingRed
@param AFormatString String of formatting codes, including currency symbol. @param AFormatString String of formatting codes, including currency symbol.
Can contain sections for different formatting of positive Can contain sections for different formatting of positive
and negative number. Example: '"EUR" #,##0.00;("EUR" #,##0.00)' and negative number. Example: '"EUR" #,##0.00;("EUR" #,##0.00)'

View File

@ -695,7 +695,7 @@ begin
Canvas.Font.Size := round(fnt.Size); Canvas.Font.Size := round(fnt.Size);
end; end;
end; end;
if (lCell^.NumberFormat in [nfCurrencyRed, nfAccountingRed]) and if (lCell^.NumberFormat = nfCurrencyRed) and
not IsNaN(lCell^.NumberValue) and (lCell^.NumberValue < 0) not IsNaN(lCell^.NumberValue) and (lCell^.NumberValue < 0)
then then
Canvas.Font.Color := FWorkbook.GetPaletteColor(scRed); Canvas.Font.Color := FWorkbook.GetPaletteColor(scRed);
@ -941,174 +941,34 @@ begin
InflateRect(ARect, -constCellPadding, -constCellPadding); InflateRect(ARect, -constCellPadding, -constCellPadding);
if (lCell^.NumberFormat in [nfAccounting, nfAccountingRed]) and not IsNaN(lCell^.Numbervalue) txt := GetCellText(ACol, ARow);
then begin if txt = '' then
case SplitAccountingFormatString(lCell^.NumberFormatStr, Sign(lCell^.NumberValue), exit;
txtLeft, txtRight) of
1: begin
txtLeft := FormatFloat(txtLeft, lCell^.NumberValue);
if txtLeft = '' then exit;
txt := txtLeft + ' ' + txtRight;
end;
2: begin
txtRight := FormatFloat(txtRight, lCell^.NumberValue);
if txtRight = '' then exit;
txt := txtLeft + ' ' + txtRight;
end;
end;
InternalDrawTextInCell(txtLeft, txt, ARect, 0, horAlign, vertAlign,
txtRot, wrapped, true);
InternalDrawTextInCell(txtRight, txt, ARect, 2, horAlign, vertAlign,
txtRot, wrapped, true);
end else begin
txt := GetCellText(ACol, ARow);
if txt = '' then
exit;
case txtRot of
trHorizontal:
case horAlign of
haLeft : justif := 0;
haCenter : justif := 1;
haRight : justif := 2;
end;
rtStacked,
rt90DegreeClockwiseRotation:
case vertAlign of
vaTop : justif := 0;
vaCenter: justif := 1;
vaBottom: justif := 2;
end;
rt90DegreeCounterClockwiseRotation:
case vertAlign of
vaTop : justif := 2;
vaCenter: justif := 1;
vaBottom: justif := 0;
end;
end;
InternalDrawTextInCell(txt, txt, ARect, justif, horAlign, vertAlign,
txtRot, wrapped, false);
end;
end;
(* case txtRot of
trHorizontal:
case horAlign of
haLeft : justif := 0;
haCenter : justif := 1;
haRight : justif := 2;
procedure InternalDrawTextInCell(AText, AMeasureText: String; ARect: TRect;
AJustification: Byte; ACellHorAlign: TsHorAlignment;
ACellVertAlign: TsVertAlignment; ATextRot: TsTextRotation;
ATextWrap, ReplaceTooLong: Boolean);
if (lCell^.TextRotation in [trHorizontal, rtStacked]) or
(not (uffTextRotation in lCell^.UsedFormattingFields))
then begin
// HORIZONAL TEXT DRAWING DIRECTION
ts := Canvas.TextStyle;
if wrapped then begin
ts.Wordbreak := true;
ts.SingleLine := false;
flags := DT_WORDBREAK and not DT_SINGLELINE;
LCLIntf.DrawText(Canvas.Handle, PChar(txt), Length(txt), txtRect,
DT_CALCRECT or flags);
w := txtRect.Right - txtRect.Left;
h := txtRect.Bottom - txtRect.Top;
end else begin
ts.WordBreak := false;
ts.SingleLine := false;
w := Canvas.TextWidth(txt);
h := Canvas.TextHeight('Tg');
end;
Canvas.Font.Orientation := 0;
ts.Alignment := HOR_ALIGNMENTS[horAlign];
ts.Opaque := false;
if h > ARect.Bottom - ARect.Top then
ts.Layout := tlTop
else
ts.Layout := VERT_ALIGNMENTS[vertAlign];
Canvas.TextStyle := ts;
Canvas.TextRect(ARect, ARect.Left, ARect.Top, txt);
end
else
begin
// ROTATED TEXT DRAWING DIRECTION
L := TStringList.Create;
try
txtRect := Bounds(ARect.Left, ARect.Top, ARect.Bottom - ARect.Top, ARect.Right - ARect.Left);
hline := Canvas.TextHeight('Tg');
if wrapped then begin
L.Text := WrapText(Canvas, txt, txtRect.Right - txtRect.Left);
flags := DT_WORDBREAK and not DT_SINGLELINE;
LCLIntf.DrawText(Canvas.Handle, PChar(L.Text), Length(L.Text), txtRect,
DT_CALCRECT or flags);
w := txtRect.Right - txtRect.Left;
h := txtRect.Bottom - txtRect.Top;
h0 := hline;
end
else begin
L.Text := txt;
w := Canvas.TextWidth(txt);
h := hline;
h0 := 0;
end; end;
rtStacked,
ts := Canvas.TextStyle; rt90DegreeClockwiseRotation:
ts.SingleLine := true; // Draw text line by line case vertAlign of
ts.Clipping := false; vaTop : justif := 0;
ts.Layout := tlTop; vaCenter: justif := 1;
ts.Alignment := taLeftJustify; vaBottom: justif := 2;
ts.Opaque := false; end;
rt90DegreeCounterClockwiseRotation:
if lCell^.TextRotation = rt90DegreeClockwiseRotation then begin case vertAlign of
// Clockwise vaTop : justif := 2;
Canvas.Font.Orientation := -900; vaCenter: justif := 1;
case horAlign of vaBottom: justif := 0;
haLeft : P.X := Min(ARect.Right-1, ARect.Left + h - h0);
haCenter : P.X := Min(ARect.Right-1, (ARect.Left + ARect.Right + h) div 2);
haRight : P.X := ARect.Right - 1;
end;
for i:= 0 to L.Count-1 do begin
w := Canvas.TextWidth(L[i]);
case vertAlign of
vaTop : P.Y := ARect.Top;
vaCenter : P.Y := Max(ARect.Top, (ARect.Top + ARect.Bottom - w) div 2);
vaBottom : P.Y := Max(ARect.Top, ARect.Bottom - w);
end;
Canvas.TextRect(ARect, P.X, P.Y, L[i], ts);
dec(P.X, hline);
end
end
else begin
// Counter-clockwise
Canvas.Font.Orientation := +900;
case horAlign of
haLeft : P.X := ARect.Left;
haCenter : P.X := Max(ARect.Left, (ARect.Left + ARect.Right - h + h0) div 2);
haRight : P.X := MAx(ARect.Left, ARect.Right - h + h0);
end;
for i:= 0 to L.Count-1 do begin
w := Canvas.TextWidth(L[i]);
case vertAlign of
vaTop : P.Y := Min(ARect.Bottom, ARect.Top + w);
vaCenter : P.Y := Min(ARect.Bottom, (ARect.Top + ARect.Bottom + w) div 2);
vaBottom : P.Y := ARect.Bottom;
end;
Canvas.TextRect(ARect, P.X, P.Y, L[i], ts);
inc(P.X, hline);
end;
end; end;
finally
L.Free;
end;
end; end;
InternalDrawTextInCell(txt, txt, ARect, justif, horAlign, vertAlign,
txtRot, wrapped, false);
end; end;
*)
procedure TsCustomWorksheetGrid.EditingDone; procedure TsCustomWorksheetGrid.EditingDone;
var var
@ -1899,7 +1759,8 @@ end;
filling the cell. filling the cell.
The reason to separate AJustification from ACellHorAlign and ACelVertAlign is The reason to separate AJustification from ACellHorAlign and ACelVertAlign is
the output of nfAccounting formatted numbers where the numbers are always the output of nfAccounting formatted numbers where the numbers are always
right-aligned, and the currency symbol is left-aligned. } right-aligned, and the currency symbol is left-aligned.
NOTE: THIS FEATURE IS NO LONGER SUPPORTED. }
procedure TsCustomWorksheetGrid.InternalDrawTextInCell(AText, AMeasureText: String; procedure TsCustomWorksheetGrid.InternalDrawTextInCell(AText, AMeasureText: String;
ARect: TRect; AJustification: Byte; ACellHorAlign: TsHorAlignment; ARect: TRect; AJustification: Byte; ACellHorAlign: TsHorAlignment;
ACellVertAlign: TsVertAlignment; ATextRot: TsTextRotation; ACellVertAlign: TsVertAlignment; ATextRot: TsTextRotation;

View File

@ -93,13 +93,9 @@ function MakeLongDateFormat(AShortDateFormat: String): String;
function MakeShortDateFormat(AShortDateFormat: String): String; function MakeShortDateFormat(AShortDateFormat: String): String;
function SpecialDateTimeFormat(ACode: String; function SpecialDateTimeFormat(ACode: String;
const AFormatSettings: TFormatSettings; ForWriting: Boolean): String; const AFormatSettings: TFormatSettings; ForWriting: Boolean): String;
function SplitAccountingFormatString(const AFormatString: String; ASection: ShortInt;
out ALeft, ARight: String): Byte;
procedure SplitFormatString(const AFormatString: String; out APositivePart, procedure SplitFormatString(const AFormatString: String; out APositivePart,
ANegativePart, AZeroPart: String); ANegativePart, AZeroPart: String);
function SciFloat(AValue: Double; ADecimals: Byte): String; overload;
function SciFloat(AValue: Double; ADecimals: Byte; AFormatSettings: TFormatSettings): String; overload;
procedure MakeTimeIntervalMask(Src: String; var Dest: String); procedure MakeTimeIntervalMask(Src: String; var Dest: String);
// These two functions are copies of fpc trunk until they are available in stable fpc. // These two functions are copies of fpc trunk until they are available in stable fpc.
@ -565,11 +561,11 @@ begin
if ACondition then Result := AValue1 else Result := AValue2; if ACondition then Result := AValue1 else Result := AValue2;
end; end;
{ Checks whether the given number format code is for currency or accounting { Checks whether the given number format code is for currency,
i.e. requires currency symbol. } i.e. requires currency symbol. }
function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean; function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean;
begin begin
Result := AFormat in [nfCurrency, nfCurrencyRed, nfAccounting, nfAccountingRed]; Result := AFormat in [nfCurrency, nfCurrencyRed];
end; end;
{ Checks whether the given number format code is for date/times. } { Checks whether the given number format code is for date/times. }
@ -648,69 +644,81 @@ begin
end; end;
end; end;
{ Builds a currency format string. The presentation of negative values (brackets, {@@
Builds a currency format string. The presentation of negative values (brackets,
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.
Additional code is inserted for the destination file format:
- AAccountingStyle = true adds code to align the currency symbols below each @param ADialect Determines whether the format string is for use by
other. fpspreadsheet (nfdDefault) or by Excel (nfdExcel)
- ANegativeValuesRed adds code to the second section of the format code (for @param ANumberFormat Identifier of the built-in number format for which the
negative values) to apply a red font color. format string is to be generated.
This code has to be removed by StripAccountingSymbols before applying to @param AFormatSettings FormatSettings to be applied (used to extract default
FormatFloat. } 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
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
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.
@return String of formatting codes, such as '"$"#,##0.00;("$"#,##0.00);"EUR"0.00'
}
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect; function BuildCurrencyFormatString(ADialect: TsNumFormatDialect;
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings; ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings;
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String; ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String;
const const
POS_FMT: array[0..3, boolean] of string = ( POS_FMT: array[0..3] of string = (
// Parameter 0 is "value", parameter 1 is "currency symbol" // Format parameter 0 is "value", parameter 1 is "currency symbol"
// AccountingStyle = false --> 1st column, true --> 2nd column ('"%1:s"%0:s'), // 0: $1
('"%1:s"%0:s', '"%1:s"* %0:s'), // 0: $1 ('%0:s"%1:s"'), // 1: 1$
('%0:s"%1:s"', '%0:s "%1:s"'), // 1: 1$ ('"%1:s" %0:s'), // 2: $ 1
('"%1:s" %0:s', '"%1:s"* %0:s'), // 2: $ 1 ('%0:s "%1:s"') // 3: 1 $
('%0:s "%1:s"', '%0:s "%1:s"') // 3: 1 $
); );
NEG_FMT: array[0..15, boolean] of string = ( NEG_FMT: array[0..15] of string = (
('("%1:s"%0:s)', '"%1:s"* (%0:s)'), // 0: ($1) ('("%1:s"%0:s)'), // 0: ($1)
('-"%1:s"%0:s', '-* "%1:s" %0:s'), // 1: -$1 ('-"%1:s"%0:s'), // 1: -$1
('"%1:s"-%0:s', '"%1:s"* -%0:s'), // 2: $-1 ('"%1:s"-%0:s'), // 2: $-1
('"%1:s"%0:s-', '"%1:s"%0:s-'), // 3: $1- ('"%1:s"%0:s-'), // 3: $1-
('(%0:s"%1:s")', '(%0:s)%1:s"'), // 4: (1$) ('(%0:s"%1:s")'), // 4: (1$)
('-%0:s"%1:s"', '-* %0:s"%1:s"'), // 5: -1$ ('-%0:s"%1:s"'), // 5: -1$
('%0:s-"%1:s"', '%0:s-"%1:s"'), // 6: 1-$ ('%0:s-"%1:s"'), // 6: 1-$
('%0:s"%1:s"-', '%0:s-"%1:s"'), // 7: 1$- ('%0:s"%1:s"-'), // 7: 1$-
('-%0:s "%1:s"', '-* %0:s"%1:s"'), // 8: -1 $ ('-%0:s "%1:s"'), // 8: -1 $
('-"%1:s" %0:s', '-* "%1:s" %0:s'), // 9: -$ 1 ('-"%1:s" %0:s'), // 9: -$ 1
('%0:s "%1:s"-', '%0:s- "%1:s"'), // 10: 1 $- ('%0:s "%1:s"-'), // 10: 1 $-
('"%1:s" %0:s-', '"%1:s"* %0:s-'), // 11: $ 1- ('"%1:s" %0:s-'), // 11: $ 1-
('"%1:s" -%0:s', '"%1:s"* -%0:s'), // 12: $ -1 ('"%1:s" -%0:s'), // 12: $ -1
('%0:s- "%1:s"', '%0:s- "%1:s"'), // 13: 1- $ ('%0:s- "%1:s"'), // 13: 1- $
('("%1:s" %0:s)', '"%1:s"* (%0:s)'), // 14: ($ 1) ('("%1:s" %0:s)'), // 14: ($ 1)
('(%0:s "%1:s")', '(%0:s "%1:s")') // 15: (1 $) ('(%0:s "%1:s")') // 15: (1 $)
); );
var var
decs: String; decs: String;
pcf, ncf: Byte; pcf, ncf: Byte;
p, n: String; p, n: String;
accStyle: Boolean;
negRed: Boolean; negRed: Boolean;
begin begin
pcf := IfThen(APosCurrFormat < 0, AFormatSettings.CurrencyFormat, APosCurrFormat); pcf := IfThen(APosCurrFormat < 0, AFormatSettings.CurrencyFormat, APosCurrFormat);
ncf := IfThen(ANegCurrFormat < 0, AFormatSettings.NegCurrFormat, ANegCurrFormat); ncf := IfThen(ANegCurrFormat < 0, AFormatSettings.NegCurrFormat, ANegCurrFormat);
if ADecimals < 0 then if (ADecimals < 0) then
ADecimals := AFormatSettings.CurrencyDecimals; ADecimals := AFormatSettings.CurrencyDecimals;
if ACurrencySymbol = '?' then if ACurrencySymbol = '?' then
ACurrencySymbol := AnsiToUTF8(AFormatSettings.CurrencyString); ACurrencySymbol := AnsiToUTF8(AFormatSettings.CurrencyString);
decs := DupeString('0', ADecimals); decs := DupeString('0', ADecimals);
if ADecimals > 0 then decs := '.' + decs; if ADecimals > 0 then decs := '.' + decs;
accStyle := ANumberFormat in [nfAccounting, nfAccountingRed]; negRed := (ANumberFormat = nfCurrencyRed);
negRed := ANumberFormat in [nfCurrencyRed, nfAccountingRed]; p := POS_FMT[pcf]; // Format mask for positive values
n := NEG_FMT[ncf]; // Format mask for negative values
p := POS_FMT[pcf, accStyle];
n := NEG_FMT[ncf, accStyle];
// 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 accStyle then if ADialect = nfdExcel then
case ncf of case ncf of
0, 14: p := p + '_)'; 0, 14: p := p + '_)';
3, 11: p := p + '_-'; 3, 11: p := p + '_-';
@ -722,7 +730,7 @@ begin
Result := Format(p, ['#,##0' + decs, ACurrencySymbol]) + ';' Result := Format(p, ['#,##0' + decs, ACurrencySymbol]) + ';'
+ IfThen(negRed and (ADialect = nfdExcel), '[red]', '') + IfThen(negRed and (ADialect = nfdExcel), '[red]', '')
+ Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';' + Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';'
+ Format(p, [IfThen(accStyle, '-', '0'+decs), ACurrencySymbol]); + Format(p, ['0'+decs, ACurrencySymbol]);
end end
else begin else begin
Result := '#,##0' + decs; Result := '#,##0' + decs;
@ -735,12 +743,22 @@ begin
1, 2, 5, 6, 8, 9, 12: Result := Result + '-#,##0' + decs; 1, 2, 5, 6, 8, 9, 12: Result := Result + '-#,##0' + decs;
else Result := Result + '#,##0' + decs + '-'; else Result := Result + '#,##0' + decs + '-';
end; end;
Result := Result + ';' + IfThen(accStyle, '-', '0'+decs); Result := Result + ';0' + decs;
end; end;
end; end;
{ Builds a number format string from the number format code, the count of {@@
decimals, and the currencysymbol (if not empty). } Builds a number format string from the number format code and the count of
decimal places.
@param ANumberFormat Identifier of the built-in numberformat for which a
format string is to be generated
@param AFormatSettings FormatSettings for default parameters
@param ADecimals Number of decimal places. If < 0 the CurrencyDecimals
value of the FormatSettings is used.
@return String of formatting codes, such as '#,##0.00' for nfFixedTh and 2 decimals
}
function BuildNumberFormatString(ANumberFormat: TsNumberFormat; function BuildNumberFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; ADecimals: Integer = -1): String; const AFormatSettings: TFormatSettings; ADecimals: Integer = -1): String;
var var
@ -758,11 +776,9 @@ begin
Result := '#,##0' + decs; Result := '#,##0' + decs;
nfExp: nfExp:
Result := '0' + decs + 'E+00'; Result := '0' + decs + 'E+00';
nfSci:
Result := '##0' + decs + 'E+0';
nfPercentage: nfPercentage:
Result := '0' + decs + '%'; Result := '0' + decs + '%';
nfCurrency, nfCurrencyRed, nfAccounting, nfAccountingRed: nfCurrency, nfCurrencyRed:
raise Exception.Create('BuildNumberFormatString: Use BuildCurrencyFormatString '+ raise Exception.Create('BuildNumberFormatString: Use BuildCurrencyFormatString '+
'to create a format string for currency values.'); 'to create a format string for currency values.');
nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime, nfShortDateTime, nfShortDate, nfLongDate, nfShortTime, nfLongTime,
@ -933,84 +949,6 @@ begin
Result := ACode; Result := ACode;
end; end;
{ Splits the sections +1 (positive) or -1 (negative values) or 0 (zero values)
of the accounting format string at the position of the '*' into a left
and right part and returns 1 if the format string is in the left, and 2 if
it is in the right part. Additionally removes Excel format codes '_' }
function SplitAccountingFormatString(const AFormatString: String; ASection: ShortInt;
out ALeft, ARight: String): Byte;
var
P: PChar;
PStart, PEnd: PChar;
token: Char;
done: Boolean;
i: Integer;
begin
Result := 0;
PStart := PChar(@AFormatString[1]);
PEnd := PStart + Length(AFormatString);
P := PStart;
done := false;
case ASection of
-1 : while (P < PEnd) and not done do begin
token := P^;
if token = ';' then done := true;
inc(P);
end;
0 : for i := 1 to 2 do begin
done := false;
while (P < PEnd) and not done do begin
token := P^;
if token = ';' then done := true;
inc(P);
end;
end;
+1: ;
end;
ALeft := '';
done := false;
while (P < PEnd) and not done do begin
token := P^;
case token of
'_': inc(P);
';': done := true;
'"': ;
'*': begin
inc(P);
done := true;
end;
'0',
'#': begin
ALeft := ALeft + token;
Result := 1;
end;
else ALeft := ALeft + token;
end;
inc(P);
end;
ARight := '';
done := false;
while (P < PEnd) and not done do begin
token := P^;
case token of
'_': inc(P);
';': done := true;
'"': ;
'0',
'#': begin
ARight := ARight + token;
Result := 2;
end;
else ARight := ARight + token;
end;
inc(P);
end;
end;
procedure SplitFormatString(const AFormatString: String; out APositivePart, procedure SplitFormatString(const AFormatString: String; out APositivePart,
ANegativePart, AZeroPart: String); ANegativePart, AZeroPart: String);
@ -1068,35 +1006,14 @@ begin
end; end;
end; end;
{ Formats the number AValue in "scientific" format with the given number of {@@
decimals. "Scientific" is the same as "exponential", but with exponents rounded Creates a "time interval" format string having the first time code identifier
to multiples of 3 (like for "kilo" - "Mega" - "Giga" etc.). } in square brackets.
function SciFloat(AValue: Double; ADecimals: Byte;
AFormatSettings: TFormatSettings): String;
var
m: Double;
ex: Integer;
begin
if AValue = 0 then
Result := Format('%0.*fE+0', [ADecimals, 0.0], AFormatSettings)
// Excel shows "000.0E+0", but I think the "0.0E+0" shown here is better.
else begin
ex := floor(log10(abs(AValue))); // exponent
// round exponent to multiples of 3
ex := (ex div 3) * 3;
if ex < 0 then dec(ex, 3);
m := AValue * Power(10, -ex); // mantisse
Result := Format('%.*fE+%d', [ADecimals, m, ex], AFormatSettings);
end;
end;
function SciFloat(AValue: Double; ADecimals: Byte): String; @param Src Source format string, must be a time format string, like 'hh:nn'
begin @param Dest Destination format string, will have the first time code element
Result := SciFloat(AValue, ADecimals, DefaultFormatSettings); of the src format string in square brackets, like '[hh]:nn'.
end; }
{ Creates a "time interval" format string having the first code identifier
in square brackets. }
procedure MakeTimeIntervalMask(Src: String; var Dest: String); procedure MakeTimeIntervalMask(Src: String; var Dest: String);
var var
L: TStrings; L: TStrings;

View File

@ -18,10 +18,10 @@ uses
var var
// Norm to test against - list of strings that should occur in spreadsheet // Norm to test against - list of strings that should occur in spreadsheet
SollNumberStrings: array[0..6, 0..8] of string; SollNumberStrings: array[0..6, 0..7] of string;
SollNumbers: array[0..6] of Double; SollNumbers: array[0..6] of Double;
SollNumberFormats: array[0..8] of TsNumberFormat; SollNumberFormats: array[0..7] of TsNumberFormat;
SollNumberDecimals: array[0..8] of word; SollNumberDecimals: array[0..7] of word;
SollDateTimeStrings: array[0..4, 0..9] of string; SollDateTimeStrings: array[0..4, 0..9] of string;
SollDateTimes: array[0..4] of TDateTime; SollDateTimes: array[0..4] of TDateTime;
@ -164,7 +164,6 @@ begin
SollNumberFormats[5] := nfExp; SollNumberDecimals[5] := 2; SollNumberFormats[5] := nfExp; SollNumberDecimals[5] := 2;
SollNumberFormats[6] := nfPercentage; SollNumberDecimals[6] := 0; SollNumberFormats[6] := nfPercentage; SollNumberDecimals[6] := 0;
SollNumberFormats[7] := nfPercentage; SollNumberDecimals[7] := 2; SollNumberFormats[7] := nfPercentage; SollNumberDecimals[7] := 2;
SollNumberFormats[8] := nfSci; SollNumberDecimals[8] := 1;
for i:=Low(SollNumbers) to High(SollNumbers) do begin for i:=Low(SollNumbers) to High(SollNumbers) do begin
SollNumberStrings[i, 0] := FloatToStr(SollNumbers[i], fs); SollNumberStrings[i, 0] := FloatToStr(SollNumbers[i], fs);
@ -175,7 +174,6 @@ begin
SollNumberStrings[i, 5] := FormatFloat('0.00E+00', SollNumbers[i], fs); SollNumberStrings[i, 5] := FormatFloat('0.00E+00', SollNumbers[i], fs);
SollNumberStrings[i, 6] := FormatFloat('0', SollNumbers[i]*100, fs) + '%'; SollNumberStrings[i, 6] := FormatFloat('0', SollNumbers[i]*100, fs) + '%';
SollNumberStrings[i, 7] := FormatFloat('0.00', SollNumbers[i]*100, fs) + '%'; SollNumberStrings[i, 7] := FormatFloat('0.00', SollNumbers[i]*100, fs) + '%';
SollNumberStrings[i, 8] := SciFloat(SollNumbers[i], 1, fs);
end; end;
// Date/time values // Date/time values
@ -288,8 +286,6 @@ begin
for Col := ord(Low(SollNumberFormats)) to ord(High(SollNumberFormats)) do begin for Col := ord(Low(SollNumberFormats)) to ord(High(SollNumberFormats)) do begin
MyWorksheet.WriteNumber(Row, Col, SollNumbers[Row], SollNumberFormats[Col], SollNumberDecimals[Col]); MyWorksheet.WriteNumber(Row, Col, SollNumbers[Row], SollNumberFormats[Col], SollNumberDecimals[Col]);
ActualString := MyWorksheet.ReadAsUTF8Text(Row, Col); ActualString := MyWorksheet.ReadAsUTF8Text(Row, Col);
if (AFormat=sfExcel2) and (SollNumberFormats[Col] = nfSci) then
Continue; // BIFF2 does not support nfSci -> ignore
CheckEquals(SollNumberStrings[Row, Col], ActualString, 'Test unsaved string mismatch cell ' + CellNotation(MyWorksheet,Row,Col)); CheckEquals(SollNumberStrings[Row, Col], ActualString, 'Test unsaved string mismatch cell ' + CellNotation(MyWorksheet,Row,Col));
end; end;
MyWorkBook.WriteToFile(TempFile, AFormat, true); MyWorkBook.WriteToFile(TempFile, AFormat, true);
@ -306,8 +302,6 @@ begin
fail('Error in test code. Failed to get named worksheet'); fail('Error in test code. Failed to get named worksheet');
for Row := Low(SollNumbers) to High(SollNumbers) do for Row := Low(SollNumbers) to High(SollNumbers) do
for Col := Low(SollNumberFormats) to High(SollNumberFormats) do begin for Col := Low(SollNumberFormats) to High(SollNumberFormats) do begin
if (AFormat=sfExcel2) and (SollNumberFormats[Col] = nfSci) then
Continue; // BIFF2 does not support nfSci --> ignore
ActualString := MyWorkSheet.ReadAsUTF8Text(Row,Col); ActualString := MyWorkSheet.ReadAsUTF8Text(Row,Col);
CheckEquals(SollNumberStrings[Row,Col],ActualString,'Test saved string mismatch cell '+CellNotation(MyWorkSheet,Row,Col)); CheckEquals(SollNumberStrings[Row,Col],ActualString,'Test saved string mismatch cell '+CellNotation(MyWorkSheet,Row,Col));
end; end;

View File

@ -22,7 +22,7 @@ uses
var var
// Norm to test against - list of numbers/times that should occur in spreadsheet // Norm to test against - list of numbers/times that should occur in spreadsheet
SollNumbers: array[0..23] of double; //"Soll" is a German word in Dutch accountancy jargon meaning "normative value to check against". There ;) SollNumbers: array[0..22] of double; //"Soll" is a German word in Dutch accountancy jargon meaning "normative value to check against". There ;)
// Initializes Soll*/normative variables. // Initializes Soll*/normative variables.
// Useful in test setup procedures to make sure the norm is correct. // Useful in test setup procedures to make sure the norm is correct.
procedure InitSollNumbers; procedure InitSollNumbers;
@ -64,7 +64,6 @@ type
procedure TestReadNumber20; procedure TestReadNumber20;
procedure TestReadNumber21; procedure TestReadNumber21;
procedure TestReadNumber22; procedure TestReadNumber22;
procedure TestReadNumber23;
procedure TestReadODFNumber0; //number tests using ODF/LibreOffice file format procedure TestReadODFNumber0; //number tests using ODF/LibreOffice file format
procedure TestReadODFNumber1; //number and time procedure TestReadODFNumber1; //number and time
procedure TestReadODFNumber2; procedure TestReadODFNumber2;
@ -88,7 +87,6 @@ type
procedure TestReadODFNumber20; procedure TestReadODFNumber20;
procedure TestReadODFNumber21; procedure TestReadODFNumber21;
procedure TestReadODFNumber22; procedure TestReadODFNumber22;
procedure TestReadODFNumber23;
end; end;
{ TSpreadWriteReadNumberTests } { TSpreadWriteReadNumberTests }
@ -142,13 +140,12 @@ begin
SollNumbers[14]:=0.3536; // 0.3536 formatted as percentage, 2 decimals SollNumbers[14]:=0.3536; // 0.3536 formatted as percentage, 2 decimals
SollNumbers[15]:=59000000.1234; // 59 million + 0.1234 formatted with thousand separator, no decimals SollNumbers[15]:=59000000.1234; // 59 million + 0.1234 formatted with thousand separator, no decimals
SollNumbers[16]:=59000000.1234; // 59 million + 0.1234 formatted with thousand separator, 2 decimals SollNumbers[16]:=59000000.1234; // 59 million + 0.1234 formatted with thousand separator, 2 decimals
SollNumbers[17]:=-59000000.1234; // minus 59 million + 0.1234, formatted as "scientific" with 1 decimal SollNumbers[17]:=-59000000.1234; // minus 59 million + 0.1234, formatted as "exp" with 2 decimals
SollNumbers[18]:=-59000000.1234; // minus 59 million + 0.1234, formatted as "exp" with 2 decimals SollNumbers[18]:=59000000.1234; // 59 million + 0.1234 formatted as currrency (EUROs, at end), 2 decimals
SollNumbers[19]:=59000000.1234; // 59 million + 0.1234 formatted as currrency (EUROs, at end), 2 decimals SollNumbers[19]:=59000000.1234; // 59 million + 0.1234 formatted as currrency (Dollars, at end), 2 decimals
SollNumbers[20]:=59000000.1234; // 59 million + 0.1234 formatted as currrency (Dollars, at end), 2 decimals SollNumbers[20]:=-59000000.1234; // minus 59 million + 0.1234 formatted as currrency (EUROs, at end), 2 decimals
SollNumbers[21]:=-59000000.1234; // minus 59 million + 0.1234 formatted as currrency (EUROs, at end), 2 decimals SollNumbers[21]:=-59000000.1234; // minus 59 million + 0.1234 formatted as currrency (Dollars, at end), 2 decimals
SollNumbers[22]:=-59000000.1234; // minus 59 million + 0.1234 formatted as currrency (Dollars, at end), 2 decimals SollNumbers[22]:=-59000000.1234; // minus 59 million + 0.1234 formatted as currrency (Dollars, at end, neg red), 2 decimals
SollNumbers[23]:=-59000000.1234; // minus 59 million + 0.1234 formatted as currrency (Dollars, at end, neg red), 2 decimals
end; end;
{ TSpreadWriteReadNumberTests } { TSpreadWriteReadNumberTests }
@ -395,11 +392,6 @@ begin
TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileBIFF8,22); TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileBIFF8,22);
end; end;
procedure TSpreadReadNumberTests.TestReadNumber23;
begin
TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileBIFF8,23);
end;
procedure TSpreadReadNumberTests.TestReadODFNumber0; procedure TSpreadReadNumberTests.TestReadODFNumber0;
begin begin
TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileODF,0); TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileODF,0);
@ -515,11 +507,6 @@ begin
TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileODF,22); TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileODF,22);
end; end;
procedure TSpreadReadNumberTests.TestReadODFNumber23;
begin
TestReadNumber(ExtractFilePath(ParamStr(0)) + TestFileODF,23);
end;
initialization initialization
// Register so these tests are included in a full run // Register so these tests are included in a full run

View File

@ -103,6 +103,7 @@
<Unit5> <Unit5>
<Filename Value="testsutility.pas"/> <Filename Value="testsutility.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="testsutility"/>
</Unit5> </Unit5>
<Unit6> <Unit6>
<Filename Value="internaltests.pas"/> <Filename Value="internaltests.pas"/>

View File

@ -30,7 +30,7 @@ uses
var var
// Norm to test against - list of strings that should occur in spreadsheet // Norm to test against - list of strings that should occur in spreadsheet
SollStrings: array[0..14] of string; //"Soll" is a German word in Dutch accountancy jargon meaning "normative value to check against". There ;) SollStrings: array[0..13] of string; //"Soll" is a German word in Dutch accountancy jargon meaning "normative value to check against". There ;)
// Initializes Soll*/normative variables. // Initializes Soll*/normative variables.
// Useful in test setup procedures to make sure the norm is correct. // Useful in test setup procedures to make sure the norm is correct.
procedure InitSollStrings; procedure InitSollStrings;
@ -63,7 +63,6 @@ type
procedure TestReadString11; procedure TestReadString11;
procedure TestReadString12; procedure TestReadString12;
procedure TestReadString13; procedure TestReadString13;
procedure TestReadString14;
procedure TestReadODFString0; //OpenDocument/LibreOffice format empty string procedure TestReadODFString0; //OpenDocument/LibreOffice format empty string
procedure TestReadODFString1; procedure TestReadODFString1;
procedure TestReadODFString2; procedure TestReadODFString2;
@ -78,7 +77,6 @@ type
procedure TestReadODFString11; procedure TestReadODFString11;
procedure TestReadODFString12; procedure TestReadODFString12;
procedure TestReadODFString13; procedure TestReadODFString13;
procedure TestReadODFString14;
end; end;
{ TSpreadWriteReadStringTests } { TSpreadWriteReadStringTests }
@ -124,10 +122,9 @@ begin
SollStrings[8]:=FormatFloat('0.00', 35.36)+'%'; // 0.3536 formatted as percentage, 2 decimals SollStrings[8]:=FormatFloat('0.00', 35.36)+'%'; // 0.3536 formatted as percentage, 2 decimals
SollStrings[9]:=FormatFloat('#,##0', 59000000.1234); // 59 million + 0.1234 formatted with thousand separator, no decimals SollStrings[9]:=FormatFloat('#,##0', 59000000.1234); // 59 million + 0.1234 formatted with thousand separator, no decimals
SollStrings[10]:=FormatFloat('#,##0.00', 59000000.1234); // 59 million + 0.1234 formatted with thousand separator, 2 decimals SollStrings[10]:=FormatFloat('#,##0.00', 59000000.1234); // 59 million + 0.1234 formatted with thousand separator, 2 decimals
SollStrings[11]:=SciFloat(-59000000.1234, 1); // minus 59 million + 0.1234, formatted as "scientific" with 1 decimal SollStrings[11]:=FormatFloat('0.00E+00', -59000000.1234); // minus 59 million + 0.1234, formatted as "exp" with 2 decimals
SollStrings[12]:=FormatFloat('0.00E+00', -59000000.1234); // minus 59 million + 0.1234, formatted as "exp" with 2 decimals SollStrings[12]:=FormatFloat('#,##0.00 "EUR";(#,##0.00 "EUR")', 59000000.1234); // 59 million + 0.1234, formatted as "currencyRed" with 2 decimals, brackets and EUR
SollStrings[13]:=FormatFloat('#,##0.00 "EUR";(#,##0.00 "EUR")', 59000000.1234); // 59 million + 0.1234, formatted as "currencyRed" with 2 decimals, brackets and EUR SollStrings[13]:=FormatFloat('#,##0.00 "EUR";(#,##0.00 "EUR")', -59000000.1234); // minus 59 million + 0.1234, formatted as "currencyRed" with 2 decimals, brackets and EUR
SollStrings[14]:=FormatFloat('#,##0.00 "EUR";(#,##0.00 "EUR")', -59000000.1234); // minus 59 million + 0.1234, formatted as "currencyRed" with 2 decimals, brackets and EUR
end; end;
{ TSpreadWriteReadStringTests } { TSpreadWriteReadStringTests }
@ -415,11 +412,6 @@ begin
TestReadString(ExtractFilePath(ParamStr(0)) + TestFileBIFF8,13); TestReadString(ExtractFilePath(ParamStr(0)) + TestFileBIFF8,13);
end; end;
procedure TSpreadReadStringTests.TestReadString14;
begin
TestReadString(ExtractFilePath(ParamStr(0)) + TestFileBIFF8,14);
end;
procedure TSpreadReadStringTests.TestReadODFString0; procedure TSpreadReadStringTests.TestReadODFString0;
begin begin
TestReadString(ExtractFilePath(ParamStr(0)) + TestFileODF,0); TestReadString(ExtractFilePath(ParamStr(0)) + TestFileODF,0);
@ -490,10 +482,6 @@ begin
TestReadString(ExtractFilePath(ParamStr(0)) + TestFileODF,13); TestReadString(ExtractFilePath(ParamStr(0)) + TestFileODF,13);
end; end;
procedure TSpreadReadStringTests.TestReadODFString14;
begin
TestReadString(ExtractFilePath(ParamStr(0)) + TestFileODF,14);
end;
initialization initialization
// Register so these tests are included in a full run // Register so these tests are included in a full run

View File

@ -235,6 +235,8 @@ var
decs: Integer; decs: Integer;
dt: string; dt: string;
begin begin
Result := 0;
parser := TsNumFormatParser.Create(Workbook, AFormatCell^.NumberFormatStr); parser := TsNumFormatParser.Create(Workbook, AFormatCell^.NumberFormatStr);
try try
decs := parser.Decimals; decs := parser.Decimals;
@ -243,25 +245,23 @@ begin
parser.Free; parser.Free;
end; end;
Result := 0;
case AFormatCell^.NumberFormat of case AFormatCell^.NumberFormat of
nfFixed : Result := IfThen(decs = 0, 1, 2); nfGeneral : exit;
nfFixedTh : Result := IfThen(decs = 0, 3, 4); nfFixed : Result := IfThen(decs = 0, 1, 2);
nfCurrency, nfFixedTh : Result := IfThen(decs = 0, 3, 4);
nfAccounting : Result := IfThen(decs = 0, 5, 7); nfCurrency : Result := IfThen(decs = 0, 5, 7);
nfCurrencyRed, nfCurrencyRed : Result := IfThen(decs = 0, 6, 8);
nfAccountingRed : Result := IfThen(decs = 0, 6, 8); nfPercentage : Result := IfThen(decs = 0, 9, 10);
nfPercentage : Result := IfThen(decs = 0, 9, 10); nfExp : Result := 11;
nfExp, nfSci : Result := 11; nfShortDate : Result := 12;
nfShortDate : Result := 12; nfLongDate : Result := 13;
nfLongDate : Result := 13; nfShortTimeAM : Result := 16;
nfShortTimeAM : Result := 16; nfLongTimeAM : Result := 17;
nfLongTimeAM : Result := 17; nfShortTime : Result := 18;
nfShortTime : Result := 18; nfLongTime : Result := 19;
nfLongTime : Result := 19; nfShortDateTime: Result := 20;
nfShortDateTime : Result := 20; nfCustom : if dt = 'dm' then Result := 14 else
nfCustom : if dt = 'dm' then Result := 14 else if dt = 'my' then Result := 15;
if dt = 'my' then Result := 15;
end; end;
end; end;

View File

@ -742,14 +742,14 @@ begin
AddFormat(38, '_(#,##0_);[Red](#,##0)', nfCurrencyRed); AddFormat(38, '_(#,##0_);[Red](#,##0)', nfCurrencyRed);
AddFormat(39, '_(#,##0.00_);(#,##0.00)', nfCurrency); AddFormat(39, '_(#,##0.00_);(#,##0.00)', nfCurrency);
AddFormat(40, '_(#,##0.00_);[Red](#,##0.00)', nfCurrencyRed); AddFormat(40, '_(#,##0.00_);[Red](#,##0.00)', nfCurrencyRed);
AddFormat(41, '_("'+cs+'"* #,##0_);_("'+cs+'"* (#,##0);_("'+cs+'"* "-"_);_(@_)', nfAccounting); AddFormat(41, '_("'+cs+'"* #,##0_);_("'+cs+'"* (#,##0);_("'+cs+'"* "-"_);_(@_)', nfCustom);
AddFormat(42, '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)', nfAccounting); AddFormat(42, '_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)', nfCustom);
AddFormat(43, '_("'+cs+'"* #,##0.00_);_("'+cs+'"* (#,##0.00);_("'+cs+'"* "-"??_);_(@_)', nfAccounting); AddFormat(43, '_("'+cs+'"* #,##0.00_);_("'+cs+'"* (#,##0.00);_("'+cs+'"* "-"??_);_(@_)', nfCustom);
AddFormat(44, '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)', nfAccounting); AddFormat(44, '_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)', nfCustom);
AddFormat(45, 'nn:ss', nfCustom); AddFormat(45, 'nn:ss', nfCustom);
AddFormat(46, '[h]:nn:ss', nfTimeInterval); AddFormat(46, '[h]:nn:ss', nfTimeInterval);
AddFormat(47, 'nn:ss.z', nfCustom); AddFormat(47, 'nn:ss.z', nfCustom);
AddFormat(48, '##0.0E+00', nfSci); AddFormat(48, '##0.0E+00', nfCustom);
// 49 ("Text") not supported // 49 ("Text") not supported
// All indexes from 0 to 163 are reserved for built-in formats. // All indexes from 0 to 163 are reserved for built-in formats.