
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@5282 8e941d3f-bd1b-0410-a28a-d453659cc2b4
191 lines
6.1 KiB
ObjectPascal
191 lines
6.1 KiB
ObjectPascal
unit fpsCurrency;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils;
|
|
|
|
procedure RegisterCurrency(ACurrencySymbol: String);
|
|
procedure RegisterCurrencies(AList: TStrings; AReplace: Boolean);
|
|
procedure UnregisterCurrency(ACurrencySymbol: String);
|
|
function CurrencyRegistered(ACurrencySymbol: String): Boolean;
|
|
procedure GetRegisteredCurrencies(AList: TStrings);
|
|
|
|
function IsNegative(var AText: String): Boolean;
|
|
function RemoveCurrencySymbol(ACurrencySymbol: String;
|
|
var AText: String): Boolean;
|
|
function TryStrToCurrency(AText: String; out ANumber: Double;
|
|
out ACurrencySymbol:String; const AFormatSettings: TFormatSettings): boolean;
|
|
|
|
|
|
implementation
|
|
|
|
var
|
|
CurrencyList: TStrings = nil;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Registers a currency symbol UTF8 string for usage by fpspreadsheet
|
|
|
|
Currency symbols are the key for detection of currency values. In order to
|
|
reckognize strings are currency symbols they have to be registered in the
|
|
internal CurrencyList.
|
|
|
|
Registration occurs automatically for USD, "$", the currencystring defined
|
|
in the DefaultFormatSettings and for the currency symbols used explicitly
|
|
when calling WriteCurrency or WriteNumerFormat.
|
|
-------------------------------------------------------------------------------}
|
|
procedure RegisterCurrency(ACurrencySymbol: String);
|
|
begin
|
|
if not CurrencyRegistered(ACurrencySymbol) and (ACurrencySymbol <> '') then
|
|
CurrencyList.Add(ACurrencySymbol);
|
|
end;
|
|
|
|
{@@ RegisterCurrencies registers the currency strings contained in the string list
|
|
If AReplace is true, the list replaces the currently registered list.
|
|
-------------------------------------------------------------------------------}
|
|
procedure RegisterCurrencies(AList: TStrings; AReplace: Boolean);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if AList = nil then
|
|
exit;
|
|
|
|
if AReplace then CurrencyList.Clear;
|
|
for i:=0 to AList.Count-1 do
|
|
RegisterCurrency(AList[i]);
|
|
end;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Removes registration of a currency symbol string for usage by fpspreadsheet
|
|
-------------------------------------------------------------------------------}
|
|
procedure UnregisterCurrency(ACurrencySymbol: String);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
i := CurrencyList.IndexOf(ACurrencySymbol);
|
|
if i <> -1 then CurrencyList.Delete(i);
|
|
end;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Checks whether a string is registered as valid currency symbol string
|
|
-------------------------------------------------------------------------------}
|
|
function CurrencyRegistered(ACurrencySymbol: String): Boolean;
|
|
begin
|
|
Result := CurrencyList.IndexOf(ACurrencySymbol) <> -1;
|
|
end;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Writes all registered currency symbols to a string list
|
|
-------------------------------------------------------------------------------}
|
|
procedure GetRegisteredCurrencies(AList: TStrings);
|
|
begin
|
|
AList.Clear;
|
|
AList.Assign(CurrencyList);
|
|
end;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Checks whether the given number string is a negative value. In case of
|
|
currency value, this can be indicated by brackets, or a minus sign at string
|
|
start or end.
|
|
-------------------------------------------------------------------------------}
|
|
function IsNegative(var AText: String): Boolean;
|
|
begin
|
|
Result := false;
|
|
if AText = '' then
|
|
exit;
|
|
if (AText[1] = '(') and (AText[Length(AText)] = ')') then
|
|
begin
|
|
Result := true;
|
|
Delete(AText, 1, 1);
|
|
Delete(AText, Length(AText), 1);
|
|
AText := Trim(AText);
|
|
end else
|
|
if (AText[1] = '-') then
|
|
begin
|
|
Result := true;
|
|
Delete(AText, 1, 1);
|
|
AText := Trim(AText);
|
|
end else
|
|
if (AText[Length(AText)] = '-') then
|
|
begin
|
|
Result := true;
|
|
Delete(AText, Length(AText), 1);
|
|
AText := Trim(AText);
|
|
end;
|
|
end;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Checks wheter a specified currency symbol is contained in a string, removes
|
|
the currency symbol and returns the remaining string.
|
|
-------------------------------------------------------------------------------}
|
|
function RemoveCurrencySymbol(ACurrencySymbol: String; var AText: String): Boolean;
|
|
var
|
|
p: Integer;
|
|
begin
|
|
p := pos(ACurrencySymbol, AText);
|
|
if p > 0 then
|
|
begin
|
|
Delete(AText, p, Length(ACurrencySymbol));
|
|
AText := Trim(AText);
|
|
Result := true;
|
|
end else
|
|
Result := false;
|
|
end;
|
|
|
|
{@@ ----------------------------------------------------------------------------
|
|
Checks whether a string is a number with attached currency symbol. Looks also
|
|
for negative values in brackets.
|
|
-------------------------------------------------------------------------------}
|
|
function TryStrToCurrency(AText: String; out ANumber: Double;
|
|
out ACurrencySymbol:String; const AFormatSettings: TFormatSettings): boolean;
|
|
var
|
|
i: Integer;
|
|
s: String;
|
|
isNeg: Boolean;
|
|
begin
|
|
Result := false;
|
|
ANumber := 0.0;
|
|
ACurrencySymbol := '';
|
|
|
|
// Check the text for the presence of each known curreny symbol
|
|
for i:= 0 to CurrencyList.Count-1 do
|
|
begin
|
|
// Store string in temporary variable since it will be modified
|
|
s := AText;
|
|
// Check for this currency sign being contained in the string, remove it if found.
|
|
if RemoveCurrencySymbol(CurrencyList[i], s) then
|
|
begin
|
|
// Check for negative signs and remove them, but keep this information
|
|
isNeg := IsNegative(s);
|
|
// Try to convert remaining string to number
|
|
if TryStrToFloat(s, ANumber, AFormatSettings) then begin
|
|
// if successful: take care of negative values
|
|
if isNeg then ANumber := -ANumber;
|
|
ACurrencySymbol := CurrencyList[i];
|
|
Result := true;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
initialization
|
|
// Known currency symbols
|
|
CurrencyList := TStringList.Create;
|
|
with TStringList(CurrencyList) do
|
|
begin
|
|
CaseSensitive := false;
|
|
Duplicates := dupIgnore;
|
|
end;
|
|
RegisterCurrency('USD');
|
|
RegisterCurrency('$');
|
|
RegisterCurrency(AnsiToUTF8(DefaultFormatSettings.CurrencyString));
|
|
|
|
finalization
|
|
FreeAndNil(CurrencyList);
|
|
|
|
end.
|
|
|