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

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

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

Почему возникает ошибка при добавлении пути к данным?

Когда мы программно меняем свойство ТекстЗапроса, сама форма и её элементы управления уже инициализированы. Система ожидает, что все пути к данным (например, Список.МоеПоле) уже известны на этапе создания формы. Если поле не было «задекларировано» заранее или не подтянулось автоматически, платформа выдает ошибку. Более того, важную роль играют сохраненные пользовательские настройки, которые могут блокировать отображение новых полей.

Решение 1: Использование объекта СхемаЗапроса

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


СхемаЗапроса = Новый СхемаЗапроса;
СхемаЗапроса.УстановитьТекстЗапроса(СписокДокументыЗакупки.ТекстЗапроса);
ЗапросСхемы = СхемаЗапроса.ПакетЗапросов[0];
ОператорВыбрать = ЗапросСхемы.Операторы[0];

ВложенныйЗапрос = "ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ СведенияОФайлах.ВладелецФайла КАК ВладелецФайла ИЗ РегистрСведений.СведенияОФайлах КАК СведенияОФайлах";
ИсточникВложенныйЗапрос = ОператорВыбрать.Источники.Добавить(Тип("ВложенныйЗапросСхемыЗапроса"), "СведенияОФайлах");
ИсточникВложенныйЗапрос.Источник.Запрос.УстановитьТекстЗапроса(ВложенныйЗапрос);

ОператорВыбрать.ВыбираемыеПоля.Добавить("ВЫБОР КОГДА СведенияОФайлах.ВладелецФайла ЕСТЬ NULL ТОГДА 0 ИНАЧЕ 1 КОНЕЦ");
ЗапросСхемы.Колонки[ЗапросСхемы.Колонки.Количество()-1].Псевдоним = "ИндексКартинкиФайл";

СвойстваСписка = ОбщегоНазначения.СтруктураСвойствДинамическогоСписка;
СвойстваСписка.ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();
ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.СписокДокументыЗакупки, СвойстваСписка);

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

Решение 2: Добавление элемента управления через код

Если запрос готов, нам нужно правильно добавить ПолеФормы в таблицу. Сделаем это по шагам:

  1. Определяем родительский элемент (таблицу списка).
  2. Используем метод Элементы.Добавить() для создания новой колонки.
  3. Присваиваем свойство ПутьКДанным, соединяя имя списка и псевдоним поля.

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

Решение 3: Особенности работы с настройками

Часто проблема кроется не в коде, а в том, что ДинамическийСписок уже сохранил свои настройки в базе данных (в том числе колонки). Если вы видите ошибку, попробуйте следующий прием:

  1. Временно сбросьте настройки списка: в режиме 1С:Предприятие нажмите Еще -> Установить стандартные настройки.
  2. Убедитесь, что у пользователя есть права на таблицы, которые вы добавляете в запрос (если прав нет, поле может игнорироваться системой).
  3. Если поле «скрывается», проверьте свойство АвтоЗаполнениеДоступныхПолей.

Решение 4: Альтернатива через событие ПриПолученииДанныхНаСервере

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


&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
    Для Каждого ТекСтрока Из Строки Цикл
        // Дозаполняем данные, если нужно
        ТекСтрока.Значение.Данные.ИМЯ_КОЛОНКИ = ПолучитьЗначение(ТекСтрока.Значение.Ссылка);
    КонецЦикла;
КонецПроцедуры

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

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

← На главную