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