Итоговая задача: построить прайс-лист с изображениями номенклатур для УТ (т.е. в прайсе предполагается выводить изображения, которые показываются в карточке номенклатуры)
После недолгих поисков выяснилось, что информация которую можно сконвертировать в изображение находится в справочнике НоменклатураПрисоединенныеФайлы, на элементы которого может ссылаться реквизит номенклатуры ФайлКартинки. Сама бинарная информация, которую можно сконвертировать в картинку, может находится либо в регистре сведений ПрисоединенныеФайлы, либо на внешнем по отношению к базе носителе (папка на диске сервера).
Будем дорабатывать стандартный отчет УТ 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 (добавление логотипа и свободных текстовых полей)