Изображения в базе 1С:Предприятие 8.3: от поля в карточке до пакетной загрузки фото товаров
Содержание
Загрузить картинку в 1С:Предприятие можно тремя путями: вручную через карточку объекта (в типовых конфигурациях это поле изображения или присоединённые файлы), пакетно обработкой из папки на диске и программно: файл помещается во временное хранилище, а оттуда записывается в реквизит типа ХранилищеЗначения. Первый путь подходит пользователю, второй и третий требуют Конфигуратора или расширения.
Типичная ситуация: менеджер просит добавить фото товаров в карточки номенклатуры, чтобы они попали в прайс и на сайт. Десяток позиций проще загрузить руками. Полторы тысячи — уже задача для обработки, и тут важно заранее решить, где хранить файлы и какого они должны быть размера, иначе база за месяц вырастет на несколько гигабайт.
Где 1С хранит изображения: выбираем способ до загрузки
Прежде чем загружать картинки, решите, куда они лягут. От этого зависит и размер базы, и скорость резервного копирования, и код загрузки.
| Способ хранения | Где лежат данные | Когда подходит | Минусы |
|---|---|---|---|
Реквизит ХранилищеЗначения | В таблице объекта в базе | Одна картинка на объект, своя доработка | Растёт размер базы и выгрузки .dt |
| Присоединённые файлы (БСП) | В базе или в томах на диске | Типовые конфигурации, несколько файлов на объект | Логика сложнее, нужен программный интерфейс БСП |
| Ссылка на файл на диске | В сетевой папке, в базе — только путь | Тяжёлые фото, общий каталог для сайта | Файл может пропасть, путь должен быть доступен всем |
💡 В типовых конфигурациях на Библиотеке стандартных подсистем (Бухгалтерия 3.0, Управление торговлей 11, УНФ, ERP) картинка номенклатуры обычно хранится как присоединённый файл, а в карточке есть ссылка на «основное» изображение. Там дорабатывать ничего не нужно — достаточно ручной загрузки или типовых механизмов.
Тома на диске включаются в разделе Администрирование, в настройках работы с файлами. После этого новые файлы пишутся в папку тома, а не в таблицы базы. Для каталога в тысячи фото это заметно облегчает базу.
Подготовка реквизита для хранения картинки в своей конфигурации
Если объект свой или в нём нет места под изображение, реквизит добавляют в Конфигураторе. В типовую конфигурацию с поддержкой правильнее добавить его через расширение: начиная с платформы 8.3.11 расширение может добавлять реквизиты к заимствованным объектам.
Шаг 1. Реквизит объекта
- Откройте справочник (например,
Номенклатура) в дереве конфигурации или в расширении. - На вкладке «Данные» добавьте реквизит, например
Картинка. - Укажите тип
ХранилищеЗначения.
Реквизиты этого типа не попадают в данные формы напрямую: на форме их нельзя вывести как обычное поле. Поэтому нужен посредник.
Шаг 2. Реквизит формы и поле картинки
- В форме элемента создайте реквизит формы
АдресКартинкис типомСтрока. - Создайте ещё один реквизит
КартинкаИзмененатипаБулево— он подскажет, что запись нужна. - Перетащите
АдресКартинкина форму и в свойствах элемента выберите вид «Поле картинки». - Добавьте команду
ЗагрузитьКартинкуи кнопку для неё рядом с полем.
Поле картинки показывает изображение по адресу во временном хранилище или по навигационной ссылке. Строка с таким адресом и есть то, что мы будем подставлять.
Ручная загрузка картинки через интерфейс пользователя
В типовой конфигурации порядок такой:
- Откройте карточку товара или другого объекта.
- Найдите область изображения (пустой квадрат рядом с реквизитами) или команду работы с файлами — в формах на БСП это кнопка со скрепкой либо ссылка «Файлы».
- Выберите файл на диске и подтвердите.
- Если файлов несколько, отметьте нужный как основное изображение — это делается из списка присоединённых файлов.
- Запишите карточку.
Расположение области изображения зависит от конфигурации и релиза: в одних карточках картинка стоит вверху справа, в других открывается через список файлов. Ориентируйтесь на значок скрепки в командной панели формы.
В веб-клиенте выбор файла работает через браузер. Для операций, где 1С сама читает файлы с диска (открыть, отредактировать и вернуть), браузер попросит установить расширение для работы с файлами. На простую загрузку одного файла это не влияет.
Программная загрузка изображения в коде 1С
Ниже рабочий каркас для формы элемента с реквизитом Картинка из предыдущего раздела. Схема: клиент выбирает файл → платформа передаёт его на сервер во временное хранилище → при записи данные переносятся в реквизит.
Показ сохранённой картинки при открытии
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Не Объект.Ссылка.Пустая() Тогда
Данные = Объект.Ссылка.Картинка.Получить();
Если Данные <> Неопределено Тогда
АдресКартинки = ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Метод Получить() возвращает то, что положили в хранилище, — здесь это ДвоичныеДанные файла.
Выбор и передача файла с клиента
&НаКлиенте
Процедура ЗагрузитьКартинку(Команда)
Оповещение = Новый ОписаниеОповещения("ЗагрузитьКартинкуЗавершение", ЭтотОбъект);
НачатьПомещениеФайла(Оповещение, , , Истина, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьКартинкуЗавершение(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
Если Не Результат Тогда
Возврат; // пользователь закрыл диалог
КонецЕсли;
Расширение = НРег(Прав(ВыбранноеИмяФайла, 4));
Если Расширение <> ".jpg" И Расширение <> "jpeg" И Расширение <> ".png" Тогда
ПоказатьПредупреждение(, "Загрузите файл JPG или PNG.");
Возврат;
КонецЕсли;
АдресКартинки = Адрес;
КартинкаИзменена = Истина;
Модифицированность = Истина;
КонецПроцедуры
Четвёртый параметр Истина открывает диалог выбора. Передача УникальныйИдентификатор формы привязывает временное хранилище к форме: данные живут, пока форма открыта.
💡 На платформе 8.3.18 и новее есть асинхронный вариант на обещаниях — ПоместитьФайлНаСерверАсинх. Логика та же, меняется только синтаксис вызова. НачатьПомещениеФайла продолжает работать и подходит, если базу открывают на разных версиях платформы.
Запись в реквизит
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
Если КартинкаИзменена И ЭтоАдресВременногоХранилища(АдресКартинки) Тогда
Данные = ПолучитьИзВременногоХранилища(АдресКартинки);
ТекущийОбъект.Картинка = Новый ХранилищеЗначения(Данные, Новый СжатиеДанных(9));
КартинкаИзменена = Ложь;
КонецЕсли;
КонецПроцедуры
Писать нужно именно в ТекущийОбъект, а не в Объект: у данных формы реквизита типа ХранилищеЗначения нет. Сжатие уровня 9 почти не уменьшает JPEG и PNG (они уже сжаты), но хорошо работает для BMP и TIFF.
Если нужна картинка в печатной форме
В макете добавьте рисунок типа «Картинка» с именем, например, Фото. При выводе:
Данные = Ссылка.Картинка.Получить();
Если Данные <> Неопределено Тогда
Область.Рисунки.Фото.Картинка = Новый Картинка(Данные);
КонецЕсли;
Свойство «Размер картинки» у рисунка в макете поставьте «Пропорционально», иначе фото растянется под рамку.
Массовая загрузка картинок через обработку
Сотни фото загружают обработкой. Самый надёжный ключ сопоставления — артикул в имени файла: A-1024.jpg ляжет в товар с артикулом A-1024. Наименование для этого не годится: в нём бывают кавычки, слэши и дубли.
Подготовка файлов:
- 📁 все фото в одной папке, без вложенных каталогов;
- 🏷️ имя файла = артикул, без пробелов в начале и в конце;
- 🖼️ форматы JPG или PNG, размеры приведены заранее (следующий раздел);
- 🔁 у каждого артикула один файл — второй перезапишет первый.
Серверная функция внешней обработки:
&НаСервереБезКонтекста
Функция ЗагрузитьКартинкиИзКаталога(Каталог)
Загружено = 0;
Маски = СтрРазделить("*.jpg;*.jpeg;*.png", ";");
Для Каждого Маска Из Маски Цикл
Файлы = НайтиФайлы(Каталог, Маска);
Для Каждого Файл Из Файлы Цикл
Ссылка = Справочники.Номенклатура.НайтиПоРеквизиту("Артикул", Файл.ИмяБезРасширения);
Если Ссылка.Пустая() Тогда
Сообщить("Не найден товар с артикулом " + Файл.ИмяБезРасширения);
Продолжить;
КонецЕсли;
Попытка
Товар = Ссылка.ПолучитьОбъект();
Товар.Картинка = Новый ХранилищеЗначения(
Новый ДвоичныеДанные(Файл.ПолноеИмя), Новый СжатиеДанных(9));
Товар.Записать();
Загружено = Загружено + 1;
Исключение
Сообщить("Ошибка для " + Файл.Имя + ": " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
КонецЦикла;
Возврат Загружено;
КонецФункции
На клиенте вызов выглядит так: Сообщить("Загружено: " + Формат(ЗагрузитьКартинкиИзКаталога(Каталог), "ЧГ=0"));. Формат убирает пробел-разделитель тысяч, который иначе появится в числе 1 500.
Три вещи, о которых забывают:
- Путь читает сервер. В клиент-серверном варианте
НайтиФайлывыполняется на сервере 1С. ПапкаC:\Фотона компьютере бухгалтера ему не видна. Нужен сетевой путь вида\\fileserver\foto, и у пользователя, от которого запущена служба 1С, должны быть права на чтение. - Регистр на Linux. Если сервер 1С работает на Linux, маска
*.jpgне найдётIMG_01.JPG. Добавьте маски в верхнем регистре или приведите имена файлов к одному виду. НайтиПоРеквизитуберёт первый найденный элемент. При дублях артикула картинка попадёт только в один товар. Проверьте уникальность артикулов до загрузки.
Для типовых конфигураций, где картинки — присоединённые файлы, писать в реквизит напрямую нельзя: файл надо создавать через программный интерфейс работы с файлами БСП. Конкретные процедуры смотрите в общем модуле РаботаСФайлами вашей версии библиотеки — их описание есть в комментариях к экспортным методам.
Пакетную загрузку сначала запускайте на копии базы. Обработка перезаписывает реквизит без вопросов, и старые изображения не вернуть без резервной копии.
Оптимизация и сжатие изображений перед загрузкой
Фото с телефона весит 3–8 МБ при размере 4000×3000 пикселей. Для карточки товара и прайса хватает 800–1200 пикселей по длинной стороне и 100–300 КБ. Разница в 20 раз: 1 500 товаров — это примерно 7 ГБ против 300 МБ.
Ориентиры по форматам:
| Назначение | Формат | Размер по длинной стороне | Вес файла |
|---|---|---|---|
| Фото товара | JPEG, качество 80–85 % | 1000–1200 px | 100–300 КБ |
| Логотип, печать, подпись | PNG с прозрачностью | 300–600 px | 20–100 КБ |
| Схема, чертёж | PNG | по необходимости | до 500 КБ |
Платформа не умеет надёжно уменьшать фото при загрузке, поэтому сжимайте до того, как файлы попадут в 1С. Для пакета удобна бесплатная утилита ImageMagick:
cd /d D:\foto
magick mogrify -resize "1200x1200>" -quality 85 *.jpg
Знак > уменьшает только те фото, что больше 1200 пикселей, мелкие не растягивает. Команда перезаписывает исходники — запускайте её на копии папки.
В коде полезно отсечь слишком тяжёлые файлы ещё на сервере:
Если Данные.Размер() > 1024 * 1024 Тогда
ВызватьИсключение "Файл больше 1 МБ. Уменьшите изображение и повторите.";
КонецЕсли;
Печать организации и подпись руководителя для печатных форм загружают в PNG с прозрачным фоном. JPEG прозрачность не поддерживает: на счёте вокруг печати останется белый прямоугольник, перекрывающий текст.
Почему картинка не загружается или не отображается
Частые вопросы о картинках в 1С
Какие форматы изображений понимает 1С?
Можно ли хранить картинку не в базе, а в папке?
Попадут ли картинки в выгрузку .dt?
Как выгрузить картинку из 1С обратно в файл?
ДвоичныеДанные из хранилища методом Получить() и вызовите у них Записать(ПутьКФайлу) на сервере или передайте их на клиент через временное хранилище.