Как передать параметры в форму выбора с динамическим списком и настроить иерархическое отображение в 1С 8.3

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

При разработке конфигураций на платформе 1С:Предприятие 8.3 (Управляемые формы) часто возникает задача контекстного ограничения списка выбора. Например, при заполнении табличной части документа перемещения оборудования необходимо предложить пользователю только те позиции, которые на дату документа физически находятся на складе-отправителе (старом адресе). Для реализации этого разработчики прибегают к созданию кастомных форм выбора с динамическими списками на основе произвольных запросов. Однако на этом пути легко столкнуться с неочевидными ошибками: от сообщения Не задано значение параметра до полностью пустой формы в режиме иерархического просмотра.

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

Выясняем причину ошибок и выстраиваем архитектуру решения

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

  1. Ошибка «Не задано значение параметра»: Возникает из-за того, что в произвольном запросе динамического списка объявлены параметры (например, &АдресБазы и &Период), но при открытии формы система не получает их значений. Платформа пытается выполнить запрос для отображения списка на форме, не находит инициализированных параметров и аварийно завершает работу.
  2. Пустой список при выборе значения: Если динамический список построен по произвольному запросу, но в его свойствах не заполнено поле Основная таблица, платформа не сможет определить, какую именно ссылку пользователь выбрал в форме. В результате выбор не возвращается в строку табличной части документа.
  3. Пустое дерево или пустой иерархический список: В режиме просмотра «Дерево» или «Иерархический список» группы (папки) справочника исчезают, а вместе с ними пропадают и элементы. Это происходит потому, что в регистре сведений остатки или местоположение хранятся только для конечных элементов (оборудования). У групп справочника записей в регистре нет. При жестком левом соединении и фильтрации в секции ГДЕ все группы отсекаются как NULL, разрушая иерархические связи динамического списка.

Решим эти проблемы по шагам, реализовав красивое и надежное решение без лишнего кода.

Шаг 1. Настройка связей параметров выбора в форме документа

Для того чтобы форма выбора вообще «узнала» о контексте (какой адрес базы и какую дату мы выбрали в документе), воспользуемся штатным механизмом платформы — Связи параметров выбора. Это позволяет передавать данные динамически, реагируя на изменение реквизитов в реальном времени.

Разберем настройку по шагам:

  1. Откроем форму документа (например, ПеремещениеОборудования) и перейдем к свойствам реквизита табличной части (поле ввода Оборудование).
  2. В палитре свойств найдем строку Связи параметров выбора.
  3. Добавим две связи, заполнив их следующим образом:
    • Имя параметра: ДатаСреза, Реквизит: Объект.Дата
    • Имя параметра: АдресБазы, Реквизит: Объект.СтарыйАдрес
  4. В свойстве ФормаВыбора этого же поля ввода укажем нашу кастомную форму выбора (например, ФормаВыбораТест).

Важное примечание: Обратите внимание, что мы передаем чистые имена параметров (ДатаСреза, АдресБазы), а не стандартный префикс Отбор.. Это связано с тем, что параметры будут использоваться внутри произвольного запроса динамического списка, а не в качестве простых условий сравнения компоновки данных.

Шаг 2. Оптимизация и исправление запроса динамического списка

Перейдем в форму выбора справочника Оборудование. Нам необходимо настроить динамический список так, чтобы он базировался на справочнике, но получал актуальный срез последних из регистра сведений Базировка.

Откроем свойства динамического списка Список:

  1. Установим флаг Произвольный запрос.
  2. В поле Основная таблица обязательно выберем Справочник.Оборудование. Это критически важно для корректного возврата выбранного элемента в документ.
  3. Нажмем кнопку Открыть для редактирования текста запроса и вставим следующий оптимизированный код:

ВЫБРАТЬ
    СправочникОборудование.Ссылка КАК Ссылка,
    СправочникОборудование.ПометкаУдаления КАК ПометкаУдаления,
    СправочникОборудование.Родитель КАК Родитель,
    СправочникОборудование.ЭтоГруппа КАК ЭтоГруппа,
    СправочникОборудование.Код КАК Код,
    СправочникОборудование.Наименование КАК Наименование,
    СправочникОборудование.ИнвентарныйНомер КАК ИнвентарныйНомер,
    БазировкаСрезПоследних.АдресБазы КАК АдресБазы,
    БазировкаСрезПоследних.Период КАК Период
ИЗ
    Справочник.Оборудование КАК СправочникОборудование
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.Базировка.СрезПоследних(&ДатаСреза, ) КАК БазировкаСрезПоследних
        ПО СправочникОборудование.Ссылка = БазировкаСрезПоследних.Оборудование
ГДЕ
    (БазировкаСрезПоследних.АдресБазы = &АдресБазы ИЛИ СправочникОборудование.ЭтоГруппа)

Рассмотрим подробнее логику этого запроса. Мы берем за основу таблицу справочника и левым соединением подключаем виртуальную таблицу СрезПоследних регистра сведений. В параметрах среза последних мы используем &ДатаСреза — это позволит получить состояние оборудования именно на момент создания документа. В секции ГДЕ мы накладываем условие отбора по переданному адресу базы, но обязательно добавляем условие ИЛИ СправочникОборудование.ЭтоГруппа. Это ключевой момент, который позволит сохранить структуру папок при иерархическом отображении списка.

Шаг 3. Инициализация параметров динамического списка на сервере

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

Откроем модуль формы выбора и пропишем следующий отказоустойчивый алгоритм:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем наличие переданного параметра "АдресБазы"
    Если Параметры.Свойство("АдресБазы") И ЗначениеЗаполнено(Параметры.АдресБазы) Тогда
        Список.Параметры.УстановитьЗначениеПараметра("АдресБазы", Параметры.АдресБазы);
    Иначе
        // Задаем пустую ссылку, чтобы избежать системной ошибки "Не задано значение параметра"
        Список.Параметры.УстановитьЗначениеПараметра("АдресБазы", Справочники.Базы.ПустаяСсылка());
    EndЕсли;
    
    // Проверяем наличие переданного параметра "ДатаСреза" (период среза последних)
    Если Параметры.Свойство("ДатаСреза") И ЗначениеЗаполнено(Параметры.ДатаСреза) Тогда
        Список.Параметры.УстановитьЗначениеПараметра("ДатаСреза", Параметры.ДатаСреза);
    Иначе
        // Если дата документа не задана или пустая, берем текущую дату системы
        Список.Параметры.УстановитьЗначениеПараметра("ДатаСреза", ТекущаяДата());
    КонецЕсли;
    
КонецПроцедуры

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

Шаг 4. Настройка корректного отображения иерархии (Режимы «Дерево» и «Список»)

Теперь разберем, как ведет себя система при различных режимах просмотра динамического списка:

Вариант А. Сохранение полной иерархии групп.
Благодаря добавленной строке ИЛИ СправочникОборудование.ЭтоГруппа в запросе динамического списка, при открытии формы в режиме «Дерево» или «Иерархический список» пользователь будет видеть всю структуру папок справочника. При этом внутри папок будут отображаться только те элементы оборудования, которые действительно находятся на выбранной базе на указанную дату. Пустые папки будут отображаться как пустые группы.

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Настройка параметров списка (код из предыдущего шага)
    // ...
    
    // Принудительно устанавливаем плоский режим просмотра "Список"
    Элементы.Список.РежимПросмотра = РежимПросмотраСписка.Список;
    
    // Запрещаем пользователю переключать его обратно в дерево, чтобы избежать путаницы
    Элементы.Список.РазрешитьИзменениеРежимаПросмотра = Ложь;
    
КонецПроцедуры

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

Резюме

Для корректного отбора элементов справочника по данным регистра сведений в управляемых формах 1С 8.3 необходимо соблюдать четыре основных правила:

← На главную