是否有类似StrToCurr的功能可以处理千位分隔符?

时间:2016-08-07 18:44:33

标签: delphi delphi-xe3 currency-formatting

我有一个类似的案例as in this question

procedure TForm2.FormCreate(Sender: TObject);
var
  S: string;
  C: Currency;
  FormatSettings: TFormatSettings;
begin
  S := '1.000.000,00';
  FormatSettings := TFormatSettings.Create;
  FormatSettings.ThousandSeparator := '.';
  FormatSettings.DecimalSeparator := ',';
  // raises an Exception which is "as designed" as per the documentation
  C := StrToCurr(S, FormatSettings);
  ShowMessage(FormatCurr(',0.00', C));
end;

引用大卫:

  

因此传递包含千位分隔符的字符串是错误的   这个功能。

那么Delphi是否有任何内置函数可以解析包含千位分隔符的货币字符串?

2 个答案:

答案 0 :(得分:6)

此设计的解决方案(缺陷)很简单:定义您自己的功能。

unit MyFixForSysUtils;

interface

function StrToCurr(const Str: string): Currency; overload;
function StrToCurr(Str: string; const FormatSettings : TFormatSettings): Currency; overload;  

implementation

uses SysUtils;

function StrToCurr(Str: string; const FormatSettings : TFormatSettings): Currency;
begin
  Str:= StringReplace(Str, FormatSettings.ThousandSeparator, '', [rfReplaceAll]);
  Result:= SysUtils.StrToCurr(Str, FormatSettings);
end;

 function StrToCurr(const Str: string): Currency;
 begin
   Result:= StrToCurr(Str, FormatSettings);
 end;

如果您确定自己的版本的范围比sysutils更近,那么您就不需要更改代码了:

uses
  SysUtils,
  MyFixForSysUtils,  <-- contains the above function
  .... other units.

现在Delphi将选择固定功能而不是破坏功能。

有关此概念的更多信息,请参阅:Delphi interposer

答案 1 :(得分:4)

您可以使用&#39; varutils.pas&#39;中的VarCyFromStr。默认情况下,它指向从&#39; oleaut32&#39;导入的COM助手VarCyFromStr。在&#39; activex.pas&#39; (你可以直接使用)。

如果您知道字符串已使用系统默认语言环境进行本地化,则可以使用:

var
  S: string;
  C: Currency;
begin
  S := '1.000.000,00';
  if varutils.VarCyFromStr(S, 0, LOCALE_NOUSEROVERRIDE, C) = VAR_OK then
    ShowMessage(FormatCurr(',0.00', C))
  else

或通过GetThreadLocale LCID来使用当前主题的设置。

如果字符串已使用默认用户区域设置进行本地化,则可以让RTL为您调用该字符串,并使用此函数进行变体转换。

var
  V: Variant;
  C: Currency;
begin
  V := '1.000.000,00';
  C := V;
  ShowMessage(FormatCurr(',0.00', C));

否则,您必须知道字符串代表货币的区域设置。例如:

var
  S: string;
  C: Currency;
begin
  S := '1,000,000.00';
  if varutils.VarCyFromStr(S, MAKELCID(LANG_ENGLISH, SORT_DEFAULT), 0, C) = VAR_OK then
    ShowMessage(FormatCurr(',0.00', C))
  else
    // handle error