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

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

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

Причина возникновения ошибки

Рассмотрим стандартный сценарий: требуется построить сводную таблицу, где в качестве колонок выступают элементы справочника (например, склады, торговые точки или контрагенты). Для этого выполняется запрос, и в цикле обхода выборки вызывается метод Колонки.Добавить():


Таблица = Новый ТаблицаЗначений;

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|   Склады.Наименование КАК Наименование
|ИЗ
|   Справочник.Склады КАК Склады";

Склады = Запрос.Выполнить().Выбрать();

Пока Склады.Следующий() Цикл
    Таблица.Колонки.Добавить(Склады.Наименование);
КонецЦикла;

При выполнении этого кода платформа генерирует исключение, если в поле Склады.Наименование содержатся пробелы, дефисы, знаки препинания, кавычки или если строка начинается с цифры. Метод Добавить() коллекции КолонкиКоллекция принимает параметры в следующем порядке:

Добавить(Имя, ТипЭлемента, Заголовок, Ширина)

Первый параметр (Имя) является техническим идентификатором колонки. К нему применяются строгие правила именования переменных и объектов в платформе 1С:

  1. Имя может содержать только буквы (русские или латинские), цифры и символ подчеркивания _.
  2. Имя обязательно должно начинаться с буквы или символа _ (не может начинаться с цифры).
  3. В имени запрещены пробелы, тире, слеши, скобки и любые спецсимволы.
  4. Имя не может быть пустой строкой.
  5. Имена колонок в пределах одной таблицы значений должны быть уникальными (без учета регистра).

Пользовательский текст с пробелами и любыми знаками должен передаваться в третий параметр — Заголовок.

Способ 1. Использование префикса со счетчиком

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


Таблица = Новый ТаблицаЗначений;

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|   Склады.Наименование КАК Наименование
|ИЗ
|   Справочник.Склады КАК Склады";

Склады = Запрос.Выполнить().Выбрать();

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

Способ 2. Формирование имени на основе уникального идентификатора (GUID)

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


Таблица = Новый ТаблицаЗначений;

Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|   Склады.Ссылка КАК Ссылка,
|   Склады.Наименование КАК Наименование
|ИЗ
|   Справочник.Склады КАК Склады";

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Заменяем недопустимые символы "-" из GUID на символ подчеркивания "_"
    ИмяКолонки = "Склад_" + СтрЗаменить(Строка(Выборка.Ссылка.УникальныйИдентификатор()), "-", "_");
    
    // Проверяем уникальность перед добавлением
    Если Таблица.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
        Таблица.Колонки.Добавить(ИмяКолонки, , Выборка.Наименование);
    КонецЕсли;
КонецЦикла;

Такой подход гарантирует абсолютную уникальность имени колонки и полное соответствие правилам синтаксиса платформы 1С.

Способ 3. Преобразование строки в корректный идентификатор 1С

Если требуется, чтобы имя колонки читалось понятно в отладчике и было основано на наименовании объекта, строку необходимо предварительно очистить от запрещенных символов.

Рассмотрим алгоритм базовой нормализации строки:

  1. Удаляем пробелы с помощью функции СокрЛП() или заменяем все пробелы и дефисы на знак подчеркивания _.
  2. Добавляем гарантированный буквенный префикс (например, Кол_), чтобы исключить ошибку, если наименование склада начинается с цифры (например, «1-й Центральный склад»).
  3. Проверяем наличие колонки с таким именем в таблице через метод Найти(), чтобы избежать ошибки дублирования.

Пока Склады.Следующий() Цикл
    ОчищенноеИмя = СтрЗаменить(Склады.Наименование, " ", "_");
    ОчищенноеИмя = СтрЗаменить(ОчищенноеИмя, "-", "_");
    ОчищенноеИмя = СтрЗаменить(ОчищенноеИмя, ".", "_");
    
    // Добавляем префикс на случай цифры в начале
    ИмяКолонки = "Склад_" + ОчищенноеИмя;
    
    // Дополнительная проверка на уникальность
    Если Таблица.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
        Таблица.Колонки.Добавить(ИмяКолонки, , Склады.Наименование);
    КонецЕсли;
КонецЦикла;

Рекомендации по связыванию данных строк и динамических колонок

Выясним, как эффективно обращаться к динамически созданным колонкам при заполнении строк таблицы значений. Чтобы не вычислять имя колонки повторно для каждой строки данных, рекомендуется использовать объект Соответствие:


СоответствиеКолонок = Новый Соответствие;

// 1. Создаем структуру колонок и фиксируем соответствие ссылки и имени колонки
Пока Склады.Следующий() Цикл
    ИмяКолонки = "Склад_" + СтрЗаменить(Строка(Склады.Ссылка.УникальныйИдентификатор()), "-", "_");
    
    Если Таблица.Колонки.Найти(ИмяКолонки) = Неопределено Тогда
        Таблица.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Число"), Склады.Наименование);
        СоответствиеКолонок.Вставить(Склады.Ссылка, ИмяКолонки);
    КонецЕсли;
КонецЦикла;

// 2. Обращение к колонке по ссылке при заполнении данных
// ИмяКолонкиДляЗаписи = СоответствиеКолонок[ТекущийСклад];
// Если ИмяКолонкиДляЗаписи <> Неопределено Тогда
//     НоваяСтрока[ИмяКолонкиДляЗаписи] = КоличествоОстатка;
// КонецЕсли;

Разделение технического имени идентификатора и пользовательского заголовка позволяет полностью исключить возникновение ошибки «Неверное имя колонки» при работе с любыми прикладными данными.

← На главную