Как передать массив данных из одной формы в другую в 1С 8.3?

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

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

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

Способ 1. Использование механизма «ОповеститьОВыборе»

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

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

В основной форме (форме элемента) при открытии вспомогательной формы используем следующий код:


ПараметрыФормы = Новый Структура;
// Если нужно передать что-то во вторую форму изначально
ОткрытьФорму("Справочник.ИмяСправочника.Форма.ПроизвольнаяФорма", ПараметрыФормы, ЭтаФорма);

Здесь крайне важен третий параметр — ЭтаФорма. Мы назначаем текущую форму владельцем открываемой формы. Теперь во вспомогательной форме, когда массив МассивДанных заполнен, мы вызываем метод:


ОповеститьОВыборе(МассивДанных);

После вызова этого метода вспомогательная форма закроется, а в основной форме сработает стандартный обработчик ОбработкаВыбора. Нам остается только поймать данные:


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

Способ 2. Использование «ОписаниеОповещения» (Callback)

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

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

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

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


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

&НаКлиенте
Процедура ПослеЗакрытияВторойФормы(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
    Если РезультатЗакрытия <> Неопределено Тогда
        // Проанализируем ситуацию: в РезультатЗакрытия придет наш массив
        МассивРезультат = РезультатЗакрытия;
        // Дальнейшая логика обработки
    КонецЕсли;
КонецПроцедуры

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


// Предположим, массив уже заполнен данными "первый", "второй", "третий"
Закрыть(МассивДанных);

Этот метод считается наиболее «чистым» с точки зрения архитектуры управляемого приложения, так как он явно связывает вызов и обработку результата.

Способ 3. Глобальное оповещение через «Оповестить»

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

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


Оповестить("СобытиеЗаполненияМассива", МассивДанных, ЭтаФорма);

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


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

Важный момент: метод Оповестить рассылает сообщение всем открытым формам, поэтому всегда проверяйте ИмяСобытия, чтобы не обработать чужие данные.

Способ 4. Использование временного хранилища

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

Схема взаимодействия выглядит так:

  1. Вторая форма помещает массив во временное хранилище на сервере и получает Адрес (строку).
  2. Этот адрес передается в первую форму любым из вышеописанных способов (через Закрыть() или ОповеститьОВыборе()).
  3. Первая форма на сервере извлекает массив по адресу.

Рассмотрим пример кода во второй форме (переход на сервер):


&НаСервере
Функция ПоместитьМассивВХранилище()
    Возврат ПоместитьВоВременноеХранилище(МассивДанных, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ЗавершитьВыбор(Команда)
    АдресДанных = ПоместитьМассивВХранилище();
    Закрыть(АдресДанных);
КонецПроцедуры

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

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

Мы рассмотрели основные способы передачи данных. Подведем итоги, какой метод выбрать:

Помните, что при передаче данных между формами на клиенте передаются только типы, доступные на клиенте. Если ваш массив содержит ссылки на справочники или документы — все будет в порядке. Но если вы попытаетесь передать через массив сам «Объект» справочника (с данными, которые еще не записаны в базу), платформа выдаст ошибку, так как такие объекты живут только на сервере. В таких случаях передавайте данные через Структура, заполненную простыми значениями.

← На главную