Почему возникает ошибка «Неверное имя колонки» при добавлении колонки в Таблицу Значений и как её исправить?

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

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

Анализ проблемы: что скрывается за ошибкой «Неверное имя колонки»

Проанализируем типовой фрагмент кода, в котором выполняется обход некоторой таблицы-источника и динамическое создание колонок во второй таблице значений:


Для Каждого Строка Из тзПоставок Цикл
    тзФакта.Колонки.Добавить("П_" + Формат(Строка.ПоставкаКод, "ЧГ="));
КонецЦикла;

На первый взгляд кажется, что к коду поставки просто добавляется префикс "П_", а функция Формат() с параметром "ЧГ=" исключает группировку разрядов числа (то есть убирает пробелы между тысячами). Однако на этапе выполнения платформа прерывает работу с ошибкой. Выясним причину такого поведения.

Платформа 1С выдает ошибку «Неверное имя колонки» в следующих ключевых случаях:

  1. Попытка добавить дублирующееся имя колонки. В объекте ТаблицаЗначений имена колонок обязаны быть уникальными в пределах одной таблицы. Если в исходной выборке (например, в результате некорректно составленного запроса) один и тот же код встречается дважды, при первой итерации колонка добавится успешно, а на второй произойдет исключение. Важно помнить: платформа не чувствительна к регистру символов, поэтому имена "П_А1" и "П_а1" считаются дублями.
  2. Скрытые или недопустимые символы. Если исходный реквизит Строка.ПоставкаКод имеет строковый тип, функция Формат(Строка.ПоставкаКод, "ЧГ=") не окажет на него влияния, так как модификатор "ЧГ=" применяется исключительно к числовым типам данных. Если в строковом коде присутствуют пробелы, неразрывные пробелы (Символы.НПП), переносы строк, дефисы или точки, они попадут в результирующее имя.
  3. Нарушение правил именования идентификаторов. Имя колонки может состоять только из букв, цифр и знаков подчеркивания _. Оно не может начинаться с цифры и не может быть пустой строкой.

Способ 1. Локализация проблемы с помощью отладчика

Прежде чем переписывать алгоритм, разберем по шагам, как локализовать ошибку в режиме «1С:Предприятие»:

  1. В конфигураторе перейдем в меню Отладка — Настройка автоматического останова при ошибке и включим флаг Останавливаться по ошибке.
  2. Запустим обработку заново. В момент падения управление передастся отладчику точно на строке вызова метода Добавить().
  3. Откроем табло отладки (Shift+F9 или Ctrl+Alt+W) и вычислим итоговое имя: "П_" + Формат(Строка.ПоставкаКод, "ЧГ=").
  4. Проверим, существует ли уже такая колонка в таблице, выполнив в табло команду: тзФакта.Колонки.Найти("П_" + Формат(Строка.ПоставкаКод, "ЧГ=")). Если возвращается не Неопределено, а объект КолонкаТаблицыЗначений, значит, в цикле происходит попытка повторного добавления уже существующей колонки.

Способ 2. Проверка наличия колонки перед добавлением

Рассмотрим самый простой и надежный программный способ защиты от дублей непосредственно в теле цикла. Будем использовать метод коллекции Найти():


Для Каждого Строка Из тзПоставок Цикл
    ИмяКолонки = "П_" + Формат(Строка.ПоставкаКод, "ЧГ=0");
    
    // Проверяем, существует ли уже колонка с таким именем
    Если тзФакта.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
        тзФакта.Колонки.Добавить(ИмяКолонки);
    КонецЕсли;
КонецЦикла;

Метод Колонки.Найти() возвращает Неопределено, если колонки в коллекции нет, что позволяет безопасно выполнить добавление только уникальных полей.

Способ 3. Устранение дубликатов в источнике данных

Если кодов много, частые вызовы поиска по коллекции внутри цикла могут снижать производительность. Правильнее всего исключить повторы на этапе подготовки данных. Рассмотрим два варианта:

  1. Корректировка исходного запроса. Если таблица поставок заполняется запросом, используем оператор РАЗЛИЧНЫЕ или группировку СГРУППИРОВАТЬ ПО, чтобы в выборку гарантированно не попадали дублирующие записи по коду.
  2. Сворачивание исходной таблицы значений. Если данные уже находятся в памяти, получим список уникальных кодов перед формированием целевой таблицы:

тзКодов = тзПоставок.Скопировать(, "ПоставкаКод");
тзКодов.Свернуть("ПоставкаКод");

Для Каждого СтрокаКода Из тзКодов Цикл
    ИмяКолонки = "П_" + Формат(СтрокаКода.ПоставкаКод, "ЧГ=0");
    тзФакта.Колонки.Добавить(ИмяКолонки);
КонецЦикла;

Способ 4. Нормализация имени и обработка спецсимволов

Посмотрим на ситуацию, когда Строка.ПоставкаКод может быть строкой произвольного формата (например, содержать дефисы вроде "А-105" или пробелы). В таком случае прямое использование кода в качестве имени колонки вызовет ошибку, даже если дублей нет. Разберем, как нормализовать строку и использовать свойство Заголовок:


Индекс = 1;
Для Каждого Строка Из тзПоставок Цикл
    // Заголовок может содержать любые символы: пробелы, дефисы, спецзнаки
    ЗаголовокКолонки = СокрЛП(Строка.ПоставкаКод);
    
    // Формируем системное уникальное имя колонки без спецсимволов
    ИмяКолонки = "Колонка_" + Формат(Индекс, "ЧГ=0");
    
    // Добавляем колонку с системным именем и пользовательским заголовком
    тзФакта.Колонки.Добавить(ИмяКолонки, , ЗаголовокКолонки);
    
    Индекс = Индекс + 1;
КонецЦикла;

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

← На главную