Как вернуть данные из открываемой формы в обычных формах 1С

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

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

Разберем подробно причины возникновения этой ошибки, а также рассмотрим три проверенных способа передачи данных между обычными формами.

Причина ошибки: Обращение к процедуре объекта как к функции (Открыть)

Проанализируем фрагмент кода, вызвавший исключительную ситуацию:


ФормаРезультата = ЭтотОбъект.ПолучитьФорму("ФормаРезультата");
// Заполнение реквизитов формы...
ВозвращаемоеЗначение = ФормаРезультата.Открыть();

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

Для решения этой задачи в обычных формах применяются три основных подхода: модальный вызов, механизм владельца формы с оповещением о выборе и глобальный механизм оповещений.

Способ 1. Модальное открытие с возвратом значения через Закрыть()

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

Разберем по шагам реализацию данного подхода:

  1. В модуле вызывающей формы вызываем метод ОткрытьМодально():

ФормаРезультата = ЭтотОбъект.ПолучитьФорму("ФормаРезультата");
ФормаРезультата.СписокХарок = СписокХарок;
ФормаРезультата.РезультатЗапроса = Результат;

ВозвращаемоеЗначение = ФормаРезультата.ОткрытьМодально();

Если ВозвращаемоеЗначение <> Неопределено Тогда
    // Обработка полученного значения
КонецЕсли;
  1. В модуле открываемой формы при выборе строки таблицы или нажатии кнопки завершаем работу с формой, передавая выбранные данные параметром в процедуру Закрыть():

Процедура ТабличноеПолеВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    НужноеЗначение = Элемент.ТекущиеДанные.Значение;
    ЭтаФорма.Закрыть(НужноеЗначение);
КонецПроцедуры

Обратите внимание: если пользователь закроет окно нажатием на крестик, клавишей Esc или без передачи параметра в метод Закрыть(), функция ОткрытьМодально() вернет значение Неопределено. Поэтому проверка на Неопределено обязательна.

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

Рассмотрим штатный немодальный механизм платформы, который не блокирует интерфейс приложения и не требует модальности. Для этого открываемой форме назначается форма-владелец.

  1. В вызывающей форме при открытии передаем текущую форму (ЭтаФорма) вторым параметром метода ПолучитьФорму() или через свойство ВладелецФормы, а также объявляем стандартную процедуру-обработчик ОбработкаВыбора:

ФормаРезультата = ЭтотОбъект.ПолучитьФорму("ФормаРезультата", ЭтаФорма);
ФормаРезультата.СписокХарок = СписокХарок;
ФормаРезультата.Открыть();

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

Процедура ТабличноеПолеВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    НужноеЗначение = Элемент.ТекущиеДанные.Значение;
    ОповеститьОВыборе(НужноеЗначение);
КонецПроцедуры

Метод ОповеститьОВыборе() автоматически передает выбранное значение в процедуру ОбработкаВыбора формы-владельца и закрывает текущую форму.

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

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

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

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

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

Важные нюансы и ограничения платформы

При выборе подходящего метода учитывайте следующие особенности платформы 1С:

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