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

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

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

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

---

Выясняем причину ошибки «Значение не является значением объектного типа»

Эта ошибка сообщает нам о том, что программа пытается обратиться к методу или свойству переменной, которая не является объектом нужного типа (или вообще содержит пустое значение Неопределено). В контексте вывода картинок разработчики чаще всего спотыкаются на следующей строке кода:


СекцияИзображение.Параметры.Изображение = Новый Картинка(Фото.ПолучитьДвоичныеДанные(), Истина);

Давайте разберем по шагам, почему этот код уязвим и где именно кроется ошибка:

  1. Отсутствие проверки на пустое значение. Если у конкретного товара или сотрудника в базе данных не загружено изображение, то при считывании из базы данных переменная Фото примет значение Неопределено. Попытка вызвать любой метод у пустого значения гарантированно приведет к аварийному завершению работы кода.
  2. Несоответствие типов данных. Метод ПолучитьДвоичныеДанные() принадлежит исключительно объекту типа Картинка. Если в переменной Фото у вас уже лежат сырые ДвоичныеДанные, считанные напрямую из базы или временного хранилища, то у них нет такого метода. И наоборот, если там уже лежит готовая Картинка, повторное преобразование избыточно.

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


// Извлекаем данные из ХранилищаЗначения безопасным способом
ДанныеФайла = Выборка.ХранилищеКартинки.Получить();

Если ДанныеФайла = Неопределено Тогда
    // Изображение отсутствует — создаем пустую картинку
    КартинкаДляВывода = Новый Картинка;
ИначеЕсли ТипЗнч(ДанныеФайла) = Тип("Картинка") Тогда
    // В хранилище уже находился готовый объект Картинка
    КартинкаДляВывода = ДанныеФайла;
ИначеЕсли ТипЗнч(ДанныеФайла) = Тип("ДвоичныеДанные") Тогда
    // В хранилище были записаны сырые двоичные данные
    КартинкаДляВывода = Новый Картинка(ДанныеФайла);
Иначе
    // Обработка непредвиденных типов (например, путей к файлам в виде строк)
    КартинкаДляВывода = Новый Картинка;
КонецЕсли;

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

---

Почему в макете вместо фотографии выводится слово «Фото»?

Другая частая проблема — когда код отрабатывает без ошибок, но в сформированном табличном документе в ячейке выводится текстовая строка «Картинка» или просто имя параметра (например, «Фото»).

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

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

---

Способ 1. Вывод картинки через специальный параметр ячейки

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

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

После этого вы можете передавать картинку в параметры области стандартным способом:


ОбластьИзображение = Макет.ПолучитьОбласть("СекцияИзображение");
ОбластьИзображение.Параметры.Изображение = КартинкаДляВывода;
ТабДок.Вывести(ОбластьИзображение);

---

Способ 2. Вывод изображения с помощью объекта «Рисунок»

Это классический, наиболее гибкий и широко распространенный способ вывода картинок, который повсеместно применяется в типовых конфигурациях фирмы 1С (например, для вывода логотипов компаний в счетах на оплату или факсимильных подписей должностных лиц).

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

Вариант А: Использование предопределенного рисунка в макете

Мы можем заранее разместить область под картинку непосредственно в шаблоне макета в конфигураторе:

  1. В меню конфигуратора выберите Таблица -> Рисунки -> Вставить картинку...
  2. Выберите любую заглушку (или оставьте рисунок пустым) и разместите его поверх ячеек в нужной секции макета.
  3. Откройте свойства созданного рисунка и задайте ему уникальное имя в поле Имя (например, ЛоготипФирмы).
  4. Установите свойство Линия в значение Нет линии, чтобы убрать рамку вокруг картинки.
  5. Свойство Размер картинки переведите в режим Пропорционально. Это критически важно, чтобы выводимые фотографии не растягивались и не сжимались, искажая реальные пропорции лица или объекта.

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


ОбластьМакета = Макет.ПолучитьОбласть("Заголовок");

// Обращаемся к коллекции рисунков области по имени объекта
Если ОбластьМакета.Рисунки.Найти("ЛоготипФирмы") <> Неопределено Тогда
    ОбластьМакета.Рисунки.ЛоготипФирмы.Картинка = КартинкаДляВывода;
КонецЕсли;

ТабДок.Вывести(ОбластьМакета);

Вариант Б: Динамическое программное создание рисунка

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


ОбластьМакета = Макет.ПолучитьОбласть("СтрокаТовара");

// Добавляем новый рисунок-картинку в коллекцию рисунков текущей области
НовыйРисунок = ОбластьМакета.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
НовыйРисунок.Картинка = КартинкаДляВывода;

// Задаем точные координаты размещения картинки в миллиметрах
НовыйРисунок.Верх = 2;   // Отступ сверху от границы области
НовыйРисунок.Лево = 5;   // Отступ слева
НовыйРисунок.Ширина = 40; // Ширина картинки
НовыйРисунок.Высота = 30; // Высота картинки

// Настраиваем отображение границ рисунка
НовыйРисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии);

// Задаем режим пропорционального масштабирования
НовыйРисунок.РазмерКартинки = РазмерКартинки.Пропорционально;

ТабДок.Вывести(ОбластьМакета);

---

Интеграция с механизмами БСП (Библиотеки Стандартных Подсистем)

В современных конфигурациях 1С файлы картинок практически никогда не хранятся в основных реквизитах справочников. Для этого используются подсистемы БСП. Хранение организуется через подчиненные справочники присоединенных файлов (например, НоменклатураПрисоединенныеФайлы), а сами бинарные данные физически записываются в регистр сведений ДвоичныеДанныеФайлов или в специализированные тома на диске.

Чтобы извлечь изображение в среде БСП без написания сложных запросов, рекомендуется использовать готовые функции общего назначения:


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

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

← На главную