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

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

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

Метод 1: Использование метода Закрыть() в модальном режиме

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

Проанализируем пример кода в вызываемой форме (той, которую открыли). Допустим, у нас есть кнопка "Выбрать", при нажатии на которую мы хотим вернуть текущую строку:


Процедура КнопкаВыбратьНажатие(Кнопка)
    // Получаем данные текущей строки
    ВыбранноеЗначение = ЭлементыФормы.ТабличнаяЧасть1.ТекущиеДанные;
    
    // Закрываем форму и передаем значение
    ЭтаФорма.Закрыть(ВыбранноеЗначение);
КонецПроцедуры

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


РезультатВыбора = ФормаВыбора.ОткрытьМодально();
Если РезультатВыбора <> Неопределено Тогда
    // Обрабатываем полученные данные
КонецЕсли;

Почему нельзя вернуть «строку» напрямую?

Важный нюанс, который мы должны учитывать: объект типа ДанныеФормыЭлементКоллекции (строка таблицы на форме) существует только в контексте открытой формы. Как только срабатывает метод Закрыть(), форма уничтожается, а вместе с ней удаляются и данные её элементов. Если вы попытаетесь вернуть саму строку, в вызывающей форме вы можете получить ошибку или пустую ссылку.

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


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

Таким образом, даже после закрытия формы, данные останутся доступны в переменной РезультатВыбора в виде структуры.

Метод 2: Использование стандартного механизма ОповеститьОВыборе()

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

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


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

Метод 3: Асинхронный подход через ОписаниеОповещения (для управляемых форм)

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

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

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

Посмотрим на пример кода в основной форме:


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

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

Метод 4: Глобальные оповещения через Оповестить()

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

В форме, которая отправляет данные:


Оповестить("СобытиеВыбораСтроки", ПередаваемыеДанные, ЭтаФорма);
ЭтаФорма.Закрыть();

В форме, которая должна принять данные, необходимо прописать обработчик события ОбработкаОповещения:


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

Метод 5: Передача данных через Временное хранилище

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

Алгоритм действий следующий:

  1. В открытой форме помещаем данные во временное хранилище методом ПоместитьВоВременноеХранилище().
  2. Метод возвращает уникальный адрес (строку).
  3. Вызываем Закрыть(АдресХранилища).
  4. В основной форме по этому адресу считываем данные и используем их.

Этот способ гарантирует, что даже объемные данные будут переданы корректно и без лишней нагрузки на интерфейсный поток.

Подведение итогов

Мы рассмотрели различные подходы к возврату значений. Выбор конкретного метода зависит от версии платформы и режима работы конфигурации:

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

← На главную