Как передать параметр в форму выбора для реквизита с составным типом данных в 1С

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

В разработке на платформе 1С:Предприятие 8 часто возникает задача ограничить выбор в поле или передать дополнительные данные в открывающуюся форму. Если реквизит имеет простой тип (например, ссылку на один справочник), задача решается стандартно. Однако, если реквизит имеет составной тип данных (например, выбор из восьми различных справочников), возникают сложности: как система поймет, в какую именно форму и какой параметр нужно передать? В данной статье мы подробно разберем, как эффективно решать эту задачу, используя как возможности платформы без написания кода, так и гибкие программные методы.

Метод 1. Использование механизма «Связи параметров выбора»

Начнем с самого элегантного способа, который предоставляет нам платформа. Рассмотрим ситуацию: у нас есть табличная часть с колонкой Техоперация (составной тип) и реквизит шапки Продукция. Нам нужно, чтобы при выборе операции в списке отображались только те записи, которые относятся к текущей продукции.

Разберем алгоритм настройки:

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

Важный нюанс: Чтобы этот механизм сработал для составного типа, необходимо, чтобы во всех восьми справочниках, входящих в состав, был либо реквизит с таким именем (если мы используем стандартный отбор), либо в их формах выбора был объявлен соответствующий Параметр. Если в каком-то справочнике параметр не будет найден, платформа просто проигнорирует его передачу для этого конкретного типа, не вызывая критической ошибки.

Метод 2. Использование события «ОбработкаНастройкиВыбора»

Проанализируем ситуацию, когда стандартных связей недостаточно. В управляемых формах существует замечательное событие ОбработкаНастройкиВыбора. Его главное преимущество заключается в том, что оно срабатывает после того, как пользователь выбрал конкретный тип из списка (если значение было пустым), но перед фактическим открытием формы выбора. Чтобы детально разобраться в последовательности выполнения этих и других обработчиков формы, можно использовать инструмент для отслеживания порядка вызова событий.

Рассмотрим пример кода, который позволит нам динамически добавить параметры:


&НаКлиенте
Процедура ВашаТабличнаяЧастьТехоперацияОбработкаНастройкиВыбора(Элемент, НастройкиВыбора, СтандартнаяОбработка)
    
    // Подготовим структуру параметров
    НовыйПараметр = Новый ПараметрВыбора("ФильтрПоПродукции", Объект.Продукция);
    
    // Добавляем параметр в настройки
    НастройкиВыбора.ПараметрыВыбора.Добавить(НовыйПараметр);
    
КонецПроцедуры

В данном случае нам не важно, какой именно справочник выбрал пользователь. Параметр ФильтрПоПродукции будет отправлен в любую форму выбора. Это избавляет нас от необходимости писать громоздкие конструкции Если ... Тогда для каждого типа справочника.

Метод 3. Программное переопределение в событии «НачалоВыбора»

Если нам нужно полностью контролировать процесс открытия формы (например, открывать не стандартную форму, а специальную), мы используем обработчик НачалоВыбора. Выясним причину, почему это сложнее в случае с составным типом: если поле пустое, мы сначала должны спросить пользователя, тип какого справочника он хочет выбрать.

Посмотрим на пример реализации, где мы учитываем уже заполненный тип:


&НаКлиенте
Процедура ВашаТабличнаяЧастьТехоперацияНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    ТекущаяСтрока = Элементы.ВашаТабличнаяЧасть.ТекущиеДанные;
    Если ТекущаяСтрока = Неопределено Тогда
        Возврат;
    КонецЕсли;

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

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

Метод 4. Передача параметра в форму нового элемента

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

Во-первых, в форме выбора (каждого из 8 справочников) необходимо принять параметр. В модуле формы выбора пишем:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Сохраняем пришедший параметр в переменную формы, чтобы использовать позже
    Если Параметры.Свойство("КодПродукции") Тогда
        ОбъектПродукцияДляНового = Параметры.КодПродукции;
    КонецЕсли;
КонецПроцедуры

Во-вторых, используем событие ПередСозданием в той же форме выбора. Это событие срабатывает при нажатии кнопки создания нового элемента в списке:


&НаКлиенте
Процедура СписокПередСозданием(Элемент, Отказ, СтандартнаяОбработка, ПараметрыФормы)
    
    // Если у нас есть данные для передачи, добавляем их в параметры открываемой формы
    Если ЗначениеЗаполнено(ОбъектПродукцияДляНового) Тогда
        ПараметрыФормы.Вставить("ЗначениеЗаполнения", Новый Структура("Продукция", ОбъектПродукцияДляНового));
    КонецЕсли;
    
КонецПроцедуры

Использование ключа ЗначениеЗаполнения является стандартным механизмом 1С. Платформа автоматически подставит эти данные в соответствующие поля нового объекта при его инициализации.

Продвинутый вариант: Использование временного хранилища

Разберем ситуацию, когда передаваемый параметр — это не просто ссылка, а сложная структура или таблица значений. Передавать такие объемы данных через параметры формы не всегда удобно и безопасно для производительности. В этом случае мы можем использовать Временное хранилище. Разобраться в принципах взаимодействия клиентского и серверного контекстов при такой передаче поможет руководство по управлению выполнением кода в управляемых формах.

Схема работы будет выглядеть так:

  1. В форме документа (владельца) помещаем данные в хранилище и получаем Адрес.
  2. Передаем этот Адрес (строку) как обычный параметр в форму выбора.
  3. В форме выбора (или форме элемента) извлекаем данные по адресу.

Проанализируем пример кода для формы документа:


&НаСервере
Функция ПодготовитьДанныеДляПередачиНаСервере()
    Данные = Новый Структура;
    Данные.Вставить("Склад", Объект.Склад);
    Данные.Вставить("Организация", Объект.Организация);
    // Помещаем во временное хранилище с уникальным идентификатором формы
    Возврат ПоместитьВоВременноеХранилище(Данные, ЭтаФорма.УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ТехоперацияНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    АдресДанных = ПодготовитьДанныеДляПередачиНаСервере();
    
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("АдресДопПараметров", АдресДанных);
    
    // Дальнейшее открытие формы с передачей адреса...
КонецПроцедуры

Этот способ универсален для составных типов данных, так как Адрес — это всегда строка, и она гарантированно будет принята любой формой выбора, поддерживающей этот параметр.

Резюме

Мы рассмотрели несколько подходов к решению задачи. Для простых отборов идеально подходят Связи параметров выбора. Если требуется программная логика при работе с составным типом — используйте ОбработкаНастройкиВыбора. А для передачи данных «сквозь» форму выбора в форму создания нового объекта используйте структуру ЗначениеЗаполнения в событии ПередСозданием. Комбинируя эти методы, вы сможете реализовать удобный и интуитивно понятный интерфейс для пользователя, минимизируя ошибки ручного ввода данных.

← На главную