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