При разработке печатных форм в 1С часто возникает задача вывода различных графических объектов: логотипов компаний, фотографий номенклатуры, изображений штрихкодов или факсимиле. Обычно эти изображения хранятся в базе данных в реквизитах с типом ХранилищеЗначений. Процесс их вывода на печать имеет ряд нюансов, связанных с позиционированием, масштабированием и безопасным извлечением данных.
В этой статье мы подробно разберем несколько практических способов вывода картинок в макет табличного документа, проанализируем возможные ошибки и выясним, как сделать верстку печатной формы адаптивной и надежной.
Перед тем как выводить картинку в макет, нам необходимо корректно извлечь ее из базы данных. Прямое обращение к хранилищу без проверок может привести к аварийному завершению работы программы, если картинка не была загружена пользователем.
Рассмотрим безопасный шаблон извлечения двоичных данных и инициализации объекта Картинка. Проанализируем следующий код:
// Получаем данные из реквизита ХранилищеЗначений
ДанныеХранилища = ДокументОбъект.Изделие.Картинка.Файл.Получить();
Если ЗначениеЗаполнено(ДанныеХранилища) Тогда
// Проверяем тип данных в хранилище (там могут быть как ДвоичныеДанные, так и готовый объект Картинка)
Если ТипЗнч(ДанныеХранилища) = Тип("ДвоичныеДанные") Тогда
КартинкаДляПечати = Новый Картинка(ДанныеХранилища);
ИначеЕсли ТипЗнч(ДанныеХранилища) = Тип("Картинка") Тогда
КартинкаДляПечати = ДанныеХранилища;
КонецЕсли;
Иначе
// Если картинки нет, подготавливаем пустое значение или дефолтную заглушку
КартинкаДляПечати = Новый Картинка;
КонецЕсли;
Использование такой проверки гарантирует, что конструктор Новый Картинка() не вызовет ошибку несоответствия типов, если в базе данных отсутствует изображение.
Этот способ во многом повторяет решение, к которому пришел автор темы на форуме. Он заключается в том, что на лету создается графический контейнер внутри области табличного документа, заполняется картинкой и позиционируется по координатам.
Давайте разберем по шагам, как это реализовать в коде:
// 1. Получаем необходимую область макета
ОбластьМакета = Макет.ПолучитьОбласть("ТехническиеХарактеристикиШапкаТч");
// 2. Создаем и добавляем новый рисунок в коллекцию рисунков области
Рисунок = ОбластьМакета.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
// 3. Задаем координаты и геометрические размеры контейнера (в миллиметрах)
Рисунок.Верх = 5;
Рисунок.Высота = 70;
Рисунок.Ширина = 70;
Рисунок.Лево = 5;
// 4. Помещаем картинку в созданный контейнер
Рисунок.Картинка = КартинкаДляПечати;
// 5. Настраиваем режим масштабирования
Рисунок.РазмерКартинки = РазмерКартинки.АвтоРазмер;
// 6. Выводим область в итоговый табличный документ
ТабличныйДокумент.Вывести(ОбластьМакета);
Преимущества: Полный контроль над созданием объекта из кода, независимость от предварительной разметки макета.
Недостатки: Координаты (Верх, Лево, Высота, Ширина) приходится прописывать вручную. При любом изменении дизайна печатной формы разработчику придется пересчитывать эти показатели в коде.
Чтобы избежать ручного прописывания координат в коде, мы можем визуально разместить контейнер для картинки прямо в конфигураторе при редактировании макета.
Рассмотрим пошаговый алгоритм настройки макета:
ИзображениеТовара).Теперь программный код для заполнения этого рисунка будет выглядеть максимально просто и лаконично:
ОбластьМакета = Макет.ПолучитьОбласть("ТехническиеХарактеристикиШапкаТч");
// Нам больше не нужно создавать рисунок и задавать координаты!
// Достаточно обратиться к нему по имени, заданному в макете:
Если ЗначениеЗаполнено(КартинкаДляПечати) Тогда
ОбластьМакета.Рисунки.ИзображениеТовара.Картинка = КартинкаДляПечати;
Иначе
// Если картинки нет, скрываем рамку, чтобы она не печаталась пустой
ОбластьМакета.Рисунки.ИзображениеТовара.Видимость = Ложь;
EndIf;
ТабличныйДокумент.Вывести(ОбластьМакета);
Существует еще один профессиональный подход, позволяющий вообще отказаться от использования графических рисунков, парящих над сеткой таблицы. Картинку можно встроить непосредственно в саму ячейку таблицы.
Разберем, как это настроить:
ФотоТовара.Заполнение такого параметра в коде происходит аналогично работе с обычным текстом:
ОбластьМакета = Макет.ПолучитьОбласть("ТехническиеХарактеристикиШапкаТч");
// Присваиваем объект Картинка непосредственно в параметр ячейки
ОбластьМакета.Параметры.ФотоТовара = КартинкаДляПечати;
ТабличныйДокумент.Вывести(ОбластьМакета);
При таком подходе картинка жестко привязана к границам ячеек, масштабируется вместе с ними при изменении ширины колонок и ведет себя стабильно при конвертации печатной формы в форматы PDF или Excel.
В процессе обсуждения на форуме автор столкнулся с тем, что изображение обрезалось. Причиной было использование свойства РазмерКартинки.РеальныйРазмер. Давайте проанализируем, какие режимы масштабирования существуют в 1С и какой выбрать:
РазмерКартинки.РеальныйРазмер — изображение выводится «как есть», пиксель в пиксель. Если исходный файл имеет большое разрешение (например, фото с телефона 4000x3000), на листе отобразится лишь крошечный левый верхний угол этого фото, остальное выйдет за границы рамки (обрежется).РазмерКартинки.АвтоРазмер — автоматически изменяет размеры самого контейнера (рисунка на макете) под габариты картинки. Использование этого режима опасно: большая картинка может растянуть рисунок на весь лист А4, сдвинув всю текстовую информацию и сломав структуру верстки.РазмерКартинки.Пропорционально — лучший выбор для печатных форм. Рамка на макете сохраняет свои жесткие размеры, а картинка масштабируется внутри нее так, чтобы полностью поместиться без искажения пропорций сторон (по вертикали или горизонтали останутся небольшие пустые поля, если пропорции не совпадают).РазмерКартинки.Растянуть — картинка принудительно заполняет всю площадь рамки. Если пропорции рамки и картинки не совпадают, изображение будет искажено (растянуто по горизонтали или сжато).По умолчанию у добавленных рисунков на печати может отображаться тонкая черная рамка. Чтобы изображение выглядело аккуратно, эту границу рекомендуется отключать программно:
// Убираем рамку вокруг рисунка
Рисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии);
Или, если вы используете заранее добавленный рисунок в макете, просто настройте свойство Линия в свойствах рисунка в конфигураторе, установив тип линии Нет линии.
Если ваша конфигурация разработана на базе Библиотеки Стандартных Подсистем (БСП), файлы картинок чаще всего хранятся в специальном справочнике присоединенных файлов. Для работы с ними рекомендуется использовать штатные программные интерфейсы БСП. Это позволит избежать прямого обращения к реквизитам и оптимизирует работу с кэшем сервера:
// Получаем двоичные данные файла через БСП
ДвоичныеДанныеФайла = РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаПрисоединенныйФайл);
Если ТипЗнч(ДвоичныеДанныеФайла) = Тип("ДвоичныеДанные") Тогда
КартинкаДляПечати = Новый Картинка(ДвоичныеДанныеФайла);
КонецЕсли;
Использование методов БСП делает код более устойчивым к обновлениям конфигурации и гарантирует высокую производительность системы.