Как программно добавить колонки в динамический список в 1С?

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

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

Почему не работает метод ИзменитьРеквизиты()?

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


РеквизитФормыКолонка1 = Новый РеквизитФормы("Колонка1", ОбщегоНазначения.ОписаниеТипаДата(...), "Список", "Колонка 1");
МассивДобавляемыхРеквизитов = Новый Массив(); 
МассивДобавляемыхРеквизитов.Добавить(РеквизитФормыКолонка1);
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);

На последней строке платформа выдает ошибку: «Недопустимый путь к реквизиту. Путь: Список». Почему это происходит? Разберем природу динамического списка.

Метод ИзменитьРеквизиты предназначен для создания реквизитов формы, которые хранятся в оперативной памяти (например, для таблицы значений или дерева значений). Динамический список устроен принципиально иначе. Структура его полей не задается массивом реквизитов, она жестко генерируется самой платформой на основе текста его запроса (или основной таблицы).

Искусственно «впихнуть» новый реквизит внутрь самого объекта типа «Динамический список» архитектурно недопустимо. Если мы программно модифицируем свойство ТекстЗапроса, добавляя в него новые вычисляемые поля, список сам (динамически) перестроит доступные поля данных. Добавлять реквизиты специально не нужно!

Разделяем понятия: данные списка и элементы формы

Итак, мы изменили текст запроса динамического списка. Отладчик показывает, что новые поля успешно появились в коллекции Список.КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора.Элементы. Однако на самой форме мы их не видим.

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

Рассмотрим пример кода для добавления колонки на форму:


НовыйЭлемент = Элементы.Добавить("ИмяНовойКолонки", Тип("ПолеФормы"), Элементы.СписокФормы);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Список.ИмяПоляВЗапросе";
НовыйЭлемент.Заголовок = "Моя новая колонка";

Решаем проблему с ошибкой «Недопустимое значение»

При использовании вышеуказанного кода для добавления элемента формы на строке присвоения свойства ПутьКДанным может возникнуть ошибка «Недопустимое значение». Проанализируем, в чем дело, если запрос изменен, а элементы управления все равно не могут привязаться к данным.

Эта ошибка чаще всего связана со следующими факторами:

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

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

Альтернативный вариант: скрытие существующих колонок

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

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


Если УсловиеОтображения Тогда 
    Элементы.ИмяТаблицыНаФорме.ПодчиненныеЭлементы.ИмяКолонки.Видимость = Истина;
Иначе
    Элементы.ИмяТаблицыНаФорме.ПодчиненныеЭлементы.ИмяКолонки.Видимость = Ложь;
КонецЕсли;

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

Продвинутый подход: используем объект СхемаЗапроса

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

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

Разберем по шагам, как это работает:

  1. Загружаем текущий текст запроса из динамического списка:
    СхемаЗапроса.УстановитьТекстЗапроса(Список.ТекстЗапроса);
  2. Находим нужный пакет (обычно последний, который возвращает результат):
    Пакет = СхемаЗапроса.ПакетЗапросов[СхемаЗапроса.ПакетЗапросов.Количество() - 1];
  3. Добавляем нужные поля выбора, связи или условия, используя методы схемы (сразу задавая им понятные псевдонимы).
  4. Выгружаем готовый текст обратно в динамический список:
    Список.ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();

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

← На главную