При работе с системой 1С:Документооборот часто возникает необходимость программно создавать внутренние документы и автоматически прикреплять к ним файлы, например, на основе определенных критериев или данных. Эта задача требует знания специфических функций и общих модулей, которые предоставляет конфигурация. В этой статье мы подробно рассмотрим различные подходы к программному прикреплению файлов, анализируя примеры кода и важные нюансы. Для автоматизации подобного процесса на основе входящей почты можно использовать обработчик бизнес-события для создания внутреннего документа и прикрепления файлов из писем.
Прежде чем мы приступим к детальному разбору, важно отметить, что любой документ, к которому мы планируем прикрепить файл, должен быть предварительно записан в информационную базу. Это необходимо для того, чтобы получить на него ссылку, которая будет использоваться в качестве владельца прикрепляемого файла. Без ссылки на записанный объект-владелец система не сможет корректно связать файл с документом.
В 1С:Документооборот существует несколько способов программного прикрепления файлов, в зависимости от места их хранения (на диске сервера или клиента) и требуемой детализации управления процессом. Рассмотрим наиболее релевантные и часто используемые методы.
Если файл, который необходимо прикрепить, уже находится на диске сервера, и нам известен полный путь к нему, наиболее прямым и эффективным способом является использование функции РаботаСФайламиВнешнийВызов.СоздатьФайлНаОсновеФайлаНаДиске(). Этот метод идеально подходит для сценариев, когда файлы генерируются или загружаются на сервер, а затем автоматически связываются с созданными в 1С документами. Для автоматической генерации и прикрепления PDF-копий к документам можно воспользоваться обработчиком для конвертации и добавления файлов PDF.
Для успешного выполнения этой операции нам потребуется два основных параметра:
Рассмотрим пример реализации:
// Предположим, что мы уже программно создали внутренний документ
// и записали его, чтобы получить ссылку.
// Если документ создается в той же транзакции, не забудьте его записать перед прикреплением файла.
ВнутреннийДокументОбъект = Справочники.ВнутренниеДокументы.СоздатьЭлемент();
ВнутреннийДокументОбъект.Наименование = "Протокол совещания от " + Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");
ВнутреннийДокументОбъект.ВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Протокол");
ВнутреннийДокументОбъект.Заголовок = ВнутреннийДокументОбъект.Наименование;
ВнутреннийДокументОбъект.ДатаСоздания = ТекущаяДатаСеанса();
ВнутреннийДокументОбъект.Ответственный = ПользователиИнформационнойБазы.ТекущийПользователь();
// Заполняем другие необходимые реквизиты документа
// ...
ВнутреннийДокументОбъект.Записать(); // Обязательно записываем документ
СсылкаНаВнутреннийДокумент = ВнутреннийДокументОбъект.Ссылка;
// Определяем полный путь к файлу на диске сервера.
// Убедитесь, что сервер 1С имеет доступ к этому пути.
ПутьКФайлуНаСервере = "C:\ПутьКФайлам\ПротоколСовещания.pdf";
// Проверяем существование файла на диске, если это критично.
ФайлДляПрикрепления = Новый Файл(ПутьКФайлуНаСервере);
Если Не ФайлДляПрикрепления.Существует() Тогда
Сообщить("Ошибка: Файл по пути '" + ПутьКФайлуНаСервере + "' не найден на диске сервера.");
Возврат;
КонецЕсли;
// Прикрепляем файл к созданному внутреннему документу
Попытка
// РаботаСФайламиВнешнийВызов - это общий модуль, который часто используется
// для серверных операций с файлами в 1С:Документооборот.
ФайлСсылка = РаботаСФайламиВнешнийВызов.СоздатьФайлНаОсновеФайлаНаДиске(СсылкаНаВнутреннийДокумент, ПутьКФайлуНаСервере);
Если ФайлСсылка <> Неопределено Тогда
Сообщить("Файл '" + ПутьКФайлуНаСервере + "' успешно прикреплен к документу '" + СсылкаНаВнутреннийДокумент + "'.");
// Теперь вы можете выполнить дополнительные действия с ФайлСсылка, если это необходимо
// Например, установить категории, изменить описание и т.д.
// ФайлОбъект = ФайлСсылка.ПолучитьОбъект();
// ФайлОбъект.Описание = "Прикреплено автоматически";
// ФайлОбъект.Записать();
Иначе
Сообщить("Не удалось прикрепить файл '" + ПутьКФайлуНаСервере + "' к документу '" + СсылкаНаВнутреннийДокумент + "'.");
КонецЕсли;
Исключение
Сообщить("Произошла ошибка при попытке прикрепления файла: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Обратите внимание: функция СоздатьФайлНаОсновеФайлаНаДиске ожидает, что указанный путь доступен с файловой системы сервера 1С. Если вы работаете в клиент-серверном варианте, а путь указывает на клиентский диск, этот метод не подойдет напрямую. В таких случаях сначала необходимо передать файл на сервер во временное хранилище.
Более детализированный подход к прикреплению файлов включает использование объекта СведенияОФайле и функций из общих модулей РаботаСФайламиКлиентСервер и РаботаСФайламиВызовСервера. Этот метод позволяет нам более точно контролировать метаданные файла (имя, расширение, размер, автор, время изменения) и сразу создавать первую версию файла. Он удобен, когда нам нужно собрать информацию о файле и его содержимом перед добавлением в систему.
Разберем процесс по шагам:
Получение двоичных данных файла и размещение их во временном хранилище. Прежде чем создать запись о файле в базе, его двоичные данные (само содержимое) должны быть временно сохранены на сервере 1С. Для этого мы читаем файл с диска (в серверном контексте) и помещаем его в хранилище значений, получая адрес временного хранилища. Если файл находится на клиенте, его сначала нужно загрузить на сервер.
// Предположим, что файл находится на сервере по известному пути.
// Если файл находится на клиенте, его следует передать на сервер,
// например, с помощью ПоместитьВоВременноеХранилище() на клиенте
// и передачей полученного адреса на сервер.
ПутьКФайлуНаДиске = "C:\МоиДокументы\ВажныйДокумент.docx";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлуНаДиске);
АдресВременногоХранилищаФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанныеФайла, УникальныйИдентификатор);
Формирование объекта СведенияОФайле.
Этот объект представляет собой структуру, содержащую всю необходимую информацию о файле и его первой версии. Мы заполняем такие поля как АдресВременногоХранилищаФайла, Имя (без расширения), Расширение (без точки), Размер, ВремяИзменения, Автор.
СведенияОФайле = РаботаСФайламиКлиентСервер.СведенияОФайле();
СведенияОФайле.АдресВременногоХранилищаФайла = АдресВременногоХранилищаФайла;
СведенияОФайле.Имя = "ВажныйДокумент"; // Имя файла без расширения
СведенияОФайле.Расширение = "docx"; // Расширение файла без точки
СведенияОФайле.Размер = ДвоичныеДанныеФайла.Размер();
СведенияОФайле.ВремяИзменения = ТекущаяДата();
СведенияОФайле.Автор = ПользователиИнформационнойБазы.ТекущийПользователь();
// Если необходимо извлечь текст для полнотекстового поиска,
// можно использовать АдресВременногоХранилищаТекста
// СведенияОФайле.АдресВременногоХранилищаТекста = ИзвлечьТекстВХранилищеЗначения(ПутьКФайлуНаДиске);
Создание файла в базе данных с привязкой к владельцу.
После подготовки всех сведений, мы вызываем функцию РаботаСФайламиВызовСервера.СоздатьФайлСВерсией(). Эта функция создает новый элемент справочника "Файлы", привязывает его к указанному владельцу (нашему внутреннему документу) и создает первую версию файла, используя предоставленные двоичные данные и метаданные.
// Предположим, у нас уже есть СсылкаНаВнутреннийДокумент
// СсылкаНаВнутреннийДокумент = ...
Попытка
ФайлСсылка = РаботаСФайламиВызовСервера.СоздатьФайлСВерсией(СсылкаНаВнутреннийДокумент, СведенияОФайле);
Если ФайлСсылка <> Неопределено Тогда
Сообщить("Файл '" + СведенияОФайле.Имя + "." + СведенияОФайле.Расширение + "' успешно создан и прикреплен к документу " + СсылкаНаВнутреннийДокумент);
Иначе
Сообщить("Не удалось создать и прикрепить файл.");
КонецЕсли;
Исключение
Сообщить("Ошибка при создании файла и версии: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Этот метод предоставляет более тонкий контроль над создаваемым файлом и его метаданными, что может быть полезно для сложных сценариев интеграции или специфических требований к хранению файлов.
В конфигурации 1С:Документооборот часто реализуются механизмы автоматической загрузки файлов, например, из папок, настроенных для определенных видов документов. Приведенный в сообщении 12 пример демонстрирует такой комплексный подход для входящих документов. Мы можем адаптировать его ключевые фрагменты для прикрепления файлов к внутренним документам.
Основная идея заключается в следующих шагах:
РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы() для записи информации о файле в базу данных.Рассмотрим ключевые фрагменты кода, необходимые для реализации этого подхода:
Перед тем как прикрепить файл, нам нужно создать и записать внутренний документ, который будет выступать в роли владельца. В примере из форума это Справочники.ВходящиеДокументы, но для нашей задачи мы используем Справочники.ВнутренниеДокументы.
// ... (предварительная обработка файла, получение его имени и расширения) ...
// Например, ИмяБезРасширения = "СлужебнаяЗаписка";
// Пользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
// Создаем новый элемент справочника "ВнутренниеДокументы"
ОбъектВладелец = Справочники.ВнутренниеДокументы.СоздатьЭлемент();
ОбъектВладелец.Наименование = СокрЛП(ИмяБезРасширения);
// Здесь мы можем установить ВидДокумента, Заголовок, Ответственного и другие реквизиты
ОбъектВладелец.ВидДокумента = Справочники.ВидыВнутреннихДокументов.НайтиПоНаименованию("Служебная записка"); // Пример
ОбъектВладелец.Заголовок = СокрЛП(ИмяБезРасширения);
ОбъектВладелец.КоличествоЛистов = 1; // Заполняем по необходимости
ОбъектВладелец.КоличествоЭкземпляров = 1;
ОбъектВладелец.Создал = Пользователь;
ОбъектВладелец.ДатаСоздания = ТекущаяДатаСеанса();
ОбъектВладелец.Записать(); // Обязательно записываем документ для получения ссылки
Владелец = ОбъектВладелец.Ссылка;
Для корректной работы полнотекстового поиска в 1С:Документооборот рекомендуется извлекать текстовое содержимое из файлов и помещать его в хранилище значений. Функция ИзвлечьТекстВХранилищеЗначения (или аналогичная) выполняет эту задачу.
// Функция ИзвлечьТекстВХранилищеЗначения(ПолноеИмяФайла)
// Это пример функции, которая может быть реализована на сервере.
// Она использует платформенные или встроенные механизмы извлечения текста.
Функция ИзвлечьТекстВХранилищеЗначения(ПолноеИмяФайла)
Текст = "";
// Проверяем настройки извлечения текста на сервере
Если Константы.ИзвлекатьТекстыФайловНаСервере.Получить() Тогда
// Проверяем тип платформы сервера, так как извлечение текста может быть платформозависимым
ТипПлатформыСервера = ОбщегоНазначенияДокументооборотПовтИсп.ТипПлатформыСервера();
Если ТипПлатформыСервера = ТипПлатформы.Windows_x86 ИЛИ ТипПлатформыСервера = ТипПлатформы.Windows_x86_64 Тогда
// Используем стандартную функцию извлечения текста
Текст = ФайловыеФункцииСлужебныйКлиентСервер.ИзвлечьТекст(ПолноеИмяФайла);
КонецЕсли;
КонецЕсли;
Если ПустаяСтрока(Текст) Тогда
Возврат Новый ХранилищеЗначения("");
КонецЕсли;
Возврат Новый ХранилищеЗначения(Текст);
КонецФункции
Результатом этой функции будет адрес временного хранилища, содержащий извлеченный текст.
Центральной частью является вызов функции РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы(). Эта функция является оберткой, которая инкапсулирует логику создания записи в справочнике "Файлы" и ее первой версии. Она принимает множество параметров, позволяя тонко настроить свойства создаваемого файла.
// ... (ранее мы уже получили ссылку на Владелец, ИмяБезРасширения, Расширение, Пользователь) ...
// Также нам нужны полные пути к файлу
ПутьКФайлуНаДиске = "C:\ПутьКФайлам\СлужебнаяЗаписка.docx"; // Пример
// Создаем объект Файл для получения метаданных
ВыбранныйФайлОбъект = Новый Файл(ПутьКФайлуНаДиске);
// Размещаем двоичные данные файла во временном хранилище
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлуНаДиске);
АдресВременногоХранилищаФайла = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
// Извлекаем текст для полнотекстового поиска
АдресВременногоХранилищаТекста = ИзвлечьТекстВХранилищеЗначения(ПутьКФайлуНаДиске);
// Определяем параметры распознавания текста (если применимо)
ПараметрыРаспознавания = Новый Структура("СтратегияРаспознавания, ЯзыкРаспознавания, РаспознатьПослеДобавления");
ПараметрыРаспознавания.СтратегияРаспознавания = Перечисления.СтратегииРаспознаванияТекста.ПоместитьТолькоВТекстовыйОбраз;
ПараметрыРаспознавания.ЯзыкРаспознавания = РаботаСФайламиВызовСервера.ПолучитьЯзыкРаспознавания(); // Например, "Русский"
ПараметрыРаспознавания.РаспознатьПослеДобавления = Истина;
// Массив для сбора ссылок на добавленные файлы
ДобавленныеФайлы = Новый Массив();
МассивСтруктурВсехФайлов = Новый Массив(); // Также может использоваться для сбора информации
КомментарийКФайлу = "Автоматически прикреплен к внутреннему документу";
ХранитьВерсии = Истина; // Если требуется версионирование файла
// Вызываем функцию для создания элемента справочника Файлы
Попытка
РаботаСФайламиКлиентСервер.СоздатьЭлементСправочникаФайлы(
ВыбранныйФайлОбъект, // Объект Файл с метаданными
МассивСтруктурВсехФайлов, // Массив для добавления информации о файлах
Владелец, // Ссылка на созданный ВнутреннийДокумент
Неопределено, // ИдентификаторФормы (для серверного вызова может быть Неопределено)
КомментарийКФайлу, // Комментарий к файлу/версии
ХранитьВерсии, // Нужно ли хранить версии
ДобавленныеФайлы, // Массив для сбора ссылок на созданные файлы
АдресВременногоХранилищаФайла, // Адрес двоичных данных в хранилище
АдресВременногоХранилищаТекста, // Адрес извлеченного текста в хранилище
Пользователь, // Пользователь, создавший файл
ПараметрыРаспознавания, // Параметры распознавания текста
Неопределено // Категории файлов (если есть)
);
Если ДобавленныеФайлы.Количество() > 0 Тогда
Сообщить("Файл успешно прикреплен к внутреннему документу: " + ДобавленныеФайлы[0]);
Иначе
Сообщить("Не удалось прикрепить файл.");
КонецЕсли;
Исключение
Сообщить("Ошибка при создании элемента справочника 'Файлы': " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Этот подход является наиболее полным и позволяет учесть практически все аспекты работы с файлами в 1С:Документооборот, включая версионирование и полнотекстовый поиск.
Для эффективной работы с файлами в 1С:Документооборот важно понимать некоторые фундаментальные принципы, которые отличают управление файлами в системе от обычной работы с файловой системой на диске:
Файлы хранятся в логической структуре папок, аналогичной файловой системе. Для каждой папки в 1С:Документооборот можно настроить индивидуальные права доступа, что обеспечивает гибкое управление безопасностью. Важной особенностью является то, что в рамках одного документа (владельца) допускается прикрепление файлов с одинаковыми именами, чего файловая система обычно не позволяет.
Понимание этих принципов позволяет более грамотно проектировать и реализовывать решения по автоматизации работы с файлами, обеспечивая их надежное хранение, быстрый поиск и эффективное управление в рамках 1С:Документооборот.
Мы рассмотрели несколько подходов к программному прикреплению файлов в 1С:Документооборот, начиная от прямого использования функции РаботаСФайламиВнешнийВызов.СоздатьФайлНаОсновеФайлаНаДиске() до более детального управления через объект СведенияОФайле и комплексный пример автоматической загрузки. Каждый из этих методов имеет свои преимущества и область применения. Критически важно убедиться, что документ-владелец записан в базу данных перед попыткой прикрепления к нему файла. Использование стандартных общих модулей 1С:Документооборот позволяет интегрировать мощный функционал управления файлами в наши программные решения, обеспечивая соответствие лучшим практикам системы.