Как в 1С прикрепить к письму несколько файлов из документа?

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

В процессе работы часто возникает задача автоматизировать отправку электронных писем с вложениями прямо из 1С. Если с одним файлом все более-менее понятно, то как быть, когда к одному документу (например, "Заявка клиента" или "Реализация товаров и услуг") прикреплено сразу несколько файлов, и все их нужно отправить одному адресату? Рассмотрим пошагово, как решить эту задачу с помощью стандартных методов Библиотеки стандартных подсистем (БСП) и разберем типичные ошибки, с которыми можно столкнуться.

Общий алгоритм решения задачи

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

  1. Найти объект-владелец. Сначала нам нужна ссылка на тот документ или элемент справочника, к которому присоединены файлы.
  2. Получить список файлов. Используя функции БСП, мы получаем массив со структурами, описывающими каждый присоединенный файл.
  3. Подготовить параметры письма. Создаем основную структуру для отправки письма, куда будем складывать информацию о получателе, теме, тексте и, конечно же, наших вложениях. Вложения будут храниться в виде массива.
  4. Организовать цикл по файлам. Запускаем цикл, который будет перебирать все найденные на шаге 2 файлы.
  5. Обработать каждый файл в цикле. Это самый важный этап. Для каждого файла из списка нужно получить его двоичные данные, поместить их во временное хранилище и сформировать описание вложения.
  6. Сформировать и отправить письмо. После того как цикл завершится и массив вложений будет полностью заполнен, вызываем стандартную функцию БСП для отправки электронного письма.

Теперь давайте разберем каждый шаг более детально, посмотрим на примеры кода и выясним, почему может возникать ошибка "Файл не обнаружен".

Разбор кода и исправление ошибки "Файл не обнаружен"

Часто начальная попытка решения выглядит примерно так: программист получает список файлов, а затем в цикле пытается как-то прикрепить их к письму. Подобная логика часто используется, когда реализуется программная отправка счетов и актов с использованием функций БСП. Посмотрим на типичный стартовый код.


Файлы = Новый Массив;
// Находим наш документ, например, по номеру
ВладелецФайла = Документы.Заявканаобразец.НайтиПоНомеру("000000001");

// Получаем список присоединенных к нему файлов с помощью процедуры БСП
РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(ВладелецФайла, Файлы);

// Далее пытаемся в цикле что-то сделать с файлами
Для Каждого Файл Из Файлы Цикл
	// ... что писать здесь?
КонецЦикла;

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

Проблема в том, что нельзя просто передать ссылку на присоединенный файл или его двоичные данные напрямую в параметры отправки письма. Механизмы БСП требуют, чтобы данные файла были сначала помещены во временное хранилище. Система получает оттуда уникальный адрес (строку) и уже по этому адресу находит содержимое файла при формировании письма. Для оптимизации таких процессов полезно изучить современный код для работы с файловой системой, который делает работу с данными более прозрачной.

Выясним причину ошибки "Файл не обнаружен". Эта ошибка возникает как раз тогда, когда мы пытаемся передать в структуру вложения что-то, кроме корректного адреса во временном хранилище. Система пытается найти файл по переданной строке, не находит его во временном хранилище и сообщает об ошибке.

Чтобы все сделать правильно, внутри цикла нужно выполнить три последовательных действия для каждого файла.

  1. Получить двоичные данные файла. Для этого используем функцию БСП РаботаСФайлами.ДвоичныеДанныеФайла(). Она принимает на вход ссылку на файл (которую мы получаем из нашего массива Файлы) и возвращает его содержимое.
  2. Поместить данные во временное хранилище. Это ключевой шаг. Используем стандартную функцию платформы ПоместитьВоВременноеХранилище(). Она забирает двоичные данные и возвращает уникальный строковый адрес, по которому эти данные будут доступны некоторое время.
  3. Сформировать структуру описания вложения и добавить ее в массив. Для каждого файла создаем новую структуру. В нее мы записываем как минимум два параметра: имя файла для отображения в письме и тот самый адрес, который мы получили на предыдущем шаге. После этого добавляем готовую структуру в общий массив вложений.

Итоговый пример кода

Теперь давайте соберем все наши знания в один работающий пример. Предположим, у нас уже есть подготовленная структура ПараметрыПисьма, и мы заполняем ее массив вложений. Если вы хотите сделать интерфейс выбора файлов более современным, можно дополнительно реализовать Drag & Drop для присоединенных файлов.


// Создаем структуру для параметров отправки письма
ПараметрыПисьма = Новый Структура;
// Инициализируем массив для хранения вложений
ПараметрыПисьма.Вставить("Вложения", Новый Массив);

// --- Шаг 1: Получаем список файлов ---

// Массив, в который будут помещены сведения о файлах
ПрисоединенныеФайлы = Новый Массив;
// Находим документ-владелец файлов
ВладелецФайлов = Документы.Заявканаобразец.НайтиПоНомеру("000000001");

// Если документ найден, получаем его файлы
Если ЗначениеЗаполнено(ВладелецФайлов) Тогда
    РаботаСФайламиКлиентСервер.ПолучитьСписокПрисоединенныхФайлов(ВладелецФайлов, ПрисоединенныеФайлы);
КонецЕсли;

// --- Шаг 2: В цикле обрабатываем каждый файл ---

Для Каждого ПрисоединенныйФайл Из ПрисоединенныеФайлы Цикл
    
    // 1. Получаем двоичные данные текущего файла
    ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(ПрисоединенныйФайл.Ссылка);
    
    // 2. Помещаем их во временное хранилище и получаем уникальный адрес
    АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
    
    // 3. Создаем структуру с описанием вложения
    ОписаниеВложения = Новый Структура;
    // Указываем имя файла, под которым он будет в письме
    ОписаниеВложения.Вставить("ИмяФайла", ПрисоединенныйФайл.Наименование + "." + ПрисоединенныйФайл.Расширение);
    // Указываем адрес данных в хранилище
    ОписаниеВложения.Вставить("АдресВоВременномХранилище", АдресВоВременномХранилище);
    
    // 4. Добавляем готовое описание в общий массив вложений
    ПараметрыПисьма.Вложения.Добавить(ОписаниеВложения);
    
КонецЦикла;


// --- Шаг 3: Отправляем письмо ---

// Заполняем остальные параметры письма (кому, тема, текст и т.д.)
// ...

// Если вложения были добавлены, вызываем функцию отправки
Если ПараметрыПисьма.Вложения.Количество() > 0 Тогда
    // Эта функция может отличаться в зависимости от конфигурации
    // Например, УправлениеЭлектроннойПочтой.ОтправитьПисьмо(ПараметрыПисьма);
    
    // Или открытие формы нового письма для пользователя
    УправлениеЭлектроннойПочтойКлиент.СоздатьПисьмо(ПараметрыПисьма);
КонецЕсли;

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

← На главную