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

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

В процессе разработки конфигураций на платформе 1С:Предприятие 8.3 начинающие программисты часто сталкиваются с задачей отображения графической информации. Типичный сценарий: в системе есть справочник Модели, где хранится фотография автомобиля, и справочник Оборудование (или ТранспортныеСредства), в котором пользователь выбирает модель. Логично, что при выборе модели на форме оборудования должна автоматически появляться соответствующая фотография.

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

Анализ архитектурных и программных ошибок автора темы

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

Фото.Объект.Картинка.Получить;

В этой короткой строке скрыты сразу три фундаментальные ошибки работы в управляемом интерфейсе:

  1. Обращение к свойствам примитивного типа: Переменная Фото на клиенте представляет собой обычную строку (навигационную ссылку или адрес во временном хранилище). У типа Строка нет и не может быть свойства Объект. Платформа закономерно сообщает об ошибке: «Значение не является значением объектного типа (Объект)».
  2. Попытка разыменования ссылок на клиенте: В управляемом приложении на стороне клиента нельзя обращаться к реквизитам базы данных «через точку». Конструкция вида Объект.Модель.Картинка на клиенте вызовет критическую ошибку, так как клиентское приложение «знает» только ссылочные метаданные, но не имеет прямого доступа к таблицам СУБД. Любое чтение данных должно происходить на сервере.
  3. Путаница между объектом и ссылкой: Метод Получить() используется для извлечения данных из объекта типа ХранилищеЗначения. Однако на форме мы работаем с навигационными ссылками, которые платформа 1С визуализирует в поле картинки автоматически, без необходимости ручного извлечения двоичных данных в память клиента.

Также частой ошибкой является обновление картинки только в процедуре ПриСозданииНаСервере. При таком подходе, если пользователь интерактивно изменит модель в открытой карточке оборудования, картинка останется прежней до тех пор, пока форму не переоткроют. Нам же требуется динамическое интерактивное обновление.

Правильная архитектура хранения и вывода картинок

Давайте спроектируем правильную структуру данных. Нам понадобятся три объекта конфигурации:

Такое разделение позволяет хранить тяжелые файлы отдельно от основных учетных данных, что положительно сказывается на производительности СУБД при выборках.

Пошаговая инструкция по реализации функционала

Рассмотрим подробнее процесс настройки формы и написания программного кода для реализации динамического отображения фото.

Шаг 1. Подготовка управляемой формы

Откроем управляемую форму элемента справочника ТранспортныеСредства (или Оборудование) и выполним следующие действия:

  1. Перейдем на вкладку Реквизиты (в правой части редактора формы) и добавим новый реквизит формы. Назовем его АдресФото. Зададим ему тип Строка. Обратите внимание: это реквизит формы, а не реквизит объекта, в базу данных он записываться не будет.
  2. Перетащим созданный реквизит АдресФото в левую часть — в дерево элементов формы.
  3. Выделим добавленный элемент формы и в палитре свойств изменим его свойство Вид на значение Поле картинки.
  4. Для того чтобы загружаемые фотографии не искажались и красиво вписывались в отведенную область, найдем в свойствах поля картинки параметр Размер картинки и установим для него значение Пропорционально.

Шаг 2. Получение навигационной ссылки на сервере

Чтобы отобразить картинку в поле формы, нам нужно передать туда ее уникальный веб-адрес внутри системы 1С — навигационную ссылку. Для обеспечения максимальной производительности мы напишем контекстно-независимую функцию. Использование директивы &НаСервереБезКонтекста гарантирует, что при вызове функции клиент не будет передавать на сервер и обратно тяжелые данные всей формы.

Проанализируем программный код серверной функции, который необходимо добавить в модуль формы:


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

В этом коде мы с помощью легкого SQL-запроса получаем ссылку на элемент справочника файлов, а затем стандартной функцией платформы ПолучитьНавигационнуюСсылку() формируем внутренний URL-адрес двоичных данных, хранящихся в СУБД. Именно этот адрес понимает наше Поле картинки на форме.

Шаг 3. Инициализация при открытии формы

При открытии уже существующего в базе данных элемента оборудования нам необходимо сразу показать картинку его модели. Для этого пропишем вызов нашей функции в стандартном обработчике события формы:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Заполняем реквизит формы адресом картинки при создании формы
    АдресФото = ПолучитьАдресИзображенияМодели(Объект.Модель);
    
КонецПроцедуры

Шаг 4. Динамическое обновление при выборе модели

Теперь решим ключевую задачу: сделаем так, чтобы картинка менялась мгновенно «на лету» при интерактивном выборе модели пользователем. Разберем этот процесс по шагам:

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

Код обработчика события будет выглядеть следующим образом:


&НаКлиенте
Процедура МодельПриИзменении(Элемент)
    
    // Динамически получаем новый адрес картинки при изменении модели пользователем
    АдресФото = ПолучитьАдресИзображенияМодели(Объект.Модель);
    
КонецПроцедуры

Благодаря этому коду, как только пользователь выберет другую модель, клиентская процедура мгновенно отправит запрос на сервер, передав туда ссылку на новую модель, получит актуальный адрес картинки во временном хранилище СУБД и обновит элемент отображения на экране.

Важные рекомендации по оптимизации работы с файлами

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

← На главную