При работе с управляемыми формами начинающие разработчики часто сталкиваются с ситуацией, когда попытка присвоить изображение напрямую элементу формы приводит к ошибке «Поле объекта недоступно для записи». В этой статье мы подробно разберем, почему возникает эта ошибка, как устроена работа с картинками в управляемом интерфейсе 1С и какие существуют правильные способы загрузки изображений.
Рассмотрим типовой сценарий. На форме расположен элемент типа «Поле картинки» с именем ПолеКартинки1. Разработчик пытается присвоить объекту элемента созданную картинку напрямую:
// Ошибочный код:
Элементы.ПолеКартинки1 = Новый Картинка(ПутьКФайлу);
При выполнении этого кода система генерирует ошибку. Проанализируем причину:
В управляемом приложении коллекция Элементы отвечает только за визуальное отображение на форме (интерфейсные элементы). Поля формы не хранят данные напрямую — они лишь отображают значение тех реквизитов формы, к которым они привязаны (свойство Данные).
Таким образом, присвоить значение напрямую объекту из коллекции Элементы нельзя. Изменять нужно значение самого реквизита формы, с которым связан элемент управления.
Разберем наиболее распространенный подход, когда реквизит формы имеет тип Строка, а на форме для него создан элемент с видом «Поле картинки».
Для отображения графических данных в таком поле реквизиту формы необходимо присвоить строковый адрес временного хранилища, в которое помещены двоичные данные или объект Картинка.
АдресКартинки) с типом Строка.АдресКартинки.Рассмотрим пример кода:
&НаКлиенте
Процедура ЗагрузитьКартинкуНажатие(Команда)
// Получаем двоичные данные файла или скачиваем их
ИмяФайла = ПолучитьИмяВременногоФайла("jpg");
// ... Загрузка файла во временный каталог ...
ЗагрузитьКартинкуНаСервере(ИмяФайла);
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьКартинкуНаСервере(ИмяФайла)
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
// Помещаем данные во временное хранилище с привязкой к текущей форме
АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецПроцедуры
Важный нюанс при работе с временным хранилищем: При вызове функции ПоместитьВоВременноеХранилище на сервере обязательно передавайте второй параметр — УникальныйИдентификатор (или ЭтаФорма.УникальныйИдентификатор). Если опустить этот параметр при вызове на сервере, данные во временном хранилище будут удалены сразу после завершения серверного вызова, и изображение на форме не отобразится.
Часто задачу загрузки капчи или внешней картинки решают с использованием внешних COM-объектов (например, WinHttp.WinHttpRequest и ADODB.Stream). Однако такой подход имеет существенные недостатки: он работает только в ОС Windows и создаёт лишние операции чтения/записи на диск.
Рассмотрим более производительный и кроссплатформенный вариант с использованием встроенных объектов HTTPСоединение и HTTPЗапрос:
&НаСервере
Процедура ЗагрузитьКартинкуСCайтаНаСервере()
Соединение = Новый HTTPСоединение("example.com", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос("/images/sample.jpg");
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
// Получаем двоичные данные напрямую из тела ответа без сохранения на диск
ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
// Записываем адрес хранилища в реквизит формы
АдресКартинки = ПоместитьВоВременноеХранилище(ДвоичныеДанные, УникальныйИдентификатор);
КонецЕсли;
КонецПроцедуры
Посмотрим на ещё один вариант реализации. Если задать реквизиту формы тип Картинка (вместо типа Строка), необходимость использовать временное хранилище отпадает.
В этом случае вы можете напрямую присваивать реквизиту формы объект типа Картинка:
&НаСервере
Процедура ОбновитьКартинкуНаСервере(ДвоичныеДанные)
// РеквизитФормыКартинка — реквизит формы с типом "Картинка"
РеквизитФормыКартинка = Новый Картинка(ДвоичныеДанные);
КонецПроцедуры
Чтобы изображение корректно выводилось на форме, обратите внимание на настройки самого элемента управления «Поле картинки»:
Пропорционально, Растянуть, Реальный размер, Вместить. Для большинства сценариев лучше всего подходит значение Пропорционально.Истина, картинка будет реагировать на нажатие мышью, активируя событие Нажатие.Подводя итог: при работе с графикой на управляемых формах 1С всегда разграничивайте элементы формы и реквизиты формы. Помещайте данные во временное хранилище с привязкой к `УникальныйИдентификатор` формы и присваивайте полученный адрес соответствующему строковому реквизиту.