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

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

Часто в процессе автоматизации бизнес-процессов на платформе «1С:Предприятие» возникает задача выгрузки отчетов в формат Excel в автоматическом режиме. Например, руководство хочет получать ежедневный отчет по продажам каждое утро на электронную почту, или система должна автоматически сбрасывать реестр платежей в определенную папку на сервере. При этом крайне важно полностью исключить «человеческий фактор» — пользователю не нужно открывать форму отчета, нажимать кнопку «Сформировать», а затем вручную выбирать пункт меню «Файл — Сохранить как...».

В этой статье мы подробно разберем, как реализовать автовыгрузку отчетов в форматы XLS и XLSX с минимальным количеством кода. Мы рассмотрим базовый метод, проанализируем возможные подводные камни, связанные с клиент-серверной архитектурой и веб-клиентом, а также предложим универсальный шаблон кода, который будет надежно работать в любых условиях.

Способ 1. Стандартный метод программного сохранения табличного документа

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

Давайте посмотрим на простой пример кода, который решает эту задачу:


// Создаем или получаем уже сформированный табличный документ
ТабДок = Новый ТабличныйДокумент;

// Здесь происходит заполнение табличного документа данными (по макету или СКД)
// ...

// Задаем полный путь к будущему файлу на диске
ИмяФайла = "d:\Отчет.xls";

Попытка    
    // Записываем документ в формате Excel 97-2003
    ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLS);
    Сообщить("Документ успешно создан в: " + ИмяФайла);
Исключение
    // Обработка возможных ошибок записи (например, нет прав или диск отсутствует)
    Сообщить("Произошла ошибка при сохранении файла: " + ОписаниеОшибки());
КонецПопытки;

Разберем этот код подробнее. Метод Записать() принимает два основных параметра: путь к файлу (строка) и тип файла (системное перечисление ТипФайлаТабличногоДокумента). В данном примере мы использовали старый формат XLS.

Важные нюансы: Выбор правильного формата (XLS или XLSX)

При использовании метода Записать() критически важно выбрать правильный тип файла из перечисления ТипФайлаТабличногоДокумента. На практике чаще всего используются два формата:

  1. ТипФайлаТабличногоДокумента.XLS — старый формат Excel 97–2003. Главное его ограничение состоит в том, что один лист документа не может содержать более 65 536 строк. Если ваш отчет окажется крупнее, 1С выдаст ошибку записи или просто обрежет "лишние" строки, что приведет к искажению данных.
  2. ТипФайлаТабличногоДокумента.XLSX — современный формат (начиная с Excel 2007). Он поддерживается платформой «1С:Предприятие», начиная с поздних версий 8.2 и во всех релизах 8.3. Этот формат поддерживает до 1 048 576 строк на одном листе, файлы занимают значительно меньше места на диске благодаря архивации данных внутри структуры, а сам процесс сохранения происходит быстрее.

Поэтому мы настоятельно рекомендуем всегда использовать современный формат XLSX:

ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

Подводные камни клиент-серверной архитектуры

Прописать жесткий путь вроде d:\Отчет.xlsx в коде — это самое простое решение, но в реальной многопользовательской базе оно быстро приведет к ошибкам. Выясним основные причины:

  1. Место выполнения кода: Если ваш код выполняется на стороне сервера (в процедуре с директивой &НаСервере), то файл запишется на диск D:\ самого сервера 1С, а не на компьютер пользователя. Пользователь просто не сможет найти этот файл.
  2. Права доступа Windows: Служба сервера 1С (обычно работающая под системным пользователем USR1CV8) имеет жестко ограниченные права в операционной системе. По умолчанию у нее нет прав на запись файлов в корень системных дисков (особенно на диск C:\ или D:\). Попытка записи вызовет ошибку доступа.
  3. Отсутствие диска: На сервере или на рабочем компьютере пользователя физически может не быть диска с буквой D.

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


// Получаем путь к стандартной папке "Документы" текущего пользователя
ПутьКаталога = КаталогДокументов(); 

// Формируем уникальное имя файла с текущей датой, чтобы файлы не перезаписывали друг друга
ИмяФайла = ПутьКаталога + "Отчет_Продажи_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd_HHmmss") + ".xlsx";

ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

Особенности работы в Веб-клиенте

Если пользователи работают с базой 1С через интернет-браузер (веб-клиент), то прямой доступ к файловой системе компьютера закрыт политиками безопасности браузера. Код ТабДок.Записать() на клиенте работать не будет.

В этом случае мы должны применить следующую схему работы:

  1. Формируем отчет на стороне сервера.
  2. Сохраняем сформированный табличный документ во временный файл на сервере с помощью функции ПолучитьИмяВременногоФайла("xlsx").
  3. Помещаем файл во временное хранилище.
  4. Передаем файл на клиентскую машину пользователя для скачивания.

Давайте посмотрим, как выглядит этот механизм в управляемом приложении:


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

&НаКлиенте
Процедура СформироватьОтчет(Команда)
    
    // Шаг 1: Формируем файл на сервере и получаем адрес во временном хранилище
    АдресФайла = СформироватьИСохранитьНаСервере();
    
    // Шаг 2: Скачиваем файл на локальный компьютер пользователя
    ИмяФайлаДляСохранения = "Ежедневный_Отчет.xlsx";
    ПолучитьФайл(АдресФайла, ИмяФайлаДляСохранения, Истина);
    
КонецПроцедуры

Метод ПолучитьФайл() автоматически предложит пользователю сохранить сформированный Excel-файл через стандартный диалог загрузки браузера.

Полное исключение человека: Автоматизация по расписанию

Если задача стоит именно так, как описал автор темы — «убрать человеческое присутствие», то идеальным решением будет использование встроенного механизма регламентных заданий 1С. В этом случае отчет генерируется сервером по расписанию (например, каждую ночь в 03:00).

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

  1. Сохранение на общий сетевой ресурс (сетевую папку). Для этого используется сетевой UNC-путь, к которому у сервера 1С есть физический доступ. Например, \\ServerName\ShareFolder\Report.xlsx.
  2. Отправка файла на электронную почту. Сформированный файл прикрепляется во вложения к письму и рассылается заинтересованным лицам.

Давайте рассмотрим пример кода для автоматической отправки готового Excel-отчета по электронной почте:


Процедура АвтоматическаяРассылкаОтчетов() Экспорт

    ТабДок = Новый ТабличныйДокумент;
    // ... заполняем отчет данными ...

    // Сохраняем во временный файл на сервере
    ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");
    ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

    // Настраиваем почтовое соединение
    Профиль = Новый ИнтернетПочтовыйПрофиль;
    Профиль.АдресСервераSMTP = "smtp.yandex.ru";
    Профиль.ПортSMTP = 465;
    Профиль.Пользователь = "report@mycompany.ru";
    Профиль.Пароль = "MyPassword123";
    Профиль.ИспользоватьSSLSMTP = Истина;

    // Создаем письмо
    Письмо = Новый ИнтернетПочтовоеСообщение;
    Письмо.Отправитель.Адрес = "report@mycompany.ru";
    Письмо.Получатели.Добавить("director@mycompany.ru");
    Письмо.Тема = "Ежедневный отчет от " + Формат(ТекущаяДата(), "ДЛФ=D");
    Письмо.Тексты.Добавить("Добрый день! Во вложении находится автоматически сформированный отчет.");

    // Прикрепляем созданный Excel-файл
    Письмо.Вложения.Добавить(ИмяФайла, "Отчет_Продажи.xlsx");

    // Отправляем почту
    Почта = Новый ИнтернетПочта;
    Попытка
        Почта.Подключиться(Профиль);
        Почта.Послать(Письмо);
        Почта.Отключиться();
    Исключение
        ЗаписьЖурналаРегистрации("Рассылка отчетов", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    КонецПопытки;

    // Удаляем временный файл с диска сервера
    УдалитьФайлы(ИмяФайла);

КонецПроцедуры

Альтернативные методы выгрузки данных в Excel

Иногда стандартного конвертирования табличного документа 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.

Универсальный надежный шаблон кода для 1С 8.3

Для повседневной работы рекомендуется использовать безопасный шаблон кода, который корректно обрабатывает ошибки доступа к файловой системе, автоматически определяет домашнюю директорию пользователя и логирует все нештатные ситуации в Журнал регистрации:


// Определяем безопасный путь к папке документов текущего пользователя
ПутьКаталога = КаталогДокументов(); 
ИмяФайла = ПутьКаталога + "Выгрузка_" + Формат(ТекущаяДата(), "ДФ=yyyyMMdd") + ".xlsx";

Попытка    
    // Записываем табличный документ в современном формате XLSX
    ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
    Сообщить("Документ успешно сохранен по пути: " + ИмяФайла);
Исключение
    // Логируем ошибку в системный журнал для администратора
    ЗаписьЖурналаРегистрации(
        "Выгрузка в Excel", 
        УровеньЖурналаРегистрации.Ошибка, 
        , 
        , 
        ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
    );
    
    // Выводим понятное сообщение пользователю
    Сообщить("Не удалось сохранить файл. Возможно, у вас нет прав на запись в каталог или файл открыт в другой программе.");
    Сообщить("Причина: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
← На главную