Часто в процессе автоматизации бизнес-процессов на платформе «1С:Предприятие» возникает задача выгрузки отчетов в формат Excel в автоматическом режиме. Например, руководство хочет получать ежедневный отчет по продажам каждое утро на электронную почту, или система должна автоматически сбрасывать реестр платежей в определенную папку на сервере. При этом крайне важно полностью исключить «человеческий фактор» — пользователю не нужно открывать форму отчета, нажимать кнопку «Сформировать», а затем вручную выбирать пункт меню «Файл — Сохранить как...».
В этой статье мы подробно разберем, как реализовать автовыгрузку отчетов в форматы XLS и XLSX с минимальным количеством кода. Мы рассмотрим базовый метод, проанализируем возможные подводные камни, связанные с клиент-серверной архитектурой и веб-клиентом, а также предложим универсальный шаблон кода, который будет надежно работать в любых условиях.
Основным инструментом для вывода отчетов в 1С является табличный документ (объект ТабличныйДокумент). Платформа предоставляет встроенную возможность сохранять этот объект в различные форматы данных, включая Microsoft Excel, с помощью метода Записать().
Давайте посмотрим на простой пример кода, который решает эту задачу:
// Создаем или получаем уже сформированный табличный документ
ТабДок = Новый ТабличныйДокумент;
// Здесь происходит заполнение табличного документа данными (по макету или СКД)
// ...
// Задаем полный путь к будущему файлу на диске
ИмяФайла = "d:\Отчет.xls";
Попытка
// Записываем документ в формате Excel 97-2003
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLS);
Сообщить("Документ успешно создан в: " + ИмяФайла);
Исключение
// Обработка возможных ошибок записи (например, нет прав или диск отсутствует)
Сообщить("Произошла ошибка при сохранении файла: " + ОписаниеОшибки());
КонецПопытки;
Разберем этот код подробнее. Метод Записать() принимает два основных параметра: путь к файлу (строка) и тип файла (системное перечисление ТипФайлаТабличногоДокумента). В данном примере мы использовали старый формат XLS.
При использовании метода Записать() критически важно выбрать правильный тип файла из перечисления ТипФайлаТабличногоДокумента. На практике чаще всего используются два формата:
Поэтому мы настоятельно рекомендуем всегда использовать современный формат XLSX:
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Прописать жесткий путь вроде d:\Отчет.xlsx в коде — это самое простое решение, но в реальной многопользовательской базе оно быстро приведет к ошибкам. Выясним основные причины:
&НаСервере), то файл запишется на диск D:\ самого сервера 1С, а не на компьютер пользователя. Пользователь просто не сможет найти этот файл.USR1CV8) имеет жестко ограниченные права в операционной системе. По умолчанию у нее нет прав на запись файлов в корень системных дисков (особенно на диск C:\ или D:\). Попытка записи вызовет ошибку доступа.D.Чтобы избежать этих проблем, всегда нужно использовать динамическое определение путей. Например, сохранять файлы во временную папку операционной системы или в каталог документов текущего пользователя:
// Получаем путь к стандартной папке "Документы" текущего пользователя
ПутьКаталога = КаталогДокументов();
// Формируем уникальное имя файла с текущей датой, чтобы файлы не перезаписывали друг друга
ИмяФайла = ПутьКаталога + "Отчет_Продажи_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".xlsx";
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Если пользователи работают с базой 1С через интернет-браузер (веб-клиент), то прямой доступ к файловой системе компьютера закрыт политиками безопасности браузера. Код ТабДок.Записать() на клиенте работать не будет.
В этом случае мы должны применить следующую схему работы:
ПолучитьИмяВременногоФайла("xlsx").Давайте посмотрим, как выглядит этот механизм в управляемом приложении:
&НаСервере
Функция СформироватьИСохранитьНаСервере()
ТабДок = Новый ТабличныйДокумент;
// ... логика заполнения отчета ...
// Получаем путь к временному файлу на сервере
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяВременногоФайла, ТипФайлаТабличногоДокумента.XLSX);
// Помещаем файл во временное хранилище и возвращаем адрес
АдресХранилища = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяВременногоФайла));
// Удаляем временный файл на сервере после помещения в хранилище
УдалитьФайлы(ИмяВременногоФайла);
Возврат АдресХранилища;
КонецФункции
&НаКлиенте
Процедура СформироватьОтчет(Команда)
// Шаг 1: Формируем файл на сервере и получаем адрес во временном хранилище
АдресФайла = СформироватьИСохранитьНаСервере();
// Шаг 2: Скачиваем файл на локальный компьютер пользователя
ИмяФайлаДляСохранения = "Ежедневный_Отчет.xlsx";
ПолучитьФайл(АдресФайла, ИмяФайлаДляСохранения, Истина);
КонецПроцедуры
Метод ПолучитьФайл() автоматически предложит пользователю сохранить сформированный Excel-файл через стандартный диалог загрузки браузера.
Если задача стоит именно так, как описал автор темы — «убрать человеческое присутствие», то идеальным решением будет использование встроенного механизма регламентных заданий 1С. В этом случае отчет генерируется сервером по расписанию (например, каждую ночь в 03:00).
Поскольку интерактивного пользователя в этот момент в системе нет, сохранять файл на локальный диск бессмысленно. Мы можем использовать два отличных варианта:
\\ServerName\ShareFolder\Report.xlsx.Давайте рассмотрим пример кода для автоматической отправки готового Excel-отчета по электронной почте:
Процедура АвтоматическаяРассылкаОтчетов() Экспорт
ТабДок = Новый ТабличныйДокумент;
// ... заполняем отчет данными ...
// Сохраняем во временный файл на сервере
ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
// Настраиваем почтовое соединение
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "smtp.yandex.ru";
Профиль.ПортSMTP = 465;
Профиль.Пользователь = "report@mycompany.ru";
Профиль.Пароль = "MyPassword123";
Профиль.ИспользоватьSSLSMTP = Истина;
// Создаем письмо
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Отправитель.Адрес = "report@mycompany.ru";
Письмо.Получатели.Добавить("director@mycompany.ru");
Письмо.Тема = "Ежедневный отчет от " + Формат(ТекущаяДата(), "ДЛФ=D");
Письмо.Тексты.Добавить("Добрый день! Во вложении находится автоматически сформированный отчет.");
// Прикрепляем созданный Excel-файл
Письмо.Вложения.Добавить(ИмяФайла, "Отчет_Продажи.xlsx");
// Отправляем почту
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Почта.Послать(Письмо);
Почта.Отключиться();
Исключение
ЗаписьЖурналаРегистрации("Рассылка отчетов", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Удаляем временный файл с диска сервера
УдалитьФайлы(ИмяФайла);
КонецПроцедуры
Иногда стандартного конвертирования табличного документа 1С в Excel недостаточно (например, если требуется программно объединить несколько разных отчетов на разные листы одной книги Excel, настроить сложные формулы или макросы). В таких случаях разработчики используют альтернативные технологии. Для вывода сложных форм можно использовать готовое решение для заполнения шаблонов Excel из 1С.
Использование COM-объекта (MS Excel)
Этот способ основан на прямом программном управлении приложением Excel через COM-интерфейс:
Попытка
Excel = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("На компьютере не установлен MS Excel!");
Возврат;
КонецПопытки;
Книга = Excel.Workbooks.Add();
Лист = Книга.Worksheets(1);
// Заполняем ячейки напрямую
Лист.Cells(1, 1).Value = "Товар";
Лист.Cells(1, 2).Value = "Количество";
// ... заполнение в цикле ...
Книга.SaveAs("d:\COM_Отчет.xlsx");
Excel.Quit();
Важно помнить, что COM-объект работает крайне медленно на больших объемах данных и требует обязательной установки лицензионного пакета Microsoft Excel непосредственно на том компьютере, где выполняется код (если код выполняется на сервере, Excel должен быть установлен на сервере). В качестве альтернативы штатному COM-соединению подойдёт компонента для быстрого вывода отчетов в Excel.
Сохранение в формате HTML
Если вам нужно очень быстро выгрузить гигантский массив структурированных данных, стандартная конвертация в XLSX может сильно загрузить процессор сервера. В качестве обходного пути можно сохранить документ в формате HTML:
ТабДок.Записать("d:\Отчет.html", ТипФайлаТабличногоДокумента.HTML4);
Секрет в том, что Excel прекрасно умеет открывать файлы HTML и отображать их как стандартные таблицы. При этом скорость генерации HTML-файла платформой 1С в несколько раз выше, чем формирование бинарного XLSX.
Для повседневной работы рекомендуется использовать безопасный шаблон кода, который корректно обрабатывает ошибки доступа к файловой системе, автоматически определяет домашнюю директорию пользователя и логирует все нештатные ситуации в Журнал регистрации:
// Определяем безопасный путь к папке документов текущего пользователя
ПутьКаталога = КаталогДокументов();
ИмяФайла = ПутьКаталога + "Выгрузка_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd") + ".xlsx";
Попытка
// Записываем табличный документ в современном формате XLSX
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Сообщить("Документ успешно сохранен по пути: " + ИмяФайла);
Исключение
// Логируем ошибку в системный журнал для администратора
ЗаписьЖурналаРегистрации(
"Выгрузка в Excel",
УровеньЖурналаРегистрации.Ошибка,
,
,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
);
// Выводим понятное сообщение пользователю
Сообщить("Не удалось сохранить файл. Возможно, у вас нет прав на запись в каталог или файл открыт в другой программе.");
Сообщить("Причина: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;