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