Germany | Finland | Saint Petersburg | Drive

Получение региональных настроек

Опубликовано в AmiSharp

При использовании AmiSharp (или иного механизма получения таблиц QUIK) приходится преобразовывать строковые представления чисел в сами числа. Процедура кажется тривиальной, однако встроенная функция StrToNum() Амиброкера не знает ничего о региональных настройках и, соответственно, оказывается бесполезной.

Например, если в таблице терминала QUIK фигурирует цена фьючерса на индекс РТС в виде 158 450, то упомянутая функция преобразует эту строку в число 158. Первый же найденный пробел введет ее в заблуждение. Также в качестве разделителя целой и дробной частей StrToNum ожидает увидеть точку, хотя Windows для наших мест по умолчанию устанавливает запятую. При этом мы из языка AFL не имеем возможности заранее знать, каким образом терминал QUIK будет форматировать числа в своих таблицах при включённом флаге форматирования - вид строк, представляющих числа будет зависеть от региональных настроек операционной системы. Значит, нужно делать универсальный механизм - перед преобразованием в число необходимо строку, содержащую это число, привести в надлежащий вид:

  • удалить разделители триад
  • заменить разделитель целой и дробной частей на точку

А для этого нужно знать, какие разделители установлены в настройках операционной системы. Как получить из AFL региональные настройки?

Я делаю это так:

function RegionalSettings()
{   local WSHShell;     if (StaticVarGetText("RegionalSettings~Locale") == "")
    { WSHShell = CreateObject("WScript.Shell");       pushdef(`GetRegistryKey', `StaticVarSetText("RegionalSettings~`$1'",WSHShell.RegRead("HKEY_CURRENT_USER\\Control Panel\\International\\`$1'"))')
      GetRegistryKey(Locale);
      GetRegistryKey(sList);               dnl рaздeлитeль элeмeнтoв cпиcкa
      GetRegistryKey(sDecimal);         dnl рaздeлитeль цeлoй и дpoбнoй чacти
      GetRegistryKey(sThousand);      dnl рaздeлитeль гpупп paзpядoв
      popdef(`GetRegistryKey')
    }
}

Функция читает 4 региональных параметра, используя Windows Script и помещает их в глобальные переменные. В тексте используются команды препроцессора M4.

Теперь перед преобразованием строки в число имеется возможность привести строковое представление в понятный для AFL вид и использовать StrToNum во всех случаях, невзирая на установленные на компьютере региональные настройки. При этом робот без каких-либо изменений будет правильно функционировать при переносе его на другой компьютер, где эти региональные настройки могут отличаться.

function NormalizeNumber(NumString)
{ RegionalSettings();
  NumString = StrReplace(NumString,StaticVarGetText("RegionalSetings~sThousand"),"");
  NumString = StrReplace(NumString,StaticVarGetText("RegionalSetings~sDecimal"),".");
  return NumString;
}

Конечно, возможны и экзотические случаи, когда рукам пользователя покоя нет. Он может поменять способ представления отрицательных чисел и подобные настройки. Можно и такие варианты отследить и исправить, но я этого не делаю: всему есть разумный предел.



Таким образом, для получения ячейки данных в виде числа при помощи AmiSharp я использую следующие 2 макроса:

define(`Get_Cell_Number',`StrToNum(NormalizeNumber(m4_amisharp.GetCell(`$1',`$2',`$3')))')
define(`Get_Cell_Name_Number',`StrToNum(NormalizeNumber(m4_amisharp.GetCellName(`$1',`$2',`$3')))')  
Комментарии   
# andre4444 01.05.2015 19:05
Если в Windows в качестве разделителя целой и дробной части установлена точка,
то значения из таблиц QUIK округляются до целой части.

Если в Windows в качестве разделителя целой и дробной части установлена запятая,
то значения из таблиц QUIK содержат все цифры но без разделителя целой и дробной части.

Как получить значение числа имеющего и целую и дробную часть и запятую.
Ответить | Ответить с цитатой | Цитировать
# admin 01.05.2015 20:04
Ээээ... что-то Вы путаете.


Строка "1.2345" (с точкой) практически во всех известных мне языках библиотечными функциями преобразуется в float без потерь

Чтобы преобразовать число с другим разделителем целой и дробной части (запятая, например), нужно заменить эту запятую на точку и сделать преобразование.

Возможно, Вы используете какой-то хитрый пакет - тут надо разбираться, по каким правилам делает преобразование он.
Ответить | Ответить с цитатой | Цитировать
Добавить комментарий


Майнинг в браузере