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

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

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

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

Способ 1. Использование встроенного события «ОбработкаЗаписиНового»

Это один из самых лаконичных и «родных» механизмов платформы 1С, предназначенный именно для таких сценариев. Суть метода заключается в том, что вызывающая форма (Форма А) подписывается на событие записи новых объектов, которые создаются в подчиненных ей формах.

Давайте разберем по шагам, как это реализовать:

  1. При открытии формы нового документа (Формы Б) мы обязательно должны явно указать текущую форму (Форму А) в качестве её владельца. Это делается через передачу параметра ЭтаФорма в метод открытия.
  2. В модуле вызывающей Формы А мы определяем стандартный обработчик события ОбработкаЗаписиНового.

Посмотрим на пример кода в вызывающей форме (Форма А):


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

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

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

Способ 2. Открытие формы объекта в режиме выбора (без изменения создаваемого документа)

Этот способ идеален, если вы работаете в полностью типовой конфигурации и не имеете возможности (или желания) менять код в форме создаваемого документа. Мы можем заставить саму платформу вернуть ссылку при закрытии формы.

Для этого мы передаем параметр РежимВыбора = Истина непосредственно при открытии формы объекта нового документа, а владельцем указываем конкретный элемент интерфейса (например, поле ввода на форме).

Проанализируем пример кода на вызывающей форме:


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

Когда пользователь заполнит документ и нажмет кнопку «Записать и закрыть», платформа определит, что форма была запущена в режиме выбора. Она автоматически закроет форму нового документа и вернет его ссылку прямо в элемент формы ПолеВводаДокумента, инициировав в нем штатное событие ПриИзменении.

Способ 3. Использование глобального оповещения (Оповестить и ОбработкаОповещения)

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

Рассмотрим, как связать формы этим способом:

Шаг 1. В вызываемой форме нового документа (Форма Б) в предопределенном обработчике события ПослеЗаписи мы отправляем оповещение в систему:


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

Шаг 2. В вызывающей форме (Форма А) мы настраиваем прием этого сообщения. Для этого используем стандартное событие управляемой формы ОбработкаОповещения:


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

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

Способ 4. Возврат через описание оповещения (Асинхронный метод)

Если вам требуется гарантированно получить значение только в момент закрытия созданного документа, наиболее современным и правильным подходом будет использование объекта ОписаниеОповещения.

Разберем реализацию этого механизма:

1. В вызывающей форме подготавливаем описание процедуры, которая сработает при закрытии новой формы:


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

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

2. В форме нового документа (Форма Б) нам нужно сохранить ссылку в переменной формы при первой записи, а при закрытии — передать её в метод Закрыть():


&НаКлиенте
Перем СсылкаДляВозврата; // Переменная модуля формы для хранения ссылки

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    // Фиксируем ссылку после успешного сохранения объекта
    СсылкаДляВозврата = Объект.Ссылка;
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытии(ЗавершениеРаботы)
    // Передаем ссылку обратно в вызывающую форму
    Если ЗначениеЗаполнено(СсылкаДляВозврата) Тогда
        Закрыть(СсылкаДляВозврата);
    КонецЕсли;
КонецПроцедуры

Резюме и рекомендации

Выбор конкретного метода зависит от архитектуры вашей конфигурации и требований к кастомизации:

← На главную