При активной работе в 1С:Управление торговлей 10.3 пользователи часто сталкиваются с проблемой стремительного роста объема базы данных. Основная причина — хранение изображений товаров непосредственно внутри базы в формате бинарных данных. Со временем это приводит к замедлению резервного копирования и снижению общей производительности системы. В современных конфигурациях на базе БСП (Библиотеки стандартных подсистем) предусмотрен механизм хранения файлов в томах на диске, но в старой доброй «десятке» эта задача требует особого подхода.
Проанализируем типичную ситуацию: администратор находит в константах опцию «Хранить файлы в томах», прописывает путь к сетевому каталогу (например, \\Sqlnew\1c_up\), но при добавлении картинки к товару файл в папке не появляется. Выясним причину такого поведения системы.
Дело в том, что в конфигурации УТ 10.3 подсистема «Хранение в томах» исторически была добавлена только для модуля Электронного документооборота (ЭДО). Все остальные объекты, включая справочник Номенклатура, используют старый механизм. Изображения товаров хранятся в справочнике ХранилищеДополнительнойИнформации. В типовом коде этого справочника жестко прописана запись данных в реквизит с типом ХранилищеЗначения, который физически находится внутри таблицы базы данных (SQL или 1Cv8.1CD). Такая архитектура — одна из причин, по которой со временем становится актуальным перенос картинок номенклатуры в УТ 11.5.
Прежде чем приступать к доработке кода, рассмотрим критически важный аспект — права доступа. Даже если вы настроили перенос файлов, они не будут записываться, если у службы 1С нет соответствующих полномочий. Проанализируем технические нюансы:
1C:Enterprise 8.3 Server Agent запускается под учетной записью LocalSystem. Эта запись не имеет прав на доступ к сетевым ресурсам (путям типа UNC).\\Sqlnew\1c_up\.Поскольку штатной обработки для переноса изображений в УТ 10.3 нет, нам потребуется внести изменения в конфигурацию, в отличие от задач переноса номенклатуры в новые программы, для которых существуют готовые решения. Рассмотрим по шагам, как реализовать механизм выноса файлов.
Шаг 1. Модификация справочника «ХранилищеДополнительнойИнформации»
Добавим в справочник новый реквизит ПутьКФайлу (тип Строка, длина неограничена). Именно здесь мы будем хранить относительный или полный путь к файлу на диске.
Шаг 2. Разработка процедуры выгрузки данных
Создадим внешнюю обработку для выгрузки и загрузки, которая переберет все существующие записи и выгрузит их на диск. Проанализируем пример кода для такого переноса:
Выборка = Справочники.ХранилищеДополнительнойИнформации.Выбрать();
Пока Выборка.Следующий() Цикл
ОбъектХранилища = Выборка.ПолучитьОбъект();
// Получаем данные из базы
ДанныеФайла = ОбъектХранилища.Хранилище.Получить();
Если ДанныеФайла <> Неопределено Тогда
// Формируем имя файла, например, по GUID или коду
ИмяФайла = Строка(ОбъектХранилища.Ссылка.УникальныйИдентификатор()) + "." + ОбъектХранилища.РасширениеФайла;
ПолныйПуть = "\\Sqlnew\1c_up\" + ИмяФайла;
// Записываем файл на диск
Попытка
ДанныеФайла.Записать(ПолныйПуть);
// Записываем путь в объект и очищаем хранилище в базе
ОбъектХранилища.ПутьКФайлу = ПолныйПуть;
ОбъектХранилища.Хранилище = Новый ХранилищеЗначения(Неопределено);
ОбъектХранилища.Записать();
Исключение
Сообщить("Ошибка при записи файла: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Шаг 3. Изменение логики отображения
Теперь, когда данные в реквизите Хранилище отсутствуют, стандартные формы перестанут показывать картинки. Нам нужно изменить код в форме элемента номенклатуры и в модуле справочника хранилища. Вместо прямого обращения к Элемент.Хранилище.Получить(), реализуем проверку: если ПутьКФайлу заполнен, считываем данные с диска.
Пример функции для получения картинки:
Функция ПолучитьКартинкуДляОтображения(ОбъектХранилище)
Если ЗначениеЗаполнено(ОбъектХранилище.ПутьКФайлу) Тогда
ФайлНаДиске = Новый Файл(ОбъектХранилище.ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
Возврат Новый Картинка(ОбъектХранилище.ПутьКФайлу);
КонецЕсли;
КонецЕсли;
// Если пути нет, пробуем получить из базы (для совместимости)
Возврат ОбъектХранилище.Хранилище.Получить();
КонецФункции
Проанализируем важный момент: если у вас 50 000 товаров, сохранение всех картинок в одну корневую папку \\Sqlnew\1c_up\ приведет к существенным тормозам файловой системы при открытии каталога. Рекомендуется использовать иерархическую структуру. Например, создавать подпапки на основе даты добавления или первых двух символов кода товара.
Пример формирования пути:
Подпапка = Формат(ТекущаяДата(), "ДФ=yyyy/MM/dd"); // Создаст структуру 2023/10/25
ПолныйПуть = КаталогТома + "\" + Подпапка + "\" + ИмяФайла;
// Перед записью обязательно создать каталог программно:
СоздатьКаталог(КаталогТома + "\" + Подпапка);
После того как вы программно очистили реквизиты ХранилищеЗначения в справочнике, размер файла базы данных или таблиц SQL автоматически не уменьшится. Система просто пометит эти области как свободные для будущих записей.
Чтобы реально освободить место на диске, выполните следующие действия:
.1CD): Запустите конфигуратор, перейдите в меню Администрирование — Тестирование и исправление и выберите пункт «Сжатие таблиц информационной базы».Таким образом, мы выяснили, что стандартная настройка в УТ 10.3 не решает задачу хранения картинок номенклатуры вне базы, но с помощью небольшой доработки и правильной настройки прав доступа к сетевым ресурсам можно эффективно оптимизировать размер базы данных и повысить стабильность работы всей системы.