При массовой загрузке данных (например, парсинге больших объемов данных из JSON или веб-сервисов) разработчики 1С нередко сталкиваются с ситуацией, когда стандартная функция Строка() или неявное приведение типов работают нестабильно. В одной и той же выборке числовые идентификаторы могут преобразовываться в текст по-разному: часть записей форматируется с разделителем групп разрядов (неразрывным пробелом Символы.НПП), а часть — сплошной строкой цифр. Разберем детально, почему это происходит и какими способами можно гарантировать требуемый формат строки.
Рассмотрим, из-за чего возникает плавающее поведение при преобразовании чисел в строковый тип:
Строка() от региональных установок: функция Строка() всегда использует текущие национальные настройки сеанса. По умолчанию для русской локали в качестве разделителя групп разрядов используется неразрывный пробел (код 160). Если разработчику требуется числовой идентификатор без пробелов, использование Строка() является архитектурной ошибкой.ЧтениеJSON) низкоуровневые системные библиотеки могут переключать системную переменную LC_NUMERIC в значение C для корректного чтения чисел с плавающей точкой. В некоторых релизах платформы этот сброс кратковременно затрагивает параллельные потоки одного рабочего процесса rphost, в результате чего числа форматируются без учета региональных разделителей.LANG и LC_ALL (например, ru_RU.UTF-8), рабочий процесс может произвольно переключаться на стандартную локаль POSIX.Проанализируем практические решения для каждой из типовых задач: когда нужно получить строку строго без разделителей и когда строку требуется сформировать строго с неразрывными пробелами.
Если числовое поле используется как строковый идентификатор, разделители тысяч в нем присутствовать не должны. Для надежного преобразования числа в плоскую строку цифр рассмотрим два проверенных инструмента.
Вариант А. Использование функции XMLСтрока():
Функция XMLСтрока() работает строго по каноническим правилам сериализации XML и схемы типов decimal. Она полностью игнорирует региональные настройки пользователя, операционной системы и сервера, всегда возвращая число без пробелов и с точкой в качестве десятичного разделителя.
// Гарантированное строковое представление без пробелов и разделителей тысяч
СтроковыйИдентификатор = XMLСтрока(ЧисловоеЗначение);
Вариант Б. Применение функции Формат() с отключением группировки:
Для явного отключения группировки разрядов в форматной строке используется параметр ЧГ=0 или ЧГ=. Чтобы исключить дробную часть у целых чисел, дополнительно задают параметр ЧДЦ=0.
// Явное отключение группировки и дробной части
СтроковыйИдентификатор = Формат(ЧисловоеЗначение, "ЧДЦ=0; ЧГ=0");
Бывают обратные ситуации: сторонние закрытые модули конфигурации или строгие алгоритмы сверки ожидают, что число в строковом реквизите обязательно содержит неразрывный пробел Символы.НПП в качестве разделителя тысяч. В условиях сбоящей локали полагаться на Строка() нельзя. Рассмотрим варианты принудительного форматирования.
Вариант А. Явное указание локали в функции Формат():
Чтобы функция Формат() не зависела от системного сброса локали рабочего процесса, передадим код локали третьим параметром функции или пропишем его прямо в форматной строке через параметр Л=ru_RU:
// Принудительное задание русской локали и неразрывного пробела в разделителе групп
СтрокаСРазделителями = Формат(ЧисловоеЗначение, "ЧГ=3,0; ЧРГ=" + Символы.НПП, "ru_RU");
Вариант Б. Форматирование через обычный пробел с последующей заменой:
Если в конкретной версии платформы параметр ЧРГ ведет себя нестабильно при прямой передаче спецсимвола, применим надежный двухэтапный шаблон: отформатируем число с обычным символом пробела, а затем заменим его на Символы.НПП через функцию СтрЗаменить().
// Форматируем число с использованием стандартного пробела
ВременнаяСтрока = Формат(ЧисловоеЗначение, "ЧЦ=15; ЧДЦ=0; ЧГ=3,0; ЧРГ=' '");
// Заменяем обычный пробел на неразрывный пробел 1С
ИтоговаяСтрока = СтрЗаменить(ВременнаяСтрока, " ", Символы.НПП);
Вариант В. Автономный алгоритм вставки разделителей (без вызова Формат):
Когда требуется стопроцентная изоляция от любых платформенных и системных механизмов локализации, разберем алгоритмическую расстановку Символы.НПП с конца строки:
ИсходныйТекст = XMLСтрока(ЧисловоеЗначение);
Длина = СтрДлина(ИсходныйТекст);
ИтоговаяСтрока = "";
Счетчик = 0;
Для Позиция = Длина По 1 Цикл
Символ = Сред(ИсходныйТекст, Позиция, 1);
Если Счетчик > 0 И Счетчик % 3 = 0 Тогда
ИтоговаяСтрока = Символы.НПП + ИтоговаяСтрока;
КонецЕсли;
ИтоговаяСтрока = Символ + ИтоговаяСтрока;
Счетчик = Счетчик + 1;
КонецЦикла;
Если сервер 1С функционирует под управлением ОС Linux, проверим корректность глобальных локалей операционной системы, в среде которых стартует служба ragent / rphost.
locale -a | grep ru_RU
/etc/default/srv1cv83, /etc/sysconfig/srv1cv83 либо Unit-файле systemd) явно укажем экспорт переменных перед запуском бинарных файлов платформы:
export LANG=ru_RU.UTF-8
export LC_ALL=ru_RU.UTF-8
Таким образом, для безопасной работы с текстовыми полями в коде конфигураций следует избегать неявных преобразований типов и функции Строка(), заменяя их на XMLСтрока() (для точных данных без оформления) или Формат() с явным указанием локали и параметров группировки.