Автоматическая ширина колонок в СКД

Программирование - Практика программирования

исправила ошибку на скриншоте

46
Случай, когда настроек по максимальной и минимальной ширине колонок в условном оформлении недостаточно.

Скорее всего, у каждого возникала необходимость в СКД выводить колонки с автоматическим подбором ширины, везде пишут что есть такая процедура "РасчетШириныКолонок", которая все рассчитывает, да есть, но вот было непонятно, как сделать, чтобы она отрабатывала в СКД... Наконец-таки получилось)) я уже здесь задавала данный вопрос, затем когда нашла решение, решила опубликовать такую "подсказку")

Я делала на примере внешнего отчета и в модуле объекта добавила всего лишь две процедуры:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	
СтандартнаяОбработка = Ложь;

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


ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);

ПроцессорВывода.НачатьВывод();
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
РасчетШириныКолонок(ДокументРезультат);//РАСЧЕТ ШИРИНЫ КОЛОНОК
ПроцессорВывода.ЗакончитьВывод();
   
КонецПроцедуры

 

А вот процедура для расчета ширины колонок, которая перебирает в цикле каждой столбец построчно и выявляет максимальное количество символов в строке каждой колонки которому и будет равна ширина колонки:


Процедура РасчетШириныКолонок(ТабличныйДокумент)
	
	Перем МаксимальноеКоличествоСтрок, МаксимальнаяШиринаКолонки;
	Перем КонечнаяСтрока, НачальнаяСтрока, ТекущаяКолонка, ТекущаяСтрока, НачалоДанных;
	Перем ОбластьШапки, ОбластьПодвала;
	Перем ШиринаКолонки, ТекстЯчейки, НомерСтрокиТекста;
	Перем КоличествоУровнейГруппировокСтрок, Отступ;
	Перем ШириныКолонок;
	
	// Максимальное количество строк отчета, которые будут использованы для расчета ширин колонок
	МаксимальноеКоличествоСтрок = ТабличныйДокумент.ВысотаТаблицы;
	// Ограничение максимальной ширины колонки
	МаксимальнаяШиринаКолонки = 20;
	// Массив, в который будут помещаться ширины колонок
	ШириныКолонок = Новый Массив;
	// Получим количество уровней группировок в отчете для учета автоматического отступа
	КоличествоУровнейГруппировокСтрок = ТабличныйДокумент.КоличествоУровнейГруппировокСтрок();
	
	// Инициализируем начальные строки
	НачальнаяСтрока = 1;//с 1 строки табличного документа начинается вывод данных в таблицу, у вас может таблица начинаться с другой строки, например если выводятся еще отборы и заголовок в отчете
	НачалоДанных = 1;
	КонечнаяСтрока = НачальнаяСтрока + МаксимальноеКоличествоСтрок;
	// Ограничим конечную строку
	КонечнаяСтрока = Мин(КонечнаяСтрока, ТабличныйДокумент.ВысотаТаблицы);
	
	// Переберем все колонки отчета
	Для ТекущаяКолонка = 1 По ТабличныйДокумент.ШиринаТаблицы Цикл
		
		АвтоОтступ = 0;
		
		// Переберем строки, которые будут использованы для расчета ширин колонок
		Для ТекущаяСтрока = НачальнаяСтрока По КонечнаяСтрока Цикл
			
			ШиринаКолонки = 0;

			// Получим область текущей ячейки
			ОбластьЯчейки = ТабличныйДокумент.Область(ТекущаяСтрока, ТекущаяКолонка);
			
			Если ОбластьЯчейки.Лево <> ТекущаяКолонка Или ОбластьЯчейки.Верх <> ТекущаяСтрока Тогда
				
				// Данная ячейка принадлежит объединенным ячейкам и не является начальной ячейкой
				Продолжить;
				
			КонецЕсли;
			
			Если КоличествоУровнейГруппировокСтрок > 0 И ТекущаяСтрока = НачалоДанных Тогда
				
				// Для первой строки с данными получим значение автоотступа
				АвтоОтступ = ОбластьЯчейки.АвтоОтступ;
				
			КонецЕсли;
			
			// Получим текст ячейки
			ТекстЯчейки = ОбластьЯчейки.Текст;
			
			// Для каждой строки из текста ячейки рассчитаем количество символов в строке
			Для НомерСтрокиТекста = 1 По СтрЧислоСтрок(ТекстЯчейки) Цикл
				
				ШиринаТекстаЯчейки = СтрДлина(СтрПолучитьСтроку(СокрЛП(ТекстЯчейки), НомерСтрокиТекста));
				
				// Если используется автоотступ, то прибавим к ширине ячейки его величину
				Если АвтоОтступ <> Неопределено И АвтоОтступ > 0 Тогда
					
					ШиринаТекстаЯчейки = ШиринаТекстаЯчейки + КоличествоУровнейГруппировокСтрок * АвтоОтступ;
					
				КонецЕсли;
				
				ШиринаКолонки = Макс(ШиринаКолонки, ШиринаТекстаЯчейки);

			КонецЦикла;

			Если ШиринаКолонки > МаксимальнаяШиринаКолонки Тогда
				
				// Ограничим ширину колонки
				ШиринаКолонки = МаксимальнаяШиринаКолонки;
			КонецЕсли;
			
			Если ШиринаКолонки <> 0 Тогда
				// Ширина колонки рассчитана
				
				// Определим, сколько ячеек по ширине используется в области для текущей ячейки
				КоличествоКолонок = ОбластьЯчейки.Право - ОбластьЯчейки.Лево;
				
				// Переберем все ячейки, расположенные в области
				Для НомерКолонки = 0 По КоличествоКолонок Цикл
					
					Если ШириныКолонок.ВГраница() > ТекущаяКолонка - 1 + НомерКолонки Тогда
						
						// В массиве ширин колонок уже был элемент для текущей колонки
						
						Если ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = Неопределено Тогда
							// Значение ширины колонки еще не было установлено
							
							ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = ШиринаКолонки / (КоличествоКолонок + 1);
							
						Иначе
							// Значение ширины колонки уже было установлено
							// Вычислим максимум ширины колонки
							ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки] = 
								Макс(ШириныКолонок[ТекущаяКолонка - 1 + НомерКолонки], ШиринаКолонки / (КоличествоКолонок + 1));
							
						КонецЕсли;
						
					Иначе
						
						// В массиве ширин колонок еще не было элемента для данной колонки
						// Добавим элемент в массив ширин колонок
						ШириныКолонок.Вставить(ТекущаяКолонка - 1 + НомерКолонки, ШиринаКолонки / (КоличествоКолонок + 1));
						
					КонецЕсли;
					
				КонецЦикла;
				
			КонецЕсли;
			
		КонецЦикла;	// Конец цикла перебора строк
		
	КонецЦикла;	// Конец цикла перебора колонок
	
	// Переберем все элементы в массиве вычисленных ширин колонок
	Для ТекущаяКолонка = 0 По ШириныКолонок.ВГраница() Цикл
		
		Если ШириныКолонок[ТекущаяКолонка] <> Неопределено Тогда
			// Ширина колонок установлена
			// Установим ширину области ячеек
			ТабличныйДокумент.Область(, ТекущаяКолонка + 1, НачалоДанных, ТекущаяКолонка + 1).ШиринаКолонки = ШириныКолонок[ТекущаяКолонка] + 1;
			
		КонецЕсли;
		
	КонецЦикла;

КонецПроцедуры

 

На картинке видно, что пустое место в колонках, выделенное красной линией, исчезло:

46

См. также

Комментарии
Избранное Подписка Сортировка: Древо
1. kiruha 369 20.04.18 10:20 Сейчас в теме
А как в плане производительности на больших объемах ?
Может есть способ не все строки обходить ?
2. Margo462 146 20.04.18 10:43 Сейчас в теме
(1) у меня было больше 3000 строк, задержка секунд 5-10 была, точно не могу сказать;
Да, можно не все строки обходить, там в цикле вместо "КонечнаяСтрока" вставить количество строк которое нужно
4. sergathome 20.04.18 12:02 Сейчас в теме
Все решения, связанные с использованием ручной компоновки, страдают одним - синхронное исполнение. Это убивает практически весь кайф...
8. rozer 220 21.04.18 11:20 Сейчас в теме
(4) в конфах на бсп это решается на раз- просто после фонового поймать табдокумент...
rpgshnik; +1 Ответить
6. unichkin 1023 20.04.18 23:28 Сейчас в теме
Можно не ставить стандартную обработку в Ложь, а просто рассчитать ширины в уже сформированном документе.. По-моему задача раз 100 решалась уже.
9. Margo462 146 21.04.18 14:20 Сейчас в теме
(6) у меня в этом примере еще внешний набор был, оставила процедуру как есть только без внешнего набора, а стандартную обработку ложь оставила)) В интернете я долго искала решение, эта процедура вобще для построителя отчета используется, а примеров для скд я не нашла, если есть другие варианты, прошу выложить
16. Margo462 146 22.04.18 16:58 Сейчас в теме
(6) Без стандартной обработки Ложь, не работает, надо ставить ложь
10. unichkin 1023 21.04.18 17:42 Сейчас в теме
Вот здесь, например https://infostart.ru/public/84642/. Заметил фразу "Пример для СКД" - а при чем здесь СКД?) Есть таб. док, считаем длины строк по ячейкам, берем максимальную, устанавливаем от нее ширину колонки. Откуда там этот ТабДок взялся - с СКД, универсального отчета, или просто произвольный - какая разница?
11. yelloo 4 21.04.18 23:35 Сейчас в теме
(10) женская логика - не поспоришь :)
12. unichkin 1023 21.04.18 23:47 Сейчас в теме
(11) Да ну, причем здесь "женская логика".. Смешение контекстов частая проблема - даже у опытнейших специалистов бывает "каша в голове". Да и возможно человек просто неверно выразился, я на всякий случай внес ясность.
15. Margo462 146 22.04.18 16:51 Сейчас в теме
(12) я еще курсы скд не проходила, поэтому учусь методом проб и ошибок
14. Margo462 146 22.04.18 16:50 Сейчас в теме
(10) статья бесплатная, в отличие от той, которую вы привели по ссылке, я конкретно хотела показать для скд, в какое место (в процедуре ПриКомпоновкеРезультата) надо добавить процедуру расчета колонок, чтобы все работало и процедуру расчета я взяла с конфы на сайте итс (https://its.1c.ru/db/metod8dev#content:2253:hdoc), другие источники я просто не искала, меня и такой вариант устраивает) подобных примеров я не видела поэтому выложила как вариант.
20. kiruha 369 23.04.18 10:09 Сейчас в теме
(10)
по вашей ссылке относящееся к этой теме :
За счет чего достигается ускорение?
При расчете ширины колонки отчета:
- пропускаются пустые ячейки не влияющие на ширину колонки;
- обрабатываются ячейки только из первых 100 строк отчета;


" обрабатываются ячейки только из первых 100 строк отчета" - хорошая идея , но можно улучшить - случайные 100 строк отчета из диапазона 1-КонечнаяСтрока
Статистически более достоверно
22. rpgshnik 836 24.04.18 04:53 Сейчас в теме
(10)
Заметил фразу "Пример для СКД" - а при чем здесь СКД?)

О это так же режет слух как многие употреблятсвуют словом "ERP" словно это отдельная платформа, типа "Пример разработки в ЕРП".
23. Margo462 146 24.04.18 07:51 Сейчас в теме
(22) так подскажите как это назвать пока еще кому-нибудь слух не порезало))))
17. unichkin 1023 22.04.18 17:45 Сейчас в теме
Да, при стандартной обработке = Ложь документ пустой в ПриКомпоновке.. Странно, почему-то мне казалось он должен быть там заполнен. Значит для корректного использования в фоновых заданиях надо ковырять варианты отчетов на ИТС. ТС - спасибо, обновил знания :)
Только если приводите статью с ИТС, то ссылайтесь сразу на первоисточник. Специально проверил ту ссылку, которую дал - там тот-же самый код.
Я обычно такое как-то на автомате решал, в другой раз попробую эту функцию заюзать.
18. Margo462 146 22.04.18 18:51 Сейчас в теме
(17) я еще чуть подредактировала процедуру расчета ширины из примера, лишнее убрала про области макета, как-то так)
21. rpgshnik 836 24.04.18 04:41 Сейчас в теме
Интересно, молодец!

Но почему у колонки "номенклатура" столько пустого места осталось? И у колонки "Поле1" имеется немного лишнего... Идеальные перфекционистские зазоры не получиться выполнить данной функцией?
24. Margo462 146 24.04.18 11:55 Сейчас в теме
(21) надо смотреть почему остается место)
25. MSK_Step 17 24.04.18 19:22 Сейчас в теме
26. dtripleh 25.04.18 18:48 Сейчас в теме
А не проще ли нарисовать макет и установить автомакс. ширину колонки?
27. Margo462 146 25.04.18 19:24 Сейчас в теме
(26) когда много данных запаришься рисовать, еще если просят постоянно что-то добавить) да и зачем рисовать если есть скд
28. Scarlett_ 04.06.18 07:11 Сейчас в теме
Оставьте свое сообщение