Как организовать удобное хранение скан-копий документов в 1С:Комплексная автоматизация без раздувания базы данных?

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

При активном ведении учета в 1С:Комплексная автоматизация 1.1 (КА 1.1) рано или поздно любая организация сталкивается с лавинообразным ростом объема базы данных. Главный виновник этого процесса — скан-копии первичных документов (счетов-фактур, накладных, актов), которые пользователи прикрепляют к объектам системы. Если хранить файлы непосредственно в СУБД, база быстро раздувается до сотен гигабайт. Это приводит к замедлению резервного копирования, снижению производительности всей системы и росту затрат на дорогостоящие SSD-диски для серверов баз данных.

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

Вариант 1. Модернизация встроенного механизма (Перенос файлов во внешние тома на диске)

В типовой конфигурации «1С:Комплексная автоматизация 1.1» предусмотрен справочник ХранилищеДополнительнойИнформации. По умолчанию файлы в нем хранятся внутри информационной базы в реквизите с типом ХранилищеЗначения. Это самый простой, но и самый опасный для производительности вариант.

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

Выясним, как правильно спроектировать этот механизм, чтобы избежать подводных камней:

  1. Использование GUID в качестве имени файла. Не стоит хранить файлы под их оригинальными названиями (например, «Акт_125_от_12_05.pdf»), так как это может привести к конфликтам имен и проблемам с кодировкой в операционной системе. Лучшее решение — сохранять файл на сервере под уникальным идентификатором (GUID) элемента справочника 1С, а реальное имя файла отображать пользователю только в интерфейсе программы.
  2. Динамическая структура каталогов. Если сложить 100 000 файлов в одну папку, операционная система (особенно Windows) начнет катастрофически тормозить при попытке открыть директорию или прочитать файл. Необходимо реализовать динамическое распределение файлов по подкаталогам. Например, создавать папки на основе даты добавления документа: \\server\share\2023\11\24\GUID.pdf.

Рассмотрим пример кода, реализующий сохранение файла на внешний диск из объекта типа ХранилищеЗначения при записи элемента справочника:


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

КонецПроцедуры

При таком подходе база данных практически перестает расти, так как текстовые метаданные занимают ничтожно мало места по сравнению с самими сканами документов.

Вариант 2. Бесшовная интеграция с «1С:Документооборот КОРП»

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

Для интеграции 1С:КА 1.1 и 1С:ДО используется штатный механизм бесшовной интеграции. Рассмотрим подробнее, как это работает на практике:

Вариант 3. Современное решение: Использование S3-совместимых объектных хранилищ

В современной практике разработки на платформе 1С всё чаще отказываются от локальных жестких дисков и сетевых UNC-путей в пользу S3-совместимых объектных хранилищ (Object Storage). Это могут быть как облачные провайдеры (Yandex Cloud, VK Cloud, Selectel), так и локально развернутый в вашей инфраструктуре бесплатный сервер MinIO.

Проанализируем преимущества хранения сканов в S3 перед обычным сетевым диском:

Интеграция со стороны 1С реализуется через объект HTTPСоединение. Посмотрим на пример кода для отправки файла в S3-хранилище:


Функция ОтправитьФайлВОблакоS3(ПутьКЛокальномуФайлу, ИмяФайлаВОблаке) Экспорт
    
    // Задаем параметры подключения к провайдеру S3
    Хост = "storage.yandexcloud.net";
    ИмяБаккета = "my-1c-scans";
    AccessKey = "Ваш_Ключ_Доступа";
    SecretKey = "Ваш_Секретный_Ключ";
    
    // Формируем заголовки авторизации (упрощенный пример)
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Host", Хост);
    Заголовки.Вставить("Content-Type", "application/pdf");
    
    // Создаем HTTP-соединение
    Соединение = Новый HTTPСоединение(Хост, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
    
    // Формируем PUT-запрос для загрузки файла
    АдресРесурса = "/" + ИмяБаккета + "/" + ИмяФайлаВОблаке;
    Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
    Запрос.УстановитьИмяФайлаТела(ПутьКЛокальномуФайлу);
    
    Попытка
        Ответ = Соединение.ОтправитьДляОбработки(Запрос);
        Если Ответ.КодСостояния = 200 Тогда
            Возврат Истина; // Файл успешно загружен
        Иначе
            ЗаписатьЛогОшибки("Ошибка загрузки S3: " + Ответ.ПолучитьТелоКакСтроку());
            Возврат Ложь;
        КонецЕсли;
    Исключение
        ЗаписатьЛогОшибки("Ошибка HTTP-соединения: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;
    
КонецФункции

Вариант 4. Использование технологии MS SQL Server FILESTREAM

Если ваша база 1С работает под управлением СУБД MS SQL Server, интересной альтернативой является технология FILESTREAM. Она позволяет СУБД хранить большие бинарные объекты (BLOB) непосредственно на файловой системе NTFS/ReFS, сохраняя при этом транзакционную целостность базы данных.

Для интеграции этого решения с 1С обычно создается отдельная база данных на MS SQL Server с поддержкой FILESTREAM. Из основной базы 1С подключение к ней осуществляется через механизм «Внешние источники данных» (доступный начиная с платформы 8.2) или посредством прямых запросов ADO. Этот способ позволяет сохранить все файлы в стандартных резервных копиях SQL-сервера (бэкап базы данных автоматически включает в себя и файлы FILESTREAM), при этом оперативная память сервера СУБД не засоряется кэшем тяжелых бинарных данных.

Особый случай: Распределенные информационные базы (РИБ)

Если у вас используется распределенная структура баз данных (РИБ), вынесение файлов за пределы информационной базы усложняет процесс репликации. При стандартном обмене файлы, хранящиеся на диске, не будут автоматически передаваться в периферийные узлы.

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

  1. Синхронизация каталогов средствами операционной системы. Вы можете настроить стороннее программное обеспечение (например, службу DFS-R в Windows Server, утилиту rsync или облачную синхронизацию) для регулярного копирования содержимого папок с файлами между серверами филиалов. При этом имена файлов (благодаря использованию GUID) гарантированно не будут пересекаться.
  2. Передача файлов через транспорт обмена 1С. При записи нового файла в одном из узлов РИБ, система временно упаковывает его в ХранилищеЗначения и помещает в специальную таблицу регистрации изменений. После того как файл будет передан в другой узел и успешно сохранен там на локальный диск, объект в базе-получателе очищается от бинарных данных.

Подведем итоги

Выбор оптимального метода хранения скан-копий зависит от бюджета проекта и долгосрочных планов компании:

← На главную