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