К статье
Практический материал

Разработка и Конфигурация · 12 мин

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

Как программно добавить динамический список на форму 1С 8.3: реквизиты, элементы формы, настройка запроса, отборы и типичные ошибки разработчика.

Динамический список в 1С — это реквизит формы с типом «ДинамическийСписок», который выводит данные из базы по запросу и автоматически обновляется при изменении данных. Обычно его добавляют через конфигуратор в визуальном редакторе формы, но в ряде задач требуется создать список программно: например, когда состав отображаемых данных зависит от настроек пользователя, права доступа или контекста вызова формы.

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

Важно понимать ограничение: динамический список, созданный полностью программно, не получает части «бесплатных» возможностей, которые платформа добавляет списку, объявленному в конфигураторе, — например, автоматической настройки командной панели с командами объекта. Часть функциональности придётся воспроизводить кодом. Ниже разобран рабочий подход, типичные ошибки и способы проверить результат.

Когда программное создание списка оправдано

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

Маршрут решения

Как выбрать действие

Состав колонок и таблиц известен заранее и не меняетсяДобавьте динамический список в конфигураторе — это быстрее и безопаснее
Запрос к данным зависит от параметров, роли пользователя или настроекСоздавайте список программно в ПриСозданииНаСервере
Нужно только изменить запрос уже существующего спискаНе пересоздавайте список — измените свойство ТекстЗапроса у существующего реквизита
Требуется несколько вариантов списка на одной формеСоздайте реквизиты в конфигураторе, а программно управляйте видимостью и настройками

Типичные случаи для программного подхода: универсальные формы-конструкторы, где пользователь сам выбирает отображаемый объект; формы, добавляемые через расширение конфигурации, где нельзя менять типовую форму; ситуации, когда текст запроса строится динамически по сложным правилам и его проще сформировать кодом, чем хранить в свойствах.

Шаг 1. Добавление реквизита формы типа «ДинамическийСписок»

Структуру реквизитов формы можно менять только методом ИзменитьРеквизиты() и только в серверном контексте. Метод принимает два массива: добавляемые и удаляемые реквизиты. Каждый новый реквизит описывается объектом Новый РеквизитФормы с именем, типом и, при необходимости, путём к владельцу.

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

ДобавляемыеРеквизиты = Новый Массив;

ОписаниеТипа = Новый ОписаниеТипов("ДинамическийСписок");

НовыйРеквизит = Новый РеквизитФормы("МойСписок", ОписаниеТипа, , "Список товаров");

ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);

ИзменитьРеквизиты(ДобавляемыеРеквизиты);

КонецПроцедуры

После вызова ИзменитьРеквизиты реквизит доступен как свойство формы: ЭтаФорма.МойСписок или через ЭтаФорма["МойСписок"]. Обращение до вызова метода приведёт к ошибке «Поле объекта не обнаружено», поэтому порядок строк в коде критичен.

Шаг 2. Настройка запроса и основной таблицы списка

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

ЭтаФорма.МойСписок.ПроизвольныйЗапрос = Истина;

ЭтаФорма.МойСписок.ОсновнаяТаблица = "Справочник.Номенклатура";

ЭтаФорма.МойСписок.ТекстЗапроса =

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка,

| Номенклатура.Код КАК Код,

| Номенклатура.Наименование КАК Наименование

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| НЕ Номенклатура.ПометкаУдаления";

ЭтаФорма.МойСписок.ДинамическоеСчитываниеДанных = Истина;

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

Шаг 3. Создание таблицы формы и колонок

Реквизит с данными сам по себе на форме не отобразится — нужен элемент формы типа ТаблицаФормы, у которого свойство ПутьКДанным указывает на созданный реквизит. Элементы добавляются через коллекцию ЭтаФорма.Элементы.Добавить() с указанием имени, типа и родителя.

ТаблицаФормы = ЭтаФорма.Элементы.Добавить("ТаблицаМойСписок", Тип("ТаблицаФормы"));

ТаблицаФормы.ПутьКДанным = "МойСписок";

ТаблицаФормы.ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы.Верх;

КолонкаКод = ЭтаФорма.Элементы.Добавить("КолонкаКод", Тип("ПолеФормы"), ТаблицаФормы);

КолонкаКод.ПутьКДанным = "МойСписок.Код";

КолонкаКод.Вид = ВидПоляФормы.ПолеВвода;

КолонкаНаименование = ЭтаФорма.Элементы.Добавить("КолонкаНаименование", Тип("ПолеФормы"), ТаблицаФормы);

КолонкаНаименование.ПутьКДанным = "МойСписок.Наименование";

КолонкаНаименование.Вид = ВидПоляФормы.ПолеВвода;

Обратите внимание на пути к данным колонок: они строятся как «ИмяРеквизита.ИмяПоляЗапроса». Если имя поля в запросе задано через псевдоним (КАК Наименование), в пути используется именно псевдоним. Ошибка в имени проявится не сразу — колонка просто останется пустой, что затрудняет диагностику.

Порядок действий
  1. 1
    В ПриСозданииНаСервере сформируйте массив с РеквизитФормы типа ДинамическийСписок и вызовите ИзменитьРеквизиты
  2. 2
    Установите реквизиту ПроизвольныйЗапрос, ОсновнуюТаблицу и ТекстЗапроса
  3. 3
    Добавьте элемент ТаблицаФормы с ПутьКДанным на реквизит
  4. 4
    Добавьте колонки типа ПолеФормы с путями к полям запроса
  5. 5
    Установите отборы и параметры запроса при необходимости
  6. 6
    Откройте форму в режиме предприятия и проверьте отображение данных

Шаг 4. Установка отборов, параметров и сортировки

После создания списка почти всегда требуется ограничить выборку. Отборы добавляются в коллекцию Отбор списка, параметры запроса — через Параметры. Работа с отбором программно устроена так же, как у настроек компоновки данных: сначала находится или создаётся элемент отбора, затем задаются вид сравнения и значение.

ЭлементОтбора = ЭтаФорма.МойСписок.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ПометкаУдаления");

ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

ЭлементОтбора.ПравоеЗначение = Ложь;

ЭлементОтбора.Использование = Истина;

ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;

Режим отображения Недоступный скрывает отбор от пользователя — он не сможет его отключить через настройки списка. Если же отбор должен быть видимым и редактируемым, используйте обычный режим. Сортировку задают аналогично через Порядок списка, либо прямо в тексте запроса конструкцией УПОРЯДОЧИТЬ ПО — второй вариант надёжнее для фиксированного порядка.

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

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

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

Контрольные точки

Как проверить результат

Данные в таблице формы
Норма

Строки отображаются, колонки заполнены значениями из запроса

Тревожный признак

Таблица пустая или колонки без данных — проверьте ПутьКДанным и псевдонимы полей

Открытие элемента двойным щелчком
Норма

Открывается форма элемента основной таблицы

Тревожный признак

Ничего не происходит — в запросе нет поля Ссылка или не задана ОсновнаяТаблица

Прокрутка большого списка
Норма

Данные подгружаются порциями, форма не зависает

Тревожный признак

Форма долго открывается — не включено ДинамическоеСчитываниеДанных

Отбор
Норма

В списке только строки, удовлетворяющие условию

Тревожный признак

Отбор не работает — проверьте Использование = Истина и имя поля в ЛевоеЗначение

Типичные ошибки
01
Обращение к реквизиту до вызова ИзменитьРеквизиты — ошибка «Поле объекта не обнаружено»
02
Вызов ИзменитьРеквизиты в клиентском обработчике — метод недоступен на клиенте, код падает с ошибкой
03
Несовпадение ПутьКДанным колонки с псевдонимом поля запроса — колонка отображается пустой без сообщений об ошибке
04
Отсутствие поля Ссылка в произвольном запросе — список теряет интерактивность, нельзя открыть элемент
05
Пересоздание элементов отбора при каждом изменении условия — накопление дублирующих отборов и неверная фильтрация
06
Добавление элементов формы с уже занятыми именами — исключение при повторном вызове кода

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

Альтернатива: изменение существующего списка вместо создания нового

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

Подмена текста запроса у существующего списка выполняется одним присваиванием в ПриСозданииНаСервере, при этом важно сохранить в новом запросе все поля, на которые ссылаются существующие колонки таблицы формы, — иначе они перестанут отображать данные. Этот вариант предпочтителен всегда, когда структура формы известна заранее.

Итог

Что важно запомнить

Программное создание динамического списка — это последовательность: ИзменитьРеквизиты с типом ДинамическийСписок, настройка запроса и основной таблицы, добавление ТаблицаФормы и колонок с корректными путями к данным. Всё выполняется на сервере в ПриСозданииНаСервере. Если список уже есть на форме, предпочтительнее менять его свойства, а не создавать новый.

Частые вопросы

Можно ли добавить динамический список на форму на клиенте?

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

Почему колонки таблицы отображаются пустыми, хотя запрос возвращает данные?

Чаще всего не совпадает ПутьКДанным колонки с псевдонимом поля в запросе. Путь должен иметь вид «ИмяРеквизита.ПсевдонимПоля». Проверьте также, что сама таблица формы связана с правильным реквизитом и что текст запроса не содержит ошибок — их видно в консоли запросов при отладке.

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

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

Почему в программно созданном списке не открывается элемент двойным щелчком?

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

Можно ли добавить динамический список на форму через расширение конфигурации?

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

Что выбрать: программное создание списка или изменение существующего?

Если список уже добавлен на форму в конфигураторе, изменяйте его свойства — ТекстЗапроса, отборы, параметры. Программное создание с нуля оправдано, когда состав данных заранее неизвестен или форма строится полностью динамически.