Что такое неявное форматирование индекса в 1С и как правильно формировать имена колонок

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

При динамическом создании колонок таблиц значений, полей структур или свойств объектов разработчики часто используют цикл со счетчиком и формируют программные имена путем сложения базовой строки и числового индекса. Однако при код-ревью или статическом анализе кода можно встретить замечание: «При формировании идентификатора колонки выполняется неявное форматирование индекса». Разберем подробно, что означает это предупреждение, к какой критической ошибке оно приводит в рабочей системе и как правильно формировать машинные идентификаторы в 1С.

Рассмотрим типовой фрагмент кода, в котором возникает эта проблема:


ТЗвыборка = Новый ТаблицаЗначений;
ТЗвыборка.Колонки.Добавить("СправочникПоОсиУ", Новый ОписаниеТипов("СправочникСсылка.Справочник1"));

Для й = 0 По МассивВыборки.Количество() - 1 Цикл
    ТЗвыборка.Колонки.Добавить("Колонка" + Строка(й), Новый ОписаниеТипов("Строка"), МассивВыборки[й].Наименование);
КонецЦикла;

В чем заключается суть проблемы и скрытая ошибка

Проанализируем механизм работы платформы 1С:Предприятие при преобразовании чисел в строки. Когда мы вызываем функцию Строка(Число) или выполняем неявное приведение типа при конкатенации вида "Колонка" + й, платформа использует стандартные региональные настройки локали информационной базы для пользовательского представления чисел.

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

  1. Если счетчик й меньше 1000, строка формируется корректно: "Колонка0", "Колонка999".
  2. Как только количество элементов в выборке достигает 1001 и значение счетчика становится равным 1000, выражение "Колонка" + Строка(й) возвращает строку "Колонка1 000" с неразрывным пробелом внутри.
  3. Первый параметр метода Колонки.Добавить() задает имя колонки, которое обязано быть валидным идентификатором встроенного языка 1С (начинаться с буквы или знака подчеркивания и не содержать пробелов, дефисов и спецсимволов).
  4. При попытке добавить колонку с именем "Колонка1 000" программа аварийно завершает работу с исключением о недопустимом имени колонки.

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

Способ 1. Использование функции Формат с отключением группировки разрядов

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


Для й = 0 По МассивВыборки.Количество() - 1 Цикл
    ИмяКолонки = "Колонка" + Формат(й, "ЧГ=0");
    ТЗвыборка.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Строка"), МассивВыборки[й].Наименование);
КонецЦикла;

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


Для й = 0 По МассивВыборки.Количество() - 1 Цикл
    ИмяКолонки = СтрШаблон("Колонка%1", Формат(й, "ЧГ=0"));
    ТЗвыборка.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Строка"), МассивВыборки[й].Наименование);
КонецЦикла;

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

Посмотрим на наиболее производительный и лаконичный вариант. Функция платформы XMLСтрока() предназначена для преобразования примитивных типов данных в их каноническое строковое представление формата XML (XSD). Она никогда не добавляет региональные разделители групп разрядов и работает быстрее функции Формат().


Для й = 0 По МассивВыборки.Количество() - 1 Цикл
    ИмяКолонки = "Колонка" + XMLСтрока(й);
    ТЗвыборка.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Строка"), МассивВыборки[й].Наименование);
КонецЦикла;

Способ 3. Очистка неразрывных пробелов через СтрЗаменить

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


Для й = 0 По МассивВыборки.Количество() - 1 Цикл
    ИмяКолонки = "Колонка" + СтрЗаменить(Строка(й), Символы.НПП, "");
    ТЗвыборка.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Строка"), МассивВыборки[й].Наименование);
КонецЦикла;

Этот вариант является рабочим, однако он менее предпочтителен по сравнению с XMLСтрока() и Формат(), так как выполняет избыточные операции выделения памяти и поиска подстрок.

Общие рекомендации по стандартам разработки 1С

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

  1. Любые машинные идентификаторы (имена колонок таблиц значений, свойства структур, имена параметров запросов, ключи соответствий, теги XML и поля JSON) должны формироваться только с каноническим представлением чисел.
  2. Никогда не используйте операторы "Имя" + Число или вызов Строка(Число) для генерации имен системных объектов.
  3. Для максимального быстродействия и чистоты кода при формировании технических строк всегда отдавайте предпочтение функции XMLСтрока().
← На главную