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