fpspreadsheet: Improved conversion of numbers to formatted strings, handles more special cases (e.g. integer-only fractions, optional digits, optional space digits).

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4094 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2015-04-22 18:48:08 +00:00
parent 3f6f45f65a
commit c2dd60bb18
4 changed files with 581 additions and 526 deletions

View File

@ -1031,6 +1031,7 @@ begin
decs := Worksheet.GetDisplayedDecimals(ACell) decs := Worksheet.GetDisplayedDecimals(ACell)
else else
decs := FDecimals; decs := FDecimals;
inc(decs, FDelta); inc(decs, FDelta);
if decs < 0 then decs := 0; if decs < 0 then decs := 0;
Worksheet.WriteDecimals(ACell, decs); Worksheet.WriteDecimals(ACell, decs);

View File

@ -135,6 +135,7 @@ begin
FWorkbook := AWorkbook; FWorkbook := AWorkbook;
Parse(AFormatString); Parse(AFormatString);
CheckSections; CheckSections;
if AFormatString = '' then FSections[0].NumFormat := nfGeneral;
end; end;
destructor TsNumFormatParser.Destroy; destructor TsNumFormatParser.Destroy;
@ -1358,12 +1359,19 @@ end;
procedure TsNumFormatParser.SetDecimals(AValue: Byte); procedure TsNumFormatParser.SetDecimals(AValue: Byte);
var var
i, j, n: Integer; i, j, n: Integer;
foundDecs: Boolean;
begin begin
foundDecs := false;
for j := 0 to High(FSections) do begin for j := 0 to High(FSections) do begin
n := Length(FSections[j].Elements); n := Length(FSections[j].Elements);
i := n-1; i := n-1;
while (i > -1) do begin while (i > -1) do begin
case FSections[j].Elements[i].Token of case FSections[j].Elements[i].Token of
nftDecSep: // this happens, e.g., for "0.E+00"
if (AValue > 0) and not foundDecs then begin
InsertElement(j, i, nftZeroDecs, AValue);
break;
end;
nftIntOptDigit, nftIntZeroDigit, nftIntSpaceDigit, nftIntTh: nftIntOptDigit, nftIntZeroDigit, nftIntSpaceDigit, nftIntTh:
// no decimals so far --> add decimal separator and decimals element // no decimals so far --> add decimal separator and decimals element
if (AValue > 0) then begin if (AValue > 0) then begin
@ -1373,16 +1381,19 @@ begin
break; break;
end; end;
nftZeroDecs, nftOptDecs, nftSpaceDecs: nftZeroDecs, nftOptDecs, nftSpaceDecs:
if AValue > 0 then begin begin
// decimals are already used, just replace value of decimal places foundDecs := true;
FSections[j].Elements[i].IntValue := AValue; if AValue > 0 then begin
FSections[j].Elements[i].Token := nftZeroDecs; // decimals are already used, just replace value of decimal places
break; FSections[j].Elements[i].IntValue := AValue;
end else begin FSections[j].Elements[i].Token := nftZeroDecs;
// No decimals any more: delete decs and decsep elements break;
DeleteElement(j, i); end else begin
DeleteElement(j, i-1); // No decimals any more: delete decs and decsep elements
break; DeleteElement(j, i);
DeleteElement(j, i-1);
break;
end;
end; end;
end; end;
dec(i); dec(i);

View File

@ -4424,12 +4424,15 @@ var
numFmt: TsNumFormatParams; numFmt: TsNumFormatParams;
numFmtStr: String; numFmtStr: String;
begin begin
if (ACell = nil) then if (ACell = nil) or (ACell^.ContentType <> cctNumber) then
exit; exit;
fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex); fmt := FWorkbook.GetCellFormat(ACell^.FormatIndex);
numFmt := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex); numFmt := FWorkbook.GetNumberFormat(fmt.NumberFormatIndex);
numFmtStr := numFmt.NumFormatStr; if numFmt <> nil then
numFmtStr := numFmt.NumFormatStr
else
numFmtStr := '0.00';
parser := TsNumFormatParser.Create(Workbook, numFmtStr); parser := TsNumFormatParser.Create(Workbook, numFmtStr);
try try
parser.Decimals := ADecimals; parser.Decimals := ADecimals;

File diff suppressed because it is too large Load Diff