Работа с полями ввода, имеющими составной тип данных (например, когда реквизит может принимать значения нескольких видов документов), в 1С:Предприятие 8.3 имеет свои особенности. Основная сложность заключается в том, что стандартный процесс выбора в таких полях состоит из двух этапов: сначала система предлагает пользователю выбрать тип данных, а затем открывает форму выбора для этого типа. Если мы просто установим СтандартнаяОбработка = Ложь в событии НачалоВыбора, то окно выбора типа не появится, и нам придется реализовывать всю логику вручную. В этой статье мы разберем несколько эффективных способов решения этой задачи.
Когда тип реквизита однозначен (например, только ДокументСсылка.РеализацияТоваровУслуг), мы можем легко перехватить событие НачалоВыбора, отменить стандартную обработку и открыть форму с нужными нам параметрами. Однако при составном типе отмена стандартной обработки в самом начале блокирует появление системного диалога выбора типа. Нам необходимо либо имитировать этот диалог, либо "вклиниться" в процесс уже после того, как тип был определен пользователем. Рассмотрим, как это реализовать на практике.
Этот метод подходит, если вы хотите полностью контролировать процесс с самого начала. Мы сами создаем список доступных типов, показываем его пользователю и, исходя из выбора, открываем нужную форму.
Рассмотрим пример реализации в обработчике начала выбора:
&НаКлиенте
Процедура ДокументНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь; // Полностью берем управление на себя
СписокТипов = Новый СписокЗначений;
СписокТипов.Добавить(Тип("ДокументСсылка.РеализацияТоваровУслуг"), "Реализация товаров");
СписокТипов.Добавить(Тип("ДокументСсылка.ОтчетОРозничныхПродажах"), "Отчет о продажах");
СписокТипов.Добавить(Тип("ДокументСсылка.ВозвратТоваровПоставщику"), "Возврат поставщику");
// Показываем пользователю список для выбора типа
СписокТипов.ПоказатьВыборЭлемента(Новый ОписаниеОповещения("ПослеВыбораТипа", ЭтотОбъект), "Выберите тип документа");
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораТипа(ВыбранныйЭлемент, ДополнительныеПараметры) Экспорт
Если ВыбранныйЭлемент = Неопределено Тогда
Возврат;
КонецЕсли;
ТипДокумента = ВыбранныйЭлемент.Значение;
ОткрытьНужнуюФормуВыбора(ТипДокумента);
КонецПроцедуры
В процедуре ОткрытьНужнуюФормуВыбора мы уже можем сформировать структуру отборов и передать её в параметры открытия формы. Это дает нам гибкость: для каждого типа документа можно задать свои уникальные условия фильтрации.
Более изящный способ — позволить платформе самой показать окно выбора типа, но перехватить управление сразу после этого. Для этого используется событие ОбработкаВыбора у элемента формы. Когда пользователь выбирает тип в пустом поле, 1С генерирует событие ОбработкаВыбора, где в качестве ВыбранноеЗначение передается сам объект типа (Тип).
Проанализируем алгоритм действий:
НачалоВыбора проверяем, заполнено ли поле. Если заполнено — отменяем стандартную обработку и открываем форму выбора текущего типа с отборами.ОбработкаВыбора ловим момент, когда выбран тип, отменяем стандартную обработку и открываем свою форму.Пример программного кода:
&НаКлиенте
Процедура ДокументНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
Если ЗначениеЗаполнено(Объект.Документ) Тогда
СтандартнаяОбработка = Ложь;
// Если тип уже выбран, сразу открываем форму выбора с отбором
ОткрытьФормуВыбораСОтбором(Объект.Документ, Элемент);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ДокументОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
// Если пользователь выбрал тип в стандартном окне выбора типов
Если ТипЗнч(ВыбранноеЗначение) = Тип("Тип") Тогда
СтандартнаяОбработка = Ложь;
// Создаем пустое значение выбранного типа, чтобы знать, форму какого объекта открывать
МассивТипов = Новый Массив;
МассивТипов.Добавить(ВыбранноеЗначение);
ОписаниеТипов = Новый ОписаниеТипов(МассивТипов);
ПустоеЗначениеТипа = ОписаниеТипов.ПривестиЗначение();
ОткрытьФормуВыбораСОтбором(ПустоеЗначениеТипа, Элемент);
КонецЕсли;
КонецПроцедуры
Теперь разберем самое важное — как именно открывать форму и накладывать отборы на ДинамическийСписок. Мы используем функцию ОткрытьФорму, передавая в неё структуру параметров.
&НаКлиенте
Процедура ОткрытьФормуВыбораСОтбором(ЗначениеДокумента, УзелЭлемента)
ПараметрыФормы = Новый Структура;
// Формируем отбор. Ключ - имя реквизита в документе, значение - условие
Отбор = Новый Структура;
Отбор.Вставить("Проведен", Истина);
Отбор.Вставить("Организация", Объект.Организация);
// Добавляем отбор в параметры
ПараметрыФормы.Вставить("Отбор", Отбор);
// Определяем имя формы метаданных
ИмяФормы = ПолучитьИмяФормыВыбораНаСервере(ЗначениеДокумента);
// Открываем форму
ОткрытьФорму(ИмяФормы, ПараметрыФормы, УзелЭлемента);
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьИмяФормыВыбораНаСервере(СсылкаИлиЗначение)
Возврат СсылкаИлиЗначение.Метаданные().ПолноеИмя() + ".ФормаВыбора";
КонецФункции
Важный момент: Передача отбора через структуру Параметры.Отбор работает только для простых сравнений на "равенство". Если вам нужны сложные условия (например, период дат или вхождение в список), такие отборы следует устанавливать в процедуре ПриСозданииНаСервере самой открываемой формы, либо использовать механизм СвязиПараметровВыбора. Для реализации гибких и нестандартных отборов в таких списках подойдёт практическое руководство по системе настроек динамического списка.
При работе с составными типами пользователи часто сталкиваются с тем, что после выбора одного типа документа им трудно переключиться на другой. Для решения этой проблемы рекомендуется настроить дополнительные свойства элемента формы:
КнопкаОчистки = Истина. Это позволит пользователю быстро обнулить поле и при следующем нажатии кнопки выбора снова увидеть диалог выбора типов.КнопкаВыбораТипа = Истина добавит кнопку "Т" рядом с полем. Это дает возможность сменить тип без предварительной очистки значения.Пример программной настройки элемента (если форма создается динамически или нужно изменить поведение в процессе работы):
ЭлементПоле = Элементы.Документ;
ЭлементПоле.КнопкаОчистки = Истина;
ЭлементПоле.КнопкаВыбораТипа = Истина;
Проанализируем ситуацию, когда нам не хочется писать много кода в обработчиках. Если отбор всегда идет по одному и тому же реквизиту (например, по Организации), который присутствует во всех документах составного типа, можно воспользоваться свойством Связи параметров выбора (ChoiceParameterLinks). В свойствах реквизита на форме укажите связь: Отбор.Организация(Организация). В этом случае 1С автоматически пробросит фильтр во все открываемые формы выбора, независимо от типа документа, без необходимости отключать стандартную обработку.
Мы рассмотрели различные подходы к реализации качественного выбора в полях с составным типом данных. Наиболее универсальным является комбинированный подход: использование стандартного выбора типов с перехватом события ОбработкаВыбора для наложения специфических фильтров. Это сохраняет привычный пользователю интерфейс системы и при этом дает разработчику полный контроль над данными, отображаемыми в списках. Не забывайте также об использовании КнопкиОчистки, чтобы сделать работу с формой максимально удобной.