fpspreadsheet: Allow number formats with no leading digits. Add corresponding unit test cases.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@6218 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2018-02-28 12:14:19 +00:00
parent 022b837553
commit f78d780b5f
6 changed files with 179 additions and 48 deletions

View File

@@ -132,6 +132,8 @@ type
NumFormat: TsNumberFormat; NumFormat: TsNumberFormat;
{@@ Number of decimal places used by the format string } {@@ Number of decimal places used by the format string }
Decimals: Byte; Decimals: Byte;
{@@ Minimum number of digits before the decimal separator }
MinIntDigits: Byte;
{@@ Factor by which a number will be multiplied before converting to string } {@@ Factor by which a number will be multiplied before converting to string }
Factor: Double; Factor: Double;
{@@ Digits to be used for the integer part of a fraction } {@@ Digits to be used for the integer part of a fraction }
@@ -310,7 +312,8 @@ function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat;
function BuildFractionFormatString(AMixedFraction: Boolean; function BuildFractionFormatString(AMixedFraction: Boolean;
ANumeratorDigits, ADenominatorDigits: Integer): String; ANumeratorDigits, ADenominatorDigits: Integer): String;
function BuildNumberFormatString(ANumberFormat: TsNumberFormat; function BuildNumberFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; ADecimals: Integer = -1): String; const AFormatSettings: TFormatSettings; ADecimals: Integer = -1;
AMinIntDigits: Integer = 1): String;
function BuildFormatStringFromSection(const ASection: TsNumFormatSection): String; function BuildFormatStringFromSection(const ASection: TsNumFormatSection): String;
@@ -1401,39 +1404,53 @@ end;
value of the FormatSettings is used. In case of a value of the FormatSettings is used. In case of a
fraction format "ADecimals" refers to the maximum count fraction format "ADecimals" refers to the maximum count
digits of the denominator. digits of the denominator.
@param AMinIntDigits minimum count of integer digits, i.e. count of '0' in
the format string before the decimal separator
@return String of formatting codes @return String of formatting codes
@example ANumberFormat = nfFixedTh, ADecimals = 2 --> '#,##0.00' @example ANumberFormat = nfFixedTh, ADecimals = 2 --> '#,##0.00'
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function BuildNumberFormatString(ANumberFormat: TsNumberFormat; function BuildNumberFormatString(ANumberFormat: TsNumberFormat;
const AFormatSettings: TFormatSettings; ADecimals: Integer = -1): String; const AFormatSettings: TFormatSettings; ADecimals: Integer = -1;
AMinIntDigits: Integer = 1): String;
var var
decs: String; decdigits: String;
intdigits: String;
begin begin
Result := ''; Result := '';
if AMinIntDigits > 0 then
intdigits := DupeString('0', AMinIntDigits)
else
intdigits := '#';
if ADecimals = -1 then if ADecimals = -1 then
ADecimals := AFormatSettings.CurrencyDecimals; ADecimals := AFormatSettings.CurrencyDecimals;
decs := DupeString('0', ADecimals); if ADecimals > 0 then
if ADecimals > 0 then decs := '.' + decs; decdigits := '.' + DupeString('0', ADecimals)
else
decdigits := '';
case ANumberFormat of case ANumberFormat of
nfText: nfText:
Result := '@'; Result := '@';
nfFixed: nfFixed:
Result := '0' + decs; Result := intdigits + decdigits;
nfFixedTh: nfFixedTh:
Result := '#,##0' + decs; begin
while Length(IntDigits) < 4 do intDigits := '#' + intdigits;
System.Insert(',', intdigits, Length(intdigits)-2);
Result := intdigits + decdigits;
end;
nfExp: nfExp:
Result := '0' + decs + 'E+00'; Result := intdigits + decdigits + 'E+00';
nfPercentage: nfPercentage:
Result := '0' + decs + '%'; Result := intdigits + decdigits + '%';
nfFraction: nfFraction:
if ADecimals = 0 then // "ADecimals" has a different meaning here... if ADecimals = 0 then // "ADecimals" has a different meaning here...
Result := '# ??/??' // This is the default fraction format Result := '# ??/??' // This is the default fraction format
else else
begin begin
decs := DupeString('?', ADecimals); decdigits := DupeString('?', ADecimals);
Result := '# ' + decs + '/' + decs; Result := '# ' + decdigits + '/' + decdigits;
end; end;
nfCurrency, nfCurrencyRed: nfCurrency, nfCurrencyRed:
Result := BuildCurrencyFormatString(ANumberFormat, AFormatSettings, Result := BuildCurrencyFormatString(ANumberFormat, AFormatSettings,
@@ -2834,7 +2851,12 @@ begin
case section^.Elements[el].Token of case section^.Elements[el].Token of
nftZeroDecs: nftZeroDecs:
section^.Decimals := section^.Elements[el].IntValue; section^.Decimals := section^.Elements[el].IntValue;
nftIntZeroDigit, nftIntOptDigit, nftIntSpaceDigit: nftIntZeroDigit:
begin
section^.MinIntDigits := section^.Elements[el].IntValue;
i := section^.Elements[el].IntValue;
end;
nftIntOptDigit, nftIntSpaceDigit:
i := section^.Elements[el].IntValue; i := section^.Elements[el].IntValue;
nftFracNumSpaceDigit, nftFracNumZeroDigit: nftFracNumSpaceDigit, nftFracNumZeroDigit:
section^.FracNumerator := section^.Elements[el].IntValue; section^.FracNumerator := section^.Elements[el].IntValue;

View File

@@ -853,7 +853,8 @@ begin
if (el+3 < nel) and (Elements[el+1].Token = nftExpChar) then if (el+3 < nel) and (Elements[el+1].Token = nftExpChar) then
begin begin
Result := Result + '<number:scientific-number number:decimal-places="0"'; Result := Result + '<number:scientific-number number:decimal-places="0"';
n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1); // n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1);
n := FSections[ASection].MinIntDigits;
Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"'; Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"';
n := Elements[el+3].IntValue; n := Elements[el+3].IntValue;
Result := Result + ' number:min-exponent-digits="' + IntToStr(n) + '"'; Result := Result + ' number:min-exponent-digits="' + IntToStr(n) + '"';
@@ -865,7 +866,8 @@ begin
if (el+5 < nel) and (Elements[el+1].Token = nftDecSep) and (Elements[el+3].Token = nftExpChar) if (el+5 < nel) and (Elements[el+1].Token = nftDecSep) and (Elements[el+3].Token = nftExpChar)
then begin then begin
Result := Result + '<number:scientific-number'; Result := Result + '<number:scientific-number';
n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1); // n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1);
n := FSections[ASection].MinIntDigits;
Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"'; Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"';
n := IfThen(Elements[el+2].Token = nftZeroDecs, Elements[el+2].IntValue, 1); n := IfThen(Elements[el+2].Token = nftZeroDecs, Elements[el+2].IntValue, 1);
Result := Result + ' number:decimal-places="' + IntToStr(n) + '"'; Result := Result + ' number:decimal-places="' + IntToStr(n) + '"';
@@ -878,7 +880,8 @@ begin
if (el+2 < nel) and (Elements[el+1].Token = nftDecSep) then if (el+2 < nel) and (Elements[el+1].Token = nftDecSep) then
begin begin
Result := Result + '<number:number'; Result := Result + '<number:number';
n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1); // n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1);
n := FSections[ASection].MinIntDigits;
Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"'; Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"';
n := IfThen(Elements[el+2].Token = nftZeroDecs, Elements[el+2].IntValue, 1); n := IfThen(Elements[el+2].Token = nftZeroDecs, Elements[el+2].IntValue, 1);
Result := Result + ' number:decimal-places="' + IntToStr(n) + '"'; Result := Result + ' number:decimal-places="' + IntToStr(n) + '"';
@@ -888,11 +891,18 @@ begin
inc(el, 2); inc(el, 2);
end end
else else
(*
// Standard integer, format '#'
if (el = 0) and (nel = 1) and (Elements[el].Token = nftIntOptDigit) then
Result := Result + '<number:number number:min-integer-digits="0" number:decimal-places="0" />'
else
*)
// Standard integer // Standard integer
if (el = nel-1) or (Elements[el+1].Token <> nftDecSep) then if (el = nel-1) or (Elements[el+1].Token <> nftDecSep) then
begin begin
Result := Result + '<number:number number:decimal-places="0"'; Result := Result + '<number:number number:decimal-places="0"';
n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1); // n := IfThen(Elements[el].Token = nftIntZeroDigit, Elements[el].IntValue, 1);
n := FSections[ASection].MinIntDigits;
Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"'; Result := Result + ' number:min-integer-digits="' + IntToStr(n) + '"';
if (nfkHasFactor in Kind) and (Factor <> 0) then if (nfkHasFactor in Kind) and (Factor <> 0) then
Result := Result + Format(' number:display-factor="%.0f"', [1.0/Factor]); Result := Result + Format(' number:display-factor="%.0f"', [1.0/Factor]);
@@ -2962,13 +2972,13 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
nodeName: String; nodeName: String;
nf: TsNumberFormat; nf: TsNumberFormat;
nfs: String; nfs: String;
decs: Byte;
sint: String;
s: String; s: String;
f: Double; f: Double;
fracInt, fracNum, fracDenom: Integer; fracInt, fracNum, fracDenom: Integer;
grouping: Boolean; grouping: Boolean;
nex: Integer; nex: Integer;
nint: Integer;
ndecs: Integer;
cs: String; cs: String;
color: TsColor; color: TsColor;
hasColor: Boolean; hasColor: Boolean;
@@ -2987,9 +2997,8 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
end else end else
if nodeName = 'number:number' then if nodeName = 'number:number' then
begin begin
sint := GetAttrValue(node, 'number:min-integer-digits'); s := GetAttrValue(node, 'number:min-integer-digits');
if sint = '' then sint := '1'; if s <> '' then nint := StrToInt(s) else nint := 0;
s := GetAttrValue(node, 'number:decimal-places'); s := GetAttrValue(node, 'number:decimal-places');
if s = '' then if s = '' then
s := GetAttrValue(node, 'decimal-places'); s := GetAttrValue(node, 'decimal-places');
@@ -2999,12 +3008,12 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
nfs := nfs + 'General'; nfs := nfs + 'General';
end else end else
begin begin
decs := StrToInt(s); ndecs := StrToInt(s);
grouping := GetAttrValue(node, 'number:grouping') = 'true'; grouping := GetAttrValue(node, 'number:grouping') = 'true';
s := GetAttrValue(node, 'number:display-factor'); s := GetAttrValue(node, 'number:display-factor');
if s <> '' then f := StrToFloat(s, FPointSeparatorSettings) else f := 1.0; if s <> '' then f := StrToFloat(s, FPointSeparatorSettings) else f := 1.0;
nf := IfThen(grouping, nfFixedTh, nfFixed); nf := IfThen(grouping, nfFixedTh, nfFixed);
nfs := nfs + BuildNumberFormatString(nf, Workbook.FormatSettings, decs); //, StrToInt(sint)); nfs := nfs + BuildNumberFormatString(nf, Workbook.FormatSettings, ndecs, nint);
if f <> 1.0 then begin if f <> 1.0 then begin
nf := nfCustom; nf := nfCustom;
while (f > 1.0) do while (f > 1.0) do
@@ -3031,11 +3040,13 @@ procedure TsSpreadOpenDocReader.ReadNumFormats(AStylesNode: TDOMNode);
if nodeName = 'number:scientific-number' then if nodeName = 'number:scientific-number' then
begin begin
nf := nfExp; nf := nfExp;
s := GetAttrValue(node, 'number:min-integer-digits');
if s <> '' then nint := StrToInt(s) else nint := 0;
s := GetAttrValue(node, 'number:decimal-places'); s := GetAttrValue(node, 'number:decimal-places');
if s <> '' then decs := StrToInt(s) else decs := 0; if s <> '' then ndecs := StrToInt(s) else ndecs := 0;
s := GetAttrValue(node, 'number:min-exponent-digits'); s := GetAttrValue(node, 'number:min-exponent-digits');
if s <> '' then nex := StrToInt(s) else nex := 1; if s <> '' then nex := StrToInt(s) else nex := 1;
nfs := nfs + BuildNumberFormatString(nfFixed, Workbook.FormatSettings, decs); nfs := nfs + BuildNumberFormatString(nfFixed, Workbook.FormatSettings, ndecs, nint);
nfs := nfs + 'E+' + DupeString('0', nex); nfs := nfs + 'E+' + DupeString('0', nex);
end else end else
if nodeName = 'number:currency-symbol' then if nodeName = 'number:currency-symbol' then

View File

@@ -256,9 +256,11 @@ type
function WriteNumber(ARow, ACol: Cardinal; ANumber: double): PCell; overload; function WriteNumber(ARow, ACol: Cardinal; ANumber: double): PCell; overload;
procedure WriteNumber(ACell: PCell; ANumber: Double); overload; procedure WriteNumber(ACell: PCell; ANumber: Double); overload;
function WriteNumber(ARow, ACol: Cardinal; ANumber: double; function WriteNumber(ARow, ACol: Cardinal; ANumber: double;
ANumFormat: TsNumberFormat; ADecimals: Byte = 2): PCell; overload; ANumFormat: TsNumberFormat; ADecimals: Byte = 2;
AMinIntDigits: Integer = 1): PCell; overload;
procedure WriteNumber(ACell: PCell; ANumber: Double; procedure WriteNumber(ACell: PCell; ANumber: Double;
ANumFormat: TsNumberFormat; ADecimals: Byte = 2); overload; ANumFormat: TsNumberFormat; ADecimals: Byte = 2;
AMinIntDigits: Integer = 1); overload;
function WriteNumber(ARow, ACol: Cardinal; ANumber: double; function WriteNumber(ARow, ACol: Cardinal; ANumber: double;
ANumFormat: TsNumberFormat; ANumFormatString: String): PCell; overload; ANumFormat: TsNumberFormat; ANumFormatString: String): PCell; overload;
procedure WriteNumber(ACell: PCell; ANumber: Double; procedure WriteNumber(ACell: PCell; ANumber: Double;
@@ -4792,16 +4794,19 @@ end;
@param ARow Cell row index @param ARow Cell row index
@param ACol Cell column index @param ACol Cell column index
@param ANumber Number to be written @param ANumber Number to be written
@param ANumFormat Identifier for a built-in number format, e.g. nfFixed (optional) @param ANumFormat Identifier for a built-in number format,
e.g. nfFixed (optional)
@param ADecimals Number of decimal places used for formatting (optional) @param ADecimals Number of decimal places used for formatting (optional)
@param AMinIntDigits Minimum count of digits before the decimal separator
@return Pointer to cell created or used @return Pointer to cell created or used
@see TsNumberFormat @see TsNumberFormat
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
function TsWorksheet.WriteNumber(ARow, ACol: Cardinal; ANumber: double; function TsWorksheet.WriteNumber(ARow, ACol: Cardinal; ANumber: double;
ANumFormat: TsNumberFormat; ADecimals: Byte = 2): PCell; ANumFormat: TsNumberFormat; ADecimals: Byte = 2;
AMinIntDigits: Integer = 1): PCell;
begin begin
Result := GetCell(ARow, ACol); Result := GetCell(ARow, ACol);
WriteNumber(Result, ANumber, ANumFormat, ADecimals); WriteNumber(Result, ANumber, ANumFormat, ADecimals, AMinIntDigits);
end; end;
{@@ ---------------------------------------------------------------------------- {@@ ----------------------------------------------------------------------------
@@ -4813,10 +4818,12 @@ end;
@param ADecimals Optional number of decimal places used for formatting @param ADecimals Optional number of decimal places used for formatting
If ANumFormat is nfFraction the ADecimals defines the If ANumFormat is nfFraction the ADecimals defines the
digits of Numerator and denominator. digits of Numerator and denominator.
@param AMinIntDigits Minimum count of digits before the decimal separator
@see TsNumberFormat @see TsNumberFormat
-------------------------------------------------------------------------------} -------------------------------------------------------------------------------}
procedure TsWorksheet.WriteNumber(ACell: PCell; ANumber: Double; procedure TsWorksheet.WriteNumber(ACell: PCell; ANumber: Double;
ANumFormat: TsNumberFormat; ADecimals: Byte = 2); ANumFormat: TsNumberFormat; ADecimals: Byte = 2;
AMinIntDigits: Integer = 1);
var var
fmt: TsCellFormat; fmt: TsCellFormat;
nfs: String; nfs: String;
@@ -4837,7 +4844,7 @@ begin
if ADecimals = 0 then ADecimals := 1; if ADecimals = 0 then ADecimals := 1;
nfs := '# ' + DupeString('?', ADecimals) + '/' + DupeString('?', ADecimals); nfs := '# ' + DupeString('?', ADecimals) + '/' + DupeString('?', ADecimals);
end else end else
nfs := BuildNumberFormatString(fmt.NumberFormat, Workbook.FormatSettings, ADecimals); nfs := BuildNumberFormatString(fmt.NumberFormat, Workbook.FormatSettings, ADecimals, AMinIntDigits);
fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs); fmt.NumberFormatIndex := Workbook.AddNumberFormat(nfs);
end else begin end else begin
Exclude(fmt.UsedFormattingFields, uffNumberFormat); Exclude(fmt.UsedFormattingFields, uffNumberFormat);

View File

@@ -75,6 +75,8 @@ type
procedure TestWriteRead_MergedCells(AFormat: TsSpreadsheetFormat); procedure TestWriteRead_MergedCells(AFormat: TsSpreadsheetFormat);
// Many XF records // Many XF records
procedure TestWriteRead_ManyXF(AFormat: TsSpreadsheetFormat); procedure TestWriteRead_ManyXF(AFormat: TsSpreadsheetFormat);
// Format strings
procedure TestWriteRead_FormatStrings(AFormat: TsSpreadsheetFormat);
published published
// Writes out numbers & reads back. // Writes out numbers & reads back.
@@ -89,6 +91,7 @@ type
procedure TestWriteRead_BIFF2_MergedCells; procedure TestWriteRead_BIFF2_MergedCells;
procedure TestWriteRead_BIFF2_NumberFormats; procedure TestWriteRead_BIFF2_NumberFormats;
procedure TestWriteRead_BIFF2_ManyXFRecords; procedure TestWriteRead_BIFF2_ManyXFRecords;
procedure TestWriteRead_BIFF2_FormatStrings;
// These features are not supported by Excel2 --> no test cases required! // These features are not supported by Excel2 --> no test cases required!
// - Background // - Background
// - BorderStyle // - BorderStyle
@@ -107,6 +110,7 @@ type
procedure TestWriteRead_BIFF5_NumberFormats; procedure TestWriteRead_BIFF5_NumberFormats;
procedure TestWriteRead_BIFF5_TextRotation; procedure TestWriteRead_BIFF5_TextRotation;
procedure TestWriteRead_BIFF5_WordWrap; procedure TestWriteRead_BIFF5_WordWrap;
procedure TestWriteRead_BIFF5_FormatStrings;
{ BIFF8 Tests } { BIFF8 Tests }
procedure TestWriteRead_BIFF8_Alignment; procedure TestWriteRead_BIFF8_Alignment;
@@ -120,6 +124,7 @@ type
procedure TestWriteRead_BIFF8_NumberFormats; procedure TestWriteRead_BIFF8_NumberFormats;
procedure TestWriteRead_BIFF8_TextRotation; procedure TestWriteRead_BIFF8_TextRotation;
procedure TestWriteRead_BIFF8_WordWrap; procedure TestWriteRead_BIFF8_WordWrap;
procedure TestWriteRead_BIFF8_FormatStrings;
{ ODS Tests } { ODS Tests }
procedure TestWriteRead_ODS_Alignment; procedure TestWriteRead_ODS_Alignment;
@@ -133,6 +138,7 @@ type
procedure TestWriteRead_ODS_NumberFormats; procedure TestWriteRead_ODS_NumberFormats;
procedure TestWriteRead_ODS_TextRotation; procedure TestWriteRead_ODS_TextRotation;
procedure TestWriteRead_ODS_WordWrap; procedure TestWriteRead_ODS_WordWrap;
procedure TestWriteRead_ODS_FormatStrings;
{ OOXML Tests } { OOXML Tests }
procedure TestWriteRead_OOXML_Alignment; procedure TestWriteRead_OOXML_Alignment;
@@ -146,6 +152,7 @@ type
procedure TestWriteRead_OOXML_NumberFormats; procedure TestWriteRead_OOXML_NumberFormats;
procedure TestWriteRead_OOXML_TextRotation; procedure TestWriteRead_OOXML_TextRotation;
procedure TestWriteRead_OOXML_WordWrap; procedure TestWriteRead_OOXML_WordWrap;
procedure TestWriteRead_OOXML_FormatStrings;
{ CSV Tests } { CSV Tests }
procedure TestWriteRead_CSV_DateTimeFormats; procedure TestWriteRead_CSV_DateTimeFormats;
@@ -1677,6 +1684,84 @@ begin
TestWriteRead_ManyXF(sfExcel2); TestWriteRead_ManyXF(sfExcel2);
end; end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_FormatStrings(
AFormat: TsSpreadsheetFormat);
const
FormatStrings: Array[0..5] of string = (
'#', '#.000', '#.000E+00', '0', '0.000', '0.000E+00');
Numbers: array[0..4] of double = (
0, 1.23456789, -1.23456789, 1234.56789, -1234.56789);
var
MyWorkBook: TsWorkbook;
MyWorkSheet: TsWorksheet;
sollStr: String;
currStr: String;
currVal: Double;
r, c: Cardinal;
TempFile: String;
begin
MyWorkbook := TsWorkbook.Create;
try
MyWorkSheet := MyWorkBook.AddWorksheet('Sheet');
for r := 0 to High(Numbers) do
for c := 0 to High(FormatStrings) do
MyWorksheet.WriteNumber(r, c, Numbers[r], nfCustom, FormatStrings[c]);
TempFile := NewTempFile;
MyWorkBook.WriteToFile(TempFile, AFormat, true);
finally
MyWorkbook.Free;
end;
MyWorkbook := TsWorkbook.Create;
try
MyWorkbook.ReadFromFile(TempFile, AFormat);
MyWorksheet := MyWorkbook.GetWorksheetByName('Sheet');
CheckEquals(High(Numbers), MyWorksheet.GetLastRowIndex, 'Row count mismatch');
CheckEquals(High(FormatStrings), MyWorksheet.GetLastColIndex, 'Col count mismatch');
for r := 0 to MyWorksheet.GetLastRowIndex do
for c := 0 to MyWorksheet.GetLastColIndex do begin
currStr := MyWorksheet.ReadAsText(r, c);
currVal := MyWorksheet.ReadAsNumber(r, c);
sollStr := FormatFloat(FormatStrings[c], currVal);
// Quick & dirty fix for FPC's issue with #.00E+00 showing a leading zero
if (sollStr <> '') and (sollStr[1] = '0') and
(pos('#.', FormatStrings[c]) = 1) and (pos('E', FormatStrings[c]) > 0)
then
Delete(sollStr, 1, 1);
CheckEquals(sollStr, currStr, Format('Formatted cell mismatch, FormatStr "%s", Cell %s', [
FormatStrings[c], GetCellString(r, c)]));
end;
finally
MyWorkbook.Free;
end;
end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_BIFF2_FormatStrings;
begin
TestWriteRead_FormatStrings(sfExcel2);
end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_BIFF5_FormatStrings;
begin
TestWriteRead_FormatStrings(sfExcel5);
end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_BIFF8_FormatStrings;
begin
TestWriteRead_FormatStrings(sfExcel8);
end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_OOXML_FormatStrings;
begin
TestWriteRead_FormatStrings(sfOOXML);
end;
procedure TSpreadWriteReadFormatTests.TestWriteRead_ODS_FormatStrings;
begin
TestWriteRead_FormatStrings(sfOpenDocument);
end;
initialization initialization
RegisterTest(TSpreadWriteReadFormatTests); RegisterTest(TSpreadWriteReadFormatTests);
InitSollFmtData; InitSollFmtData;

View File

@@ -35,7 +35,7 @@ type
var var
ParserTestData: Array[0..13] of TParserTestData; ParserTestData: Array[0..13] of TParserTestData;
RoundingTestData: Array[0..62] of TRoundingTestData = ( RoundingTestData: Array[0..65] of TRoundingTestData = (
// 0 // 0
(FormatString: '0'; Number: 1.2; SollString: '1'), (FormatString: '0'; Number: 1.2; SollString: '1'),
(FormatString: '0'; Number: 1.9; SollString: '2'), (FormatString: '0'; Number: 1.9; SollString: '2'),
@@ -109,7 +109,12 @@ var
(FormatString: '0.0##'; Number: 1.21; SollString: '1.21'), (FormatString: '0.0##'; Number: 1.21; SollString: '1.21'),
(FormatString: '0.0##'; Number: 1.212; SollString: '1.212'), (FormatString: '0.0##'; Number: 1.212; SollString: '1.212'),
(FormatString: '0.0##'; Number: 1.2134; SollString: '1.213'), (FormatString: '0.0##'; Number: 1.2134; SollString: '1.213'),
(FormatString: '0.0##'; Number: 1.2135; SollString: '1.214') (FormatString: '0.0##'; Number: 1.2135; SollString: '1.214'),
// 63
(FormatString: '#'; Number: 0; SollString: ''),
(FormatString: '#'; Number: 1.2; SollString: '1'),
(FormatString: '#'; Number: -1.2; SollString: '-1')
); );

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<CONFIG> <CONFIG>
<ProjectOptions> <ProjectOptions>
<Version Value="10"/> <Version Value="11"/>
<PathDelim Value="\"/> <PathDelim Value="\"/>
<General> <General>
<SessionStorage Value="InProjectDir"/> <SessionStorage Value="InProjectDir"/>
@@ -19,9 +19,10 @@
<Version Value="2"/> <Version Value="2"/>
</PublishOptions> </PublishOptions>
<RunParams> <RunParams>
<local> <FormatVersion Value="2"/>
<FormatVersion Value="1"/> <Modes Count="1">
</local> <Mode0 Name="default"/>
</Modes>
</RunParams> </RunParams>
<RequiredPackages Count="4"> <RequiredPackages Count="4">
<Item1> <Item1>