Вопрос хранения внешних файлов (договоров в Word, сканов PDF, изображений) в системе 1С:Предприятие является одной из классических задач, с которой сталкивается каждый разработчик. Основная дилемма заключается в выборе между хранением внутри базы данных (в виде двоичных данных) и хранением на внешних ресурсах (в томах на диске). В первом случае мы получаем целостность данных, но быстро растущий размер базы (LDF/MDF файлов), что затрудняет резервное копирование. Во втором случае база остается «легкой», но возникают вопросы безопасности, прав доступа и синхронизации бэкапов.
В данной статье мы рассмотрим несколько подходов: от создания собственного простого механизма хранения на диске до использования профессиональных инструментов, таких как Библиотека стандартных подсистем (БСП). Мы проанализируем примеры кода, разберем типичные ошибки и выясним, как сделать систему надежной.
Рассмотрим ситуацию, когда нам необходимо привязать файл Microsoft Word к конкретному элементу справочника, не загружая при этом сам файл в информационную базу. Основная идея заключается в том, чтобы хранить в реквизите справочника только строковый путь к файлу на сервере или в сетевой папке.
Для реализации этого алгоритма разберем следующие шаги:
ПутьКФайлу (тип Строка, длина неограничена).КаталогХраненияФайлов, где будет прописан путь к общей сетевой папке.Посмотрим на пример кода, который позволяет выбрать файл на компьютере пользователя и переместить его в централизованное хранилище:
&НаКлиенте
Процедура ВыбратьИСохранитьФайл(Элемент)
ПолноеИмяФайла = "";
ПутьФайла = "";
// Используем диалог выбора файла
Если ПоместитьФайл(ПутьФайла, , ПолноеИмяФайла, Истина) Тогда
// Получаем имя файла из полного пути
ИмяФайла = ПолучитьИмяФайлаИзПути(ПолноеИмяФайла);
// Формируем путь назначения на основе константы
КаталогНазначения = ПолучитьКаталогХраненияСервер();
МестоКудаКопируем = КаталогНазначения + "\" + ИмяФайла;
// Выполняем копирование
КопироватьФайл(ПолноеИмяФайла, МестоКудаКопируем);
// Записываем путь в реквизит объекта
Объект.ПутьКМакетуWord = МестоКудаКопируем;
КонецЕсли;
КонецПроцедуры
Для корректной работы нам понадобятся вспомогательные функции на сервере и клиенте. Проанализируем функцию выделения имени файла, которая важна для корректного формирования пути:
&НаКлиенте
Функция ПолучитьИмяФайлаИзПути(ПолныйПуть)
ПозицияРазделителя = Найти(ПолныйПуть, "\");
ВременныйПуть = ПолныйПуть;
Пока Найти(ВременныйПуть, "\") > 0 Цикл
ПозицияРазделителя = Найти(ВременныйПуть, "\");
ВременныйПуть = Сред(ВременныйПуть, ПозицияРазделителя + 1);
КонецЦикла;
Возврат ВременныйПуть;
КонецФункции
Плюсы данного решения: оно максимально простое в реализации, не требует глубоких знаний БСП и практически не увеличивает размер базы данных. Минусы: отсутствие версионности, слабая защищенность (любой пользователь с доступом к папке может удалить файл) и сложности с правами доступа в клиент-серверном варианте.
Если ваша конфигурация основана на современных типовых решениях (УТ 11, КА 2, ERP, БП 3.0), самым правильным путем будет использование подсистемы «Работа с файлами». Это «промышленный» стандарт, который уже учитывает все подводные камни.
Основные преимущества использования БСП:
Для внедрения этого механизма в свой справочник, вам достаточно включить его в состав префикса ПрисоединенныеФайлы и добавить соответствующую команду на форму. Рекомендуем изучить документацию на ИТС в разделе «Работа с файлами», так как ручное написание подобного функционала может занять недели работы квалифицированного программиста.
Разберем основные риски, с которыми столкнется разработчик при реализации хранения файлов через прямые пути на диске (как в Варианте 1):
1. Безопасность и шифровальщики. Если вы предоставляете пользователям прямой доступ к сетевой папке на запись, любая вирусная атака (шифровальщик) на компьютер пользователя уничтожит весь архив документов компании. Профессиональные решения работают через проксирование сервером 1С, когда у пользователя нет прав на саму папку, а чтение/запись выполняет серверный процесс 1С под специальной учетной записью.
2. Целостность при бэкапе. Главный риск — рассинхронизация. Если вы восстановили базу из вчерашнего бэкапа, а файлы на диске остались сегодняшними, часть ссылок может указывать на файлы, которых еще «не существует» в логике базы, или наоборот. При использовании внешних томов необходимо строго регламентировать одновременное создание бэкапа SQL-базы и файлового хранилища.
3. Проблемы блокировок. Если один пользователь открыл Word-файл по прямой ссылке, операционная система заблокирует его на запись. Другой пользователь не сможет внести правки. В БСП эта проблема решается механизмом «извлечения» (checkout) файла во временный локальный каталог пользователя.
Проанализируем ситуацию, когда файлов становится действительно много (терабайты данных). В этом случае стоит рассмотреть дополнительные методы:
Контроль хеш-сумм. При загрузке файла в систему рекомендуется рассчитывать его MD5 или SHA-хеш и сохранять его в базе. Это позволит:
Асинхронная работа. В современных версиях платформы 8.3 рекомендуется отказываться от синхронных методов ПоместитьФайл в пользу асинхронных, таких как НачатьПомещениеФайлаНаСервер. Это предотвращает «зависание» интерфейса при передаче больших файлов и является обязательным требованием для работы в веб-клиенте.
Рассмотрим пример использования асинхронного вызова (упрощенно):
&НаКлиенте
Асинхронная Процедура ДобавитьФайлАсинхронно()
Описание = Новый ОписаниеПередаваемогоФайла(ВыбранноеИмяФайла, "");
МассивФайлов = Новый Массив;
МассивФайлов.Добавить(Описание);
Результат = Ждать НачатьПомещениеФайловНаСервер( , МассивФайлов, УникальныйИдентификатор);
// Далее обработка результата на сервере
КонецПроцедуры
Выясним, какой метод выбрать именно вам. Если вы создаете небольшую внутреннюю обработку для одного пользователя — вариант с хранением пути в реквизите и простым копированием (Вариант 1) вполне допустим. Он нагляден и легок в отладке.
Однако для корпоративных систем с множеством пользователей единственным верным решением будет использование БСП или интеграция с внешними объектными хранилищами (S3, MinIO) через API. Это гарантирует, что ваша база данных не превратится в неповоротливого гиганта, а файлы будут надежно защищены от случайного удаления или повреждения.
Помните, что архитектура хранения файлов — это фундамент системы. Исправление ошибок на этапе, когда в папке уже лежат сотни тысяч документов, обойдется гораздо дороже, чем грамотное проектирование в самом начале разработки.