В процессе разработки в среде 1С часто возникает задача автоматизации почтовых рассылок, к которым необходимо прикрепить файлы, хранящиеся внутри информационной базы. На первый взгляд задача кажется простой, однако начинающие разработчики часто сталкиваются с техническими трудностями: от ошибок при работе с временным хранилищем до проблем с получением данных, если файлы хранятся не в самой базе, а в томах на диске. В этой статье мы подробно разберем, как правильно извлечь файл из справочника и корректно отправить его адресату.
Рассмотрим ситуацию, с которой столкнулся автор темы. Первая попытка получить файл заключалась в поиске элемента справочника и попытке поместить весь объект СправочникОбъект.Файлы во временное хранилище. Это привело к ошибке: "Переданное значение не может быть помещено во временное хранилище". Проанализируем причину: во временное хранилище нельзя помещать объекты данных (такие как ссылки или объекты справочников в чистом виде) для передачи их между клиентом и сервером в таком контексте, если система ожидает именно поток данных.
Важно понимать разницу между метаданными (карточкой файла в справочнике) и самим содержимым файла. Содержимое файла в 1С обычно хранится в реквизите с типом ХранилищеЗначения. Однако просто получить этот реквизит недостаточно — данные из него нужно извлечь методом Получить().
Если ваша конфигурация не использует Библиотеку стандартных подсистем (БСП) и файлы хранятся непосредственно в реквизите справочника, мы можем применить следующий алгоритм. Разберем его по шагам:
ФайлХранилище).ДвоичныеДанные из хранилища.Посмотрим на пример кода, который реализует эту логику:
&НаСервере
Функция ПолучитьАдресФайлаНаСервере(ИмяФайла)
// Поиск элемента справочника по наименованию
ЭлементСправочника = Справочники.Файлы.НайтиПоНаименованию(ИмяФайла);
Если ЭлементСправочника.Пустая() Тогда
Возврат Неопределено;
КонецЕсли;
// Извлечение данных из реквизита ХранилищеЗначения
// Реквизит ФайлХранилище содержит объект типа ХранилищеЗначения
ДвоичныеДанные = ЭлементСправочника.ФайлХранилище.Получить();
Если ТипЗнч(ДвоичныеДанные) <> Тип("ДвоичныеДанные") Тогда
Возврат Неопределено;
КонецЕсли;
// Помещаем данные во временное хранилище, чтобы клиент мог их скачать или отправить
Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
Возврат Адрес;
КонецФункции
Этот метод рабочий, но у него есть существенный недостаток: он не учитывает современные стандарты хранения файлов в 1С (БСП), где файлы могут находиться в томах на сервере (вне базы данных).
Если вы работаете в современных конфигурациях (таких как ERP, УТ 11, БП 3.0), настоятельно рекомендуется использовать программный интерфейс библиотеки стандартных подсистем. Проанализируем, почему это лучше: методы БСП автоматически проверяют, где физически лежит файл (в базе или в томе на диске), проверяют права доступа пользователя и корректно обрабатывают расширения файлов.
Для решения нашей задачи идеально подходит общий модуль РаботаСФайлами. Рассмотрим итоговый вариант кода, который оказался успешным у автора темы:
&НаСервере
Функция ПолучитьДвоичныеДанныеФайла(СсылкаНаФайл)
// Используем стандартный метод БСП для получения данных
// Он вернет объект типа ДвоичныеДанные независимо от способа хранения
Попытка
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
Возврат ДвоичныеДанные;
Исключение
ЗаписьЖурналаРегистрации("ОтправкаПочты", УровеньЖурналаРегистрации.Ошибка, , ,
"Не удалось получить данные файла: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
Стоит отметить, что в более свежих версиях БСП рекомендуется использовать метод ПрисоединенныеФайлы.ПолучитьДанныеФайла(СсылкаНаФайл), так как он является более универсальным для подсистемы присоединенных файлов.
Теперь, когда мы научились получать двоичные данные файла, выясним, как правильно прикрепить их к письму. Процесс создания письма обычно происходит на стороне сервера, так как именно там настроены учетные записи почты и системные параметры.
Разберем ситуацию: часто разработчики совершают ошибку, передавая в метод Добавить() вложений просто двоичные данные без указания имени файла. В этом случае получатель может получить файл с непонятным названием вроде "noname.bin". Чтобы этого избежать, всегда нужно указывать имя файла с его расширением.
Проанализируем пример кода для отправки письма с вложением:
&НаСервере
Процедура ОтправитьПисьмоСФайлом(СсылкаНаФайл, АдресПолучателя)
// 1. Получаем данные и имя файла
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
ИмяФайлаСРасширением = СсылкаНаФайл.Наименование + "." + СсылкаНаФайл.Расширение;
// 2. Создаем объект сообщения
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Вам отправлен файл из 1С";
Письмо.Получатели.Добавить(АдресПолучателя);
Письмо.Тексты.Добавить("Добрый день! Во вложении находится запрашиваемый файл.", ТипТекстаПочтовогоСообщения.ПростойТекст);
// 3. Добавляем вложение
// Важно: вторым параметром передаем имя файла, которое увидит пользователь
Письмо.Вложения.Добавить(ДвоичныеДанные, ИмяФайлаСРасширением);
// 4. Отправка через системную учетную запись
// Предполагается, что УчетнаяЗапись уже настроена в системе
УчетнаяЗапись = Справочники.УчетныеЗаписиЭлектроннойПочты.НайтиПоНаименованию("ОсновнаяПочта");
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(РаботаСПочтовымиСообщениями.ПараметрыПодключения(УчетнаяЗапись));
Почта.Послать(Письмо);
Почта.Отключиться();
Сообщить("Письмо успешно отправлено!");
Исключение
Сообщить("Ошибка при отправке: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Рассмотрим важный нюанс: передача файлов через ДвоичныеДанные напрямую в оперативную память может быть накладной для сервера, если файлы весят десятки или сотни мегабайт. Если вы планируете работать с тяжелыми вложениями, проанализируем альтернативный путь — использование временных файлов на диске.
Вместо хранения данных в оперативной памяти (в переменной типа ДвоичныеДанные), мы можем записать файл во временную директорию сервера:
ПолучитьИмяВременногоФайла() для генерации пути.ДвоичныеДанные.Записать().Такой подход гарантирует стабильную работу системы даже при одновременной отправке множества тяжелых документов несколькими пользователями.
Для успешного получения файла из справочника и его отправки почтой необходимо:
РаботаСФайлами или ПрисоединенныеФайлы) для корректного извлечения данных, особенно если используются тома хранения.Следуя этим рекомендациям, вы сможете создать надежный механизм обмена файлами в ваших решениях на платформе 1С:Предприятие.