Многоуровневая нумерация в отчете СКД (программный вывод)

16.01.20

Разработка - СКД

Реализация многоуровневой нумерации при программном выводе отчета СКД основываясь на его структуре.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Пример внешнего отчета с иерархической нумерацией.
.erf 8,32Kb
24 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

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

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Задача: нередко при разработке отчетов возникает необходимость многоуровневой нумерации элементов отчета в соответствии с его структурой. Система компоновки данных не предоставляет средств для решения этой задачи. Проблема усугубляется в случае отчетов с иерархической группировкой где количество уровней вложенности произвольно и заранее неизвестно.

Попытки решения данной задачи только средствами СКД успехом не увенчались. Поиск существующих решений желаемых результатов не принес:

  • вариант Ильи Васильева (swimdog) имеет ограничение по уровням вложенности и требует анализа выходного табличного документа для определения размещения номера;
  • вариант Алексея А (Isonic) с произвольной иерархией представляется неудобным в реализации так как вложенность заранее неизвестна и при изменении группировок придется переопределять значение поля иерархической нумерации;

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

Фрагмент кода формирования иерархического номера:

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

			КонецЕсли
		КонецЕсли;
//}}
	    ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
	    ЭлементРезультата = ПроцессорКомпоновки.Следующий();
	КонецЦикла;
	ПроцессорВывода.ЗакончитьВывод()
КонецПроцедуры

Код функции ПолучитьМногоуровневыйНомерПоИерархии:

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

Также вам потребуется функция "ПолучитьИменаПараметровВМакетеКомпоновкиПоИмениПоля" которую можно взять из статьи о установке собственных значений полей при программном выводе отчета СКД либо скачать пример отчета в котором "все включено".

P.S. Алгоритм разработан для иерархической нумерации по строкам отчета, но работает и при наличии группировок колонок. Вывод номера по колонкам не предусмотрен.

Огромная благодарность Денису Урянскому (dhurricane) за вдумчивое тестирование и подсказки.

Внешний отчет с примером иерархической нумерации тестировался на платформе 8.3.13.1644.

Обновление 16.01.2020: Перезагружен файл с примером. Просьба скачавшим связаться с автором для получения новой версии, либо самостоятельно  обновить код функции ПолучитьИменаПараметровВМакетеКомпоновкиПоИмениПоля() из текста статьи про нее. В прежней реализации возможен несистематический пропуск параметров.

Вступайте в нашу телеграмм-группу Инфостарт

Иерархическая нумерация многоуровневая СКД

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    262737    1462    421    

1172

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Как решить проблему с отборами по полям СКД, когда с одинаковым отбором Отчет показывает одно, а Консоль запросов другое.

вчера в 09:00    1386    sapervodichka    42    

42

Инструментарий разработчика СКД Программист 1С 8.3 Бесплатно (free)

В этой статье представлен СКДБилдер — общий модуль-обёртка над объектной моделью СКД, который сокращает код в 3-4 раза и делает его читаемым.

29.01.2026    7273    375    shapa_pro    27    

69

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Статья написана по результатам проведенного внутреннего обучающего вебинара для разработчиков ГК «СофтБаланс». Если осилить 25 000 знаков - задача для вас непосильная, где-то на бескрайних просторах интернета видео есть (или будет). Но здесь информация точнее. Разберем, чем запрос для СКД принципиально отличается от обычного запроса и как модифицируется в зависимости от настроек. Изучим «базовый рецепт» написания запроса для СКД, сформируем чек-лист. Полезно будет всем – от стажеров до тех. лидов. Всем, кто не снимает галку «автозаполнение» и пишет запросы для отчетов в консоли запросов – читать (вдумчиво) обязательно.

29.10.2025    21034    ovetgana    112    

115

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Описан способ заполнения списка доступных значений для полей наборов данных и параметров в схеме компоновки данных для любых конфигураций (с использованием БСП или без).

01.07.2025    12022    krasnoshchekovpavel    7    

68

СКД Программист Стажер 1С:Предприятие 8 Россия Бесплатно (free)

Несколько способов управления формами выбора параметров и отборов СКД.

10.04.2025    11658    Neti    0    

42

СКД Программист 1С:Предприятие 8 Бесплатно (free)

Хорошая отчетная форма - сродни искусству. Есть какое-то невероятное эстетическое удовольствие в том, чтобы разобраться в логике учета и анализируемых показателях, спроектировать архитектуру хранения данных так, чтобы оптимально собрать эти показатели вместе с аналитическими разрезами в запросе, а затем настроить отображение так, чтобы, глядя на результат, сразу было понятно, что это за отчет и какие задачи он призван решать. Система компоновки данных - это моя первая, главная и, наверное, единственная "рабочая" любовь. Ее я использую везде, где только можно и где нельзя тоже. Хочу поделиться с вами некоторыми практическими приемами в работе с отчетами на СКД, которые, надеюсь, будут полезны.

27.02.2025    17196    ovetgana    50    

93

СКД Программист 1С:Предприятие 8 Бесплатно (free)

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

24.12.2024    14945    Akcium    17    

47
Вознаграждение за ответ
Показать полностью
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dhurricane 02.07.19 07:48 Сейчас в теме
Спасибо за идею и пример реализации. Единственное, что хотелось бы отметить в качестве недостатка, это анализ типа элемента результата для получения уровня. При работе, например, с таблицей, когда есть группировки не только нумеруемых строк, но и группировки колонок, Ваш алгоритм даст некорректную нумерацию в иерархии.
2. lmnlmn 71 02.07.19 08:27 Сейчас в теме
(1) Спасибо за подсказку. Вообще в реальной ситуации этот алгоритм используется в кросс-таблице с группировкой колонок и проблем нет. Но я добавлю группировку колонок в пример и проверю. Если будут сбои в нумерации - доработаю алгоритм и на этот случай.
3. lmnlmn 71 02.07.19 09:17 Сейчас в теме
(1) Внес исправления в код и пример. Теперь корректно нумерует и при наличии группировок колонок. Но нумерация работает только по строкам. По колонкам лучше не нумеровать.
4. dhurricane 02.07.19 09:42 Сейчас в теме
(3) Спасибо. Есть еще один небольшой недочет, касающийся функции "ПолучитьМногоуровневыйНомерПоИерархии". Вы обходите таблицу номеров стека и в этом же цикле удаляете строки таблицы. Это может привести к ошибкам. Корректнее удалять, например, так:
НомераКУдалению = Новый Массив;
Для Каждого Номер Из СтекНомеров Цикл
	Если Номер.Уровень <= УровеньОтчетаСКД Тогда
		СтрНомерПоИерархии = СтрНомерПоИерархии + Номер.Номер + ".";
	Иначе
		//Чистим элементы стека нижних уровней
		НомераКУдалению.Добавить(Номер);
	КонецЕсли
КонецЦикла;
Для каждого Номер Из НомераКУдалению Цикл
	СтекНомеров.Удалить(Номер);
КонецЦикла;
Показать
Ну и хотел бы предложить небольшое упрощение Вашего алгоритма в целом. А именно избавиться от вычисляемого поля "НомерПоИерархии", а вместо него в выбранные поля добавить "СистемныеПоля.Уровень". Тогда при выводе строк отчета можно значение уровня получать прямо из макета, вычислять номер в иерархии и устанавливать его обратно в системное поле.
5. lmnlmn 71 02.07.19 10:02 Сейчас в теме
(4) Вообще по удалению, формально, ваш вариант "каноничнее", но в данном алгоритме это к проблемам не приведет так как номера нижних уровней надо просто отсечь. Но, да, "дурной тон" в программировании.

С системными полями идея хорошая, но на практике есть одна проблема. Если другой разработчик (да я и сам через полгодика запамятовать могу) будет дорабатывать отчет, то он будет долго и с проклятиями недоумевать что за ерунда вместо уровня пишется, пока разберется в происходящем. А вычисляемое поле с понятным именем путаницу не вносит. Вообще для коллег можно в выражении вычисляемого поля написать "заполняется программно", например.
6. dhurricane 02.07.19 10:23 Сейчас в теме +1 $m
(5)
но в данном алгоритме это к проблемам не приведет
Проблемы будут при удалении нескольких строк, т.е. если разница в уровне между предшествующей и текущей строкой будет больше 1. Для Вашего примера: если "Трансмиссию" переместить на верхний уровень из под подчинения "Автомобилю", то на платформе 8.3.13.1809 в файловой базе получим номера, представленные на скрине ниже.

то он будет долго и с проклятиями недоумевать что за ерунда вместо уровня пишется, пока разберется в происходящем
Согласен, предложенный мной вариант вносит путаницу.
Прикрепленные файлы:
ELInfinito; +1 Ответить
7. lmnlmn 71 02.07.19 10:37 Сейчас в теме
(6)
Проблемы будут при удалении нескольких строк, т.е. если разница в уровне между предшествующей и текущей строкой будет больше 1.

Спасибо, проглядел. Исправил.
Для отправки сообщения требуется регистрация/авторизация