Как исправить ошибку «Поле объекта недоступно для записи (Картинка)» в 1С:Предприятии 8.3

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

При переходе со старых версий платформы (например, 1С 8.1 или ранних релизов 8.2) на современную платформу 1С 8.3 разработчики часто сталкиваются со странным поведением печатных форм. Чтобы упростить техническое обслуживание процесса обновления, можно автоматизировать архивирование и обновление нескольких баз 1С. Код, который годами успешно выводил штрихкоды или логотипы компаний в табличные документы, внезапно прерывает работу с ошибкой: «Поле объекта недоступно для записи (Картинка)».

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

Выясняем причину ошибки: почему это работало в 1С 8.1 и сломалось в 1С 8.3?

Для начала проанализируем архитектуру хранения графических объектов в табличном документе. Объект РисунокТабличногоДокумента может иметь совершенно разные типы. Это может быть геометрическая фигура (линия, прямоугольник), текст, стандартная картинка или объект стороннего приложения (ActiveX).

Во времена платформы 1С:Предприятие 8.1 для печати штрихкодов практически во всех типовых и самописных конфигурациях использовалась внешняя компонента «1С:Печать штрихкодов» (1CBarCode). Она поставлялась в виде элемента управления ActiveX. Разработчики вставляли этот объект непосредственно в макет табличного документа через меню «Таблица — Рисунки — Вставить объект». Платформа позволяла обращаться к свойствам этого объекта программно, а иногда некорректно интерпретировала типы, прощая программистам вольности в коде.

С выходом платформы 1С 8.3 правила работы с типами данных стали гораздо строже. Появились 64-разрядные клиентские приложения, тонкий клиент и веб-клиент, в среде которых старые 32-битные ActiveX-компоненты физически не могут функционировать. Современные компоненты генерации штрихкодов (например, использующие технологию Native API) формируют изображение штрихкода в памяти сервера и возвращают его в виде обычного бинарного файла (PNG или BMP) или готового объекта Картинка.

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

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

Шаг 1. Модернизация макета печатной формы в Конфигураторе

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

  1. Откроем конфигурацию и найдем макет нашей печатной формы (это может быть макет документа, справочника или внешней печатной формы).
  2. Внимательно изучим область, где выводится изображение или штрихкод. Найдем рамку рисунка, которая вызывает ошибку.
  3. Выделим этот рисунок и полностью удалим его, нажав клавишу Delete. Мы должны избавиться от старого ActiveX-контейнера.
  4. Теперь добавим современный и правильный графический контейнер. Для этого перейдем в главное меню: «Таблица» — «Рисунки» — «Картинка...».
  5. На экране появится диалоговое окно выбора картинки. Важный нюанс: нам не нужно выбирать конкретный файл с диска или из библиотеки картинок. Просто нажмите кнопку «Отмена» (или закройте окно). На макете появится пустая прямоугольная область с системной надписью «Картинка».
  6. Перетащим созданную область в нужное место макета, настроим ее границы и размеры так, как это требуется для корректного вывода печатной формы.
  7. Нажмем на добавленный рисунок правой кнопкой мыши и выберем пункт «Свойства».
  8. В панели свойств найдем поле «Имя» и зададим ему то имя, по которому к нему обращаются в программном коде. Например, если в коде написано Рисунок = ОбластьМакета.Рисунки.Штрихкод, то в поле «Имя» мы должны написать Штрихкод. Обратите внимание на регистр букв — он должен совпадать с программным кодом.
  9. Дополнительно в свойствах рисунка рекомендуется проверить параметр «Выводить на печать» (должен быть установлен в значение «Истина») и снять флажок «Защита», чтобы избежать возможных блокировок при интерактивной работе пользователя с табличным документом.

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

Шаг 2. Написание отказоустойчивого кода для вывода картинки

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

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


// Получаем область макета, подготовленную к выводу
ОбластьМакета = Макет.ПолучитьОбласть("Шапка");

// Предположим, что внешняя компонента вернула нам данные штрихкода
// Данные могут прийти как в формате ДвоичныеДанные, так и в виде готового объекта Картинка
ДвоичныеДанныеФайла = ВнешняяКомпонента.ПолучитьШтрихкод(); 

// Создаем пустую переменную для результирующей картинки
КартинкаДляПечати = Неопределено;

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

// Производим безопасное присвоение картинки объекту макета
Попытка
    ОбластьМакета.Рисунки.Штрихкод.Картинка = КартинкаДляПечати;
Исключение
    ЗаписьЖурналаРегистрации("ПечатьШтрихкода",
        УровеньЖурналаРегистрации.Ошибка,
        ,
        ,
        "Не удалось записать картинку в макет. Описание ошибки: " + ОписаниеОшибки());
КонецПопытки;

// Выводим область в результирующий табличный документ
ТабличныйДокумент.Вывести(ОбластьМакета);

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

Дополнительная диагностика: как проверить тип рисунка в отладчике?

Если после выполнения всех инструкций вы все еще сталкиваетесь с ошибками работы с рисунком, давайте вместе проведем диагностику в режиме отладки. Чтобы исключить влияние технических сбоев или программных правок на учет, можно автоматически проверить бухгалтерские и налоговые проводки на наличие расхождений. Остановите выполнение программы на строке присвоения картинки и добавьте в табло следующее выражение:

ОбластьМакета.Рисунки.Штрихкод.ТипРисунка

Платформа вернет значение из системного перечисления ТипРисункаТабличногоДокумента. Проанализируем результат:

Используя этот простой алгоритм, вы легко сможете перевести любые старые печатные формы на стандарты платформы 1С 8.3, обеспечив их быструю и стабильную работу без ошибок записи объектных полей. Если же помимо правки макетов требуется полноценная миграция учета, стоит изучить раздел с решениями по переносу данных 1С по тарифу PRO.

← На главную