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

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

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

Анализ проблемы: почему стандартный подход не всегда работает

Когда тип реквизита однозначен (например, только ДокументСсылка.РеализацияТоваровУслуг), мы можем легко перехватить событие НачалоВыбора, отменить стандартную обработку и открыть форму с нужными нам параметрами. Однако при составном типе отмена стандартной обработки в самом начале блокирует появление системного диалога выбора типа. Нам необходимо либо имитировать этот диалог, либо "вклиниться" в процесс уже после того, как тип был определен пользователем. Рассмотрим, как это реализовать на практике.

Способ 1: Использование списка значений для выбора типа

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

Рассмотрим пример реализации в обработчике начала выбора:


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

&НаКлиенте
Процедура ПослеВыбораТипа(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
    
    Если ВыбранныйЭлемент = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ТипДокумента = ВыбранныйЭлемент.Значение;
    ОткрытьНужнуюФормуВыбора(ТипДокумента);
    
КонецПроцедуры

В процедуре ОткрытьНужнуюФормуВыбора мы уже можем сформировать структуру отборов и передать её в параметры открытия формы. Это дает нам гибкость: для каждого типа документа можно задать свои уникальные условия фильтрации.

Способ 2: Перехват после стандартного выбора типа

Более изящный способ — позволить платформе самой показать окно выбора типа, но перехватить управление сразу после этого. Для этого используется событие ОбработкаВыбора у элемента формы. Когда пользователь выбирает тип в пустом поле, 1С генерирует событие ОбработкаВыбора, где в качестве ВыбранноеЗначение передается сам объект типа (Тип).

Проанализируем алгоритм действий:

  1. В НачалоВыбора проверяем, заполнено ли поле. Если заполнено — отменяем стандартную обработку и открываем форму выбора текущего типа с отборами.
  2. Если поле пустое — ничего не делаем, позволяя платформе показать выбор типов.
  3. В ОбработкаВыбора ловим момент, когда выбран тип, отменяем стандартную обработку и открываем свою форму.

Пример программного кода:


&НаКлиенте
Процедура ДокументНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    Если ЗначениеЗаполнено(Объект.Документ) Тогда
        СтандартнаяОбработка = Ложь;
        // Если тип уже выбран, сразу открываем форму выбора с отбором
        ОткрытьФормуВыбораСОтбором(Объект.Документ, Элемент);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Процедура ДокументОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
    
    // Если пользователь выбрал тип в стандартном окне выбора типов
    Если ТипЗнч(ВыбранноеЗначение) = Тип("Тип") Тогда
        СтандартнаяОбработка = Ложь;
        
        // Создаем пустое значение выбранного типа, чтобы знать, форму какого объекта открывать
        МассивТипов = Новый Массив;
        МассивТипов.Добавить(ВыбранноеЗначение);
        ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
        ПустоеЗначениеТипа = ОписаниеТипов.ПривестиЗначение();
        
        ОткрытьФормуВыбораСОтбором(ПустоеЗначениеТипа, Элемент);
    КонецЕсли;
    
КонецПроцедуры

Программное открытие формы с динамическими отборами

Теперь разберем самое важное — как именно открывать форму и накладывать отборы на ДинамическийСписок. Мы используем функцию ОткрытьФорму, передавая в неё структуру параметров.


&НаКлиенте
Процедура ОткрытьФормуВыбораСОтбором(ЗначениеДокумента, УзелЭлемента)
    
    ПараметрыФормы = Новый Структура;
    
    // Формируем отбор. Ключ - имя реквизита в документе, значение - условие
    Отбор = Новый Структура;
    Отбор.Вставить("Проведен", Истина);
    Отбор.Вставить("Организация", Объект.Организация);
    
    // Добавляем отбор в параметры
    ПараметрыФормы.Вставить("Отбор", Отбор);
    
    // Определяем имя формы метаданных
    ИмяФормы = ПолучитьИмяФормыВыбораНаСервере(ЗначениеДокумента);
    
    // Открываем форму
    ОткрытьФорму(ИмяФормы, ПараметрыФормы, УзелЭлемента);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьИмяФормыВыбораНаСервере(СсылкаИлиЗначение)
    Возврат СсылкаИлиЗначение.Метаданные().ПолноеИмя() + ".ФормаВыбора";
КонецФункции

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

Улучшение пользовательского интерфейса

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

Пример программной настройки элемента (если форма создается динамически или нужно изменить поведение в процессе работы):


ЭлементПоле = Элементы.Документ;
ЭлементПоле.КнопкаОчистки = Истина;
ЭлементПоле.КнопкаВыбораТипа = Истина;

Альтернатива: Связи параметров выбора

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

Заключение

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

← На главную