Как передать значения из произвольной управляемой формы назад в форму документа при закрытии в 1С?

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

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

Способ 1. Использование описания оповещения о закрытии (рекомендуемый асинхронный вариант)

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

Разберем по шагам, как реализовать этот механизм:

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

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

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

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

Способ 2. Стандартный механизм выбора (ОповеститьОВыборе и ОбработкаВыбора)

Посмотрим на второй распространенный способ, когда открываемая форма выступает в роли формы выбора единичного значения или структуры.

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

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

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

&НаКлиенте
Процедура ВыбратьИЗакрыть(Команда)
    
    ЗначениеВыбора = Элементы.Список.ТекущаяСтрока;
    ОповеститьОВыборе(ЗначениеВыбора);
    
КонецПроцедуры
  1. В форме документа перехватываем стандартное клиентское событие ОбработкаВыбора:

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    
    Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
        // Обрабатываем выбранные данные
        Объект.ОсновноеЗначение = ВыбранноеЗначение;
    КонецЕсли;
    
КонецПроцедуры

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

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

В этом случае используется пара методов Оповестить() и предопределенный обработчик ОбработкаОповещения.

  1. В открытой форме отправляем оповещение с уникальным именем события:

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

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

Важные нюансы при передаче данных между формами

Выясним частые ошибки и важные технические особенности платформы 1С:

  1. Модальность: Использование модальных вызовов (ОткрытьФормуМодально()) считается устаревшим и заблокировано в конфигурациях с выключенным режимом модальности. Всегда используйте асинхронные методы (ОписаниеОповещения).
  2. Типы передаваемых данных: Через клиентские оповещения и параметры закрытия можно передавать только типы, поддерживаемые на клиенте (структуры, массивы, числа, строки, ссылки). Нельзя передавать серверные объекты (такие как ДокументОбъект или ТаблицаЗначений).
  3. Несохраненный документ: Обращение к ВладелецФормы.Ключ в еще не записанном документе вернет пустую ссылку. Для идентификации конкретного экземпляра несохраненного документа передавайте в открываемую форму УникальныйИдентификатор формы-владельца через структуру параметров.
← На главную