25 февр. 2013 г.

Вывод изображений в СКД


К сожалению, на данный момент СКД не позволяет через свои стандартные настройки выводить картинки, хранящиеся в реквизитах типа "ХранилищеЗначений" в виде изображений в результирующий табличный документ. Тем не менее, с помощью небольшой доработки, это можно реализовать.
Я добавлю в свою тестовую конфигурацию справочник "ИзображенияНоменклатуры", подчиненный справочнику "Номенклатура", с реквизитом "Изображение", тип "ХранилищеЗначений".

Набросаем простую форму элемента этого справочника с возможностью загрузки изображения:

&НаКлиенте
Процедура ЗагрузитьИзображение(Команда)
 
 Режим = РежимДиалогаВыбораФайла.Открытие;
 ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
 ДиалогОткрытияФайла.ПолноеИмяФайла = "";
 ДиалогОткрытияФайла.Фильтр = ".png|*.png|.jpg|*.jpg";
 ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
 ДиалогОткрытияФайла.Заголовок = "Выберите файл";
 Если ДиалогОткрытияФайла.Выбрать() Тогда
  мФайл = ДиалогОткрытияФайла.ПолноеИмяФайла;
  ПоместитьНаСервер(Новый ДвоичныеДанные(мФайл));
 Иначе
  Текст = "Файл не выбран!";
  Предупреждение(Текст);
 КонецЕсли;
 
КонецПроцедуры

&НаКлиенте
Процедура УдалитьИзображение(Команда)
 
 ПоместитьНаСервер();
 
КонецПроцедуры

&НаСервере
Процедура ОбновитьКартинкуФорма(ХранилищеКартинки)

 Изображение = ПоместитьВоВременноеХранилище(ХранилищеКартинки.Получить(), УникальныйИдентификатор);
 
КонецПроцедуры // ОбновитьКартинку()

&НаСервере
Процедура ПоместитьНаСервер(Данные = Неопределено)

 ХранилищеКартинки = ?(Данные = Неопределено, Неопределено, Новый ХранилищеЗначения(Данные));
 ОбновитьКартинкуФорма(ХранилищеКартинки);

КонецПроцедуры // ПоместитьНаСервер()

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
 
 ОбновитьКартинкуФорма(ТекущийОбъект.Изображение);
 
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
 
 ТекущийОбъект.Изображение = ?(ПустаяСтрока(Изображение), Неопределено, Новый ХранилищеЗначения(ПолучитьИзВременногоХранилища(Изображение)));
 
КонецПроцедуры 

Так же, добавим форму элемента справочника "Номенклатура" с возможностью просмотра подчиненных элементов справочника "ИзображенияНоменклатуры":

&НаСервере
Процедура ПоместитьИзображениеФорма(СсылкаФайл)

 ИзображениеХранилище = ПоместитьВоВременноеХранилище(СсылкаФайл.Изображение.Получить(), УникальныйИдентификатор);

КонецПроцедуры // ПоместитьИзображениеФорма()

&НаСервере
Процедура ВладелецИзображенийУстановить()

 ИзображенияСписок.Отбор.Элементы[0].ПравоеЗначение = Объект.Ссылка;

КонецПроцедуры // ВладелецИзображенийУстановить()

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
 
 ВладелецИзображенийУстановить();
 
КонецПроцедуры

&НаКлиенте
Процедура ИзображенияПриАктивизацииСтроки(Элемент)
 
 Если Элемент.ТекущиеДанные = Неопределено Тогда
  Возврат;
 КонецЕсли;
 
 ПоместитьИзображениеФорма(Элемент.ТекущиеДанные.Ссылка);
 
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
 
 ВладелецИзображенийУстановить();
 
КонецПроцедуры 

Теперь создадим отчет "ИзображенияНоменклатуры", в схеме компоновки данных напишем простой запрос:

ВЫБРАТЬ
 ИзображенияНоменклатуры.Ссылка,
 ИзображенияНоменклатуры.Владелец,
 ИзображенияНоменклатуры.Изображение
ИЗ
 Справочник.ИзображенияНоменклатуры КАК ИзображенияНоменклатуры 


В модуле отчета опишем предопределенную процедуру "ПриКомпоновкеРезультата".

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

Все, формируем отчет, получаем результат:

Рамки изображений при желании можно переопределить.

Тестовая конфигурация

UPD: в 8.3.14 для СКД добавили возможность вывода изображения из реквизитов с типом ХранилищеЗначений.

3 комментария: