Вывод условного оформления дерева значений или табличной части в эксель

09.02.24

Разработка - Работа с интерфейсом

Имеем табличную часть с условным оформлением или дерево значений. Каким способ сохранить в эксель без костылей?

Всем дня. Столкнулся в работе с просьбой клиента разрешить сохранять дерево значений в эксель.

Плевое дело, ведь так? Так и подумал:)   

 

Содержание статьи:

1. Введение

2. Типовые методы решения и их проблемы

3. Итоговый вариант решения

 

 Введение

 

Внешний отчет имеет условное оформление (цвета фонов, цвета текста и выделение в некоторых местах другим шрифтом). Необходимо сохранить текущую таблицу в эксель, при этом сохранив все форматирование.

 

 

 Типовые методы решения и их проблемы

 

Первым делом решил открыть доступ к типовой команде табличных частей "Вывести список". Сказано - сделано. 

 

 

Можно выбрать колонки, можно вывести выделенный фрагмент, спрятать подчиненные. Шикарно, пока не увидишь, что при таком выводе условное оформление пропадает :(

В грустных эмоциях начал копать интернет и ничего толкового не нашел. В статьях предлагали костыли по типу "сохранять в эксель" или "формировать сразу в эксель файл".

И если вариант "формировать сразу в эксель" точно не подходит, ибо человеку надо видеть данные (и из 20 раз сохранять всего один), то с "сохранять в эксель после" еще можно подумать. В реализации относительно ничего сложного, но нужно будет читать каждую ячейку и ее свойства и сохранять тоже самое в эксель, используя свойства экселя.

Минусы данного подхода:

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

- Сугубо мое мнение - костыль

- Если вдруг добавится новое условное оформление нужно дописывать выгрузку

- Надо сопоставить свойство 1С и экселя (натянуто, но все же) 

ps. Сопоставить свойства можно с помощью записи макросов. 

 

 Итоговый вариант решения

 

Немного погуляв вспомнил, что при сохранении отчета из СКД с установленным условным оформлением табличный документ сохраняет свое оформление. Проверил - действительно!

Итак, приступаем к реализации.

1. Формируем дерево значений в обработке

2. На основании дерева создаем схему СКД

3. Формируем отчет СКД

4. Выводим типовыми средствами

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

&НаКлиенте
Процедура ВывестиСписок(Команда)
	
	СформированныйТабличныйДокумент = СформироватьТабличныйДокументСервер();	
	
   	КоллекцияПечатныхФорм = УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм("СквознойОтчет");
	ПечатнаяФорма = УправлениеПечатьюКлиент.ОписаниеПечатнойФормы(КоллекцияПечатныхФорм, "СквознойОтчет");
	ПечатнаяФорма.ТабличныйДокумент = СформированныйТабличныйДокумент;
	КлючУникальности = Строка(Новый УникальныйИдентификатор);
	
	ПараметрыОткрытия = Новый Структура("ИмяМенеджераПечати,ИменаМакетов,ПараметрКоманды,ПараметрыПечати");
	ПараметрыОткрытия.ПараметрКоманды = Новый Массив;
	ПараметрыОткрытия.ПараметрыПечати = Новый Структура("Идентификатор", "");
	ПараметрыОткрытия.Вставить("КоллекцияПечатныхФорм", КоллекцияПечатныхФорм);
	
	ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия, ВладелецФормы, КлючУникальности);
	
КонецПроцедуры

 

&НаСервере
Функция СформироватьТабличныйДокументСервер()
	
	ТабДокумент = Новый ТабличныйДокумент;
	
	ДанныеДерева = РеквизитФормыВЗначение("ДеревоЗначенийДерево");
	
	НастройкиВидимостиКолонок = Новый ТаблицаЗначений;
	НастройкиВидимостиКолонок.Колонки.Добавить("Имя");
	НастройкиВидимостиКолонок.Колонки.Добавить("Заголовок");
	
	ПорядокКолонокВыводим = 	"Организация,ЗаказКлиента,СтоимостьЗаказаКлиента,СуммаРеализацийПоЗаказуКлиента,СебестоимостьЗаказаКлиента,СуммаВсехПоступленийПоЗаказуКлиента,
								|СуммаДолгаПоЗаказуКлиента,ЗаказПоставщику,СтоимостьЗаказаПоставщику,ОбщаяСтоимостьПоступившихТоваровПоЗаказуПоставщика,ОбщаяСуммаСписанияБСпоЗаказуПоставщика,
								|ЗадолжностьПоЗаказуПоставщику,СуммаБлижайшегоЭтапаПлатежаПоЗаказуПоставщика,ДатаБлижайшегоЭтапаПлатежаПоЗаказуПоставщика,КомментарийЗаказа";

	ПорядокКолонокМассивВыводим = СтрРазделить(ПорядокКолонокВыводим, ",", Ложь);
	
	Для каждого СтрокаМассива Из ПорядокКолонокМассивВыводим Цикл
		
		НоваяСтрока = НастройкиВидимостиКолонок.Добавить();
		НоваяСтрока.Имя 		= СтрокаМассива;
		
		//ЗАГОЛОВОК ПОЛУЧАЮ ИЗ ДЕРЕВА НА ФОРМЕ 
		ДеревоНаФормеКолонки 	= Элементы.ДеревоЗначенийДерево.ПодчиненныеЭлементы;
		ТекущаяКолонка 			= ДеревоНаФормеКолонки.Найти("ДеревоЗначенийДерево" + СтрокаМассива);
		НоваяСтрока.Заголовок 	= ?(ТекущаяКолонка = Неопределено, СтрокаМассива, ТекущаяКолонка.Заголовок);
	КонецЦикла;
	
	ИсточникиДанных = Новый Структура("ДанныеДерева", ДанныеДерева);
	СхемаКомпоновки = ПолучитьСхемуКомпоновкиПоДереву(ДанныеДерева, НастройкиВидимостиКолонок);
	
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, СхемаКомпоновки.НастройкиПоУмолчанию);
	
	ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;	
	ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ИсточникиДанных);
	
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ТабДокумент);
	ПроцессорВывода.Вывести(ПроцессорКомпоновки);
	
	Возврат ТабДокумент;
	
КонецФункции

Т.к. в дереве есть служебные колонки с данными, которые скрыты в исходном отчете, также скрываю в выводимом отчете.

Дополнительно устанавливаю сортировку в нужном порядке (если обращаюсь Элементы.ИмяДерева) колонки в порядке А-Я. Возможно, просто затупил (если есть другой вариант, напишите, буду благодарен).

И сама функция создания схемы компоновки:

&НаСервере
Функция ПолучитьСхемуКомпоновкиПоДереву(ДанныеДерева, ВыбранныеПоляДерева = Неопределено, ПолеИД = "КлючСвязи", ПолеРодительИД = "КлючСвязиРодителя")
	
	Если ВыбранныеПоляДерева = Неопределено Тогда
		ВыбранныеПоляДерева = Новый Массив;
	КонецЕсли;
	
	ЗаполнитьВыбранныеПоляДерева = НЕ ВыбранныеПоляДерева.Количество();
	
	СхемаКомпоновки = Новый СхемаКомпоновкиДанных;
	НастройкиКомпоновки = СхемаКомпоновки.НастройкиПоУмолчанию;
	
	ИсточникДанных = СхемаКомпоновки.ИсточникиДанных.Добавить();
	ИсточникДанных.Имя = "ИсточникДанных";
	ИсточникДанных.ТипИсточникаДанных = "Local";	 
	
	НаборДанных = СхемаКомпоновки.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
	НаборДанных.ИмяОбъекта = "ДанныеДерева";
	НаборДанных.Имя = "НаборДанных";
	НаборДанных.ИсточникДанных = "ИсточникДанных";	
	
	Для Каждого КолонкаДерева Из ДанныеДерева.Колонки Цикл
		
		ИмяПоля = КолонкаДерева.Имя;
		ЗаголовокПоля = КолонкаДерева.Заголовок;
		
		ПолеНабора = НаборДанных.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		ПолеНабора.Заголовок = ЗаголовокПоля;
		ПолеНабора.Поле = ИмяПоля;
		
		Если ЗаполнитьВыбранныеПоляДерева И НЕ (ИмяПоля = ПолеИД ИЛИ ИмяПоля = ПолеРодительИД) Тогда
			ВыбранныеПоляДерева.Добавить(Новый Структура("Имя, Заголовок", ИмяПоля, ЗаголовокПоля));
		КонецЕсли;
		
	КонецЦикла;
	
	СвязьНабора = СхемаКомпоновки.СвязиНаборовДанных.Добавить();
	СвязьНабора.НаборДанныхИсточник = "НаборДанных";
	СвязьНабора.НаборДанныхПриемник = "НаборДанных";
	СвязьНабора.ВыражениеИсточник = ПолеИД;
	СвязьНабора.ВыражениеПриемник = ПолеРодительИд;
	СвязьНабора.НачальноеВыражение = "0";
	
	ВыбранныеПоля = НастройкиКомпоновки.Выбор.Элементы;
	Для Каждого ПолеДерева Из ВыбранныеПоляДерева Цикл
		ПолеОтчет = ВыбранныеПоля.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
		ПолеОтчет.Поле = Новый ПолеКомпоновкиДанных(ПолеДерева.Имя);
		ПолеОтчет.Заголовок = ПолеДерева.Заголовок;
	КонецЦикла;
	
 	СтруктураГруппировки = НастройкиКомпоновки.Структура;	
	ЭлементГруппировки = СтруктураГруппировки.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
 	ЭлементГруппировки.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	
	УсловноеОформлениеСКД = НастройкиКомпоновки.УсловноеОформление.Элементы;
	
	Для каждого ЭлементУсловногоОформления Из ЭтаФорма.УсловноеОформление.Элементы Цикл
		
		НовоеУсловноеОформление = УсловноеОформлениеСКД.Добавить();
		
		//ОФОРМЛЕНИЕ
		Для каждого ЭлементОформления Из ЭлементУсловногоОформления.Оформление.Элементы Цикл
			
			Если ЭлементОформления.Использование Тогда
				
				НовоеУсловноеОформление.Оформление.УстановитьЗначениеПараметра(ЭлементОформления.Параметр, ЭлементОформления.Значение);	
				НовоеУсловноеОформление.Использование = Истина;	
				
			КонецЕсли;
		КонецЦикла;
		
		//ОТБОР УСЛОВИЕ 
		Для каждого ОтборОформления Из ЭлементУсловногоОформления.Отбор.Элементы Цикл
			
			ЭлементОтбора = НовоеУсловноеОформление.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
			ЗаполнитьЗначенияСвойств(ЭлементОтбора, ОтборОформления);
			
			ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(СтрЗаменить(СтрЗаменить(ОтборОформления.ЛевоеЗначение, "ДеревоЗначенийДерево.", ""), "ДеревоЗначенийДерево", ""));

		КонецЦикла;
		
		//ВЫБРАННЫЕ ПОЛЯ 
		Для каждого ОформляемоеПоле Из ЭлементУсловногоОформления.Поля.Элементы Цикл
			
			НовоеПолеОформления = НовоеУсловноеОформление.Поля.Элементы.Добавить();
			
			НовоеПолеОформления.Использование 	= Истина;
			НовоеПолеОформления.Поле 			= Новый ПолеКомпоновкиДанных(СтрЗаменить(ОформляемоеПоле.Поле, "ДеревоЗначенийДерево", ""));
			
		КонецЦикла;
		
	КонецЦикла;

	Возврат СхемаКомпоновки; 
	
КонецФункции

На основании дерева значений создаем схему компоновки, передаем дерево значений во внешний набор данных, устанавливаем условное оформление (не учитывал, что могут быть группы условий в отборе).

ВАЖНО. Для вывода именно дерева значений необходимо сделать два служебных реквизита (ключ связи и ключ связи родителя - тип число). В данные поля записываем значение ПолучитьИндентификатор() + 1). 

Данный реквизит используется для связи строк по уровням (через наборы данных) в компоновке данных.  

Вроде все интуитивно просто :) А главное - клиент доволен.

 

См. также

Работа с интерфейсом Рабочее место Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Платные (руб)

Богатый редактор картинок 1С предназначен для обработки изображений в режиме «Предприятие», с возможностью РИСОВАТЬ на них. Поддерживается работа как в обычных формах (толстый клиент) так и на управляемых формах (тонкий клиент). Обработка позволяет редактировать как картинки, хранимые в базе, так и графические файлы с диска на файловой системе. Помимо базовых функций (изменение размеров, преобразование формата, обрезание картинки, повороты и т.п.) – редактор имеет богатый набор инструментов для рисования. Доступна функция вставки изображения из буфера обмена. Объект может быть использован: на стороне клиента, на стороне сервера, из внешнего соединения. Обработка будет особенно полезна тем, кто вносит картинки в базу (изображения номенклатуры, фотографии физических лиц и т.п.). Функционал реализуется с использованием JavaScript и бесплатного ПО ImageMagick (без использования внешних компонент).

6000 руб.

16.01.2015    62985    44    59    

82

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 1С:ERP Управление предприятием 2 Платные (руб)

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

2400 руб.

29.06.2020    18854    26    6    

41

Работа с интерфейсом Программист Платформа 1С v8.3 Управляемые формы Конфигурации 1cv8 Россия Платные (руб)

Редактор графов в 1С - внешний отчет, который формирует графы на основе таблицы значений, используя рисунки табличного документа. Есть возможность добавления, редактирования объектов графа и выгрузки результата в таблицу значений.

1500 руб.

06.10.2020    10224    7    7    

10

Работа с интерфейсом Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Это инструкция по дизайну форм в среде 1С. Гайд охватывает рекомендации и стандарты для оптимизации пользовательского интерфейса. В гайде содержатся указания по использованию элементов интерфейса, включая как основные, так и продвинутые аспекты. Предоставляются также примеры и антипримеры для наглядного понимания принципов дизайна

20.08.2024    16796    mrXoxot    43    

121

Работа с интерфейсом Программист Платформа 1С v8.3 Бесплатно (free)

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

27.05.2024    7349    smielka    37    

100

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    14787    913    elcoan    47    

117

Инструментарий разработчика Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Подходит для создания web-страниц для замены управляемых форм 1С, красивых отчетов, интерфейса мобильного приложения на платформе 1С и для простых страниц веб-сайтов.

2 стартмани

10.04.2023    11913    162    acces969    31    

124
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. GonziK_KIV 05.06.24 09:56 Сейчас в теме
Служебные реквизиты то добавил, но не работает. Что я делаю не так?
2. user_snowbars 26 24.06.24 18:31 Сейчас в теме
Добрый, поздно заметил.
Необходимо сделать в исходном дереве значений (который сохраняется) два служебных реквизита и заполнить их при формировании дерева значений

ВложеннаяВетка.КлючСвязи = ВложеннаяВетка.ПолучитьИдентификатор() + 1; ВложеннаяВетка.КлючСвязиРодителя = ОсновнаяВетка.ПолучитьИдентификатор() + 1;
Оставьте свое сообщение