В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача разделения логики интерфейса. Например, когда основная форма обработки отвечает за подготовку данных, а дополнительная — за выбор параметров или фильтров (в нашем случае — выбор макетов для печати). Рассмотрим подробнее, как организовать передачу данных между формами в режиме Управляемого приложения и как объединить несколько табличных документов в одну книгу Excel.
Основная сложность, с которой сталкиваются разработчики при работе с управляемыми формами, заключается в том, что экземпляр объекта обработки на сервере для каждой формы создается заново. Если вы измените реквизит Объект.Флажок1 во второй форме, он не изменится в первой форме автоматически. Поэтому нам необходимо использовать механизмы обмена данными, встроенные в платформу:
Предположим, на основной форме у нас есть данные макетов, а на второй форме пользователь должен отметить флажками, какие именно макеты нужно сохранить. Разберем, как правильно открыть вторую форму и подготовиться к получению результата. Для этого мы будем использовать объект ОписаниеОповещения.
Пример кода на основной форме:
&НаКлиенте
Процедура ВыгрузитьВExcel(Команда)
// Создаем описание оповещения, указывая процедуру, которая выполнится после закрытия второй формы
Оповещение = Новый ОписаниеОповещения("ПослеВыбораФлажков", ЭтотОбъект);
// Можно передать начальные значения во вторую форму через структуру параметров
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("Флаг1", Истина); // Значение по умолчанию
ОткрытьФорму("Обработка.МояОбработка.Форма.ФормаВыбораФлагов", ПараметрыОткрытия, ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);
КонецПроцедуры
Во второй форме (где расположены булевы реквизиты) нам нужно программно вернуть результат выбора. Проанализируем ситуацию: пользователь нажал кнопку "ОК". В этот момент мы должны собрать значения флажков в структуру и передать её в метод Закрыть().
&НаКлиенте
Процедура КомандаОК(Команда)
РезультатВыбора = Новый Структура;
РезультатВыбора.Вставить("ВыгружатьРеквизит1", Объект.Флажок1);
РезультатВыбора.Вставить("ВыгружатьРеквизит2", Объект.Флажок2);
РезультатВыбора.Вставить("ВыгружатьРеквизит3", Объект.Флажок3);
// Закрываем форму и передаем структуру в процедуру оповещения основной формы
Закрыть(РезультатВыбора);
КонецПроцедуры
Теперь вернемся в основную форму. Выясним причину, почему данные не передаются напрямую: как уже упоминалось, формы изолированы. После закрытия второй формы сработает процедура ПослеВыбораФлажков. Именно здесь мы реализуем логику сохранения в Excel, используя ПакетОтображаемыхДокументов. Этот объект позволяет объединить несколько табличных документов в один файл, где каждый документ станет отдельным листом.
&НаКлиенте
Процедура ПослеВыбораФлажков(Результат, ДополнительныеПараметры) Экспорт
// Если пользователь просто закрыл форму крестиком, Результат будет Неопределено
Если Результат = Неопределено Тогда
Возврат;
КонецЕсли;
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Фильтр = "Файл Excel (*.xlsx)|*.xlsx";
Если Диалог.Выбрать() Тогда
ИмяФайла = Диалог.ПолноеИмяФайла;
СформироватьПакетНаСервере(ИмяФайла, Результат);
ПоказатьПредупреждение(, "Файл успешно сохранен!");
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СформироватьПакетНаСервере(ИмяФайла, СтруктураФлагов)
Пакет = Новый ПакетОтображаемыхДокументов;
// Проверяем каждый флаг, полученный из второй формы
Если СтруктураФлагов.ВыгружатьРеквизит1 Тогда
ДобавитьЛистВПакет(Пакет, Объект.Реквизит1, "Лист 1");
КонецЕсли;
Если СтруктураФлагов.ВыгружатьРеквизит2 Тогда
ДобавитьЛистВПакет(Пакет, Объект.Реквизит2, "Лист 2");
КонецЕсли;
Если СтруктураФлагов.ВыгружатьРеквизит3 Тогда
ДобавитьЛистВПакет(Пакет, Объект.Реквизит3, "Лист 3");
КонецЕсли;
Пакет.Записать(ИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
КонецПроцедуры
&НаСервере
Процедура ДобавитьЛистВПакет(Пакет, ТабДок, НаименованиеЛиста)
Элемент = Пакет.Состав.Добавить();
// Помещаем табличный документ во временное хранилище для передачи в пакет
Элемент.Данные = ПоместитьВоВременноеХранилище(ТабДок, УникальныйИдентификатор);
Элемент.Наименование = НаименованиеЛиста;
КонецПроцедуры
Рассмотрим подробнее ключевые моменты, которые обеспечивают стабильную работу данного кода:
ПоместитьВоВременноеХранилище крайне важно передавать вторым параметром УникальныйИдентификатор текущей формы. Это гарантирует, что данные не будут удалены системой до момента записи файла на диск.ПакетОтображаемыхДокументов свойство Наименование элемента состава напрямую преобразуется в название вкладки Excel. Помните, что Excel накладывает ограничения на длину названия листа (до 31 символа) и запрещает спецсимволы.Таким образом, мы проанализировали ситуацию и реализовали надежную схему взаимодействия двух форм. Использование Описания оповещения является стандартом разработки для современных конфигураций на базе 1С:Библиотека стандартных подсистем (БСП) и обеспечивает корректную работу кода как в тонком клиенте, так и в веб-клиенте.