Для решения проблемы с неприличным объёмом базы данных 1C из-за хранения в ней приложенных файлов в справочнике типа "ХранилищеДополнительнойИнформации" и всех вытекающих из этого неудобств, таких как огромного размера выгрузки ИБ и файла бэкапов, было написано следующее. (Данное решение не претендует на замену встроенных механизмов хранения файлов в конфигурациях типа "документооборот" без соответствующей доработки, однако, ничто не мешает доработать описанный принцип под конкретные нужды.)
Принцип довольно прост:
- Добавляем на форму нужного объекта HTML-поле, в котором будет отображаться web-интерфейс файлового менеджера (по-моему, ограничений на платформу здесь нет, HTML на форме можно было и в 7.7 отобразить, поправьте, если не прав),
- Берём любой понравившийся web- файловый менеджер, и ставим его на web-сервер (в данной статье как пример взят и изменен под свои нужды дистрибутив простого php файлового менеджера Sabre (изменённая версия на github) как web сервер использовался WAMP с основной кодировкой utf-8. Также все отлчино работает на LAMP. Версия php - предпочитаю свежую, но, возможно, Sabre будет работать и на 5.3 и ниже.)
- При открытии формы объекта, отображаем на нашей форме файл-менеджер, вызванный с определенными GET-параметрами (например, относительный путь к папке, формируемый из имени и номера объекта). Также, если нужно, можно сделать разделение по ролям, кому можно удалять\редактировать\просматривать, кому - нет и вместо передачи простых GET-запросов хоть XML или JSON через POST и авторизацию прикрутить, как душе угодно)
- В итоге пользователь может скачивать и прикреплять файлы, подробности процесса остаются для него не очевидными, а сами файлы лежат себе на том же (или другом) сервере в определенном месте, удобно распределенные по папкам - напр. /Документ/325/файл_документа_325.pdf и не захламляют базу.
Реализация:
Рассмотрим довольно простую и быструю реализацию задумки на примере WAMP:
устанавливаем последнюю версию web-сервера (допустим, в папку d:\wamp) Чтобы можно было загружать файлы до 100 мегабайт изменяем php.ini в d:\wamp\bin\apache\apache_ВЕРСИЯ_\bin\
...
post_max_size = 100M
...
upload_max_filesize = 100M
...
Чтобы сервис стартовал автоматически, запускаем services.msc, ищем wampapache64 (если x64) и ставим тип запуска - "Автоматически"
Важно! Чтобы wampmanager.exe при выходе не завершал заодно и работу web-сервера, что, сами понимаете чем чревато, изменяем wampmanager.tpl и wampmanager.ini предварительно завершив wampmanager.exe. Ищем блок [myexit] и комментируем нежелательные действия: wampmanager.ini:
[myexit]
;WAMPMYEXITSTART
;Action: service; Service: wampapache64; ServiceAction: stop; Flags: ignoreerrors
;Action: service; Service: wampmysqld64; ServiceAction: stop; Flags: ignoreerrors
Action: exit
;WAMPMYEXITEND
wampmanager.tpl:
[myexit]
;WAMPMYEXITSTART
;Action: service; Service: ${c_apacheService}; ServiceAction: stop; Flags: ignoreerrors
;Action: service; Service: ${c_mysqlService}; ServiceAction: stop; Flags: ignoreerrors
Action: exit
;WAMPMYEXITEND
Далее распаковываем в папку d:\wamp\www\ изменённую вверсия Sabre с github, переходим в браузере на http://localhost/Sabre1c-master/install/ и настраиваем как пожелаем. Создаём папку для загрузок, какую указали (по-умолчанию upload) в d:\wamp\www\Sabre1c-master\ переходим на http://localhost/Sabre1c-master/?CWD=\Тест\123 и загружаем любой файл, проверяем результат в папке d:\wamp\www\Sabre1c-master\upload\Тест\123\ появился загруженный файл.
Работу файл-менеджера проверял как на windows, так и на linux web-серверах, проблем с кодировкой имени файла при загрузке\скачивании удалось избежать. Пробелы в имени файла при загрузке заменяются символами нижнего подчёркивания. Если есть необходимость запретить загружать файлы с расширением, не включенным в список разрешенных, можно раскоментировать и попровить несколько строк в файле core\upload.php:
$ext_allowed = array('txt', 'jpg', 'pdf', 'zip', 'png');
if(!in_array(strtolower($extension), $ext_allowed)){
header('location: ../?action=upload&file=');
exit;
}
Теперь идём в 1с и размещаем на нужном документе или справочнике ПолеHTMLДокумента с аналогичным именем и добавляем в функцию модуля ПриОткрытии() код:
// пример для обычных форм 8.X, Документ
Процедура ПриОткрытии(Отказ) {
Если ДокументОбъект.Номер Тогда
ЭлементыФормы.ПолеHTMLДокумента.Видимость=Истина;
// если у вас числовая нумерация, Адрес="http://localhost/Sabre1c-master/?CWD="+"/"+ДокументОбъект.Метаданные().Имя+"/"+Формат(ДокументОбъект.Номер,"ЧГ=0");
Адрес="http://localhost/Sabre1c-master/?CWD="+"/"+ДокументОбъект.Метаданные().Имя+"/"+ДокументОбъект.Номер;
ЭлементыФормы.ПолеHTMLДокумента.Документ.URL = Адрес;
КонецЕсли;
КонецПроцедуры
// пример для управляемых форм 8.X, Справочник
&НаКлиенте
Процедура ПриОткрытии(Отказ)
Если Объект.Код Тогда
Элементы.ПолеHTMLДокумента.Видимость=Истина;
// если у вас числовая нумерация, Адрес="localhost/Sabre1c-master/?CWD="+"/contacts/"+Формат(Объект.Код,"ЧГ=0");
Адрес="localhost/Sabre1c-master/?CWD="+"/contacts/"+Объект.Код;
ПолеHTMLДокумента=Адрес;
КонецЕсли;
КонецПроцедуры
Готово.
Также можно написать простейшую обработку, чтобы выгрузить все файлы из хранилища в базе в папку на диске.
Процедура ЭкспортФайловХранилищаНажатие(Элемент)
Путь="d:\wamp\www\Sabre1c-master\upload\"
ИмяХранилищаДопИнф="ХранилищеДополнительнойИнформации";
Выборка = Справочники[ИмяХранилищаДопИнф].Выбрать();
Пока выборка.Следующий() = 1 Цикл
Попытка
// если у вас числовая нумерация, ID=Формат(выборка.Объект.Код,"ЧГ=0");
ID=выборка.Объект.Код;
Исключение
Попытка
// если у вас числовая нумерация, ID=Формат(выборка.Объект.Номер,"ЧГ=0");
ID=выборка.Объект.Номер;
Исключение
ID="null";
КонецПопытки;
КонецПопытки;
РезультПуть=Путь + выборка.Объект.Метаданные().Имя + "\" + ID + "\";
СоздатьКаталог(РезультПуть);
Если выборка.ИмяФайла <>"" Тогда
Результ = РезультПуть + СтрЗаменить(выборка.ИмяФайла, "/", " ");
выборка.Хранилище.Получить().Записать(Результ);
Сообщить("Выгружен "+Результ);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Всё нижеописанное Вы можете повторить для себя, но исключительно на свой страх и риск. Автор не несет ответственности за возникновение каких-либо проблем.
И удалить выгруженные файлы из БД.
Процедура УдалениеФайловХранилищаНажатие(Элемент)
Выборка = Справочники.ХранилищеДополнительнойИнформации.Выбрать();
Пока Выборка.Следующий() Цикл
Если Выборка.Объект.Метаданные().Имя = "ЗаказПокупателя" Тогда
ТекЭлемент = Выборка.ПолучитьОбъект();
Попытка
ТекЭлемент.Удалить();
Исключение
Сообщить("Не удалось удалить элемент!" + ТекЭлемент.Код);
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Теперь, чтобы фактический размер БД уменьшился после удаления из нее хлама, осталось только выгрузить и загрузить ИБ.