Как вывести изображения товаров в прайс-лист на СКД в 1С 8.3?

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

При формировании прайс-листов и каталогов номенклатуры с использованием системы компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда в колонке с фотографией товара вместо графического объекта отображаются пустые угловые скобки <>. Выясним причину такого поведения платформы 1С и разберем по шагам надежные способы корректного вывода изображений и настройки высоты строк.

Почему в СКД появляется символ <> и не работает автовысота?

Проанализируем механику работы платформы 1С:

  1. Отображение типов данных в ячейках: Ячейки табличного документа по умолчанию рассчитаны на хранение строк, чисел, дат и булевых значений. Если поле набора данных возвращает значение с типом Картинка, ДвоичныеДанные, ХранилищеЗначения или ссылку на справочник файлов, стандартный процессор вывода СКД преобразует нетекстовый объект в его строковое представление по умолчанию — пустые скобки <>.
  2. Ограничения автоматической высоты строк: Графические элементы в табличном документе создаются через коллекцию Рисунки и располагаются в отдельном слое поверх ячеек. Свойство АвтоВысотаСтроки рассчитывается генератором табличного документа исключительно на основе объема текста и размера шрифта. Графические объекты механизмом автовысоты полностью игнорируются, из-за чего изображение может перекрывать соседние строки или сжиматься в узкую полоску.

Способ 1. Программная постобработка табличного документа

Рассмотрим классический и наиболее гибкий вариант решения задачи — перехват компоновки в модуле объекта отчета и программное размещение графических объектов поверх ячеек с данными.

Для этого в модуле объекта отчета переопределим стандартную процедуру ПриКомпоновкеРезультата:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    // Формируем базовый табличный документ стандартными средствами
    СкомпоноватьРезультат(ДокументРезультат, ДанныеРасшифровки);
    
    // Запускаем алгоритм вывода изображений
    ВывестиКартинкиСКД(ДокументРезультат, ДанныеРасшифровки);
    
КонецПроцедуры

Теперь добавим саму процедуру обхода сформированного табличного документа. Алгоритм анализирует поля расшифровки каждой ячейки, извлекает двоичные данные или картинку из хранилища и размещает графический объект в границах ячейки:


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

Способ 2. Использование собственных макетов СКД

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

  1. Перейдем на вкладку Макеты в схеме компоновки данных.
  2. Добавим Макет поля для поля номенклатуры или группировки строк.
  3. В свойствах ячейки макета зададим жесткие размеры: фиксированную ширину колонки и высоту строки в пунктах (например, 50–80 пунктов). Это гарантирует, что ячейка не сожмется при выводе.
  4. В коде вывода связываем графический объект с ячейкой через Рисунок.Расположить(Область), используя режим масштабирования РазмерКартинки.Пропорционально или РазмерКартинки.Автомасштаб.

Способ 3. Поэлементный вывод через процессор компоновки

Для объемных прайс-листов двойной перебор матрицы ячеек может занимать заметное время. В таких случаях эффективнее использовать поэлементный вывод результата:

  1. Инициализируем ПроцессорКомпоновкиДанных и ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент.
  2. В цикле обходим результат методом ПроцессорКомпоновкиДанных.Следующий().
  3. При выводе строки номенклатуры методом ПроцессорВывода.ВывестиЭлемент() сразу получаем координаты добавленной области, выставляем ее высоту и добавляем рисунок.

Рекомендации по оптимизации прайс-листов

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

  1. Генерация миниатюр: Не выводите в отчет исходные файлы фотографий в высоком разрешении. Подготовьте уменьшенные копии (превью) размером 100–150 пикселей по ширине и сохраняйте их отдельно. Это ускорит формирование отчета в десятки раз.
  2. Очистка текста в ячейке с рисунком: Чтобы в ячейке не оставался текст <>, перед размещением рисунка очищайте значение области: Область.Текст = "";.
← На главную