В процессе разработки отчетов на платформе 1С:Предприятие часто возникает задача выгрузить результат не просто в один плоский файл, а разделить его на несколько логических частей. Классический пример — выгрузка отчета по продажам, где данные по каждому магазину или подразделению должны располагаться на отдельном листе файла Excel. При этом критически важно сохранить оформление, шрифты, границы и иерархические группировки («плюсики»), настроенные в исходном табличном документе.
В этой статье мы подробно разберем, как реализовать такую выгрузку, рассмотрим программные методы манипуляции областями табличного документа и научимся использовать встроенные механизмы платформы для формирования многолистовых книг XLSX.
Начиная с версии платформы 8.3.6, в 1С появился замечательный объект — ПакетОтображаемыхДокументов. Это наиболее современный и эффективный способ создания многолистовых файлов Excel без необходимости устанавливать Microsoft Office на сервере или клиентском компьютере. Суть метода заключается в том, что мы создаем «пакет», наполняем его отдельными табличными документами, и при записи в формате XLSX система автоматически преобразует каждый документ в отдельный лист книги.
Рассмотрим реализацию этого метода на примере. Предположим, у нас есть сформированный отчет в поле табличного документа на форме, и нам нужно «нарезать» его по колонкам (магазинам).
Разберем алгоритм действий:
ПакетОтображаемыхДокументов.ТабличныйДокумент для каждого листа.ВставитьОбласть.Посмотрим на программный код, реализующий эту логику:
Процедура ВыгрузитьПоМагазинамНаЛисты(Элемент)
// Получаем исходный табличный документ из формы
ИсходныйТаб = ЭлементыФормы.Результат.ПолучитьОбласть();
// Инициализируем координаты (пример: данные начинаются со 2-й колонки)
КолонкаНачала = 2;
КолонкаКонца = 4;
ИмяФайла = "C:\Отчеты\ВыгрузкаПоМагазинам.xlsx";
// Создаем пакет документов
Пакет = Новый ПакетОтображаемыхДокументов;
// Цикл по группировкам (в данном примере — по колонкам магазинов)
Пока ЗначениеЗаполнено(ИсходныйТаб.Область(6, КолонкаНачала).Текст) Цикл
// Создаем временный табличный документ для одного листа
ТабДокЛист = Новый ТабличныйДокумент;
// Копируем фиксированную область (например, номенклатуру из первой колонки)
ОбластьНоменклатуры = ИсходныйТаб.Область(6, 1, 400, 1);
ТабДокЛист.ВставитьОбласть(ОбластьНоменклатуры);
// Копируем данные конкретного магазина
ОбластьДанныхМагазина = ИсходныйТаб.Область(6, КолонкаНачала, 400, КолонкаКонца);
// Вставляем данные магазина правее номенклатуры
ТабДокЛист.ВставитьОбласть(ОбластьДанныхМагазина, ТабДокЛист.Область(6, 2));
// Настраиваем параметры оформления для текущего листа
ТабДокЛист.НачатьАвтогруппировкуСтрок();
ТабДокЛист.Область().АвтоПротяжка = Истина;
// Добавляем лист в пакет
ЭлементПакета = Пакет.Состав.Добавить();
// Имя листа в Excel берется из Наименования
ЭлементПакета.Наименование = ИсходныйТаб.Область(6, КолонкаНачала).Текст;
ЭлементПакета.Данные = ПоместитьВоВременноеХранилище(ТабДокЛист);
// Сдвигаем счетчик колонок к следующему магазину
КолонкаНачала = КолонкаНачала + 3;
КолонкаКонца = КолонкаКонца + 3;
КонецЦикла;
// Записываем весь пакет в один файл Excel
Пакет.Записать(ИмяФайла, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
// Открываем файл для просмотра
ЗапуститьПриложение(ИмяФайла);
КонецПроцедуры
Проанализируем ситуацию с именованием листов. Microsoft Excel накладывает строгие ограничения на названия вкладок, о которых важно помнить программисту 1С, чтобы избежать ошибок выполнения:
Лев()./ \ ? * [ ] :. Перед передачей строки в свойство Наименование рекомендуется выполнить очистку текста через СтрЗаменить().Также обратим внимание на метод ВставитьОбласть. При его использовании 1С старается максимально сохранить форматирование: цвета, шрифты и даже объединения ячеек. Однако, если в исходном документе были сложные иерархические группировки строк, для их корректного отображения в Excel необходимо вызвать метод ПоказатьСтроки() для всех уровней группировок перед помещением документа в пакет.
Рассмотрим более продвинутый случай. Что если мы не знаем заранее номера строк для каждого магазина, так как отчет формируется динамически через СКД (Систему компоновки данных)?
В настройках СКД для группировки «Магазин» мы можем установить свойство «Тип разрыва страницы» в значение «Перед». После формирования отчета в табличном документе появятся горизонтальные разрывы страниц.
Проанализируем, как использовать это программно. Мы можем перебрать все строки документа и с помощью метода ПроверитьВывод() определить, где заканчиваются данные одного магазина и начинаются данные другого. Это позволит нам динамически «нарезать» один большой отчет на несколько маленьких ТабличныйДокумент, которые затем так же объединяются через ПакетОтображаемыхДокументов.
Выясним причину, по которой выгрузка больших отчетов может занимать длительное время. Основная нагрузка ложится на метод ВставитьОбласть и процесс сериализации данных во временное хранилище. Если в вашем отчете сотни магазинов и десятки тысяч строк, рекомендуется:
УдалитьИзВременногоХранилища, если вы используете серверные вызовы в цикле.Excel.Application. Однако помните, что этот метод требует установленного Microsoft Office и работает медленнее, чем нативный ПакетОтображаемыхДокументов.Таким образом, мы рассмотрели основной инструментарий для решения задачи. Использование ПакетОтображаемыхДокументов в сочетании с грамотным управлением областями ТабличногоДокумента позволяет создавать профессиональные отчеты в формате Excel, которые удобны для конечных пользователей и сохраняют всю бизнес-логику визуализации из 1С.