Разберем достаточно распространенную задачу при разработке на управляемых формах 1С: как программно добавить новые колонки в существующий динамический список. Часто разработчики пытаются решить эту задачу теми же методами, что и для таблиц значений, и сталкиваются с рядом специфических ошибок. Проанализируем ситуацию по шагам, выясним причину ошибок и найдем правильный подход к решению.
Посмотрим на типичный фрагмент кода, который вызывает ошибку:
РеквизитФормыКолонка1 = Новый РеквизитФормы("Колонка1", ОбщегоНазначения.ОписаниеТипаДата(...), "Список", "Колонка 1");
МассивДобавляемыхРеквизитов = Новый Массив();
МассивДобавляемыхРеквизитов.Добавить(РеквизитФормыКолонка1);
ИзменитьРеквизиты(МассивДобавляемыхРеквизитов);
На последней строке платформа выдает ошибку: «Недопустимый путь к реквизиту. Путь: Список». Почему это происходит? Разберем природу динамического списка.
Метод ИзменитьРеквизиты предназначен для создания реквизитов формы, которые хранятся в оперативной памяти (например, для таблицы значений или дерева значений). Динамический список устроен принципиально иначе. Структура его полей не задается массивом реквизитов, она жестко генерируется самой платформой на основе текста его запроса (или основной таблицы).
Искусственно «впихнуть» новый реквизит внутрь самого объекта типа «Динамический список» архитектурно недопустимо. Если мы программно модифицируем свойство ТекстЗапроса, добавляя в него новые вычисляемые поля, список сам (динамически) перестроит доступные поля данных. Добавлять реквизиты специально не нужно!
Итак, мы изменили текст запроса динамического списка. Отладчик показывает, что новые поля успешно появились в коллекции Список.КомпоновщикНастроек.Настройки.ДоступныеПоляВыбора.Элементы. Однако на самой форме мы их не видим.
Здесь важно понимать разницу между данными (информацией в памяти) и визуальными элементами управления. Данные уже есть, но чтобы пользователь их увидел, добавим на форму соответствующий элемент управления (колонку таблицы) и свяжем его с нашим новым полем из запроса.
Рассмотрим пример кода для добавления колонки на форму:
НовыйЭлемент = Элементы.Добавить("ИмяНовойКолонки", Тип("ПолеФормы"), Элементы.СписокФормы);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "Список.ИмяПоляВЗапросе";
НовыйЭлемент.Заголовок = "Моя новая колонка";
При использовании вышеуказанного кода для добавления элемента формы на строке присвоения свойства ПутьКДанным может возникнуть ошибка «Недопустимое значение». Проанализируем, в чем дело, если запрос изменен, а элементы управления все равно не могут привязаться к данным.
Эта ошибка чаще всего связана со следующими факторами:
Таблица.НовоеПоле), но не задали ему явный псевдоним с помощью оператора КАК, платформа генерирует для него техническое имя (например, Поле1). Когда вы пытаетесь обратиться к нему как Список.НовоеПоле, платформа его не находит. Всегда указывайте псевдонимы: Таблица.НовоеПоле КАК МойПсевдоним.Список, поэтому путь выглядит как Список.ИмяПоля. Если ваш реквизит называется иначе, путь нужно скорректировать.Как только мы корректно пропишем псевдонимы в измененном тексте запроса, привязка данных через ПутьКДанным пройдет без ошибок, и новые колонки отобразятся на форме.
Рассмотрим еще один, более простой подход, если структура полей известна заранее. Вы можете добавить все необходимые поля и расчеты в текст запроса динамического списка еще на этапе конфигуратора (в режиме конструктора запросов) и вывести соответствующие колонки на форму.
Вместо того чтобы программно добавлять колонки, мы будем управлять их видимостью или доступностью в зависимости от логики работы формы. Посмотрим на пример реализации:
Если УсловиеОтображения Тогда
Элементы.ИмяТаблицыНаФорме.ПодчиненныеЭлементы.ИмяКолонки.Видимость = Истина;
Иначе
Элементы.ИмяТаблицыНаФорме.ПодчиненныеЭлементы.ИмяКолонки.Видимость = Ложь;
КонецЕсли;
Этот подход избавляет от необходимости программно менять текст запроса и генерировать элементы формы, делая код более читаемым и предсказуемым.
Если вам все же необходимо модифицировать текст запроса динамического списка программно (например, при сложных настройках формы), не используйте функцию СтрЗаменить. В современных конфигурациях тексты запросов списков бывают очень объемными и сложными. Замена строк может привести к синтаксическим ошибкам.
Проанализируем более профессиональный инструмент — СхемаЗапроса. Он позволяет разобрать запрос на объекты и модифицировать его структуру безопасно.
Разберем по шагам, как это работает:
СхемаЗапроса.УстановитьТекстЗапроса(Список.ТекстЗапроса);Пакет = СхемаЗапроса.ПакетЗапросов[СхемаЗапроса.ПакетЗапросов.Количество() - 1];Список.ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();Использование схемы гарантирует, что запрос не будет поврежден, все запятые и операторы останутся на своих местах, а добавленные поля получат правильные имена для последующей генерации элементов формы.