Картинка в таблице СКД (управляемое приложение) на примере УТ11, простое решение "в лоб" или легкая модификация стандартного отчета Прайс-Лист

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

Итоговая задача: построить прайс-лист с изображениями номенклатур для УТ (т.е. в прайсе предполагается выводить изображения, которые показываются в карточке номенклатуры)

После недолгих поисков выяснилось, что информация которую можно сконвертировать в изображение находится в справочнике НоменклатураПрисоединенныеФайлы, на элементы которого может ссылаться реквизит номенклатуры ФайлКартинки. Сама бинарная информация, которую можно сконвертировать в картинку, может находится либо в регистре сведений ПрисоединенныеФайлы, либо на внешнем по отношению к базе носителе (папка на диске сервера).

Будем дорабатывать стандартный отчет УТ 11.0.9.15 Прайс-лист, для удобства сохраним его в качестве внешнего.  

Порядок действий для вывода картинок в печатной форме СКД:

1. К запросу СКД добавляем поле со ссылкой на справочник НоменклатураПрисоединенныеФайлы, соответствущей элементу номенклатуры.

2. При выводе соответствующего элемента макета читаем информацию о картинке и выводим её в соответствующей ячейке:

   2.1. Получаем ячейку табличного документа, в которой предполагается вывести кртинку.

   2.2. Преобразуем бинарную информацию по ссылке, полученной в п.1. в картинку и выводим её в ячейке, полученной в п.2.1.

   2.3. Производим дополнительное оформление ячейки и картинки (меняем размер, цвет линии и тд.)

 

Итак по вышеописанному плану:

Добавим в запрос СКД новое поле Изображение:

ЦеныНоменклатурыСрезПоследних.Номенклатура.ФайлКартинки КАК Изображение

Поле в Запрос СКД

Видоизменим варианты настроек (добавим группировку по Изображению):

Изменение настроек СКД 

Добавим новый параметр ШиринаКолонкиИзображения, через который будем регулировать размер изображения:

Параметры СКД

Нам потребуется вмешиваться в процесс формирования отчета, поэтому добавим в конец процедуры модуля объекта ПриКомпоновкеРезультата, следующий код:

СтандартнаяОбработка = Ложь;
ИмяКолонкиИзображения = «Изображение»;
ДокументРезультат.Очистить();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
//Получаем параметр отчета ШиринаКолонкиИзображения, и устанавливаем ширину колонки, в которой предполагаем выводить изображение
ШиринаКолонкиИзображения = ВернутьЗначениеПараметраНастройкиСКД(КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы, «ШиринаКолонкиИзображения», 20); //В средних символах

ПолеИзображения = СхемаКомпоновкиДанных.НаборыДанных.ПрайсЛист.Поля.Найти(ИмяКолонкиИзображения);
Если Не ПолеИзображения = Неопределено Тогда
     ОформлениеМинимальнойШириныКолонки = СхемаКомпоновкиДанных.НаборыДанных.ПрайсЛист.Поля.Найти(ИмяКолонкиИзображения).Оформление.Элементы.Найти(«МинимальнаяШирина»);
     ОформлениеМинимальнойШириныКолонки.Использование = Истина;
     ОформлениеМинимальнойШириныКолонки.Значение = ШиринаКолонкиИзображения;
КонецЕсли;
 

//Выводим макет, здесь все почти стандартно.

Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.НачатьВывод();
Пока Истина Цикл
     ЭлементРезультата = ПроцессорКомпоновки.Следующий();
     Если ЭлементРезультата = Неопределено Тогда Прервать;КонецЕсли;
     ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
     Если ЭлементРезультата.ЗначенияПараметров.Количество() = 0 Тогда Продолжить; КонецЕсли;
 
     Для Каждого ЭлементПараметра Из ЭлементРезультата.ЗначенияПараметров Цикл
         Если ТипЗнч(ЭлементПараметра.Значение) = Тип(«ИдентификаторРасшифровкиКомпоновкиДанных«) Тогда
             Поля = ДанныеРасшифровки.Элементы[ЭлементПараметра.Значение].ПолучитьПоля();
             Для Каждого Поле Из Поля Цикл
                 Если ТипЗнч(Поле.Значение) = Тип(«СправочникСсылка.НоменклатураПрисоединенныеФайлы») Тогда
                     Если Поле.Значение.Пустая() Тогда Продолжить; КонецЕсли;
                     //Поиск номера колонки, с нужным именем ИмяКолонкиИзображения, для таки вывода изображения
                     Для НомерКолонки = 1 По ДокументРезультат.ШиринаТаблицы Цикл
                         Расшифровка = ДокументРезультат.Область(ДокументРезультат.ВысотаТаблицы, НомерКолонки, ДокументРезультат.ВысотаТаблицы, НомерКолонки).Расшифровка;
                         Если Расшифровка = Неопределено Тогда Продолжить; КонецЕсли;
                         Поля = ДанныеРасшифровки.Элементы.Получить(Расшифровка).ПолучитьПоля();
                         Если Поля.Найти(ИмяКолонкиИзображения) = Неопределено Тогда Продолжить; КонецЕсли;
                         ОбластьИзображения = ДокументРезультат.Область(ДокументРезультат.ВысотаТаблицы, НомерКолонки);
                         ВывестиИзображениеЭлементаНоменклатуры(ДокументРезультат, Поле.Значение, ОбластьИзображения, ШиринаКолонкиИзображения);
                     КонецЦикла;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
КонецЦикла;
ПроцессорВывода.ЗакончитьВывод();

Для удобства процедура вывода изображения выделена в отдельную, эта процедура просто получает данные для вывода рисунка, выводит его (используя функцию), настраивает его оформление.

Процедура ВывестиИзображениеЭлементаНоменклатуры(ТД, ЭлементСправочника, Область, ШиринаКолонкиИзображения)
     Если ЭлементСправочника.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе Тогда
         СтуктураРег = РегистрыСведений.ПрисоединенныеФайлы.Получить(Новый Структура(«ПрисоединенныйФайл», ЭлементСправочника));
         ДанныеКартинки = СтуктураРег.ХранимыйФайл.Получить();
     Иначе
         ДанныеКартинки = ?(ЗначениеЗаполнено(ЭлементСправочника.Том.ПолныйПутьWindows), ЭлементСправочника.Том.ПолныйПутьWindows, ЭлементСправочника.Том.ПолныйПутьLinux)
         + ЭлементСправочника.ПутьКФайлу;
     КонецЕсли;
     Рисунок = ВывестиИзображениеВОбластиТД(ДанныеКартинки, ТД, Область);
     Область.АвтоВысотаСтроки = Ложь;
     Область.ВысотаСтроки = ШиринаКолонкиИзображения * 1.31 / 0.3759;// Среднее значение пункта 1 пункт = 0.3759 мм (по Wiki)
     Область.Расшифровка = ЭлементСправочника;
     Рисунок.ЦветЛинии = Область.ЦветРамки;
КонецПроцедуры 

Из предыдущей процедуры вызывается функция, которая непосредственно выводит изображение в заданной области табличного документа 

Функция ВывестиИзображениеВОбластиТД(ДанныеКартинки, ТД, Область)
     Изображение = ТД.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
     Изображение.РазмерКартинки = РазмерКартинки.АвтоРазмер;
     Индекс = ТД.Рисунки.Индекс(Изображение);
     ТД.Рисунки[Индекс].Картинка = Новый Картинка(ДанныеКартинки, Истина);
     ТД.Рисунки[Индекс].Расположить(Область);
     Возврат ТД.Рисунки[Индекс];
КонецФункции

Кроме того при компоновке используется процедура извлечения параметра из СКД:

Функция ВернутьЗначениеПараметраНастройкиСКД(КоллекцияЭлементовНастройки, ИмяНастройки, ЗначениеПоУмолчанию = Неопределено)

     Настройка = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(ИмяНастройки);
     Если Настройка = Неопределено Тогда Возврат ЗначениеПоУмолчанию; КонецЕсли;
     НастрокаПоИД = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Настройка.ИдентификаторПользовательскойНастройки);
     Если Не ЗначениеЗаполнено(НастрокаПоИД.Значение) Тогда
         Если Не ЗначениеПоУмолчанию = Неопределено Тогда
             НастрокаПоИД.Значение = ЗначениеПоУмолчанию;
         КонецЕсли;
     КонецЕсли;
     Возврат ?(НастрокаПоИД.Использование, НастрокаПоИД.Значение, ЗначениеПоУмолчанию);
КонецФункции

Готовый отчет доступен к скачиванию. 

Сформированный отчет выглядит приблизительно так:

ПрайсЛист

ЗЫ: Существует некоторое незначительное развитие данного отчета: Прайс лист с картинками для УТ11 (добавление логотипа и свободных текстовых полей)

 

30 Comments

  1. @lexandr

    Пришлось немного эту функцию переделать, а то ошибки иногда выдает, а так очень помогло, вывел в прайс на ут 11.1.1.13 картинку.

    Функция ВернутьЗначениеПараметраНастройкиСКД(КоллекцияЭлементовНастройки, ИмяНастройки, ЗначениеПоУмолчанию = Неопределено)

    Настройка = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(ИмяНастройки);

    Если Настройка = Неопределено Тогда Возврат ЗначениеПоУмолчанию; КонецЕсли;

    НастрокаПоИД = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Настройка.ИдентификаторПользовательскойНастройки);

    Если НастрокаПоИД = Неопределено Тогда

    Возврат ЗначениеПоУмолчанию;

    Конецесли;

    Если Не ЗначениеЗаполнено(НастрокаПоИД.Значение) Тогда

    Если Не ЗначениеПоУмолчанию = Неопределено Тогда

    НастрокаПоИД.Значение = ЗначениеПоУмолчанию;

    КонецЕсли;

    КонецЕсли;

    Возврат ?(НастрокаПоИД.Использование, НастрокаПоИД.Значение, ЗначениеПоУмолчанию);

    КонецФункции

    Reply
  2. mxm2

    (1) @lexandr, Странно, у меня вообще ошибок не возникало никогда, причем во всех трех версиях отчета, даже здесь http://infostart.ru/public/178422/, возможно проблема в том, что какое-либо поле исключено из пользовательских настроек.

    Reply
  3. tolyan_ekb

    Отличное решение без доп. макета. На основе публикации сделал похожее для картинок из внешних файлов. Огромное спасибо.

    Reply
  4. tolyan_ekb

    Почему-то у меня не получается изменить высоту строки с изображением. Пробовал и явно, и с помощью изменения в коде

    Область.ВысотаСтроки = ШиринаКолонкиИзображения * 134.31 / 0.3759;
    Reply
  5. mxm2

    (4) tolyan_ekb,

    вот здесь: http://infostart.ru/public/178422/

    Upd 07.04.2013: Добавлена возможность подгонки строки прайса по высоте отображаемой картинки (устанавливается в параметрах), использует стандартную библиотеку wiaaut.dll, доступную, например в windows 7, и не будет работать, если сервер вертится на linux системе (файл ПрайсЛистХX)

    родной адекватно работающей функции — не нашел.

    Reply
  6. mxm2

    (4) tolyan_ekb, смотрите пятый комментарий.

    Reply
  7. mxm2

    (4) tolyan_ekb, еще возможно в Вашем макете стоИт ограничение минимальной высоты строки или автовысота.

    Reply
  8. tolyan_ekb

    (6) спасибо. Но я установил высоту напрямую в условном оформлении, после чего она изменилась. Возможно, программно чего-то не доуказал.

    Reply
  9. varovinm

    (6) Спасибо!

    Не срабатывает инициализация ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки)

    Дело в том, что у меня в СКД есть параметры в которых задано выражение, например, Справочники.Валюты.НайтиПоКоду(«156»). Может быть подскажете как получить значение у этих параметров????

    Reply
  10. mxm2

    (9) varovinm, попробуйте

    ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки, Истина);

    вообще лучше либо задавать валюту в параметрах (неявно), либо получать её в запросе, например из констант.

    Reply
  11. killexx

    Реально ли сделать такой прайс для 1С 8.1, «Управление торговлей для Украины», редакция 2.3 ?

    Reply
  12. mxm2

    (11) killexx, Реально всё. Если Ваша конфигурация на управляемых формах то за образец можете использовать текущую разработку. Если же на обычных формах — то, например вот эту http://infostart.ru/public/151012/.

    Reply
  13. MarryJane

    Коллеги, а скажите может есть мысли при выведении отчета с картинками уж больно долго выводится. Может у кого нить есть мысли куда копать. (Я попробывал выводить в УПР интерфейсе и в простом, так вот в простом интерфейсе выводится быстрее на порядок). может начать смотреть размеры картинок.

    Reply
  14. ReSY

    Понравилась реализация, автору плюс! На примере публикации создал отчет. Большое спасибо.

    Reply
  15. Graf71

    Спасибо автору за публикацию. Очень помогло в собственной разработке.

    Reply
  16. sergiowood

    Попробовал сделать по данной схеме отчёт, выдаёт ошибку

    «Поле изображение не может быть использовано в группировке номенклатура, упаковка, характеристика»

    Подскажите пожалуйста в чём может быть проблемка?

    Делал на УТ 11.1.4.14 , на основе типового отчёта «Прайс»

    Если «изображение» как ресурс, то ошибку не выдаёт но и поле «изображение» не выводит вообще

    Reply
  17. Lev292

    В последних версиях УТ11 этот отчет уже не работает!!!

    Ребята из 1С сами задействовали Процедуру ПриКомпоновкеРезультата и если там поставить СтандартнаяОбработка = Ложь. то отчет перестает работать

    Reply
  18. ssn5810

    Да отчет не работает

    Метод объекта не обнаружен ПолучитьПараметр

    Reply
  19. Margo_X

    В версии УТ 11 _11.3.2.207 отчет не работает

    Метод объекта не обнаружен ПолучитьПараметр

    Reply
  20. Orchild

    Функция ПоучитьПараметр находится в общем модуле КомпоновкаДанныхКлиентСервер.

    Reply
  21. waol

    прекрасно — работает )

    спасибо!

    Reply
  22. bad_wag

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

    Reply
  23. RocKeR_13

    Хм, делал по аналогии и такая получается штука: в файловой базе 550 строк с картинками выводит за 3-4 минуты, перевожу базу на SQL — спустя полчасатак никаких результатов и не видно… Пока отладку не включал, вставил записи в ЖР: в процедуре «ПриКомпоновкеРезультата» строку «ПроцессорВывода.ЗакончитьВывод();» успешно проходит… Картинки пробовал и в базе размещать, и в каталогах

    UPD: спустя 40 минут все-таки вывел

    Reply
  24. Els11

    Для текущих версий ЕРП и УТ11 в процедуре ВывестиИзображениеНоменклатуры вместо обращения к РС Присоединенные файлы необходимо прописать следующее (Сначала закомментированный код):

    //Если ЭлементСправочника.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе Тогда

    // СтуктураРег = РегистрыСведений.ПрисоединенныеФайлы.Получить(Новый Структура(«ПрисоединенныйФайл», ЭлементСправочника));

    // ДанныеКартинки = СтуктураРег.ХранимыйФайл.Получить();

    //Иначе

    // ДанныеКартинки = ?(ЗначениеЗаполнено(ЭлементСправочника.Том.ПолныйПутьWindows), ЭлементСправочника.Том.ПолныйПутьWindows, ЭлементСправочника.Том.ПолныйПутьLinux)

    // + ЭлементСправочника.ПутьКФайлу;

    //КонецЕсли;

    Вместо закомментированного, следующее

    ДанныеКартинки = ПолучитьИзВременногоХранилища(РаботаСФайлами.ДанныеФайла(ЭлементСправочника).СсылкаНаДвоичныеДанныеФайла);

    P.s. Если кто кинет ссылку на инструкцию как в комментариях красиво код оформлять, буду благодарен. (Чтобы красненькое красненьким было, синенькое сининьким).

    Reply
  25. RocKeR_13

    (25)

    Вот так))
    Reply
  26. Els11

    (24) Самое узкое место в выводе отчета с картинками это передача его обратно с сервера на клиента, При передаче платформа сериализует табличный документ и передает таким образом в разы больше информации , чем нужно. А на клиенте съедаются в это время Гигабайты.дискового постранства. У меня при выводе отчета продаж за месяц отчет вообще падал с ошибкой формата потока. Нашел следующий выход:

    Если отчет не в типовом решении, то в обработку на сервер не надо передавать табличный документ.

    При окончании обработки на сервере созданный табличный документ помещается во временной хранилище. Адрес временного хранилища можно задать или в реквизите формы или передать с клиента. А на клиенте уже из временного хранилища создается табличный документ. Что-то типа следующего:

    &НаКлиенте
    Процедура Сформировать(Команда)
    Адрес = «»;
    СформироватьОтчетНаСервере(Адрес, Период);
    
    ТабДок = ПолучитьИзВременногоХранилища(Адрес);
    ТабДок.Показать();
    КонецПроцедуры
    
    &НаСервере
    Процедура СформироватьОтчетНаСервере(Адрес, Период);
    ТабДок = Новый ТабличныйДокумент;
    ОбъектОтчет = РеквизитФормыВЗначение(«Отчет»);
    ОбъектОтчет.СформироватьОтчет(ТабДок, Период);
    
    Адрес = ПоместитьВоВременноеХранилище(ТабДок,ЭтаФорма.УникальныйИдентификатор);
    КонецПроцедуры
    

    Показать

    Если про типовое решение, то в отчете по себестоимости и выручке продаж сделал так:

    1) скопировал и создал из типового отчета свой отчет ОтчетПродажиСИзображением

    2) Скопировал общую форму отчета и поместил ее в новый отчет

    3) Выбрал форму отчета — новую форму отчета

    4) в новой форме отчета добавил реквизит АдресН Тип строка неограниченной длины

    5) в форме отчета в процедуре ФоновоеЗаданиеЗагрузитьРезультат закомментировал стандартную передачу результата табличного документа и добавил строку по помещению табличного документа во временное хранилище

     //ОтчетТабличныйДокумент = РезультатФормирования.ТабличныйДокумент;
    АдресН = ПоместитьВоВременноеХранилище(РезультатФормирования.ТабличныйДокумент,ЭтаФорма.УникальныйИдентификатор);
    

    6) в процедуре ПослеФормирванияНаКлиенте добавил строку в начале процедуры

     ОтчетТабличныйДокумент = ПолучитьИзВременногоХранилища(АдресН);
    

    Отчет из полутора тысяч строк вводится за 3 минуты. Отчет за месяц, который ранее не выводился вообще, выводится менее 15 минут. Работает в фоне, при условии, что отчет в конфигурации, а не внешний. Все сделанные доработки тоже касаются варианта, что отчет встроенный. Если внешний, то возможно алгоритмы идут по другим веткам и потребуются доработки.

    Reply
  27. user771753

    Айайай братюня затащил вообще молодец, все работает, даже без допиливания))) красавчик вообще, лукаснул тебе)))

    Reply
  28. Serj1C

    В 8.3.14 вывод картинок в СКД появится из коробки!

    Для системы компоновки данных реализована возможность отображения картинок, расположенных в информационной базе. В отчете могут отображаться картинки, заданные в качестве навигационной ссылки на картинку и собственно картинкой, размещенной в реквизите типа ХранилищеЗначения.

    Для объектов ОформлениеКомпоновкиДанных и ОформлениеЯчейкиТаблицыОбластиКомпоновкиДанных реализованы свойства ВыводитьКартинку, РазмерКартинки, ПоложениеТекстаОтносительноКартинки, ГоризонтальноеПоложениеКартинки, ВертикальноеПоложениеКартиинки.

    В режиме совместимости с версией 8.3.13 поведение по умолчанию не изменилось.

    Источник: https://dl04.1c.ru/content/Platform/8_3_14_1565/1cv8upd_8_3_14_1565.htm#a06301e2-a9ff-11e8-a3f7-0050569f678a

    Reply
  29. Nigelist

    (1) Спасибо, помогло

    Reply
  30. notka

    Добрый день, может кто подскажет ((( Бьюсь с выводом картинок и вроде все норм, кроме того что картинка пустая. Картинки хранятся и в томах и в информационной базе. База УТ 11.3, платформа 8.3.10. Неделю уже всеми способами ковыряюсь, все равно пустые(

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *