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