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