Как отправить письмо с вложением в 1С без сохранения файла на диск

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

В практике разработчика 1С часто возникает задача автоматической рассылки отчетов. Например, когда регламентное задание должно сформировать персональные отчеты для сотрудников и отправить их по электронной почте. Типичная сложность здесь заключается в том, что серверный код «не видит» локальные диски пользователя, а плодить временные файлы на сервере не всегда удобно или безопасно с точки зрения прав доступа. В этой статье мы подробно разберем, как решить проблему «невидимых каталогов» и научимся отправлять вложения, используя оперативную память сервера.

Почему возникает ошибка «Каталог не обнаружен»

Разберем ситуацию: вы написали код, который сохраняет отчет на диск E:\TMP\Отчет.xls и пытается прикрепить его к письму. На вашем локальном компьютере всё работает, но как только обработка запускается на сервере (или как регламентное задание), система выдает ошибку. Выясним причину: в клиент-серверной базе код с директивой &НаСервере исполняется на физической машине, где установлен сервер 1С. Этот сервер ничего не знает о ваших локальных дисках C: или E:. Он ищет файл в своей собственной файловой системе. Более того, у службы, под которой запущен 1С (обычно это usr1cv8), может просто не быть прав на запись в корень диска или системные папки.

Решение 1: Использование временных файлов сервера

Проанализируем самый простой способ, который часто применяется в промышленной разработке. Если вам всё же нужно записать файл на диск, никогда не используйте жестко прописанные пути вроде C:\Temp\. Правильнее будет использовать функцию ПолучитьИмяВременногоФайла(). Рассмотрим алгоритм действий:

  1. Программа генерирует уникальное имя файла в системной временной папке сервера, к которой у 1С гарантированно есть доступ.
  2. Мы записываем отчет в этот файл.
  3. Создаем объект ДвоичныеДанные на основе этого файла.
  4. Удаляем временный файл сразу после использования, чтобы не засорять память сервера.

Однако такой метод создает лишнюю нагрузку на дисковую подсистему. Посмотрим, как можно обойтись вовсе без записи на диск.

Решение 2: Отправка отчета через ПотокВПамяти (без диска)

Начиная с версии платформы 8.3.15, в 1С появилась возможность работать с потоками. Это позволяет превратить сформированный табличный документ в набор байтов прямо в оперативной памяти. Рассмотрим этот современный подход подробнее. Мы будем использовать объект ПотокВПамяти и методы БСП (Библиотеки стандартных подсистем) для отправки.

Проанализируем следующий пример кода:


// 1. Формируем поток в оперативной памяти
ПотокВПамяти = Новый ПотокВПамяти;

// 2. Записываем табличный документ (отчет) в этот поток
// Можно выбрать форматы: PDF, XLSX, DOCX и т.д.
ТабДок.Записать(ПотокВПамяти, ТипФайлаТабличногоДокумента.XLSX);

// 3. Получаем двоичные данные из потока и закрываем его
ДвоичныеДанные = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();

// 4. Подготавливаем структуру вложения для БСП
Вложение = Новый Структура;
Вложение.Вставить("АдресВоВременномХранилище", ПоместитьВоВременноеХранилище(ДвоичныеДанные));
Вложение.Вставить("Представление", "ВашОтчет.xlsx");

// 5. Помещаем вложение в массив (так требует типовой механизм)
СписокВложений = Новый Массив;
СписокВложений.Добавить(Вложение);

// 6. Формируем параметры письма и отправляем через типовые функции
ПараметрыПисьма = Новый Структура;
ПараметрыПисьма.Вставить("Кому", "user@example.com");
ПараметрыПисьма.Вставить("Тема", "Автоматический отчет");
ПараметрыПисьма.Вставить("Тело", "Добрый день! Во вложении ваш отчет.");
ПараметрыПисьма.Вставить("Вложения", СписокВложений);

УчетнаяЗапись = Справочники.УчетныеЗаписиЭлектроннойПочты.НайтиПоНаименованию("Основная");

Попытка
    РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(УчетнаяЗапись, ПараметрыПисьма);
    Сообщить("Отчет успешно отправлен без записи на диск!");
Исключение
    Сообщить("Ошибка при отправке: " + ОписаниеОшибки());
КонецПопытки;

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

Важные технические нюансы

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

  1. Объем оперативной памяти: Когда мы используем ДвоичныеДанные в памяти, весь объем отчета загружается в RAM сервера. Если вы формируете гигантский отчет на миллион строк, процесс rphost может потреблять слишком много ресурсов. Для очень тяжелых файлов (более 50-100 Мб) всё же лучше вернуться к методу временных файлов на диске.
  2. Формат PDF как стандарт: Хотя в коде выше мы использовали XLSX, для рассылки отчетов пользователям рекомендуется использовать ТипФайлаТабличногоДокумента.PDF. Это гарантирует, что оформление отчета не «поедет» при просмотре на смартфоне или в почтовом клиенте.
  3. Работа в фоновых заданиях: Если вы планируете запускать этот код через регламентное задание, помните, что отладка серверного кода требует включения соответствующей опции в конфигураторе. Все сообщения об ошибках обязательно логируйте в ЖурналРегистрации, так как пользователь не увидит всплывающих окон при фоновом выполнении.
  4. Лимиты почтовых серверов: Помните, что большинство почтовых сервисов (Mail.ru, Gmail) имеют ограничение на размер вложения (обычно 20-25 Мб). Если ваш отчет в памяти окажется больше, 1С выдаст ошибку протокола SMTP. В таких случаях стоит рассмотреть архивацию файла в ZIP (объект ЗаписьZipФайла также поддерживает работу с потоками).

Таким образом, мы выяснили, что для корректной работы серверной отправки почты в 1С 8.3 лучше всего использовать механизм потоков или временных хранилищ. Это избавляет от проблем с правами доступа к папкам и делает вашу обработку универсальной для любой инфраструктуры.

← На главную