Как программно установить картинку кнопке или команде на управляемой форме в 1С:Предприятие 8.3?

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

При разработке интерфейсов на управляемых формах в 1С:Предприятие 8.3 программисты часто сталкиваются с задачей динамического изменения внешнего вида элементов. Например, требуется установить на кнопку картинку, которая хранится в базе данных (в присоединенных файлах, справочнике номенклатуры или регистре сведений) или генерируется программно "на лету".

Однако при попытке напрямую присвоить созданный объект Картинка свойству кнопки в коде управляемой формы разработчик неизбежно сталкивается с ошибкой: «Ошибка при установке значения атрибута контекста (Картинка) по причине: Недопустимое значение».

В этой статье мы подробно разберем, почему возникает это ограничение платформы, проанализируем синтаксис и рассмотрим четыре проверенных практических способа, которые помогут вам обойти это ограничение и реализовать требуемый функционал в ваших конфигурациях.

Выясняем причину: почему стандартный подход вызывает ошибку?

Обратимся к официальной документации и Синтакс-Помощнику 1С. Для свойства Картинка элемента формы типа «Кнопка» установлено жесткое системное ограничение. Если заполнение данного свойства происходит программно, то в него может быть передан только объект Картинка определенного вида, а именно:

  1. Пустая картинка (используется для очистки элемента).
  2. Картинка из библиотеки (предопределенная системная картинка или общая картинка, добавленная в метаданные конфигурации).

Попытка передать туда картинку, созданную из двоичных данных, файла на диске или временного хранилища (например, Новый Картинка(ПутьКФайлу)), приводит к вызову исключения. Платформа просто не поддерживает динамическое назначение произвольных бинарных картинок стандартным кнопкам управляемой формы на лету. Тем не менее, эту задачу можно элегантно решить обходными путями.

Вариант 1. Использование «Поля картинки» в режиме гиперссылки

Это самый популярный, надежный и простой в реализации обходной путь. Вместо стандартного элемента формы «Кнопка» мы будем использовать «Полотно» для вывода изображений, которое заставим вести себя в интерфейсе в точности как обычная кнопка.

Разберем реализацию этого метода по шагам:

  1. Создадим в реквизитах управляемой формы новый реквизит. Назовем его, например, АдресИзображенияКнопки. Тип данных для этого реквизита укажем как Строка.
  2. Перетащим созданный реквизит мышью на форму. По умолчанию платформа создаст поле ввода. Нам необходимо изменить его вид. В свойствах созданного элемента формы в поле Вид выберем значение Поле картинки.
  3. Перейдем в свойства нового поля картинки и установим флажок Гиперссылка в значение Истина (в программном коде это свойство доступно как Элементы.ПолеКартинки.Гиперссылка). Благодаря этому при наведении указателя мыши на картинку курсор будет принимать форму «руки», визуально подсказывая пользователю, что на элемент можно нажать.
  4. Настроим свойство Размер картинки. Рекомендуется установить значение Пропорционально или Авто, чтобы динамически загружаемые изображения корректно масштабировались под размеры элемента формы.
  5. Создадим обработчик события Нажатие для нашего поля картинки. Именно в этом обработчике мы пропишем логику, которая должна выполняться при клике на нашу «кнопку».
  6. Теперь нам остается программно передать адрес картинки в созданный строковый реквизит формы. Делать это нужно на сервере.

Рассмотрим подробнее пример серверного кода, который помещает картинку в реквизит формы:


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

КонецПроцедуры

Этот метод визуально ничем не отличается для пользователя от обычной кнопки, работает крайне быстро и не вызывает зависаний интерфейса. Для организации загрузки и хранения картинок в базе данных подойдёт готовый шаблон сохранения изображений в ХранилищеЗначения.

Вариант 2. Использование «Поля HTML-документа»

Если перед вами стоит задача спроектировать сложный и динамичный плиточный интерфейс (например, графическое меню для рабочего места кассира (РМК), терминала самообслуживания или рабочего стола официанта), то предыдущий метод может оказаться слишком громоздким. В таких случаях идеальным решением будет использование встроенного браузера 1С.

Проанализируем ситуацию: поле HTML-документа позволяет вывести абсолютно любую верстку, поддерживающую современные стандарты стилей CSS и разметки HTML. Мы можем налету сгенерировать красивую сетку кнопок с любыми картинками.

Разберем по шагам алгоритм реализации:

  1. Добавим на форму реквизит с типом Строка, например, HTMLКодПанели.
  2. Разместим этот реквизит на форме и установим для него вид элемента Поле HTML-документа.
  3. Чтобы внедрить произвольные картинки из базы данных непосредственно в HTML-код без сохранения во временные файлы, переведем их в формат Base64. Картинку можно вставить прямо в тело тега картинки.

Посмотрим на пример формирования такого кода в модуле формы:


&НаСервере
Процедура СформироватьДинамическоеМеню()
    
    // Получаем двоичные данные нашей картинки из базы данных
    ДвоичныеДанныеКартинки = Справочники.Номенклатура.НайтиПоКоду("00000001").ПолучитьОбъект().Изображение.Получить();
    
    Если ДвоичныеДанныеКартинки <> Неопределено Тогда
        // Кодируем бинарные данные в строку Base64
        СтрокаBase64 = ПолучитьСтрокуBase64ИзДвоичныхДанных(ДвоичныеДанныеКартинки);
        ФорматКартинки = "image/png"; // Укажите нужный формат (png, jpeg, gif)
        
        // Формируем HTML-код с внедренной картинкой и стилизованной кнопкой
        ТекстHTML = "<html><body style='margin:0; padding:0; background-color:#f0f0f0;'>";
        ТекстHTML = ТекстHTML + "<div style='display:flex; justify-content:center; align-items:center; height:100vh;'>";
        ТекстHTML = ТекстHTML + "<a href='onclick:MyActionButton' id='btn1' style='text-decoration:none; display:inline-block; padding:10px; background:#fff; border:1px solid #ccc; border-radius:5px;'>";
        ТекстHTML = ТекстHTML + "<img src='data:" + ФорматКартинки + ";base64," + СтрокаBase64 + "' width='64' height='64' />";
        ТекстHTML = ТекстHTML + "<p style='text-align:center; margin:5px 0 0 0; font-family:Arial; font-size:12px;'>Нажми меня</p>";
        ТекстHTML = ТекстHTML + "</a></div></body></html>";
        
        HTMLКодПанели = ТекстHTML;
    КонецЕсли;

КонецПроцедуры

Для обработки нажатия на такую кнопку мы используем стандартное событие элемента формы ПриНажатии у поля HTML-документа. Программа перехватит переход по навигационной ссылке вида onclick:MyActionButton, отменит стандартное поведение браузера и выполнит необходимый код на встроенном языке 1С.

Вариант 3. Динамическая смена картинок из библиотеки метаданных

Рассмотрим сценарий, когда набор картинок, которые могут быть установлены на кнопку, известен заранее и ограничен. Например, кнопка должна менять свой внешний вид в зависимости от статуса документа: «Новый», «В работе», «Проведен», «Отклонен».

В этом случае нам не нужно пытаться загружать файлы из внешних источников на лету. Мы можем использовать штатные механизмы платформы, так как замена картинок из библиотеки разрешена разработчиками 1С программно. Для наполнения библиотеки метаданных можно использовать набор графических ресурсов и иконок платформы 1С.

Для реализации этого подхода выполним следующие действия:

  1. Загрузим все необходимые изображения в конфигураторе в ветку дерева метаданных Общие картинки. Присвоим им понятные имена (например, СтатусНовый, СтатусВРаботе, СтатусЗавершен).
  2. В коде управляемой формы мы можем напрямую присваивать свойству Картинка кнопки элементы из системной библиотеки картинок.

Давайте посмотрим на пример программного кода:


&НаКлиенте
Процедура ОбновитьВидКнопкиПоСтатусу(ТекущийСтатус)
    
    // Программное изменение картинки кнопки разрешено, если картинка берется из библиотеки
    Если ТекущийСтатус = ПредопределенноеЗначение("Перечисление.СтатусыЗаказов.Новый") Тогда
        Элементы.КнопкаДействия.Картинка = БиблиотекаКартинок.СтатусНовый;
        Элементы.КнопкаДействия.Заголовок = "Запустить в работу";
    ИначеЕсли ТекущийСтатус = ПредопределенноеЗначение("Перечисление.СтатусыЗаказов.ВРаботе") Тогда
        Элементы.КнопкаДействия.Картинка = БиблиотекаКартинок.СтатусВРаботе;
        Элементы.КнопкаДействия.Заголовок = "Завершить работу";
    Иначе
        Элементы.КнопкаДействия.Картинка = БиблиотекаКартинок.СтатусЗавершен;
        Элементы.КнопкаДействия.Заголовок = "Закрыть заказ";
    КонецЕсли;
    
КонецПроцедуры

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

Вариант 4. Переключатель видимости группы подготовленных кнопок

Если вариантов отображения кнопки всего два или три, и при этом они статичны, можно применить простой трюк с видимостью элементов. Вместо того чтобы мучаться с программным переопределением свойств одной кнопки, мы создаем в конфигураторе несколько физически разных кнопок.

Каждой кнопке мы жестко и статично задаем свою картинку из библиотеки или файлов еще на этапе разработки формы. Затем мы объединяем эти кнопки в одну группу (без отображения границ) и управляем их отображением.

Проанализируем пример кода, управляющего видимостью элементов на форме:


&НаСервере
Процедура УправлениеКнопкамиНаСервере(ЗначениеПереключателя)
    
    // В зависимости от логики делаем видимой только одну нужную кнопку
    Элементы.КнопкаВариантА.Видимость = (ЗначениеПереключателя = 1);
    Элементы.КнопкаВариантБ.Видимость = (ЗначениеПереключателя = 2);
    Элементы.КнопкаВариантВ.Видимость = (ЗначениеПереключателя = 3);
    
КонецПроцедуры

Этот метод чрезвычайно прост в отладке, не создает никакой нагрузки на серверную часть и моментально отрабатывает на стороне тонкого клиента.

Резюме

Мы подробно разобрали системное ограничение управляемых форм 1С:Предприятие 8.3 на программную установку произвольных картинок для кнопок и изучили методы его обхода. Выбор конкретного решения зависит от вашей архитектурной задачи:

← На главную