В разработке на платформе 1С:Предприятие 8.3 часто возникает задача хранения изображений внутри базы данных. Типичный сценарий: у нас есть справочник (например, «Товары» или «Сотрудники»), где нужно хранить фото. Для этого используется реквизит с типом ХранилищеЗначения. Однако новички часто сталкиваются с проблемой: данные в базу вроде бы попадают, но на форме вместо картинки отображается надпись «Хранилище значения» или пустая область. Разберем подробно, как реализовать этот механизм правильно.
Проанализируем ситуацию, описанную автором темы. Основная ошибка заключается в попытке присвоить реквизиту формы, имеющему вид Поле картинки, сам объект Картинка или ХранилищеЗначения. Платформа 1С работает иначе: для отображения визуального контента в управляемых формах реквизит формы (обычно типа Строка) должен содержать адрес (навигационную ссылку). Это может быть либо ссылка на объект в базе данных, либо адрес во временном хранилище сервера.
Прежде всего, проверим структуру нашего справочника в конфигураторе. Нам понадобятся:
Изображение, тип ХранилищеЗначения. Здесь будет храниться сам бинарный файл картинки.АдресКартинки, тип Строка. Именно его мы вытаскиваем на форму и устанавливаем ему вид Поле картинки.Рассмотрим, как сделать так, чтобы при открытии карточки элемента картинка уже была видна. Выясним причину: если объект уже записан в базу, нам нужно получить на него навигационную ссылку. Сделаем это в процедуре ПриСозданииНаСервере.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Если это существующий элемент, получаем ссылку на его картинку
Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
АдресКартинки = ПолучитьНавигационнуюСсылку(Объект.Ссылка, "Изображение");
КонецЕсли;
КонецПроцедуры
Метод ПолучитьНавигационнуюСсылку принимает два параметра: ссылку на сам элемент справочника и имя реквизита типа ХранилищеЗначения в кавычках. Теперь при открытии формы 1С сама подтянет данные из базы по этому адресу.
Теперь разберем ситуацию, когда пользователь вводит путь к файлу (например, C:\Photos\image.jpg) и хочет, чтобы картинка загрузилась автоматически. Посмотрим на алгоритм: нам нужно прочитать файл с диска, передать его на сервер, поместить во временное хранилище и обновить АдресКартинки.
&НаКлиенте
Процедура ПутьПриИзменении(Элемент)
Если ПустаяСтрока(Объект.Путь) Тогда
Возврат;
КонецЕсли;
// Проверяем существование файла на клиенте
ФайлКартинки = Новый Файл(Объект.Путь);
Если НЕ ФайлКартинки.Существует() Тогда
Сообщить("Файл не найден по указанному пути!");
Возврат;
КонецЕсли;
// Читаем файл в двоичные данные
ДвоичныеДанные = Новый ДвоичныеДанные(Объект.Путь);
// Помещаем данные во временное хранилище, чтобы сервер их "увидел"
// Используем УникальныйИдентификатор формы для привязки данных
АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, ЭтаФорма.УникальныйИдентификатор);
// Теперь поле картинки на форме обновится автоматически, так как адрес изменился
КонецПроцедуры
Важный момент: использование функции ПоместитьВоВременноеХранилище позволяет нам отобразить картинку еще до того, как пользователь нажмет кнопку «Записать». Это создает удобный интерфейс.
После того как мы выбрали картинку и она отобразилась на форме, ее нужно физически записать в реквизит Изображение. Проанализируем ситуацию: данные сейчас находятся во временном хранилище по адресу АдресКартинки. Нам нужно извлечь их и обернуть в ХранилищеЗначения.
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Проверяем, является ли АдресКартинки адресом во временном хранилище
// (адреса временного хранилища начинаются с "e1cib/tempstorage")
Если ЭтоАдресВременногоХранилища(АдресКартинки) Тогда
// Получаем двоичные данные из хранилища
ДанныеИзображения = ПолучитьИзВременногоХранилища(АдресКартинки);
// Помещаем их в реквизит объекта
ТекущийОбъект.Изображение = Новый ХранилищеЗначения(ДанныеИзображения);
КонецЕсли;
КонецПроцедуры
Рассмотрим подробнее несколько профессиональных советов, которые помогут сделать решение более надежным:
НачатьПомещениеФайлаНаСервер() вместо прямого создания объекта ДвоичныеДанные, чтобы избежать блокировки интерфейса при работе с большими файлами или в веб-клиенте.АдресКартинки и реквизит Изображение, чтобы не хранить в базе лишние данные.Таким образом, мы выяснили, что ключевой секрет успеха — разделение понятий «хранение данных» (реквизит объекта) и «отображение данных» (адрес на форме). Следуя этой структуре, вы сможете реализовать загрузку любых медиафайлов в ваши конфигурации 1С.