Разработка и Конфигурация · 12 мин
Как программно добавить динамический список на форму в 1С
Как программно добавить динамический список на форму 1С 8.3: реквизиты, элементы формы, настройка запроса, отборы и типичные ошибки разработчика.
Динамический список в 1С — это реквизит формы с типом «ДинамическийСписок», который выводит данные из базы по запросу и автоматически обновляется при изменении данных. Обычно его добавляют через конфигуратор в визуальном редакторе формы, но в ряде задач требуется создать список программно: например, когда состав отображаемых данных зависит от настроек пользователя, права доступа или контекста вызова формы.
Программное создание динамического списка состоит из трёх этапов: добавление реквизита формы нужного типа, создание элемента формы (таблицы), связанного с этим реквизитом, и настройка самого списка — текста запроса, основной таблицы, отборов и колонок. Все эти действия выполняются в модуле формы, чаще всего в обработчике ПриСозданииНаСервере, потому что изменение структуры реквизитов формы возможно только на сервере.
Важно понимать ограничение: динамический список, созданный полностью программно, не получает части «бесплатных» возможностей, которые платформа добавляет списку, объявленному в конфигураторе, — например, автоматической настройки командной панели с командами объекта. Часть функциональности придётся воспроизводить кодом. Ниже разобран рабочий подход, типичные ошибки и способы проверить результат.
Когда программное создание списка оправдано
Не каждая задача требует программного подхода. Если список фиксированный и известен на этапе разработки, проще и надёжнее добавить его в конфигураторе — платформа сама создаст реквизит, таблицу формы, командную панель и стандартные команды. Программное создание оправдано в конкретных сценариях.
Как выбрать действие
Типичные случаи для программного подхода: универсальные формы-конструкторы, где пользователь сам выбирает отображаемый объект; формы, добавляемые через расширение конфигурации, где нельзя менять типовую форму; ситуации, когда текст запроса строится динамически по сложным правилам и его проще сформировать кодом, чем хранить в свойствах.
Шаг 1. Добавление реквизита формы типа «ДинамическийСписок»
Структуру реквизитов формы можно менять только методом ИзменитьРеквизиты() и только в серверном контексте. Метод принимает два массива: добавляемые и удаляемые реквизиты. Каждый новый реквизит описывается объектом Новый РеквизитФормы с именем, типом и, при необходимости, путём к владельцу.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ДобавляемыеРеквизиты = Новый Массив;
ОписаниеТипа = Новый ОписаниеТипов("ДинамическийСписок");
НовыйРеквизит = Новый РеквизитФормы("МойСписок", ОписаниеТипа, , "Список товаров");
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
ИзменитьРеквизиты(ДобавляемыеРеквизиты);
КонецПроцедуры
После вызова ИзменитьРеквизиты реквизит доступен как свойство формы: ЭтаФорма.МойСписок или через ЭтаФорма["МойСписок"]. Обращение до вызова метода приведёт к ошибке «Поле объекта не обнаружено», поэтому порядок строк в коде критичен.
Шаг 2. Настройка запроса и основной таблицы списка
Реквизит создан, но пока он пуст: у него нет ни источника данных, ни настроек. Динамический список требует указать либо основную таблицу (тогда платформа сама построит простой запрос), либо произвольный текст запроса. Для произвольного запроса свойство ПроизвольныйЗапрос нужно установить в Истина.
ЭтаФорма.МойСписок.ПроизвольныйЗапрос = Истина;
ЭтаФорма.МойСписок.ОсновнаяТаблица = "Справочник.Номенклатура";
ЭтаФорма.МойСписок.ТекстЗапроса =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления";
ЭтаФорма.МойСписок.ДинамическоеСчитываниеДанных = Истина;
Несколько важных правил. Поле Ссылка в выборке обязательно, если список должен поддерживать интерактивные действия — открытие элемента, копирование, пометку удаления. Без основной таблицы и поля ссылки список будет работать в режиме «только просмотр». Свойство ДинамическоеСчитываниеДанных включает порционную подгрузку данных при прокрутке — без него большие таблицы будут загружаться целиком, что замедлит открытие формы.
Шаг 3. Создание таблицы формы и колонок
Реквизит с данными сам по себе на форме не отобразится — нужен элемент формы типа ТаблицаФормы, у которого свойство ПутьКДанным указывает на созданный реквизит. Элементы добавляются через коллекцию ЭтаФорма.Элементы.Добавить() с указанием имени, типа и родителя.
ТаблицаФормы = ЭтаФорма.Элементы.Добавить("ТаблицаМойСписок", Тип("ТаблицаФормы"));
ТаблицаФормы.ПутьКДанным = "МойСписок";
ТаблицаФормы.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Верх;
КолонкаКод = ЭтаФорма.Элементы.Добавить("КолонкаКод", Тип("ПолеФормы"), ТаблицаФормы);
КолонкаКод.ПутьКДанным = "МойСписок.Код";
КолонкаКод.Вид = ВидПоляФормы.ПолеВвода;
КолонкаНаименование = ЭтаФорма.Элементы.Добавить("КолонкаНаименование", Тип("ПолеФормы"), ТаблицаФормы);
КолонкаНаименование.ПутьКДанным = "МойСписок.Наименование";
КолонкаНаименование.Вид = ВидПоляФормы.ПолеВвода;
Обратите внимание на пути к данным колонок: они строятся как «ИмяРеквизита.ИмяПоляЗапроса». Если имя поля в запросе задано через псевдоним (КАК Наименование), в пути используется именно псевдоним. Ошибка в имени проявится не сразу — колонка просто останется пустой, что затрудняет диагностику.
- 1В ПриСозданииНаСервере сформируйте массив с РеквизитФормы типа ДинамическийСписок и вызовите ИзменитьРеквизиты
- 2Установите реквизиту ПроизвольныйЗапрос, ОсновнуюТаблицу и ТекстЗапроса
- 3Добавьте элемент ТаблицаФормы с ПутьКДанным на реквизит
- 4Добавьте колонки типа ПолеФормы с путями к полям запроса
- 5Установите отборы и параметры запроса при необходимости
- 6Откройте форму в режиме предприятия и проверьте отображение данных
Шаг 4. Установка отборов, параметров и сортировки
После создания списка почти всегда требуется ограничить выборку. Отборы добавляются в коллекцию Отбор списка, параметры запроса — через Параметры. Работа с отбором программно устроена так же, как у настроек компоновки данных: сначала находится или создаётся элемент отбора, затем задаются вид сравнения и значение.
ЭлементОтбора = ЭтаФорма.МойСписок.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПометкаУдаления");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Ложь;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
Режим отображения Недоступный скрывает отбор от пользователя — он не сможет его отключить через настройки списка. Если же отбор должен быть видимым и редактируемым, используйте обычный режим. Сортировку задают аналогично через Порядок списка, либо прямо в тексте запроса конструкцией УПОРЯДОЧИТЬ ПО — второй вариант надёжнее для фиксированного порядка.
Если отбор нужно менять после открытия формы (например, по нажатию кнопки), не пересоздавайте элементы отбора заново — найдите существующий элемент в коллекции Отбор.Элементы и измените его ПравоеЗначение и Использование. Постоянное добавление новых элементов приводит к накоплению дублей и непредсказуемой фильтрации.
Проверка результата и типичные ошибки
После открытия формы проверьте не только факт отображения данных, но и поведение списка: прокрутку при большом объёме, открытие элемента двойным щелчком, работу отборов. Часть ошибок проявляется только при интерактивных действиях.
Как проверить результат
Строки отображаются, колонки заполнены значениями из запроса
Таблица пустая или колонки без данных — проверьте ПутьКДанным и псевдонимы полей
Открывается форма элемента основной таблицы
Ничего не происходит — в запросе нет поля Ссылка или не задана ОсновнаяТаблица
Данные подгружаются порциями, форма не зависает
Форма долго открывается — не включено ДинамическоеСчитываниеДанных
В списке только строки, удовлетворяющие условию
Отбор не работает — проверьте Использование = Истина и имя поля в ЛевоеЗначение
Отдельная группа проблем связана с расширениями конфигурации. Если форма заимствована из типовой конфигурации и изменяется расширением, программное добавление реквизитов возможно, но требует осторожности при обновлении типовой: проверяйте, что имена добавляемых элементов не пересекаются с новыми элементами поставщика.
Альтернатива: изменение существующего списка вместо создания нового
Во многих задачах создавать список с нуля не нужно. Если на форме уже есть динамический список, добавленный в конфигураторе, достаточно программно изменить его свойства: подменить ТекстЗапроса, добавить отборы или параметры. Такой подход сохраняет все стандартные команды, настройки колонок и поведение платформы, а код становится заметно короче и устойчивее к обновлениям.
Подмена текста запроса у существующего списка выполняется одним присваиванием в ПриСозданииНаСервере, при этом важно сохранить в новом запросе все поля, на которые ссылаются существующие колонки таблицы формы, — иначе они перестанут отображать данные. Этот вариант предпочтителен всегда, когда структура формы известна заранее.
Что важно запомнить
Программное создание динамического списка — это последовательность: ИзменитьРеквизиты с типом ДинамическийСписок, настройка запроса и основной таблицы, добавление ТаблицаФормы и колонок с корректными путями к данным. Всё выполняется на сервере в ПриСозданииНаСервере. Если список уже есть на форме, предпочтительнее менять его свойства, а не создавать новый.
Частые вопросы
Можно ли добавить динамический список на форму на клиенте?
Нет. Изменение состава реквизитов формы методом ИзменитьРеквизиты доступно только в серверном контексте. Все действия по созданию реквизита и элементов выполняют в обработчиках с директивой &НаСервере, чаще всего в ПриСозданииНаСервере.
Почему колонки таблицы отображаются пустыми, хотя запрос возвращает данные?
Чаще всего не совпадает ПутьКДанным колонки с псевдонимом поля в запросе. Путь должен иметь вид «ИмяРеквизита.ПсевдонимПоля». Проверьте также, что сама таблица формы связана с правильным реквизитом и что текст запроса не содержит ошибок — их видно в консоли запросов при отладке.
Как сделать, чтобы пользователь не мог снять программно установленный отбор?
У элемента отбора установите свойство РежимОтображения в значение Недоступный. Такой отбор не появится в пользовательских настройках списка, и отключить его стандартными средствами будет нельзя.
Почему в программно созданном списке не открывается элемент двойным щелчком?
Для интерактивных действий списку нужны основная таблица (свойство ОсновнаяТаблица) и поле Ссылка в выборке запроса. Если запрос строится по соединению таблиц без однозначной ссылки на объект, платформа переводит список в режим просмотра.
Можно ли добавить динамический список на форму через расширение конфигурации?
Да, программное добавление реквизитов и элементов работает и в модулях форм расширений. Используйте уникальные префиксы в именах реквизитов и элементов, чтобы избежать конфликтов с типовой формой при её обновлении поставщиком.
Что выбрать: программное создание списка или изменение существующего?
Если список уже добавлен на форму в конфигураторе, изменяйте его свойства — ТекстЗапроса, отборы, параметры. Программное создание с нуля оправдано, когда состав данных заранее неизвестен или форма строится полностью динамически.