Как передать данные между двумя формами обработки и программно сформировать пакет документов в Excel

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

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

Анализ проблемы и выбор архитектуры

Основная сложность, с которой сталкиваются разработчики при работе с управляемыми формами, заключается в том, что экземпляр объекта обработки на сервере для каждой формы создается заново. Если вы измените реквизит Объект.Флажок1 во второй форме, он не изменится в первой форме автоматически. Поэтому нам необходимо использовать механизмы обмена данными, встроенные в платформу:

  1. Параметры формы — для передачи данных при открытии "туда".
  2. Описание оповещения (Callback) — для возврата выбранных значений "обратно".
  3. Временное хранилище — если передаваемые данные объемные (например, готовые табличные документы).

Шаг 1: Вызов второй формы для выбора параметров

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

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


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

Шаг 2: Возврат данных из второй формы

Во второй форме (где расположены булевы реквизиты) нам нужно программно вернуть результат выбора. Проанализируем ситуацию: пользователь нажал кнопку "ОК". В этот момент мы должны собрать значения флажков в структуру и передать её в метод Закрыть().


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

Шаг 3: Обработка результата и формирование Excel-файла

Теперь вернемся в основную форму. Выясним причину, почему данные не передаются напрямую: как уже упоминалось, формы изолированы. После закрытия второй формы сработает процедура ПослеВыбораФлажков. Именно здесь мы реализуем логику сохранения в Excel, используя ПакетОтображаемыхДокументов. Этот объект позволяет объединить несколько табличных документов в один файл, где каждый документ станет отдельным листом.


&НаКлиенте
Процедура ПослеВыбораФлажков(Результат, ДополнительныеПараметры) Экспорт
    
    // Если пользователь просто закрыл форму крестиком, Результат будет Неопределено
    Если Результат = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
    Диалог.Фильтр = "Файл Excel (*.xlsx)|*.xlsx";
    
    Если Диалог.Выбрать() Тогда
        
        ИмяФайла = Диалог.ПолноеИмяФайла;
        СформироватьПакетНаСервере(ИмяФайла, Результат);
        
        ПоказатьПредупреждение(, "Файл успешно сохранен!");
        
    КонецЕсли;
    
КонецПроцедуры

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

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

Важные технические нюансы

Рассмотрим подробнее ключевые моменты, которые обеспечивают стабильную работу данного кода:

  1. Временное хранилище: При использовании ПоместитьВоВременноеХранилище крайне важно передавать вторым параметром УникальныйИдентификатор текущей формы. Это гарантирует, что данные не будут удалены системой до момента записи файла на диск.
  2. Наименование листов: В объекте ПакетОтображаемыхДокументов свойство Наименование элемента состава напрямую преобразуется в название вкладки Excel. Помните, что Excel накладывает ограничения на длину названия листа (до 31 символа) и запрещает спецсимволы.
  3. Объектная модель: Если ваши макеты хранятся не в реквизитах формы, а формируются динамически, лучше передавать во вторую форму не сами документы, а только адреса их временного хранилища. Это существенно экономит оперативную память сервера.

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

← На главную