При формировании прайс-листов и каталогов номенклатуры с использованием системы компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда в колонке с фотографией товара вместо графического объекта отображаются пустые угловые скобки <>. Выясним причину такого поведения платформы 1С и разберем по шагам надежные способы корректного вывода изображений и настройки высоты строк.
Проанализируем механику работы платформы 1С:
Картинка, ДвоичныеДанные, ХранилищеЗначения или ссылку на справочник файлов, стандартный процессор вывода СКД преобразует нетекстовый объект в его строковое представление по умолчанию — пустые скобки <>.Рисунки и располагаются в отдельном слое поверх ячеек. Свойство АвтоВысотаСтроки рассчитывается генератором табличного документа исключительно на основе объема текста и размера шрифта. Графические объекты механизмом автовысоты полностью игнорируются, из-за чего изображение может перекрывать соседние строки или сжиматься в узкую полоску.Рассмотрим классический и наиболее гибкий вариант решения задачи — перехват компоновки в модуле объекта отчета и программное размещение графических объектов поверх ячеек с данными.
Для этого в модуле объекта отчета переопределим стандартную процедуру ПриКомпоновкеРезультата:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Формируем базовый табличный документ стандартными средствами
СкомпоноватьРезультат(ДокументРезультат, ДанныеРасшифровки);
// Запускаем алгоритм вывода изображений
ВывестиКартинкиСКД(ДокументРезультат, ДанныеРасшифровки);
КонецПроцедуры
Теперь добавим саму процедуру обхода сформированного табличного документа. Алгоритм анализирует поля расшифровки каждой ячейки, извлекает двоичные данные или картинку из хранилища и размещает графический объект в границах ячейки:
Процедура ВывестиКартинкиСКД(ДокументРезультат, ДанныеРасшифровки)
Для НомерСтроки = 1 По ДокументРезультат.ВысотаТаблицы Цикл
Для НомерКолонки = 1 По ДокументРезультат.ШиринаТаблицы Цикл
Область = ДокументРезультат.Область(НомерСтроки, НомерКолонки);
Расшифровка = Область.Расшифровка;
Если ТипЗнч(Расшифровка) = Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
ПоляРасшифровки = ДанныеРасшифровки.Элементы.Получить(Расшифровка).ПолучитьПоля();
ОбъектКартинка = Неопределено;
Для Каждого ПолеРасшифровки Из ПоляРасшифровки Цикл
// Проверяем наличие поля с хранилищем или ссылкой на присоединенный файл
Если ТипЗнч(ПолеРасшифровки.Значение) = Тип("СправочникСсылка.ХранилищеДополнительнойИнформации")
И ЗначениеЗаполнено(ПолеРасшифровки.Значение) Тогда
ЗначениеИзХранилища = ПолеРасшифровки.Значение.Хранилище.Получить();
Если ТипЗнч(ЗначениеИзХранилища) = Тип("Картинка") Тогда
ОбъектКартинка = ЗначениеИзХранилища;
ИначеЕсли ТипЗнч(ЗначениеИзХранилища) = Тип("ДвоичныеДанные") Тогда
ОбъектКартинка = Новый Картинка(ЗначениеИзХранилища);
КонецЕсли;
Прервать;
КонецЕсли;
КонецЦикла;
Если ОбъектКартинка <> Неопределено Тогда
// Принудительно задаем высоту строки таблицы в пунктах
Область.ВысотаСтроки = 60;
// Добавляем и позиционируем рисунок
НовыйРисунок = ДокументРезультат.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
НовыйРисунок.Картинка = ОбъектКартинка;
НовыйРисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
// Отключаем границы рисунка
НовыйРисунок.ГраницаСверху = Ложь;
НовыйРисунок.ГраницаСлева = Ложь;
НовыйРисунок.ГраницаСнизу = Ложь;
НовыйРисунок.ГраницаСправа = Ложь;
// Привязываем рисунок к границам текущей ячейки
НовыйРисунок.Расположить(Область);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Если требуется зафиксировать оформление без глубокого программного перебора всего табличного документа, применим пользовательские макеты в схеме компоновки данных:
Рисунок.Расположить(Область), используя режим масштабирования РазмерКартинки.Пропорционально или РазмерКартинки.Автомасштаб.Для объемных прайс-листов двойной перебор матрицы ячеек может занимать заметное время. В таких случаях эффективнее использовать поэлементный вывод результата:
ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент.ПроцессорКомпоновкиДанных.Следующий().ПроцессорВывода.ВывестиЭлемент() сразу получаем координаты добавленной области, выставляем ее высоту и добавляем рисунок.Посмотрим на ключевые правила, которые помогут избежать зависаний и повышенного расхода памяти:
<>, перед размещением рисунка очищайте значение области: Область.Текст = "";.