You've already forked lazarus-ccr
fpspreadsheet: Fix changing of decimal places for currency format in fpsgrid demo.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3162 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -463,6 +463,10 @@ begin
|
||||
exit;
|
||||
cell := Worksheet.FindCell(GetWorksheetRow(Row), GetWorksheetCol(Col));
|
||||
if (cell <> nil) then begin
|
||||
if cell^.NumberFormat = nfGeneral then begin
|
||||
Worksheet.WriteNumberFormat(cell, nfFixed, '0.00');
|
||||
exit;
|
||||
end;
|
||||
Worksheet.GetNumberFormatAttributes(cell, decs, currSym);
|
||||
if (Sender = AcIncDecimals) then
|
||||
Worksheet.WriteDecimals(cell, decs+1)
|
||||
@ -507,6 +511,7 @@ begin
|
||||
r := GetWorksheetRow(Row);
|
||||
cell := Worksheet.GetCell(r, c);
|
||||
Worksheet.GetNumberFormatAttributes(cell, decs, cs);
|
||||
if cs = '' then cs := '?';
|
||||
case cell^.ContentType of
|
||||
cctNumber, cctDateTime:
|
||||
if isDateTimeFmt then begin
|
||||
|
@ -91,6 +91,10 @@ type
|
||||
procedure AddElement(AToken: TsNumFormatToken; AIntValue: Integer); overload;
|
||||
procedure AddElement(AToken: TsNumFormatToken; AFloatValue: Double); overload;
|
||||
procedure AddSection;
|
||||
procedure DeleteElement(ASection, AIndex: Integer);
|
||||
procedure InsertElement(ASection, AIndex: Integer; AToken: TsNumFormatToken; AText: String); overload;
|
||||
procedure InsertElement(ASection, AIndex: Integer; AToken: TsNumFormatToken; AIntValue: Integer); overload;
|
||||
procedure InsertElement(ASection, AIndex: Integer; AToken: TsNumFormatToken; AFloatValue: Double); overload;
|
||||
function NextToken: Char;
|
||||
function PrevToken: Char;
|
||||
|
||||
@ -634,6 +638,55 @@ begin
|
||||
end;
|
||||
*)
|
||||
|
||||
procedure TsNumFormatParser.DeleteElement(ASection, AIndex: Integer);
|
||||
var
|
||||
i, n: Integer;
|
||||
begin
|
||||
n := Length(FSections[ASection].Elements);
|
||||
for i:= AIndex+1 to n-1 do
|
||||
FSections[ASection].Elements[i-1] := FSections[ASection].Elements[i];
|
||||
SetLength(FSections[ASection].Elements, n-1);
|
||||
end;
|
||||
|
||||
procedure TsNumFormatParser.InsertElement(ASection, AIndex: Integer;
|
||||
AToken: TsNumFormatToken; AText: String);
|
||||
var
|
||||
i, n: Integer;
|
||||
begin
|
||||
n := Length(FSections[ASection].Elements);
|
||||
SetLength(FSections[ASection].Elements, n+1);
|
||||
for i:= n-1 downto AIndex+1 do
|
||||
FSections[ASection].Elements[i+1] := FSections[ASection].Elements[i];
|
||||
FSections[ASection].Elements[AIndex+1].Token := AToken;
|
||||
FSections[ASection].Elements[AIndex+1].TextValue := AText;
|
||||
end;
|
||||
|
||||
procedure TsNumFormatParser.InsertElement(ASection, AIndex: Integer;
|
||||
AToken: TsNumFormatToken; AIntValue: Integer);
|
||||
var
|
||||
i, n: Integer;
|
||||
begin
|
||||
n := Length(FSections[ASection].Elements);
|
||||
SetLength(FSections[ASection].Elements, n+1);
|
||||
for i:= n-1 downto AIndex+1 do
|
||||
FSections[ASection].Elements[i+1] := FSections[ASection].Elements[i];
|
||||
FSections[ASection].Elements[AIndex+1].Token := AToken;
|
||||
FSections[ASection].Elements[AIndex+1].IntValue := AIntValue;
|
||||
end;
|
||||
|
||||
procedure TsNumFormatParser.InsertElement(ASection, AIndex: Integer;
|
||||
AToken: TsNumFormatToken; AFloatValue: Double);
|
||||
var
|
||||
i, n: Integer;
|
||||
begin
|
||||
n := Length(FSections[ASection].Elements);
|
||||
SetLength(FSections[ASection].Elements, n+1);
|
||||
for i:= n-1 downto AIndex+1 do
|
||||
FSections[ASection].Elements[i+1] := FSections[ASection].Elements[i];
|
||||
FSections[ASection].Elements[AIndex+1].Token := AToken;
|
||||
FSections[ASection].Elements[AIndex+1].FloatValue := AFloatValue;
|
||||
end;
|
||||
|
||||
function TsNumFormatParser.GetFormatString(ADialect: TsNumFormatDialect): String;
|
||||
var
|
||||
i: Integer;
|
||||
@ -1653,25 +1706,31 @@ var
|
||||
i, j, n: Integer;
|
||||
begin
|
||||
for j := 0 to High(FSections) do begin
|
||||
i := 0;
|
||||
n := Length(FSections[j].Elements);
|
||||
while (i < n) do begin
|
||||
i := n-1;
|
||||
while (i > -1) do begin
|
||||
case FSections[j].Elements[i].Token of
|
||||
nftDigit:
|
||||
// no decimals so far --> add decimal separator and decimals element
|
||||
if i = n-1 then begin
|
||||
AddElement(nftDecSep, '.');
|
||||
AddElement(nftDecs, AValue);
|
||||
exit;
|
||||
if (AValue > 0) then begin
|
||||
// Don't use "AddElements" because nfCurrency etc have elements after the number.
|
||||
InsertElement(j, i, nftDecSep, '.');
|
||||
InsertElement(j, i+1, nftDecs, AValue);
|
||||
break;
|
||||
end;
|
||||
nftDecs:
|
||||
begin
|
||||
if AValue > 0 then begin
|
||||
// decimals are already used, just replace value of decimal places
|
||||
FSections[j].Elements[i].IntValue := AValue;
|
||||
exit;
|
||||
break;
|
||||
end else begin
|
||||
// No decimals any more: delete decs and decsep elements
|
||||
DeleteElement(j, i);
|
||||
DeleteElement(j, i-1);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
inc(i);
|
||||
dec(i);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -1399,14 +1399,22 @@ function TsWorksheet.GetNumberFormatAttributes(ACell: PCell; out ADecimals: byte
|
||||
out ACurrencySymbol: String): Boolean;
|
||||
var
|
||||
parser: TsNumFormatParser;
|
||||
nf: TsNumberFormat;
|
||||
begin
|
||||
Result := false;
|
||||
if ACell <> nil then begin
|
||||
parser := TsNumFormatParser.Create(FWorkbook, ACell^.NumberFormatStr);
|
||||
try
|
||||
if parser.Status = psOK then begin
|
||||
ADecimals := parser.Decimals;
|
||||
ACurrencySymbol := parser.CurrencySymbol;
|
||||
nf := parser.NumFormat;
|
||||
if (nf = nfGeneral) or IsDateTimeFormat(nf) then begin
|
||||
ADecimals := 2;
|
||||
ACurrencySymbol := '?';
|
||||
end
|
||||
else begin
|
||||
ADecimals := parser.Decimals;
|
||||
ACurrencySymbol := parser.CurrencySymbol;
|
||||
end;
|
||||
Result := true;
|
||||
end;
|
||||
finally
|
||||
@ -2053,14 +2061,14 @@ begin
|
||||
if ANegCurrFormat = -1 then
|
||||
ANegCurrFormat := Workbook.FormatSettings.NegCurrFormat;
|
||||
if ACurrencySymbol = '?' then
|
||||
ACurrencySymbol := Workbook.FormatSettings.CurrencyString;
|
||||
ACurrencySymbol := AnsiToUTF8(Workbook.FormatSettings.CurrencyString);
|
||||
|
||||
fmt := BuildCurrencyFormatString(
|
||||
nfdDefault,
|
||||
AFormat,
|
||||
Workbook.FormatSettings,
|
||||
ADecimals,
|
||||
APosCurrFormat, ANegCurrFormat,
|
||||
AFormat in [nfCurrencyRed, nfAccountingRed],
|
||||
AFormat in [nfAccounting, nfAccountingRed],
|
||||
ACurrencySymbol);
|
||||
|
||||
WriteCurrency(ACell, AValue, AFormat, fmt);
|
||||
@ -3836,20 +3844,6 @@ begin
|
||||
// Iterate through all cells and collect the individual styles
|
||||
for i := 0 to Workbook.GetWorksheetCount - 1 do
|
||||
IterateThroughCells(nil, Workbook.GetWorksheetByIndex(i).Cells, ListAllFormattingStylesCallback);
|
||||
|
||||
(*
|
||||
// Convert the numberformats of the collected styles to be compatible with the destination file
|
||||
for i:=0 to High(FFormattingStyles) do
|
||||
if (FFormattingStyles[i].NumberFormatStr <> '') and
|
||||
(FFormattingStyles[i].NumberFormat <> nfCustom) // don't touch custom formatstrings!
|
||||
then
|
||||
FNumFormatList.ConvertBeforeWriting(
|
||||
FFormattingStyles[i].NumberFormatStr,
|
||||
FFormattingStyles[i].NumberFormat,
|
||||
FFormattingStyles[i].Decimals,
|
||||
FFormattingStyles[i].CurrencySymbol
|
||||
);
|
||||
*)
|
||||
end;
|
||||
|
||||
{@@
|
||||
|
@ -12,7 +12,7 @@ unit fpsutils;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, StrUtils, fpspreadsheet;
|
||||
Classes, SysUtils, StrUtils, fpspreadsheet, fpsNumFormatParser;
|
||||
|
||||
// Exported types
|
||||
type
|
||||
@ -72,9 +72,9 @@ function IsCurrencyFormat(AFormat: TsNumberFormat): Boolean;
|
||||
function IsDateTimeFormat(AFormat: TsNumberFormat): Boolean; overload;
|
||||
//function IsDateTimeFormat(AFormatStr: String): Boolean; overload;
|
||||
|
||||
function BuildCurrencyFormatString(const AFormatSettings: TFormatSettings;
|
||||
ADecimals, APosCurrFormat, ANegCurrFormat: Integer;
|
||||
ANegativeValuesRed, AAccountingStyle: Boolean; ACurrencySymbol: String = '?'): String;
|
||||
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect;
|
||||
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings;
|
||||
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String;
|
||||
function BuildDateTimeFormatString(ANumberFormat: TsNumberFormat;
|
||||
const AFormatSettings: TFormatSettings; AFormatString: String = ''): String;
|
||||
function BuildNumberFormatString(ANumberFormat: TsNumberFormat;
|
||||
@ -624,9 +624,9 @@ end;
|
||||
negative values) to apply a red font color.
|
||||
This code has to be removed by StripAccountingSymbols before applying to
|
||||
FormatFloat. }
|
||||
function BuildCurrencyFormatString(const AFormatSettings: TFormatSettings;
|
||||
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ANegativeValuesRed: Boolean;
|
||||
AAccountingStyle: Boolean; ACurrencySymbol: String = '?'): String;
|
||||
function BuildCurrencyFormatString(ADialect: TsNumFormatDialect;
|
||||
ANumberFormat: TsNumberFormat; const AFormatSettings: TFormatSettings;
|
||||
ADecimals, APosCurrFormat, ANegCurrFormat: Integer; ACurrencySymbol: String): String;
|
||||
const
|
||||
POS_FMT: array[0..3, boolean] of string = (
|
||||
// Parameter 0 is "value", parameter 1 is "currency symbol"
|
||||
@ -658,6 +658,8 @@ var
|
||||
decs: String;
|
||||
cf, ncf: Byte;
|
||||
p, n: String;
|
||||
accStyle: Boolean;
|
||||
negRed: Boolean;
|
||||
begin
|
||||
cf := IfThen(APosCurrFormat < 0, AFormatSettings.CurrencyFormat, APosCurrFormat);
|
||||
ncf := IfThen(ANegCurrFormat < 0, AFormatSettings.NegCurrFormat, ANegCurrFormat);
|
||||
@ -668,10 +670,13 @@ begin
|
||||
decs := DupeString('0', ADecimals);
|
||||
if ADecimals > 0 then decs := '.' + decs;
|
||||
|
||||
p := POS_FMT[cf, AAccountingStyle];
|
||||
n := NEG_FMT[ncf, AAccountingStyle];
|
||||
accStyle := ANumberFormat in [nfAccounting, nfAccountingRed];
|
||||
negRed := ANumberFormat in [nfCurrencyRed, nfAccountingRed];
|
||||
|
||||
p := POS_FMT[cf, accStyle];
|
||||
n := NEG_FMT[ncf, accStyle];
|
||||
// add extra space for the sign of the number for perfect alignment in Excel
|
||||
if AAccountingStyle then
|
||||
if accStyle then
|
||||
case ncf of
|
||||
0, 14: p := p + '_)';
|
||||
3, 11: p := p + '_-';
|
||||
@ -681,17 +686,22 @@ begin
|
||||
|
||||
if ACurrencySymbol <> '' then begin
|
||||
Result := Format(p, ['#,##0' + decs, ACurrencySymbol]) + ';'
|
||||
+ IfThen(ANegativeValuesRed, '[red]', '') + Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';'
|
||||
+ Format(p, [IfThen(AAccountingStyle, '-', '0'+decs), ACurrencySymbol]);
|
||||
+ IfThen(negRed and (ADialect = nfdExcel), '[red]', '')
|
||||
+ Format(n, ['#,##0' + decs, ACurrencySymbol]) + ';'
|
||||
+ Format(p, [IfThen(accStyle, '-', '0'+decs), ACurrencySymbol]);
|
||||
end
|
||||
else begin
|
||||
Result := '#,##0' + decs;
|
||||
if negRed and (ADialect = nfdExcel) then
|
||||
Result := Result +';[red]'
|
||||
else
|
||||
Result := Result +';';
|
||||
case ncf of
|
||||
0, 14, 15 : Result := Result + ';(#,##0' + decs + ')';
|
||||
1, 2, 5, 6, 8, 9, 12: Result := Result + ';-#,##0' + decs;
|
||||
else Result := Result + ';#,##0' + decs + '-';
|
||||
0, 14, 15 : Result := Result + '(#,##0' + decs + ')';
|
||||
1, 2, 5, 6, 8, 9, 12: Result := Result + '-#,##0' + decs;
|
||||
else Result := Result + '#,##0' + decs + '-';
|
||||
end;
|
||||
Result := Result + ';' + IfThen(AAccountingStyle, '-', '0'+decs);
|
||||
Result := Result + ';' + IfThen(accStyle, '-', '0'+decs);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Reference in New Issue
Block a user