Как программно прикрепить файл к внутреннему документу в 1С:Документооборот 8?

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

При работе с системой 1С:Документооборот часто возникает необходимость программно создавать внутренние документы и автоматически прикреплять к ним файлы, например, на основе определенных критериев или данных. Эта задача требует знания специфических функций и общих модулей, которые предоставляет конфигурация. В этой статье мы подробно рассмотрим различные подходы к программному прикреплению файлов, анализируя примеры кода и важные нюансы. Для автоматизации подобного процесса на основе входящей почты можно использовать обработчик бизнес-события для создания внутреннего документа и прикрепления файлов из писем.

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

Основные подходы к программному прикреплению файлов

В 1С:Документооборот существует несколько способов программного прикрепления файлов, в зависимости от места их хранения (на диске сервера или клиента) и требуемой детализации управления процессом. Рассмотрим наиболее релевантные и часто используемые методы.

Прикрепление файла, расположенного на диске сервера

Если файл, который необходимо прикрепить, уже находится на диске сервера, и нам известен полный путь к нему, наиболее прямым и эффективным способом является использование функции РаботаСФайламиВнешнийВызов.СоздатьФайлНаОсновеФайлаНаДиске(). Этот метод идеально подходит для сценариев, когда файлы генерируются или загружаются на сервер, а затем автоматически связываются с созданными в 1С документами. Для автоматической генерации и прикрепления PDF-копий к документам можно воспользоваться обработчиком для конвертации и добавления файлов PDF.

Для успешного выполнения этой операции нам потребуется два основных параметра:

  1. СсылкаНаВнутреннийДокумент: Ссылка на объект внутреннего документа, который уже сохранен в информационной базе и к которому мы хотим прикрепить файл.
  2. ПутьКФайлу: Полный путь к файлу на диске сервера, включая имя файла и его расширение (например, "C:\МоиДокументы\Отчет.pdf").

Рассмотрим пример реализации:


// Предположим, что мы уже программно создали внутренний документ
// и записали его, чтобы получить ссылку.
// Если документ создается в той же транзакции, не забудьте его записать перед прикреплением файла.
ВнутреннийДокументОбъект = Справочники.ВнутренниеДокументы.СоздатьЭлемент();
ВнутреннийДокументОбъект.Наименование = "Протокол совещания от " + Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
ВнутреннийДокументОбъект.ВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Протокол");
ВнутреннийДокументОбъект.Заголовок = ВнутреннийДокументОбъект.Наименование;
ВнутреннийДокументОбъект.ДатаСоздания = ТекущаяДатаСеанса();
ВнутреннийДокументОбъект.Ответственный = ПользователиИнформационнойБазы.ТекущийПользователь();
// Заполняем другие необходимые реквизиты документа
// ...
ВнутреннийДокументОбъект.Записать(); // Обязательно записываем документ
СсылкаНаВнутреннийДокумент = ВнутреннийДокументОбъект.Ссылка;

// Определяем полный путь к файлу на диске сервера.
// Убедитесь, что сервер 1С имеет доступ к этому пути.
ПутьКФайлуНаСервере = "C:\ПутьКФайлам\ПротоколСовещания.pdf"; 

// Проверяем существование файла на диске, если это критично.
ФайлДляПрикрепления = Новый Файл(ПутьКФайлуНаСервере);
Если Не ФайлДляПрикрепления.Существует() Тогда
    Сообщить("Ошибка: Файл по пути '" + ПутьКФайлуНаСервере + "' не найден на диске сервера.");
    Возврат;
КонецЕсли;

// Прикрепляем файл к созданному внутреннему документу
Попытка
    // РаботаСФайламиВнешнийВызов - это общий модуль, который часто используется
    // для серверных операций с файлами в 1С:Документооборот.
    ФайлСсылка = РаботаСФайламиВнешнийВызов.СоздатьФайлНаОсновеФайлаНаДиске(СсылкаНаВнутреннийДокумент, ПутьКФайлуНаСервере);
    
    Если ФайлСсылка <> Неопределено Тогда
        Сообщить("Файл '" + ПутьКФайлуНаСервере + "' успешно прикреплен к документу '" + СсылкаНаВнутреннийДокумент + "'.");
        // Теперь вы можете выполнить дополнительные действия с ФайлСсылка, если это необходимо
        // Например, установить категории, изменить описание и т.д.
        // ФайлОбъект = ФайлСсылка.ПолучитьОбъект();
        // ФайлОбъект.Описание = "Прикреплено автоматически";
        // ФайлОбъект.Записать();
    Иначе
        Сообщить("Не удалось прикрепить файл '" + ПутьКФайлуНаСервере + "' к документу '" + СсылкаНаВнутреннийДокумент + "'.");
    КонецЕсли;
Исключение
    Сообщить("Произошла ошибка при попытке прикрепления файла: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;

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

Создание файла и его версии через объект "СведенияОФайле"

Более детализированный подход к прикреплению файлов включает использование объекта СведенияОФайле и функций из общих модулей РаботаСФайламиКлиентСервер и РаботаСФайламиВызовСервера. Этот метод позволяет нам более точно контролировать метаданные файла (имя, расширение, размер, автор, время изменения) и сразу создавать первую версию файла. Он удобен, когда нам нужно собрать информацию о файле и его содержимом перед добавлением в систему.

Разберем процесс по шагам:

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

    
    // Предположим, что файл находится на сервере по известному пути.
    // Если файл находится на клиенте, его следует передать на сервер,
    // например, с помощью ПоместитьВоВременноеХранилище() на клиенте
    // и передачей полученного адреса на сервер.
    ПутьКФайлуНаДиске = "C:\МоиДокументы\ВажныйДокумент.docx"; 
    
    ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлуНаДиске);
    АдресВременногоХранилищаФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, УникальныйИдентификатор);
    
  2. Формирование объекта СведенияОФайле. Этот объект представляет собой структуру, содержащую всю необходимую информацию о файле и его первой версии. Мы заполняем такие поля как АдресВременногоХранилищаФайла, Имя (без расширения), Расширение (без точки), Размер, ВремяИзменения, Автор.

    
    СведенияОФайле = РаботаСФайламиКлиентСервер.СведенияОФайле();
    СведенияОФайле.АдресВременногоХранилищаФайла = АдресВременногоХранилищаФайла;
    СведенияОФайле.Имя = "ВажныйДокумент"; // Имя файла без расширения
    СведенияОФайле.Расширение = "docx";     // Расширение файла без точки
    СведенияОФайле.Размер = ДвоичныеДанныеФайла.Размер();
    СведенияОФайле.ВремяИзменения = ТекущаяДата();
    СведенияОФайле.Автор = ПользователиИнформационнойБазы.ТекущийПользователь(); 
    // Если необходимо извлечь текст для полнотекстового поиска, 
    // можно использовать АдресВременногоХранилищаТекста
    // СведенияОФайле.АдресВременногоХранилищаТекста = ИзвлечьТекстВХранилищеЗначения(ПутьКФайлуНаДиске);
    
  3. Создание файла в базе данных с привязкой к владельцу. После подготовки всех сведений, мы вызываем функцию РаботаСФайламиВызовСервера.СоздатьФайлСВерсией(). Эта функция создает новый элемент справочника "Файлы", привязывает его к указанному владельцу (нашему внутреннему документу) и создает первую версию файла, используя предоставленные двоичные данные и метаданные.

    
    // Предположим, у нас уже есть СсылкаНаВнутреннийДокумент
    // СсылкаНаВнутреннийДокумент = ...
    
    Попытка
        ФайлСсылка = РаботаСФайламиВызовСервера.СоздатьФайлСВерсией(СсылкаНаВнутреннийДокумент, СведенияОФайле);
                
        Если ФайлСсылка <> Неопределено Тогда
            Сообщить("Файл '" + СведенияОФайле.Имя + "." + СведенияОФайле.Расширение + "' успешно создан и прикреплен к документу " + СсылкаНаВнутреннийДокумент);
        Иначе
            Сообщить("Не удалось создать и прикрепить файл.");
        КонецЕсли;
    Исключение
        Сообщить("Ошибка при создании файла и версии: " + ОписаниеОшибки(), СтатусСообщения.Важное);
    КонецПопытки;
    

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

Комплексный пример автоматической загрузки входящих документов

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

Основная идея заключается в следующих шагах:

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

Рассмотрим ключевые фрагменты кода, необходимые для реализации этого подхода:

1. Создание внутреннего документа (владельца файла)

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


// ... (предварительная обработка файла, получение его имени и расширения) ...
// Например, ИмяБезРасширения = "СлужебнаяЗаписка";
// Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();

// Создаем новый элемент справочника "ВнутренниеДокументы"
ОбъектВладелец = Справочники.ВнутренниеДокументы.СоздатьЭлемент();
ОбъектВладелец.Наименование = СокрЛП(ИмяБезРасширения);
// Здесь мы можем установить ВидДокумента, Заголовок, Ответственного и другие реквизиты
ОбъектВладелец.ВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Служебная записка"); // Пример
ОбъектВладелец.Заголовок = СокрЛП(ИмяБезРасширения);
ОбъектВладелец.КоличествоЛистов = 1; // Заполняем по необходимости
ОбъектВладелец.КоличествоЭкземпляров = 1;
ОбъектВладелец.Создал = Пользователь;
ОбъектВладелец.ДатаСоздания = ТекущаяДатаСеанса();
ОбъектВладелец.Записать(); // Обязательно записываем документ для получения ссылки
Владелец = ОбъектВладелец.Ссылка;

2. Извлечение текста и помещение в хранилище значений (для полнотекстового поиска)

Для корректной работы полнотекстового поиска в 1С:Документооборот рекомендуется извлекать текстовое содержимое из файлов и помещать его в хранилище значений. Функция ИзвлечьТекстВХранилищеЗначения (или аналогичная) выполняет эту задачу.


// Функция ИзвлечьТекстВХранилищеЗначения(ПолноеИмяФайла)
// Это пример функции, которая может быть реализована на сервере.
// Она использует платформенные или встроенные механизмы извлечения текста.
Функция ИзвлечьТекстВХранилищеЗначения(ПолноеИмяФайла)
    Текст = "";
    // Проверяем настройки извлечения текста на сервере
    Если Константы.ИзвлекатьТекстыФайловНаСервере.Получить() Тогда
        // Проверяем тип платформы сервера, так как извлечение текста может быть платформозависимым
        ТипПлатформыСервера = ОбщегоНазначенияДокументооборотПовтИсп.ТипПлатформыСервера();
        Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда
            // Используем стандартную функцию извлечения текста
            Текст = ФайловыеФункцииСлужебныйКлиентСервер.ИзвлечьТекст(ПолноеИмяФайла);
        КонецЕсли;
    КонецЕсли;

    Если ПустаяСтрока(Текст) Тогда
        Возврат Новый ХранилищеЗначения("");
    КонецЕсли;
    
    Возврат Новый ХранилищеЗначения(Текст);
КонецФункции

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

3. Создание элемента справочника "Файлы"

Центральной частью является вызов функции РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы(). Эта функция является оберткой, которая инкапсулирует логику создания записи в справочнике "Файлы" и ее первой версии. Она принимает множество параметров, позволяя тонко настроить свойства создаваемого файла.


// ... (ранее мы уже получили ссылку на Владелец, ИмяБезРасширения, Расширение, Пользователь) ...
// Также нам нужны полные пути к файлу
ПутьКФайлуНаДиске = "C:\ПутьКФайлам\СлужебнаяЗаписка.docx"; // Пример

// Создаем объект Файл для получения метаданных
ВыбранныйФайлОбъект = Новый Файл(ПутьКФайлуНаДиске);

// Размещаем двоичные данные файла во временном хранилище
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлуНаДиске);
АдресВременногоХранилищаФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);

// Извлекаем текст для полнотекстового поиска
АдресВременногоХранилищаТекста = ИзвлечьТекстВХранилищеЗначения(ПутьКФайлуНаДиске);

// Определяем параметры распознавания текста (если применимо)
ПараметрыРаспознавания = Новый Структура("СтратегияРаспознавания, ЯзыкРаспознавания, РаспознатьПослеДобавления");
ПараметрыРаспознавания.СтратегияРаспознавания = Перечисления.СтратегииРаспознаванияТекста.ПоместитьТолькоВТекстовыйОбраз;
ПараметрыРаспознавания.ЯзыкРаспознавания = РаботаСФайламиВызовСервера.ПолучитьЯзыкРаспознавания(); // Например, "Русский"
ПараметрыРаспознавания.РаспознатьПослеДобавления = Истина;

// Массив для сбора ссылок на добавленные файлы
ДобавленныеФайлы = Новый Массив();
МассивСтруктурВсехФайлов = Новый Массив(); // Также может использоваться для сбора информации

КомментарийКФайлу = "Автоматически прикреплен к внутреннему документу";
ХранитьВерсии = Истина; // Если требуется версионирование файла

// Вызываем функцию для создания элемента справочника Файлы
Попытка
    РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы(
        ВыбранныйФайлОбъект,                     // Объект Файл с метаданными
        МассивСтруктурВсехФайлов,              // Массив для добавления информации о файлах
        Владелец,                              // Ссылка на созданный ВнутреннийДокумент
        Неопределено,                          // ИдентификаторФормы (для серверного вызова может быть Неопределено)
        КомментарийКФайлу,                     // Комментарий к файлу/версии
        ХранитьВерсии,                         // Нужно ли хранить версии
        ДобавленныеФайлы,                      // Массив для сбора ссылок на созданные файлы
        АдресВременногоХранилищаФайла,         // Адрес двоичных данных в хранилище
        АдресВременногоХранилищаТекста,        // Адрес извлеченного текста в хранилище
        Пользователь,                          // Пользователь, создавший файл
        ПараметрыРаспознавания,                // Параметры распознавания текста
        Неопределено                           // Категории файлов (если есть)
    );
    Если ДобавленныеФайлы.Количество() > 0 Тогда
        Сообщить("Файл успешно прикреплен к внутреннему документу: " + ДобавленныеФайлы[0]);
    Иначе
        Сообщить("Не удалось прикрепить файл.");
    КонецЕсли;
Исключение
    Сообщить("Ошибка при создании элемента справочника 'Файлы': " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;

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

Общие принципы и важные нюансы работы с файлами в 1С:Документооборот

Для эффективной работы с файлами в 1С:Документооборот важно понимать некоторые фундаментальные принципы, которые отличают управление файлами в системе от обычной работы с файловой системой на диске:

  1. Копии файлов: При загрузке файлов в 1С:Документооборот всегда создаются их копии. Это означает, что связь между исходным файлом на диске и его копией в информационной системе не сохраняется. Любые изменения, внесенные в оригинальный файл на диске после его загрузки, не приведут к автоматическому обновлению копии в системе. Для поддержания актуальности рекомендуется работать с файлом исключительно в 1С:Документооборот, а его оригинал с диска, при необходимости, удалять после успешной загрузки.
  2. Хранение: Все файлы могут храниться либо непосредственно в информационной базе (что удобно для небольших баз и файлов), либо в томах на диске. Последний вариант предпочтителен для больших объемов данных, так как позволяет разгрузить основную базу и оптимизировать производительность. Для просмотра или редактирования файлы копируются на локальный компьютер пользователя и открываются соответствующими приложениями (например, Microsoft Office).
  3. Структура хранения: Файлы в соответствующем справочнике Файлы хранятся в логической структуре папок, аналогичной файловой системе. Для каждой папки в 1С:Документооборот можно настроить индивидуальные права доступа, что обеспечивает гибкое управление безопасностью. Важной особенностью является то, что в рамках одного документа (владельца) допускается прикрепление файлов с одинаковыми именами, чего файловая система обычно не позволяет.
  4. Версионирование: Система 1С:Документооборот поддерживает хранение истории изменений файла, то есть его версий. Версии сохраняются автоматически при каждом изменении, если для файла установлено свойство "Хранить версии". Это критически важная функциональность для контроля изменений и возможности отката к предыдущим состояниям файла. Рекомендуется добавлять краткие описания внесенных изменений к каждой сохраняемой версии.
  5. Максимальный размер файла: В системе предусмотрена возможность ограничения максимального размера файлов, которые могут быть добавлены в информационную базу. Это важная настройка для предотвращения проблем с производительностью и нехваткой памяти при работе с очень большими файлами. По умолчанию часто устанавливается ограничение, например, в 50 Мб.
  6. Извлечение текста: Для корректной работы полнотекстового поиска, который позволяет находить документы по содержимому прикрепленных файлов, из файлов популярных форматов (например, PDF, DOCX, XLSX) извлекается текстовое содержимое. Процесс извлечения может производиться на сервере (обычно в фоновом задании) или на клиентских компьютерах непосредственно перед загрузкой, в зависимости от настроек конфигурации.
  7. Роли файлов (в редакции 3.0): В 1С:Документооборот версии 3.0 появилась концепция "ролей файлов". Роли позволяют более осмысленно группировать файлы, прикрепленные к документу, и определять их функциональное назначение (например, "Договор", "Приложение 1", "Акт"). Для каждой роли можно настроить дополнительные параметры, такие как "Обязательный файл" или "Только один файл для этой роли", что повышает контроль над комплектностью документов.
  8. Интеграция: 1С:Документооборот 8 предлагает разнообразные механизмы для интеграции с другими информационными системами. Это включает в себя использование веб-сервисов, RESTful API, протоколов HTTP и FTP, а также готовые инструменты для массовой загрузки файлов. Такая гибкость позволяет встраивать функционал документооборота в сложные ИТ-ландшафты предприятия.

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

Заключение

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

← На главную