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

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

При выводе дат с помощью функции Формат разработчики часто сталкиваются с неожиданным поведением. Например, при использовании локального формата длинной даты ДЛФ=DD код возвращает строку вида «24 апреля 2017 г.». Однако при детальном анализе строки в текстовых редакторах или при передаче данных во внешние системы выясняется, что между цифрой года и сокращением «г.» находится не стандартный пробел, а специальный непечатаемый символ. Разберем, почему так происходит, какие скрытые проблемы это влечет за собой и как корректно управлять пробелами при форматировании.

Причины поведения платформы 1С

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

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

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

Скрытые ошибки и сложности при работе с неразрывным пробелом

Проанализируем ситуации, в которых наличие символа Символы.НПП приводит к трудноуловимым ошибкам в коде:

  1. Ошибки сравнения строк. Если в программном коде написать условие сравнения строки, полученной через Формат, с обычной строковой константой, условие вернет Ложь. Например, выражение СтрокаДаты = "24 апреля 2017 г." не сработает, так как в литерале задан обычный пробел (код 32), а в переменной содержится код 160.
  2. Сбои интеграции и обмена данными. При выгрузке информации в форматы JSON, XML, CSV или при отправке через веб-сервисы (REST/SOAP) неразрывный пробел может нарушать валидацию XSD-схем, вызывать сбои во внешних парсерах или превращаться в искаженные символы («кракозябры») при конвертации кодировок.
  3. Поиск и фильтрация строк. Использование функции СтрНайти или наложение отборов может давать пустой результат, если пользователь вводит строку поиска с обычной клавиатуры.

Способ 1. Использование явного шаблона даты вместо локального формата

Рассмотрим самый надежный и простой способ избежать появления неразрывных пробелов. Вместо локального формата ДЛФ зададим точный шаблон даты с помощью параметра ДФ. Все символы и пробелы, явно указанные внутри одинарных кавычек строки формата, платформа сохраняет без изменений:


ФорматированнаяДата = Формат(ТекущаяДата(), "ДФ='d MMMM yyyy г.'");
Сообщить(ФорматированнаяДата);

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

Способ 2. Программная замена неразрывного пробела

Если в алгоритме требуется сохранить именно системное локальное представление даты через ДЛФ, обработаем готовую строку с помощью функции СтрЗаменить. Заменим спецсимвол Символы.НПП на стандартный пробел:


ФорматированнаяДата = Формат(ТекущаяДата(), "ДЛФ=DD");
ФорматированнаяДата = СтрЗаменить(ФорматированнаяДата, Символы.НПП, " ");

Посмотрим на альтернативный вариант замены через код символа, который дает абсолютно аналогичный результат:

ФорматированнаяДата = СтрЗаменить(ФорматированнаяДата, Символ(160), " ");

Способ 3. Использование функций Библиотеки стандартных подсистем (БСП)

Разберем вариант для типовых конфигураций, разработанных на базе Библиотеки стандартных подсистем. Чтобы не писать собственные обработчики строк, применим готовую экспортную функцию общего модуля:


ФорматированнаяДата = Формат(ТекущаяДата(), "ДЛФ=DD");
ФорматированнаяДата = СтроковыеФункцииКлиентСервер.УдалитьНеразрывныеПробелы(ФорматированнаяДата);

Этот метод заменяет все неразрывные пробелы в переданном тексте на стандартные пробелы пробельной клавиши, обеспечивая корректность дальнейшей строковой обработки.

Способ 4. Сборка строки по шаблону

В задачах, где требуется полностью изолировать логику формирования представления даты от настроек платформы и региональных стандартов, соберем строку вручную с помощью СтрШаблон:


ДатаДляВывода = ТекущаяДата();
ФорматированнаяДата = СтрШаблон("%1 %2 %3 г.", 
    День(ДатаДляВывода), 
    Формат(ДатаДляВывода, "ДФ=MMMM"), 
    Формат(Год(ДатаДляВывода), "ЧГ=0"));

Обратим внимание на параметр ЧГ=0 при форматировании года: он отключает группировку разрядов числа, предотвращая подстановку неразрывного пробела между тысячами и сотнями.

← На главную