Рисунки табличного документа: вставить, куда надо

Рисунки табличного документа: вставить, куда надо

Тривиальная задача вывода в табличный документ рисунков, того или иного вида и формата, начиная с 7.7 и до сих пор не имеет красивого универсального решения. Да, существует несколько общеизвестных приёмов, но большинство их базируется либо на собственном, заранее подготовленном макете, и значит, неуниверсально, либо на обработке уже сформированного таб.документа путём его поячейного рассмотрения, что долго и не очень надёжно. Кроме того, сложностью является и размещение рисунка, т.к. однозначной привязки координат рисунка к областям таб.документа не существует, равно как и корреляции размеров рисунка, задаваемых в миллиметрах, с шириной области, задаваемой в условных символах, и особенно с высотой (задаваемой в пунктах). Учтём также, что, несмотря на заверения СП, при свойстве "АвтоВысота" = Истина высота строки всегда нулевая, и узнать её, реальную, невозможно. В этих условиях размещение рисунка превращается в стрельбу по тарелочкам ночью вслепую.

Идея, использованная в публикации, баянна и банальна - сериализовать табличный документ в строку, сделать те действия, которые минимально необходимы и/или единственно возможны только с xml-текстом, и сериализовать обратно, после чего уже с помощью языка 1С доустановить нужное. Как показали эксперименты, привязка рисунка к области ячейки всё же есть, но только в xml, поэтому она там и указывается. Там же создаётся сам рисунок, и выставляются основные свойства по умолчанию, которые потом уже можно переустановить, а также имя и тип, которые поменять позже нельзя.

Разумеется, можно добиться нужного формата прямо в тексте xml, но это более громоздко, менее надёжно и вообще для любителей - например, xml чувствителен к порядку блоков <format>, а рисунки ссылаются на них по их индексам как по порядку расположения в тексте, чуть перепутаете - съедет всё форматирование. В этом смысле приятно, что <namedItem> имеет чёткую привязку по индексу. Также, например, можно устанавливать картинку для "картинки", указав её Base64 в элементе <picture>, но там тоже важен порядок блоков, да и громоздко это.

Реализация ближе к парсингу готового документа, но всё-таки не по ячейкам в цикле, а с помощью XPath. Не стоит пугаться, в большинстве случаев XPath- запросы окажутся просты и понятны. Например, в приведённом примере я ищу вхождения ссылок на справочник "Номенклатура" в расшифровках ячеек (тег "d", атрибут "xsi:type"). Это позволяет быстро найти именно нужные узлы. Исходя из узлов, определяются № строки и № колонки, где таковая ячейка нашлась. А это значит, что мы не зависим от формата документа, и табличный документ может иметь любой вид, быть любым выходным результатом СКД - и неважно, какие там уровни, да группировки, да колонки, объёдинённые и не очень. Найти содержание в xml можно однозначно, если правильно составить запрос XPath.

Конечно, дальше могут начаться некоторые сложности. Например, высоту строки всё равно придётся либо подгонять, либо делать с запасом. Объединённые ячейки могут привнести свою специфику позиционирования. И, увы, то, что мне победить не удалось - размеры рисунка придётся всё так же подгонять методом тыка, зависимостей я не делал. Но хоть размещён рисунок будет правильно, уже что-то)

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

Зачем публикация - поделиться способом; а ещё продемонстрировать, что xml-ипостась привычных нам общих объектов 1С в некоторых случаях даёт интересные возможности, но не является панацеей, и что совместное применение разных приёмов очень даже нормальный способ решения задачи.

Сразу извиняюсь, что выкладываю без "разукрашки" кода, но она съедает теги.

Тестировалось под толстым клиентом, но, подозреваю, всё это спокойно компилится как на клиенте, так и на сервере во всех вариациях. Если только в параметрах попадётся нечто, непригодное к передаче на сервер, но это уж на ваше усмотрение.

Я с помощью этой штуковины вывел текстовые подписи о скидках и картинки из карточек номенклатуры в УТ 10.3, пример вызова таков:

// настраиваем свойства рисунка рСвойстваРисунка1 =Новый Структура ; рСвойстваРисунка1 . Вставить ( "ТипРисунка" , ТипРисункаТабличногоДокумента . Текст ); рСвойстваРисунка1 . Вставить ( "Текст" , "СКИДКИ. " ); рСвойстваРисунка1 . Вставить ( "АвтоРазмер" ,Истина); рСвойстваРисунка1 . Вставить ( "ВертикальноеПоложение" , ВертикальноеПоложение . Низ ); рСвойстваРисунка1 . Вставить ( "ЛевоВЯчейке" , 140 ); рСвойстваРисунка1 . Вставить ( "ПравоВЯчейке" , 180 ); рСвойстваРисунка1 . Вставить ( "ВерхВЯчейке" , 60 ); рСвойстваРисунка1 . Вставить ( "НизВЯчейке" , 230 ); рСвойстваРисунка1 . Вставить ( "ГраницаСверху" ,Ложь); рСвойстваРисунка1 . Вставить ( "ГраницаСлева" ,Ложь); рСвойстваРисунка1 . Вставить ( "ГраницаСнизу" ,Ложь); рСвойстваРисунка1 . Вставить ( "ГраницаСправа" ,Ложь); рСвойстваРисунка1 . Вставить ( "ЦветТекста" , WebЦвета . Коричневый ); // соотТоваров1 =Новый Соответствие ; соотТоваров2 =Новый Соответствие ; Для каждого стротрез Из тРезультатНекоегоЗапроса Цикл рТовар = стротрез . Товар ; гуид = Строка ( рТовар . УникальныйИдентификатор ()); соотТоваров1 . Вставить ( гуид , рСвойстваРисунка1 ); Если не рТовар . ОсновноеИзображение . Пустая () Тогда рСвойстваРисунка2 =Новый Структура ; рСвойстваРисунка2 . Вставить ( "ТипРисунка" , ТипРисункаТабличногоДокумента . Картинка ); рСвойстваРисунка2 . Вставить ( "АвтоРазмер" ,Истина); рСвойстваРисунка2 . Вставить ( "ЛевоВЯчейке" , 1 ); рСвойстваРисунка2 . Вставить ( "ПравоВЯчейке" , 280 ); рСвойстваРисунка2 . Вставить ( "ВерхВЯчейке" , 1 ); рСвойстваРисунка2 . Вставить ( "НизВЯчейке" , 230 ); рСвойстваРисунка2 . Вставить ( "Ширина" , 30 ); рСвойстваРисунка2 . Вставить ( "Высота" , 30 ); рСвойстваРисунка2 . Вставить ( "Картинка" , рТовар . ОсновноеИзображение . Хранилище . Получить ()); соотТоваров2 . Вставить ( гуид , рСвойстваРисунка2 ); КонецЕсли; КонецЦикла; // // готовим прочие параметры рСвойстваОбласти =Новый Структура ; рСвойстваОбласти . Вставить ( "ВертикальноеПоложение" , ВертикальноеПоложение . Верх ); // стру1 =Новый Структура ; стру1 . Вставить ( "ВыражениеXPath" , "//d[@xsi:type='d6p1:CatalogRef.Номенклатура']" ); // ищем по участию ссылок в расшифровках стру1 . Вставить ( "ВысотаСтроки" , 90 ); стру1 . Вставить ( "СвойстваОбласти" , рСвойстваОбласти ); стру1 . Вставить ( "КлючПолученияКлючаДанных" , "ТекстовоеСодержимое" ); стру1 . Вставить ( "Данные" , соотТоваров1 ); // стру2 =Новый Структура ; стру2 . Вставить ( "ВыражениеXPath" , "//d[@xsi:type='d6p1:CatalogRef.Номенклатура']" ); // ищем по участию ссылок в расшифровках стру2 . Вставить ( "ВысотаСтроки" , 87 ); стру2 . Вставить ( "НомерКолонки" , 3 ); стру2 . Вставить ( "КлючПолученияКлючаДанных" , "ТекстовоеСодержимое" ); стру2 . Вставить ( "Данные" , соотТоваров2 ); // мстру =Новый Массив ; мстру . Добавить ( стру1 ); мстру . Добавить ( стру2 ); пар =Новый Структура ( "ОбрабатываемыеОбласти" , мстру ); // ВставитьРисункиВТабличныйДокумент ( ТабДокумент , пар );

Кому пригодится - велкам. Кто доведёт до ума привязку размеров - тому респект.

📎📎📎📎📎📎📎📎📎📎