Как сохранить отчет из 1С в книгу Excel на разные листы?

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

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

Проанализируем поведение типовых инструментов. При использовании объекта ТабличныйДокумент разработчики нередко вставляют разделители страниц, рассчитывая, что программа автоматически разобьет таблицу на вкладки книги. Однако встроенный метод ТабличныйДокумент.Записать() экспортирует документ строго на один рабочий лист. Горизонтальные и вертикальные разделители предназначены исключительно для разделения печатных страниц при отправке на принтер или при предварительном просмотре, но не влияют на структуру книги Excel.

Рассмотрим два основных подхода к решению этой задачи: современный штатный механизм платформы без использования сторонних программ и классический сценарий через COM-объект Microsoft Excel.

Способ 1. Штатный механизм платформы через ПакетОтображаемыхДокументов

Начиная с версии платформы 8.3.3, в 1С предусмотрен встроенный объект ПакетОтображаемыхДокументов. Это наиболее универсальный и рекомендуемый метод. Он полностью кроссплатформенный: выполняется как на клиенте, так и на сервере под управлением Windows или Linux, и не требует установки Microsoft Office.

Разберем по шагам логику реализации данного подхода:

  1. Формируем каждую таблицу или отдельный раздел отчета в собственный независимый объект ТабличныйДокумент.
  2. Помещаем каждый сформированный табличный документ во временное хранилище с помощью функции ПоместитьВоВременноеХранилище().
  3. Создаем объект ПакетОтображаемыхДокументов и наполняем его коллекцию Состав. Для каждого элемента указываем ссылку на данные во временном хранилище и наименование, которое станет именем листа в Excel.
  4. Сохраняем весь пакет в единый файл при помощи метода Записать(), указав формат ТипФайлаПакетаОтображаемыхДокументов.XLSX.

Посмотрим на пример программного кода:


// Создаем пакет документов
Пакет = Новый ПакетОтображаемыхДокументов;

// Пример добавления первого листа
АдресТаб1 = ПоместитьВоВременноеХранилище(ТабДокументПродажи);
ЭлементПакета1 = Пакет.Состав.Добавить();
ЭлементПакета1.Данные = АдресТаб1;
ЭлементПакета1.Наименование = "Продажи";

// Пример добавления второго листа
АдресТаб2 = ПоместитьВоВременноеХранилище(ТабДокументВзаиморасчеты);
ЭлементПакета2 = Пакет.Состав.Добавить();
ЭлементПакета2.Данные = АдресТаб2;
ЭлементПакета2.Наименование = "Взаиморасчеты";

// Запись сформированной книги в файл XLSX
Пакет.Записать("C:\Reports\СводныйОтчет.xlsx", ТипФайлаПакетаОтображаемыхДокументов.XLSX);

Рассмотрим подробнее важные нюансы при работе со штатным пакетом:

  1. Ограничения на имена листов: наименование вкладки не должно быть длиннее 31 символа, не должно повторяться и не может содержать зарезервированные символы стандартов электронных таблиц (например, :, \, /, ?, *, [, ]).
  2. Потребление памяти: если формируется большое количество массивных таблиц, размещение их во временном хранилище потребует значительного объема оперативной памяти сервера, поэтому при сверхбольших отчетах процесс рекомендуется оптимизировать.

Способ 2. Объединение файлов через COM-объект Excel.Application

Если решение разрабатывается для рабочей станции под управлением ОС Windows с установленным пакетом Microsoft Office, можно воспользоваться автоматизацией через COM-соединение. Данный способ заключается в сохранении каждой таблицы в отдельный промежуточный файл с последующим их объединением в общую книгу.

Посмотрим на пример реализации данного алгоритма:


ДокЭксель = Новый COMОбъект("Excel.Application");
ДокЭксель.DisplayAlerts = 0;

// Открываем основной файл, куда будем добавлять остальные листы
ОбщаяКнига = ДокЭксель.WorkBooks.Open(ИмяОсновногоФайла);
ЛистСДанными = ОбщаяКнига.Sheets(1);
ЛистСДанными.Select();
ЛистСДанными.Name = "Титульный";

Сч = 1;
Для каждого ПутьКФайлуXLS Из МассивПутейФайловXLS Цикл
    Книга = ДокЭксель.WorkBooks.Open(ПутьКФайлуXLS.Значение);
    ЛистСДанными = Книга.Sheets(1);
    ЛистСДанными.Select();
    
    // Формируем имя нового листа из имени файла
    ИмяЛиста = СтрЗаменить(Книга.Name, СокрЛП(ПутьДляСохранения), "");
    ИмяЛиста = СтрЗаменить(ИмяЛиста, ".xls", "");
    ЛистСДанными.Name = ИмяЛиста;
    
    // Копируем лист в основную книгу
    ЛистСДанными.Copy(ОбщаяКнига.Sheets(Сч));
    Сч = Сч + 1;
    Книга.Close();
КонецЦикла;    

ОбщаяКнига.Save();        
ОбщаяКнига.Close();
ДокЭксель.Quit();
ДокЭксель = Неопределено;    

// Удаляем временные промежуточные файлы
Для каждого ПутьКФайлуXLS Из МассивПутейФайловXLS Цикл        
    УдалитьФайлы(СокрЛП(ПутьКФайлуXLS.Значение));        
КонецЦикла;

Проанализируем ограничения этого подхода:

  1. Привязка к среде Windows: технология COM не работает в среде Linux, что делает невозможным выполнение кода на серверах под управлением свободных ОС.
  2. Наличие установленного офисного пакета: на рабочей станции или сервере обязательно должен быть инсталлирован Microsoft Excel.
  3. Зависание процессов: при аварийном завершении сценария процесс EXCEL.EXE может остаться в памяти, блокируя системные ресурсы.

Таким образом, для современных конфигураций 1С наиболее надежным, быстрым и кроссплатформенным решением является использование объекта ПакетОтображаемыхДокументов.

← На главную