При переходе со старых версий платформы (например, 1С 8.1 или ранних релизов 8.2) на современную платформу 1С 8.3 разработчики часто сталкиваются со странным поведением печатных форм. Чтобы упростить техническое обслуживание процесса обновления, можно автоматизировать архивирование и обновление нескольких баз 1С. Код, который годами успешно выводил штрихкоды или логотипы компаний в табличные документы, внезапно прерывает работу с ошибкой: «Поле объекта недоступно для записи (Картинка)».
В этой статье мы подробно разберем, почему возникает данная проблема, как внутренние механизмы платформы 1С изменились со времен версии 8.1, и пошагово исправим макет печатной формы, чтобы код работал стабильно на любых современных релизах платформы.
Для начала проанализируем архитектуру хранения графических объектов в табличном документе. Объект РисунокТабличногоДокумента может иметь совершенно разные типы. Это может быть геометрическая фигура (линия, прямоугольник), текст, стандартная картинка или объект стороннего приложения (ActiveX).
Во времена платформы 1С:Предприятие 8.1 для печати штрихкодов практически во всех типовых и самописных конфигурациях использовалась внешняя компонента «1С:Печать штрихкодов» (1CBarCode). Она поставлялась в виде элемента управления ActiveX. Разработчики вставляли этот объект непосредственно в макет табличного документа через меню «Таблица — Рисунки — Вставить объект». Платформа позволяла обращаться к свойствам этого объекта программно, а иногда некорректно интерпретировала типы, прощая программистам вольности в коде.
С выходом платформы 1С 8.3 правила работы с типами данных стали гораздо строже. Появились 64-разрядные клиентские приложения, тонкий клиент и веб-клиент, в среде которых старые 32-битные ActiveX-компоненты физически не могут функционировать. Современные компоненты генерации штрихкодов (например, использующие технологию Native API) формируют изображение штрихкода в памяти сервера и возвращают его в виде обычного бинарного файла (PNG или BMP) или готового объекта Картинка.
Когда мы пытаемся присвоить программно созданную картинку объекту в макете, платформа проверяет тип этого объекта:
ТипРисункаТабличногоДокумента.Картинка, то операция присвоения проходит успешно.Картинка у такого рисунка заблокировано. В отладчике мы увидим, что значение свойства недоступно ни для чтения, ни для записи. При попытке выполнить присвоение платформа незамедлительно выбросит исключение.Таким образом, главная причина ошибки заключается в несоответствии типа объекта в макете типу присваиваемого значения. Нам необходимо заменить устаревший элемент макета на стандартный контейнер для графики.
Разберем по шагам, как исправить макет печатной формы, чтобы очистить его от наследия старых версий платформы:
Рисунок = ОбластьМакета.Рисунки.Штрихкод, то в поле «Имя» мы должны написать Штрихкод. Обратите внимание на регистр букв — он должен совпадать с программным кодом.Сохраним изменения в макете. Теперь наш шаблон подготовлен к работе по новым стандартам платформы 1С 8.3. При необходимости можно воспользоваться готовым примером разработки внешней печатной формы для актуальных версий БСП.
Чтобы программа работала надежно и не зависела от того, в каком именно формате внешняя компонента или база данных вернула изображение штрихкода (в виде готового объекта картинки или в виде двоичных данных), мы должны написать правильный обработчик в модуле печати.
Проанализируем пример кода, который проверяет тип входящих данных и корректно инициализирует объект Картинка перед выводом на печать:
// Получаем область макета, подготовленную к выводу
ОбластьМакета = Макет.ПолучитьОбласть("Шапка");
// Предположим, что внешняя компонента вернула нам данные штрихкода
// Данные могут прийти как в формате ДвоичныеДанные, так и в виде готового объекта Картинка
ДвоичныеДанныеФайла = ВнешняяКомпонента.ПолучитьШтрихкод();
// Создаем пустую переменную для результирующей картинки
КартинкаДляПечати = Неопределено;
// Разберем по шагам определение типа полученных данных
Если ТипЗнч(ДвоичныеДанныеФайла) = Тип("Картинка") Тогда
// Если компонента сразу вернула картинку, просто присваиваем ее
КартинкаДляПечати = ДвоичныеДанныеФайла;
ИначеЕсли ТипЗнч(ДвоичныеДанныеФайла) = Тип("ДвоичныеДанные") Тогда
// Если пришли двоичные данные, инициализируем новый объект Картинка
КартинкаДляПечати = Новый Картинка(ДвоичныеДанныеФайла);
Иначе
// В случае непредвиденных данных инициализируем пустую картинку во избежание падения системы
КартинкаДляПечати = Новый Картинка;
КонецЕсли;
// Производим безопасное присвоение картинки объекту макета
Попытка
ОбластьМакета.Рисунки.Штрихкод.Картинка = КартинкаДляПечати;
Исключение
ЗаписьЖурналаРегистрации("ПечатьШтрихкода",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Не удалось записать картинку в макет. Описание ошибки: " + ОписаниеОшибки());
КонецПопытки;
// Выводим область в результирующий табличный документ
ТабличныйДокумент.Вывести(ОбластьМакета);
В данном коде мы предусмотрели все возможные варианты развития событий. Конструкция Попытка ... Исключение застрахует пользователей от аварийного завершения работы программы, если по какой-то причине имя рисунка в макете будет случайно изменено или стерто при последующих доработках конфигурации другими разработчиками.
Если после выполнения всех инструкций вы все еще сталкиваетесь с ошибками работы с рисунком, давайте вместе проведем диагностику в режиме отладки. Чтобы исключить влияние технических сбоев или программных правок на учет, можно автоматически проверить бухгалтерские и налоговые проводки на наличие расхождений. Остановите выполнение программы на строке присвоения картинки и добавьте в табло следующее выражение:
ОбластьМакета.Рисунки.Штрихкод.ТипРисунка
Платформа вернет значение из системного перечисления ТипРисункаТабличногоДокумента. Проанализируем результат:
ТипРисункаТабличногоДокумента.Картинка (в числовом представлении это обычно значение 4) — макет обновлен правильно, и запись свойства Картинка разрешена.ТипРисункаТабличногоДокумента.Объект — это явный признак того, что в макете все еще присутствует старый элемент управления ActiveX. Повторите процедуру очистки макета, описанную в первом шаге.ТипРисункаТабличногоДокумента.Прямоугольник или другой графический примитив — это означает, что вместо контейнера картинок в макет была добавлена обычная геометрическая фигура из панели рисования. Ее также необходимо заменить на полноценную пустую картинку.Используя этот простой алгоритм, вы легко сможете перевести любые старые печатные формы на стандарты платформы 1С 8.3, обеспечив их быструю и стабильную работу без ошибок записи объектных полей. Если же помимо правки макетов требуется полноценная миграция учета, стоит изучить раздел с решениями по переносу данных 1С по тарифу PRO.