Как программно добавить и отобразить несколько картинок на обычной форме 1С?

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

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

Разберем способы реализации этой задачи: от прямого программного создания элементов управления до альтернативных вариантов с использованием табличных документов и полей HTML.

Способ 1. Программное создание элементов «ПолеКартинки» на панели формы

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

Синтаксис метода:

ЭлементыФормы.Добавить(<Тип>, <Имя>, <Видимость>, <ПоместитьНа>)

Рассмотрим по шагам логику создания галереи изображений на панели:

  1. Очистка ранее созданных элементов: перед выводом нового набора миниатюр необходимо найти и удалить старые поля, чтобы избежать дублирования имен и перегрузки интерфейса.
  2. Обход данных и создание полей: в цикле по строкам источника создается элемент ПолеКартинки с уникальным именем.
  3. Загрузка данных: если данные хранятся в формате Base64, выполняется их декодирование с помощью Base64Значение() и создание объекта Картинка.
  4. Геометрическое позиционирование: каждому новому элементу задаются координаты Лево, Верх, Ширина, Высота, а также настраиваются привязки границ.

Посмотрим на пример практической реализации:


// 1. Поиск и удаление ранее созданных элементов
МассивУдаляемых = Новый Массив;    
Для Каждого ЭлементФ Из ЭлементыФормы Цикл    
    Если Найти(СокрЛП(ЭлементФ.Имя), "Эскиз_") > 0 Тогда
        МассивУдаляемых.Добавить(ЭлементФ);
    КонецЕсли;
КонецЦикла;

Для Каждого ЭлементФ Из МассивУдаляемых Цикл    
    ЭлементыФормы.Удалить(ЭлементФ); 
КонецЦикла;

// 2. Динамическое добавление новых полей
Индекс = 0;
Для Каждого Стр Из ЭлементыФормы.ЗаказНаПроизводство.ТекущиеДанные.Ссылка.Продукция Цикл
    Если ПустаяСтрока(Стр.Схема) Тогда 
        Продолжить; 
    КонецЕсли;
    
    ИмяЭлемента = "Эскиз_" + Индекс;
    Эл = ЭлементыФормы.Добавить(Тип("ПолеКартинки"), ИмяЭлемента, Истина, ЭлементыФормы.Панель2);
    
    // Преобразование данных из Base64 в объект Картинка
    СтрокаBase64 = Стр.Схема;
    ДвоичныеДанные = Base64Значение(СтрокаBase64);
    Эл.Картинка = Новый Картинка(ДвоичныеДанные);
    Эл.РазмерКартинки = РазмерКартинки.АвтоРазмер;
        
    // Расчет координат размещения по горизонтали
    Эл.Лево = 10 + Индекс * 160;
    Эл.Верх = 10;
    Эл.Ширина = 150;
    Эл.Высота = 100;

    // Настройка привязок к границам формы/панели
    Эл.УстановитьПривязку(ГраницаЭлементаУправления.Верх, ЭлементыФормы.Панель2, ГраницаЭлементаУправления.Верх);
    Эл.УстановитьПривязку(ГраницаЭлементаУправления.Низ, ЭлементыФормы.Панель2, ГраницаЭлементаУправления.Верх);
    
    Индекс = Индекс + 1;
КонецЦикла;

Подводные камни и риски программного добавления элементов

Проанализируем ограничения, с которыми можно столкнуться при использовании данного подхода:

  1. Мерцание формы и производительность: частое удаление и добавление элементов в цикле при переключении строк таблицы нагружает интерфейсный поток и может вызывать визуальное мерцание.
  2. Отсутствие прокрутки на панели: элемент Панель в обычных формах не имеет автоматических полос прокрутки. Если элементов больше, чем ширина формы, они скроются за правой границей.
  3. Сложность привязок: метод УстановитьПривязку() требует аккуратного указания базовых элементов и границ. Ошибочные привязки приведут к искажению интерфейса при изменении размера окна пользователем.

Способ 2. Оптимизация через предварительный пул элементов

Чтобы избежать мерцания и постоянного пересоздания объектов в памяти, применим концепцию пула элементов:

  1. В конфигураторе или при открытии формы создаем фиксированное количество полей (например, 20 штук) и скрываем их (Видимость = Ложь).
  2. При обновлении данных в цикле заполняем только необходимые поля новыми картинками и делаем их видимыми (Видимость = Истина).
  3. Остальным полям из пула возвращаем свойство Видимость = Ложь.

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

Для отображения произвольного количества изображений с поддержкой автоматической прокрутки и адаптивной сетки отлично подходит ПолеHTMLДокумента:

  1. Размещаем на форме статический элемент с типом ПолеHTMLДокумента.
  2. В коде генерируем HTML-строку, встраивая данные изображений через Data URL (<img src="data:image/jpeg;base64,...">).
  3. Загружаем полученный код в элемент через метод УстановитьТекст().

Этот подход гарантирует плавную прокрутку, легко масштабируется с помощью CSS-стилей и не перегружает структуру элементов самой формы 1С.

Способ 4. Использование «Поля табличного документа»

Еще один надежный способ — вывод изображений в ПолеТабличногоДокумента:

  1. На форме размещается ПолеТабличногоДокумента.
  2. В цикле добавляются графические объекты: ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка).
  3. Рисунки привязываются к ячейкам с помощью метода Расположить(), после чего в свойство Картинка передаются двоичные данные.

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

Способ 5. Отображение миниатюр прямо в строках табличного поля

Если требуется сопоставить изображение конкретной строке таблицы без вывода отдельной галереи:

  1. В табличное поле добавляется колонка для отображения эскиза.
  2. В обработчике события ПриВыводеСтроки или ПриПолученииДанных активируется отображение графики:

Процедура ТабличноеПолеПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
    Если ДанныеСтроки <> Неопределено И НЕ ПустаяСтрока(ДанныеСтроки.Схема) Тогда
        ОформлениеСтроки.Ячейки.КолонкаЭскиз.ОтображатьКартинку = Истина;
        ДвоичныеДанные = Base64Значение(ДанныеСтроки.Схема);
        ОформлениеСтроки.Ячейки.КолонкаЭскиз.УстановитьКартинку(Новый Картинка(ДвоичныеДанные));
    КонецЕсли;
КонецПроцедуры

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

← На главную