是否有类似 StrToCurr 的函数可以处理千位分隔符?
Is there a StrToCurr like function that can deal with thousand separators?
我有一个类似的案例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;
引用大卫的话:
So it is a mistake to pass a string containing a thousands separator
to this function.
那么 Delphi 是否有任何内置函数可以解析包含千位分隔符的货币字符串?
这个设计(缺陷)的解决方案很简单:定义你自己的函数。
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 将 select 固定功能而不是损坏的功能。
有关此概念的更多信息,请参阅:Delphi interposer
您可以在'activex.pas'中使用从'oleaut32'导入的VarCyFromStr
from 'varutils.pas' which by default points to the COM helper VarCyFromStr
(您可以直接使用)。
如果您知道字符串是使用系统默认语言环境本地化的,您可以使用:
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
或为 LCID
传递 GetThreadLocale
以使用当前线程的设置。
如果字符串是使用默认用户区域设置本地化的,您可以让 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
我有一个类似的案例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;
引用大卫的话:
So it is a mistake to pass a string containing a thousands separator to this function.
那么 Delphi 是否有任何内置函数可以解析包含千位分隔符的货币字符串?
这个设计(缺陷)的解决方案很简单:定义你自己的函数。
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 将 select 固定功能而不是损坏的功能。
有关此概念的更多信息,请参阅:Delphi interposer
您可以在'activex.pas'中使用从'oleaut32'导入的VarCyFromStr
from 'varutils.pas' which by default points to the COM helper VarCyFromStr
(您可以直接使用)。
如果您知道字符串是使用系统默认语言环境本地化的,您可以使用:
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
或为 LCID
传递 GetThreadLocale
以使用当前线程的设置。
如果字符串是使用默认用户区域设置本地化的,您可以让 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