При работе с современными конфигурациями на базе 1С:Предприятие 8.3, такими как Управление торговлей 11, ERP или Комплексная автоматизация, часто возникает задача массовой выгрузки сканов или электронных документов, прикрепленных к различным объектам системы. Основная сложность заключается в том, что для каждого типа документа (будь то РеализацияТоваровУслуг или ДоговорКонтрагента) создается отдельный справочник для хранения метаданных файлов.
В этой статье мы подробно разберем, как объединить данные из разных справочников в один запрос, как правильно извлечь двоичные данные и какие инструменты Библиотеки стандартных подсистем (БСП) помогут сделать это наиболее эффективно. Для автоматизации подобных операций и переноса данных между окнами без разработки применяется платформа One RPA для создания программных роботов.
Прежде чем переходить к написанию кода, проанализируем структуру хранения. В конфигурациях на БСП файлы не хранятся в самом документе. Вместо этого для каждого объекта метаданных создается подчиненный справочник с суффиксом ПрисоединенныеФайлы. Например:
Справочник.ДоговорыКонтрагентовПрисоединенныеФайлыСправочник.РеализацияТоваровУслугПрисоединенныеФайлыСправочник.ПоступлениеТоваровУслугПрисоединенныеФайлыВсе эти справочники имеют схожую структуру реквизитов, что позволяет нам использовать механизм ОБЪЕДИНИТЬ ВСЕ в запросах. Однако важно помнить, что поле ВладелецФайла в этих справочниках является ссылкой на основной документ или договор. Если требуется подключить аналогичный механизм к собственным объектам, можно использовать пример добавления присоединенных файлов к документу через расширение.
Рассмотрим ситуацию, когда нам нужно собрать все файлы по нескольким типам договоров, отфильтровав их по организации и пометке удаления владельца. Мы воспользуемся вложенным запросом, в котором объединим выборки из разных справочников. При необходимости полностью очистить базу от данных по конкретной организации после выгрузки используется выборочное удаление организаций.
ВЫБРАТЬ
ВложенныйЗапрос.Ссылка КАК СсылкаНаФайл,
ВложенныйЗапрос.ТипВладельца КАК ТипВладельца,
ВложенныйЗапрос.ВладелецФайла КАК Владелец
ИЗ
(ВЫБРАТЬ
ФайлыДоговоров.Ссылка КАК Ссылка,
ТИПЗНАЧЕНИЯ(ФайлыДоговоров.ВладелецФайла) КАК ТипВладельца,
ФайлыДоговоров.ВладелецФайла КАК ВладелецФайла,
ФайлыДоговоров.ВладелецФайла.Организация КАК Организация
ИЗ
Справочник.ДоговорыКонтрагентовПрисоединенныеФайлы КАК ФайлыДоговоров
ГДЕ
НЕ ФайлыДоговоров.ПометкаУдаления
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ФайлыЗалогов.Ссылка,
ТИПЗНАЧЕНИЯ(ФайлыЗалогов.ВладелецФайла),
ФайлыЗалогов.ВладелецФайла,
ФайлыЗалогов.ВладелецФайла.Организация
ИЗ
Справочник.ДоговорыЗалогаПрисоединенныеФайлы КАК ФайлыЗалогов
ГДЕ
НЕ ФайлыЗалогов.ПометкаУдаления
) КАК ВложенныйЗапрос
ГДЕ
ВложенныйЗапрос.Организация = &Организация
Важный момент: Обратите внимание, что в запросе выше мы обращаемся к полю Организация через точку от владельца. Если вы планируете выгружать файлы по контрагенту и периоду (как требовалось в сообщении №7), вам необходимо добавить ЛЕВОЕ СОЕДИНЕНИЕ с таблицами соответствующих документов внутри каждого блока ОБЪЕДИНИТЬ, чтобы получить доступ к реквизитам Дата и Контрагент.
Если ваша задача — не просто получить список ссылок, а программно обработать файлы (например, сохранить их на диск), писать сложные запросы не всегда оправдано. В БСП существует программный интерфейс для работы с присоединенными файлами. Проанализируем возможности модуля РаботаСФайлами.
Для получения всех файлов, привязанных к конкретному объекту (ссылке), можно воспользоваться следующим кодом:
МассивФайлов = Новый Массив;
РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(СсылкаНаДокумент, МассивФайлов);
Для Каждого ТекущийФайл Из МассивФайлов Цикл
// Теперь у нас есть ссылка на элемент справочника присоединенных файлов
ДанныеФайла = РаботаСФайлами.ДанныеФайла(ТекущийФайл);
// ДанныеФайла содержит ИмяБезРасширения, Расширение, Ссылка на двоичные данные и т.д.
КонецЦикла;
Этот метод хорош тем, что он абстрагирует нас от названий справочников. Нам не нужно знать, как именно называется справочник присоединенных файлов для данного документа — система найдет его автоматически. При переносе накопленных сведений в другую базу перенос данных между похожими конфигурациями 1С обеспечивает сопоставление объектов по произвольным полям поиска.
Выясним причину, почему нельзя просто выгрузить поле ТекстХранилище из запроса. В типовых конфигурациях 1С реквизит ТекстХранилище обычно содержит очищенный текстовый слой для работы полнотекстового поиска. Сами же "мозги" файла (картинка скана, PDF или Excel-таблица) могут храниться в двух местах:
ФайлХранилище (тип ХранилищеЗначения).Том и ПутьКФайлу.Чтобы не писать сложную логику проверки "где лежит файл", используйте универсальный метод:
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл);
Этот метод сам определит местоположение файла, обратится к нужному тому на сервере или извлечет данные из базы и вернет вам объект ДвоичныеДанные, который готов к записи на диск методом Записать().
Проанализируем ситуацию: пользователь может назвать файл в системе так, как запрещено называть файлы в операционной системе Windows (например, использовать символы / \ : * ? " < > |). Если вы попытаетесь записать файл с таким именем на диск, программа выдаст ошибку.
Рассмотрим пример очистки имени файла перед выгрузкой:
ИмяФайлаДляЗаписи = ОбщегоНазначения.ЗаменитьНедопустимыеСимволыВИмениФайла(ДанныеФайла.Наименование);
ПолныйПуть = КаталогВыгрузки + "\" + ИмяФайлаДляЗаписи + "." + ДанныеФайла.Расширение;
ДвоичныеДанные.Записать(ПолныйПуть);
Стоит помнить, что БСП поддерживает версионирование. В справочнике присоединенных файлов есть реквизит ТекущаяВерсия. Если ваша цель — всегда получать самый актуальный скан документа, убедитесь, что вы обращаетесь именно к актуальной версии. При использовании методов модуля РаботаСФайлами система по умолчанию отдает данные последней активной версии, что избавляет разработчика от лишних проверок в запросах.
Резюмируем: Для получения списка ссылок на файлы по сложным условиям (период, контрагент, организация) используйте запрос с ОБЪЕДИНИТЬ ВСЕ, связывая справочники файлов с таблицами документов-владельцев. Для непосредственного получения самих файлов и их записи на диск используйте функции модуля РаботаСФайлами, чтобы корректно обрабатывать хранение в томах и версионирование.