Почему в 1С на мобильной платформе число преобразуется с пробелом вместо точки и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разработка под мобильную платформу «1С:Предприятие» имеет множество нюансов, связанных с тем, что мобильные операционные системы (Android и iOS) накладывают свои ограничения и используют собственные системные библиотеки локализации. Часто разработчики сталкиваются с ситуацией, когда код, идеально работающий на настольной («большой») платформе, на мобильном устройстве начинает вести себя непредсказуемо.

В этой статье мы подробно разберем один крайне коварный баг мобильной платформы, связанный с неявным преобразованием дробных чисел в строку, выясним причины его возникновения и рассмотрим эффективные методы решения этой проблемы.

В чем суть проблемы?

Представим стандартную ситуацию: в коде выполняется вывод дробного числа на экран или его неявное преобразование в строку. Например, мы пишем простейшую конструкцию:

Сообщить(Число(1.234));

На настольной платформе мы получим ожидаемый результат (например, "1,234" в зависимости от локали). Однако на некоторых версиях мобильной платформы (в частности, на ветках 8.3.10.х) на экране появится строка "1 234". Точка или запятая, отделяющая дробную часть, загадочным образом превращается в пробел!

При этом наблюдается странная закономерность:

  1. Если передать число с тремя знаками после запятой — Число(1.234) преобразуется в "1 234" (с пробелом).
  2. Если передать число с четырьмя знаками — Число(1.2345) преобразуется корректно: "1,2345" (с запятой).
  3. Если принудительно добавить нули справа — Число(1.2340), платформа выведет нормальное число "1,234".

Давайте разберем по шагам, почему так происходит, чем это грозит разработчику и как исправить поведение платформы.

Причина возникновения бага: ловушка локализации и триады

Поведение системы объясняется особенностями работы парсера и форматтера чисел в мобильной платформе 1С, которые тесно завязаны на региональные настройки операционной системы устройства.

В русской локали приняты следующие стандарты форматирования чисел:

При вызове функции Сообщить() происходит неявное приведение переданного значения к типу Строка. В старых версиях мобильного движка алгоритм форматирования содержал ошибку: когда на вход поступало число ровно с тремя знаками в дробной части, парсер ошибочно распознавал эту тройку цифр как полноценную «триаду» (тысячную группу) целой части числа. В результате вместо разделения дробной части платформа применяла правила группировки разрядов целой части и заменяла разделитель на пробел.

Если количество знаков после запятой отличалось от трех (было меньше или больше), шаблон группы из трех цифр не совпадал, алгоритм отрабатывал штатно, и разделитель оставался на месте.

Скрытая угроза: обычный пробел против неразрывного (НПП)

Многие разработчики, обнаружив пробел в строке числа, пытаются решить проблему «в лоб» с помощью стандартной функции удаления пробелов:

Результат = СтрЗаменить(СтрокаЧисла, " ", "");

Проанализируем эту ситуацию. На самом деле такой код не сработает. Дело в том, что платформа вставляет в качестве разделителя не обычный пробел (символ с ASCII-кодом 32), а неразрывный пробел (символ Символы.НПП, Unicode-код 160 или U+00A0).

Чтобы удалить такой символ вручную, необходимо использовать системные константы 1С:


// Правильное удаление неразрывного пробела
Результат = СтрЗаменить(СтрокаЧисла, Символы.НПП, "");
// Или альтернативный вариант через код символа
Результат = СтрЗаменить(СтрокаЧисла, Символ(160), "");

Почему это опасно для интеграций (XML/JSON)?

Данная ошибка критична не только из-за эстетического отображения чисел на экране пользователя. Гораздо серьезнее последствия при обмене данными.

Если в мобильном приложении настроена отправка данных на веб-сервер, в базу SQL или интеграция со сторонними сервисами через форматы XML, JSON или CSV, неявное преобразование типов может полностью заблокировать обмен:

Способы решения проблемы

Рассмотрим три надежных способа обойти и полностью решить эту проблему на мобильной платформе.

Способ 1. Использование явного форматирования (Best Practice)

Самый надежный способ, гарантирующий стабильную работу кода на любой платформе (как мобильной, так и настольной) независимо от региональных настроек устройства — это полное исключение неявного преобразования типов. Никогда не полагайтесь на автоматическое приведение числа к строке!

Для гарантированного получения строки без лишних символов группировки используйте встроенную функцию Формат() с параметром ЧГ=0 (отключение группировки разрядов):


// Исключаем группировку разрядов (пробелы исчезнут)
СтрокаДляВыгрузки = Формат(МоеЧисло, "ЧГ=0");

Если вам необходимо подготовить число для передачи во внешние API (где в качестве разделителя дробной части жестко требуется точка), используйте явную установку разделителя дробной части ЧРД=.:


// Отключаем группировку и жестко задаем точку в качестве разделителя
СтрокаДляAPI = Формат(МоеЧисло, "ЧГ=0; ЧРД=.");
Сообщить(СтрокаДляAPI); // Выведет "1.234" при любых региональных настройках

Способ 2. Настройка региональных установок конфигурации

Если вы хотите переопределить стандартное поведение форматирования для всей конфигурации целиком, выполните следующие действия в Конфигураторе:

  1. Откройте свойства корневого элемента конфигурации.
  2. Найдите свойство «Региональные установки».
  3. В открывшемся окне переопределите символы по умолчанию:
    • Установите свойство «Разделитель групп» как пустую строку (чтобы пробелы вообще не добавлялись автоматически).
    • Зафиксируйте «Разделитель дробной части» в зависимости от стандартов вашего учета (запятая или точка).

Важное примечание: На некоторых старых релизах мобильной платформы системные настройки операционной системы Android/iOS могут иметь более высокий приоритет, чем региональные установки конфигурации 1С. Поэтому использование явного форматирования через Формат() в коде остается более приоритетным и безопасным вариантом.

Способ 3. Обновление версии мобильной платформы

Поскольку данная проблема локализации является явным багом платформы, разработчики фирмы «1С» зафиксировали её и исправили в последующих релизах.

Если в вашей системе до сих пор используется устаревшая ветка платформы (например, 8.3.10.84), мы настоятельно рекомендуем выполнить обновление мобильной платформы до актуальных версий (начиная с линеек 8.3.11, 8.3.12 и выше). В новых версиях логика форматирования чисел приведена в полное соответствие с настольной платформой, и ошибка с ошибочной группировкой трех знаков дробной части полностью устранена.

← На главную