Постановка задачи
После завершения основного этапа внедрения модуля Диадок в корпоративную систему принялись за оптимизацию модулей, в частности, вынести хранение файлов Диадок из СУБД в файловое хранилище, с использованием возможностей БСП.
Так же нам требовалось внедриться максимально аккуратно, чтобы иметь возможность максимально просто устанавливать обновления поставляемого модуля без риска поломать наш функционал.
Первым делом изучили штатный функционал. В обработке Диадока (на момент добавления функционала версия 4.10.6) есть настройка для хранения файлов документов и подписей на диске:
Но данная реализация нас не устроила т.к. нужно было вводить ещё один адрес хранения на сетевом ресурсе, осуществлять передачу нового ресурса системным администраторам для поддержки, организовать мероприятия, необходимые для корректной работы системы.
В своей работе уже используем функционал присоединенных файлов (версия БСП 2.3.3.66):
1. установлена настройка «хранить файлы в томах на диске»;
2. настроена работа с томом на сетевом диске: проверка на вирусы;
3. включен мониторинг объема занимаемых присоединённых файлов и контроль свободного места на диске;
4. штатный механизм очистки файлов для старых документов;
5. со временем планируется даже миграция файлов в облако (что БСПшным функционалом будет реализовать гораздо проще.
Реализация
За основу реализации задачи был взят механизм Диадок «Хранить файлы документов и подписей на диске» с небольшими дополнениями.
Можно выделить следующие доработки:
- Подключение подсистемы хранения вложенных файлов БСП
- Добавление настроек на форму НастройкиУправляемая;
- Сохранение значение настройки для использования в модулях;
- Изменение функций записи файлов на сетевой том;
- Изменение функция чтения файлов из сетевого тома;
Добавили механизм БСП «Присоединенные файлы» для справочника Диадок_Документы. Как это сделать подробно написано на сайте ИТС (инструкция для БСП версии 2.3).
Добавление опции хранения в присоединенных файлах
Далее уже правили обработку «КонтурЭДО». Тексты процедур и функций штатной обработки публиковать не буду, а только тот код, который сами добавляли.
Добавили настройку, которая переключает хранение файлов по нашему алгоритму. Для этого в обработке Диадок на форму «НастройкиУправляемая» добавили новый реквизит формы ХранитьДокументыВПрикрепленныхФайлах тип Булево.
И вынесли на форму рядом со штатной настройкой:
В обработчике события «При изменении» сохраняем значение нашего реквизита в настройках Диадок (был скопирован штатный код с небольшими правками):
Далее написали функционал для обработки настройки. Для этого выгрузили макеты «Ядро_epf» и «ХранениеДанных_epf» из обработки в файлы «Ядро.epf» и «ХранениеДанных.epf».
В модуле объекта обработки «Ядро.epf» в функцию Контракт_ОбщиеНастройки() добавили к стандартным настройкам нашу настройку:
Результат.Вставить("ХранитьДокументыВПрикрепленныхФайлах", Ложь);
В функцию ОбщиеНастройки_ОбработанныеЗначенияПередЗаписью(СтруктураНастроек) добавили проверку на нашу переменную:
Если НЕ (СтруктураНастроек.ХранитьДокументыНаДиске ИЛИ СтруктураНастроек.ХранитьДокументыВПрикрепленныхФайлах) Тогда
СтруктураНастроек.УдалятьСодержимоеУстаревшихДокументов = Ложь;
КонецЕсли;
На этом изменения в «Ядро.epf» готовы. Импортировали обработку обратно в макет обработки «КонтурЭДО».
Запись файлов документов и подписей в присоединенные файлы.
Настала очередь «ХранениеДанных.epf».
Для установки настройки по умолчанию, не заданной в предыдущем релизе модуля в процедуру Настройки_ОбщиеНастройки() прописали условие:
Если Результат.Свойство("ХранитьДокументыВПрикрепленныхФайлах") И ТипЗнч(Результат.ХранитьДокументыВПрикрепленныхФайлах) <> Тип("Булево") Тогда
Результат.ХранитьДокументыВПрикрепленныхФайлах = Ложь;
КонецЕсли;
Для добавления файлов в присоединенные в процедуре Документы_ЗаписатьДанныеХранилища_Диадок(ДанныеХранения, ИмяХранилища, ДокументЭДО) добавили обработку переменной:
Если Данные <> Неопределено Тогда
...
ИначеЕсли Настройки_ОбщиеНастройки().ХранитьДокументыВПрикрепленныхФайлах Тогда
Документы_ЗаписатьДанныеХранилища_ПрикрепленныеФайлы(Данные, ДокументЭДО, ИмяХранилища);
...
КонецЕсли;
Если ЗашифрованныеДанные <> Неопределено Тогда
…
ИначеЕсли Настройки_ОбщиеНастройки().ХранитьДокументыВПрикрепленныхФайлах Тогда
Документы_ЗаписатьДанныеХранилища_ПрикрепленныеФайлы(ЗашифрованныеДанные, ДокументЭДО, ИмяХранилища, Истина);
…
КонецЕсли;
Процедура из условия:
Получение файлов подписей и документов из присоединенных файлов.
Для получения данных из присоединенных файлов добавили изменения в функцию Документы_КонтрактДанныхХранилищаПоВыборке_Диадок(Выборка, ИмяХранилища) условие:
Если Настройки_ОбщиеНастройки().ХранитьДокументыНаДиске Тогда
…
ИначеЕсли Настройки_ОбщиеНастройки().ХранитьДокументыВПрикрепленныхФайлах Тогда
УстановитьПривилегированныйРежим(Истина);
СтруктураДанных = Документы_ДвоичныеДанныеХранилища_ПрикрепленныеФайлы(Результат, Выборка.КодПакета, Выборка.КодДокумента, ИмяХранилища);
ЗаполнитьЗначенияСвойств(Результат, СтруктураДанных, "Данные, ЗашифрованныеДанные");
Функция из условия:
Для получения данных подписи нужно добавить в функцию Документы_КонтрактПодписиПоВыборке_Диадок ветку условия:
Если Настройки_ОбщиеНастройки().ХранитьДокументыНаДиске Тогда
…
ИначеЕсли Настройки_ОбщиеНастройки().ХранитьДокументыВПрикрепленныхФайлах Тогда
ДанныеПодписи = Документы_ДвоичныеДанныеПодписи_ПрикрепленныеФайлы(Выборка.КодПакета, Выборка.КодДокумента, ИмяХранилища);
Результат.ДанныеПодписи = ДанныеПодписи;
И сама функция:
На этом сохранили «ХранениеДанных.epf» и импортировали в макет обработки «КонтурЭДО».
Результат
Для справочника «Диадок: Документы» подключен функционал БСП «Присоединенные файлы»
Для документов Диадок список присоединенных файлов
Проблемы, которые возникли в процессе
- Исторические данные. После установки настройки, все документы, которые получили до установки параметра, перестали подписываться. Поэтому в процедуре Документы_КонтрактДанныхХранилищаПоВыборке_Диадок добавили проверку на тот случай если присоединенного файла нет, то данные брать из базы.
Позже написали обработку, которая для старых документов перекладывала файлы из базы в присоединенные файлы.
- При переносе исторических данных стала возникать ошибка: «Ошибка при добавлении файла в том: Access is denied».
В ходе анализа выяснили, что БСП при сохранении файла, проверяет наличие в этой папке файла с таким же именем. Если файл уже есть в папке, то создается вложенная папка со случайными именем A, B, ... Z, A1, B1, .. Z1, .. A2, B2, …, Z99 и в неё сохраняется файл.
Наименование файлов для всех документов Диадок постоянны (ХранилищеКонтента, ПодписьПокупателя, ОтказВПодписанииДокумента и т.д.), поэтому при сохранении файла средствами БСП в сетевую папку возникли проблемы: БСП не могла создать новую папку т.к. закончился лимит на наименование папки и вызывала исключение.
У нас стоит версия БСП 2.3.3.66 и функция (ФайловыеФункцииСлужебныйКлиентСервер.ПолучитьУникальноеИмяСПутем), которая определяет путь для сохранения файлов, может сгенерировать всего 2600 папок с различными именами. Если за день придёт документов ЭДО свыше 2600 шт, то БСП уже не сможет сохранить присоединенный файл.
Проблему решили просто, обновили процедуру из новых версий БСП. В новых версиях переписали алгоритм и теперь количество папок для присоединенных файлов может быть 26 в степени 5. Такое количество нас устраивает и ошибок больше не возникало.
Но даже для старых версий БСП можно было бы избежать ошибки. В процедуре Документы_ЗаписатьДанныеХранилища_ПрикрепленныеФайлы при формировании структуры ПараметрыФайла для ключа ИмяБезРасширения добавлять значение по маске «номер пакета»-«номер документа»-«Имя файла без расширения». В таком виде файлы были бы уникальны и хранились бы все в папке с наименованием равной текущей дате.
- Обновление обработки «КонтурЭДО». Теперь нужно помнить, что у нас есть изменения в макетах. Поэтому это нужно учитывать при переходе на новую версию обработки КонтурЭДО. Для каждой новой версии обработки нужно добавлять изменения в макеты «Ядро_epf» и «ХранениеДанных_epf». Для упрощения обновления макетов используем Git. Более подробно как это реализовали расскажу в другой статье.
Заключение
После доработки системы хранения входящих файлов ЭДО удалось сократить размер базы примерно на 6% (30.4 Гб) и получили единый сетевой ресурс для хранения всех файлов в 1С.