Как перенести подбор договоров контрагента в список значений из управляемой формы в обычную в 1С?

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

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

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

В чем заключаются ограничения обычных форм?

Проанализируем основные причины, почему привычные механизмы управляемого приложения не работают в обычном режиме:

  1. Отсутствие свойства Связь по владельцу для списков значений. В обычных формах автосвязь работает только для элементов типа ПолеВвода, связанных со ссылочным реквизитом единичного типа (один договор). На элемент типа ПолеСписка или реквизит СписокЗначений этот механизм не распространяется.
  2. Отсутствие объекта ПараметрыВыбора. Механизм передачи параметров через фиксированные массивы и структуру параметров выбора появился только в управляемом интерфейсе.
  3. Системный диалог списка значений. При нажатии кнопки подбора в стандартном окне списка значений платформа открывает системный диалог, у которого нет программных событий для перехвата отбора.

Способ 1. Перехват события НачалоВыбора с вызовом формы выбора справочника

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

Рассмотрим пошаговый алгоритм реализации:

  1. Размещаем на форме реквизит Контрагенты (тип СправочникСсылка.Контрагенты) и реквизит Договор (тип СписокЗначений).
  2. Для элемента формы, связанного со списком договоров, назначаем обработчик события НачалоВыбора.
  3. В обработчике отменяем стандартную обработку (СтандартнаяОбработка = Ложь), создаем форму выбора справочника, устанавливаем режим множественного выбора и фильтр по владельцу.

Разберем пример кода для событии НачалоВыбора:


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

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

Способ 2. Подбор без закрытия формы выбора (подбор по клику)

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

Рассмотрим, как настроить данный режим программно:


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

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

В самой основной форме обработка выбранных значений происходит в стандартном обработчике события ОбработкаВыбора:


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

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

Способ 3. Использование промежуточной формы подбора во внешней обработке

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

Плюсы этого подхода:

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

Итоги и рекомендации

При переводе функционала с управляемых форм на обычные помните, что обычный интерфейс требует более явного программирования поведения элементов. Для решения задачи подбора нескольких договоров контрагента наиболее оптимальным является Способ 1 (модальное открытие с множественным выбором) либо Способ 2 (открытие формы без закрытия при выборе). Это позволяет сохранить стандартное поведение программы и обеспечить удобную работу пользователей без необходимости доработки объектов самой конфигурации.

← На главную