Заставьте VarToDoubleAsString использовать настройки Delphi (не настройки ОС) - PullRequest
4 голосов
/ 23 февраля 2011

Когда присваивается вариант, содержащий строковое значение, переменной с плавающей запятой, Delphi вызывает VarToDoubleAsString для выполнения преобразования, которое, в свою очередь, использует параметры ОС для разделителя десятичных разрядов и тысяч (через VarR8FromStr). Это проблематично, если нужно изменить SysUtils.DecimalSeparator и SysUtils.ThousandSeparator. Например, запустите следующую программу:

program VarStrToFloat;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Math;

function FormatFloatUsingDelphiSettings(Value: Extended): string;
begin
  Result := FormatFloat('#,##0.00', Value);
end;

procedure Test(const AMsg: string);
var
  r1, r2: Extended;
  s1, s2: string;
  v: Variant;
begin
  r1 := 5432.1;
  s1 := FormatFloatUsingDelphiSettings(r1);
  v := s1; // <== conversion uses OS settings
  r2 := v;
  s2 := FormatFloatUsingDelphiSettings(r2);

  Write(AMsg: 8, s1: 10, s2: 10, '  ');
  if SameValue(r1, r2) then
    Writeln('OK')
  else
    Writeln('FAIL');
end;

procedure SwapEm;
var
  tmp: Char;
begin
  tmp := DecimalSeparator;
  DecimalSeparator := ThousandSeparator;
  ThousandSeparator := tmp;
end;

begin
  Test('Default');
  SwapEm;
  Test('Changed');
  Readln;
end.

Первый тест работает нормально, второй не пройден.

Есть ли способ заставить Variant преобразование использовать SysUtils.DecimalSeparator и SysUtils.ThousandSeparator?

1 Ответ

11 голосов
/ 23 февраля 2011

Вы можете заменить функцию VarR8FromStr в varutils.pas по своему вкусу, и VarToDoubleAsString будет использовать ее вместо:

function MyConversion(const strIn: WideString; LCID: Integer; dwFlags: Longint;
    out dblOut: Double): HRESULT; stdcall;
const
  CResult: array [False..True] of HRESULT = (VAR_INVALIDARG, VAR_OK);
var
  s: string;
begin
  s := StringReplace(StrIn, ThousandSeparator, '', [rfReplaceAll]);
  Result := CResult[TryStrToFloat(s, dblOut)];
end;

[...]

begin
  varutils.VarR8FromStr := MyConversion;
  [...]
...