Как передать массивы данных между управляемыми формами в 1С и вернуть результат обработки?

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

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

Постановка задачи и выбор метода передачи

Рассмотрим ситуацию: в Форме1 (например, форме заказа) пользователь выбирает определенные объекты. На основании этого выбора формируются три массива данных: Объекты, Операции и Компоненты. Эти данные необходимо передать в Форму2, где пользователь введет фактические показатели, после чего результаты должны вернуться в Форму1 для окончательного расчета и записи в базу данных.

Проанализируем основные способы решения этой задачи:

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

Шаг 1: Подготовка данных в Форме 1 и использование Временного хранилища

Для начала нам необходимо собрать данные в единый контейнер. В 1С наилучшим контейнером является Структура. Мы поместим в нее все наши массивы. Выясним важный нюанс: чтобы данные во временном хранилище «жили» ровно столько, сколько открыта форма, при помещении необходимо указывать УникальныйИдентификатор формы.

Рассмотрим пример кода на клиенте и сервере Формы1:


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

    // Помещаем данные в хранилище на сервере
    АдресХранилища = ПоместитьДанныеВоВременноеХранилище(ДанныеДляПередачи);
    
    // Подготавливаем параметры для открытия Формы 2
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("АдресДанных", АдресХранилища);
    
    // Используем ОписаниеОповещения для получения результата обратно
    Оповещение = Новый ОписаниеОповещения("ОбработатьЗакрытиеФормы2", ЭтаФорма);
    
    ОткрытьФорму("Документ.Заказ.Форма.ФормаПодтверждения", ПараметрыОткрытия, ЭтаФорма, , , , Оповещение);

КонецПроцедуры

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

Обратите внимание, что мы используем ОписаниеОповещения. Это позволяет Форме1 «подписаться» на событие закрытия Формы2 и сразу получить результат обработки без использования глобальных переменных или лишних обращений к базе.

Шаг 2: Получение и обработка данных в Форме 2

Теперь разберем, как принять данные в открываемой форме. В Форме2 в обработчике ПриСозданииНаСервере мы обращаемся к параметрам, извлекаем адрес хранилища и получаем саму структуру с массивами.

Проанализируем процесс извлечения:


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

Важный совет: Если вы передаете Массив, в котором лежат Структуры, вы фактически передаете аналог таблицы значений. Это очень удобно, так как Структура (в отличие от ТаблицыЗначений) прекрасно сериализуется и передается между клиентом и сервером без лишних ошибок типа «Данные данного типа не могут быть переданы на клиент».

Шаг 3: Возврат результатов в Форму 1

После того как пользователь ввел данные в Форме2 и нажал кнопку «Подтвердить», нам нужно вернуть измененные показатели обратно. Рассмотрим ситуацию, когда мы хотим вернуть не просто «Ок», а измененный массив с данными.

В Форме2 создадим процедуру завершения:


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

Теперь в Форме1 сработает процедура, указанная в ОписаниеОповещения:


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

Альтернативный подход: Использование страниц формы

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

Разберем, как это работает:

  1. Создаем на форме группу типа Страницы и отключаем отображение закладок (свойство ОтображениеЗакладок = Не отображать).
  2. Размещаем на одной странице основные данные заказа, на другой — интерфейс «Подтверждения».
  3. По кнопке «Перейти к подтверждению» просто меняем ТекущаяСтраница.

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

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

Оптимизация: Метод ValueToFormData (ЗначениеВРеквизитФормы)

Когда данных много, ручной перебор строк в цикле Для каждого работает медленно. Проанализируем, как ускорить процесс заполнения табличных частей. Если вы подготовили Таблицу Значений на сервере, используйте встроенные методы платформы:


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

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

Заключение

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

← На главную