Как исправить ошибку «Несоответствие типов» при выводе картинки из ХранилищаЗначения на форму в 1С?

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

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

Причина ошибки: несоответствие типов данных

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


КартинкаОбъект = Новый Картинка(ДиалогВыбораФайлаОбъект.ПолноеИмяФайла);
НовыйЭлемент.ДанныеКартинки = Новый ХранилищеЗначения(КартинкаОбъект.ПолучитьДвоичныеДанные());

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


мТекущееОсновноеИзображение = Элементы.ДанныеКартинки.Получить();
ЭлементыФормы.ПолеКартинкиФотография.Картинка = мТекущееОсновноеИзображение;

Платформа выдает ошибку несоответствия типов. Причина заключается в том, что в ХранилищеЗначения был помещен результат вызова ПолучитьДвоичныеДанные() — объект типа ДвоичныеДанные. Соответственно, метод Получить() возвращает не объект Картинка, а именно ДвоичныеДанные, которые нельзя напрямую передать в свойство ЭлементыФормы.ПолеКартинки.Картинка.

Способ 1. Создание объекта «Картинка» из двоичных данных при чтении

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

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

  1. Извлекаем содержимое из реквизита с типом ХранилищеЗначения.
  2. Проверяем, что полученное значение не равно Неопределено и имеет правильный тип.
  3. Создаем объект Картинка на основе двоичных данных.
  4. Присваиваем полученную картинку элементу формы.

Процедура ПоказатьОсновноеИзображение(АктивнаяСтрока)
    
    ДвоичныеДанныеИзображения = Неопределено;
    
    // Получаем значение из строки табличной части или реквизита
    Если ЗначениеЗаполнено(АктивнаяСтрока.ДанныеКартинки) Тогда
        ДвоичныеДанныеИзображения = АктивнаяСтрока.ДанныеКартинки.Получить();
    КонецЕсли;
    
    Если ТипЗнч(ДвоичныеДанныеИзображения) = Тип("ДвоичныеДанные") Тогда
        ЭлементыФормы.ПолеКартинкиФотография.Картинка = Новый Картинка(ДвоичныеДанныеИзображения);
    Иначе
        ЭлементыФормы.ПолеКартинкиФотография.Картинка = Новый Картинка;
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Сохранение объекта «Картинка» напрямую в ХранилищеЗначения

Объект ХранилищеЗначения в 1С поддерживает сериализацию не только двоичных данных, но и самих объектов типа Картинка. Преобразовывать изображение в ДвоичныеДанные перед записью необязательно.

Посмотрим на пример сохранения и извлечения объекта напрямую:


// 1. Сохранение картинки
КартинкаДляЗаписи = Новый Картинка(ДиалогВыбораФайлаОбъект.ПолноеИмяФайла);
НовыйЭлемент.ДанныеКартинки = Новый ХранилищеЗначения(КартинкаДляЗаписи);

// 2. Чтение картинки
ЗначениеИзХранилища = СтрокаТабличнойЧасти.ДанныеКартинки.Получить();
Если ТипЗнч(ЗначениеИзХранилища) = Тип("Картинка") Тогда
    ЭлементыФормы.ПолеКартинкиФотография.Картинка = ЗначениеИзХранилища;
Иначе
    ЭлементыФормы.ПолеКартинкиФотография.Картинка = Новый Картинка;
КонецЕсли;

Практические рекомендации и оптимизация кода

Рассмотрим несколько важных нюансов, которые помогут избежать снижения производительности и ошибок при работе с файлами:

  1. Управление сжатием данных: По умолчанию конструктор ХранилищеЗначения использует степень сжатия СтепеньСжатия.Обычная. Если вы сохраняете форматы, которые уже сжаты (например, JPEG или PNG), повторное сжатие не уменьшит размер файла, но создаст лишнюю нагрузку на процессор. Рекомендуется отключать сжатие явно:
    
    НовыйЭлемент.ДанныеКартинки = Новый ХранилищеЗначения(КартинкаОбъект, СтепеньСжатия.БезСжатия);
    
  2. Извлечение имени файла: Для получения имени файла из полного пути не следует писать сложные циклы посимвольной обработки строки. Для этого в платформе предусмотрен объект Файл:
    
    ВыбранныйФайл = Новый Файл(ДиалогВыбораФайлаОбъект.ПолноеИмяФайла);
    ИмяФайла = ВыбранныйФайл.Имя;
    
  3. Архитектура хранения данных: Размещение реквизитов типа ХранилищеЗначения внутри табличных частей объектов (справочников, документов, задач) крайне не рекомендуется. При чтении объекта табличная часть целиком считывается в оперативную память вместе со всеми тяжелыми бинарными данными. Оптимальным решением является хранение файлов в отдельном справочнике, регистре сведений либо на внешних дисковых томах.
← На главную