Как загрузить и отобразить изображение в управляемой форме 1С

Программист 1С v8.3 (Управляемые формы) 1С:Розница IT и автоматизация бизнеса
← На главную

При работе с управляемыми формами начинающие разработчики часто сталкиваются с ситуацией, когда попытка присвоить изображение напрямую элементу формы приводит к ошибке «Поле объекта недоступно для записи». В этой статье мы подробно разберем, почему возникает эта ошибка, как устроена работа с картинками в управляемом интерфейсе 1С и какие существуют правильные способы загрузки изображений.

Выясним причину ошибки

Рассмотрим типовой сценарий. На форме расположен элемент типа «Поле картинки» с именем ПолеКартинки1. Разработчик пытается присвоить объекту элемента созданную картинку напрямую:


// Ошибочный код:
Элементы.ПолеКартинки1 = Новый Картинка(ПутьКФайлу);

При выполнении этого кода система генерирует ошибку. Проанализируем причину:

В управляемом приложении коллекция Элементы отвечает только за визуальное отображение на форме (интерфейсные элементы). Поля формы не хранят данные напрямую — они лишь отображают значение тех реквизитов формы, к которым они привязаны (свойство Данные).

Таким образом, присвоить значение напрямую объекту из коллекции Элементы нельзя. Изменять нужно значение самого реквизита формы, с которым связан элемент управления.

Способ 1. Загрузка через временное хранилище (реквизит типа «Строка»)

Разберем наиболее распространенный подход, когда реквизит формы имеет тип Строка, а на форме для него создан элемент с видом «Поле картинки».

Для отображения графических данных в таком поле реквизиту формы необходимо присвоить строковый адрес временного хранилища, в которое помещены двоичные данные или объект Картинка.

  1. Создадим на форме реквизит (например, АдресКартинки) с типом Строка.
  2. В свойствах элемента формы типа «Поле картинки» укажем в качестве данных реквизит АдресКартинки.
  3. На сервере поместим данные картинки во временное хранилище и запишем полученный адрес в реквизит формы.

Рассмотрим пример кода:


&НаКлиенте
Процедура ЗагрузитьКартинкуНажатие(Команда)
    // Получаем двоичные данные файла или скачиваем их
    ИмяФайла = ПолучитьИмяВременногоФайла("jpg");
    
    // ... Загрузка файла во временный каталог ...
    
    ЗагрузитьКартинкуНаСервере(ИмяФайла);
КонецПроцедуры

&НаСервере
Процедура ЗагрузитьКартинкуНаСервере(ИмяФайла)
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
    
    // Помещаем данные во временное хранилище с привязкой к текущей форме
    АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецПроцедуры

Важный нюанс при работе с временным хранилищем: При вызове функции ПоместитьВоВременноеХранилище на сервере обязательно передавайте второй параметр — УникальныйИдентификатор (или ЭтаФорма.УникальныйИдентификатор). Если опустить этот параметр при вызове на сервере, данные во временном хранилище будут удалены сразу после завершения серверного вызова, и изображение на форме не отобразится.

Способ 2. Оптимальная загрузка по HTTP средствами платформы 1С

Часто задачу загрузки капчи или внешней картинки решают с использованием внешних COM-объектов (например, WinHttp.WinHttpRequest и ADODB.Stream). Однако такой подход имеет существенные недостатки: он работает только в ОС Windows и создаёт лишние операции чтения/записи на диск.

Рассмотрим более производительный и кроссплатформенный вариант с использованием встроенных объектов HTTPСоединение и HTTPЗапрос:


&НаСервере
Процедура ЗагрузитьКартинкуСCайтаНаСервере()
    Соединение = Новый HTTPСоединение("example.com", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
    Запрос = Новый HTTPЗапрос("/images/sample.jpg");
    
    Ответ = Соединение.Получить(Запрос);
    Если Ответ.КодСостояния = 200 Тогда
        // Получаем двоичные данные напрямую из тела ответа без сохранения на диск
        ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
        
        // Записываем адрес хранилища в реквизит формы
        АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
    КонецЕсли;
КонецПроцедуры

Способ 3. Использование реквизита формы с типом «Картинка»

Посмотрим на ещё один вариант реализации. Если задать реквизиту формы тип Картинка (вместо типа Строка), необходимость использовать временное хранилище отпадает.

В этом случае вы можете напрямую присваивать реквизиту формы объект типа Картинка:


&НаСервере
Процедура ОбновитьКартинкуНаСервере(ДвоичныеДанные)
    // РеквизитФормыКартинка — реквизит формы с типом "Картинка"
    РеквизитФормыКартинка = Новый Картинка(ДвоичныеДанные);
КонецПроцедуры

Настройка отображения элемента на форме

Чтобы изображение корректно выводилось на форме, обратите внимание на настройки самого элемента управления «Поле картинки»:

Подводя итог: при работе с графикой на управляемых формах 1С всегда разграничивайте элементы формы и реквизиты формы. Помещайте данные во временное хранилище с привязкой к `УникальныйИдентификатор` формы и присваивайте полученный адрес соответствующему строковому реквизиту.

← На главную