Универсальный отчёт для ЗУП: как сократить время разработки сложных отчётов в разы

29.12.25

База данных - HighLoad оптимизация

ЗУП редко отдаёт корректные данные простыми запросами: за ними стоит программный интерфейс и сложная бизнес-логика. Ранее я решил эту проблему на уровне консоли запросов — с помощью QueryConsole1C и механизма исполняемых представлений, позволяющего обращаться к методам программного интерфейса ЗУП прямо из текста запроса. В этой статье я переношу тот же подход в Универсальный отчёт. Теперь источником данных становится полноценный запрос с поддержкой исполняемых представлений, что позволяет использовать бизнес-логику ЗУП непосредственно в отчётах и в разы ускоряет разработку сложной аналитики без дублирования сложных алгоритмов.

Файлы

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

Наименование Скачано Купить файл
Универсальный отчёт для ЗУП: как сократить время разработки сложных отчётов в разы:
.cfe 869,54Kb
1 1 850 руб. Купить

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

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

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

Для лучшего понимания материала статьи рекомендую сначала ознакомиться с предыдущей статьёй «Консоль запросов ЗУП с поддержкой обращения к методам программного интерфейса в запросах».

 

Недостатки универсального отчёта в контексте ЗУП

Универсальный отчёт удобен для простой аналитики, но в 1С:Зарплата и управление персоналом он быстро упирается в ограничения. Причина в том, что ключевые данные ЗУП — кадровые данные сотрудников, данные учета времени, расчётная база — не хранятся в регистрах в готовом виде, а формируются бизнес-логикой через программный интерфейс.

Универсальный отчёт работает с таблицами и не учитывает эту логику. В результате даже типовые задачи — например, план-фактный анализ рабочего времени — невозможно корректно решить без СКД или программного кода с вызовами ПИ и созданием временных таблиц.

Дополнительное ограничение — один источник данных. Универсальный отчёт плохо подходит для задач, где требуется объединять несколько источников с расчётной логикой, поэтому в ЗУП он чаще используется для вспомогательных выборок, а не для полноценной аналитики.

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


От консоли запросов к универсальному отчёту: развитие идеи

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

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

В результате универсальный отчёт сохраняет привычный интерфейс и сценарии использования, но при этом получает доступ к программному интерфейсу ЗУП. Это позволяет строить сложные аналитические отчёты без дублирования бизнес-логики, без написания обработок и без глубокого погружения во внутреннее устройство конфигурации.


Новый универсальный отчёт: привычный интерфейс и возможность задать запрос

Доработанный универсальный отчёт для ЗУП сохраняет привычный пользовательский интерфейс. Все основные элементы — формирование отчёта, настройки, компоновка — остаются на своих местах.
Ключевое отличие заключается в появлении новой возможности — установить собственный запрос в качестве источника данных отчёта.


 

В открывшемся редакторе мы можем как установить уже готовый текст запроса (например написанный и отлаженный в консоли запросов), так и воспользоваться конструктором запросов


 

В этом конструкторе доступны исполняемые представления, сгруппированные по предметным областям ЗУП: кадровый учёт, учёт времени, расчёт заработной платы и другие.
С точки зрения конструктора они выглядят как обычные источники данных, однако по своей сути являются аналогом виртуальных таблиц, позволяющими получить доступ к программному интерфейсу ЗУП.


Практический пример: отчёт по отклонениям рабочего времени

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

Отчёт должен решать сразу несколько задач:

  • показывать отклонения по рабочему времени за выбранный период;

  • поддерживать вывод данных в разных разрезах:

    • по сотрудникам,

    • по подразделениям,

    • по позициям штатного расписания;

  • предоставлять гибкие возможности отбора:

    • по периоду,

    • по подразделениям,

    • по конкретным сотрудникам или должностям.
       

Реализация отчёта

В качестве источника данных для универсального отчёта используется следующий запрос:

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

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ПлановоеВремяСотрудников.Сотрудник,
	ПлановоеВремяСотрудников.Дата,
	ПлановоеВремяСотрудников.ВидУчетаВремени,
	0,
	0,
	ПлановоеВремяСотрудников.ДниПлан,
	ПлановоеВремяСотрудников.ЧасыПлан
ИЗ
	ИсполняемоеПредставление.ПлановоеВремяСотрудников(
		(Сотрудник, ДатаНачала, ДатаОкончания, ДатаАктуальности) В 
		(ВЫБРАТЬ РАЗЛИЧНЫЕ
			ВТОтборСотрудников.Сотрудник КАК Сотрудник,
			&ДатаНачала КАК ДатаНачала,
			&ДатаОкончания КАК ДатаОкончания,
			&ДатаОкончания КАК ДатаАктуальности
		ИЗ
			ВТПериодыКадровойИстории КАК ВТОтборСотрудников
				ЛЕВОЕ СОЕДИНЕНИЕ ИсполняемоеПредставление.Периоды(
					НачалоИнтервала = &ДатаНачала,
					ОкончаниеИнтервала = &ДатаОкончания,
					Периодичность = "МЕСЯЦ") КАК Периоды
				ПО Периоды.Период МЕЖДУ &ДатаНачала И &ДатаОкончания)
) КАК ПлановоеВремяСотрудников) КАК ДанныеОВремени
		{ЛЕВОЕ СОЕДИНЕНИЕ ВТПериодыКадровойИстории КАК КадроваяИсторияСотрудниковПериоды
		ПО ДанныеОВремени.Сотрудник = КадроваяИсторияСотрудниковПериоды.Сотрудник
		И ДанныеОВремени.Дата МЕЖДУ КадроваяИсторияСотрудниковПериоды.НачалоПериода И КадроваяИсторияСотрудниковПериоды.КонецПериода}
ГДЕ
	ДанныеОВремени.ВидУчетаВремени <> ЗНАЧЕНИЕ(Справочник.ВидыИспользованияРабочегоВремени.РабочееВремя)

СГРУППИРОВАТЬ ПО
	ДанныеОВремени.Сотрудник,
	ДанныеОВремени.Дата,
	ДанныеОВремени.ВидУчетаВремени,
	КадроваяИсторияСотрудниковПериоды.ГоловнаяОрганизация,
	КадроваяИсторияСотрудниковПериоды.Организация,
	КадроваяИсторияСотрудниковПериоды.Подразделение,
	КадроваяИсторияСотрудниковПериоды.Должность,
	КадроваяИсторияСотрудниковПериоды.ДолжностьПоШтатномуРасписанию,
	КадроваяИсторияСотрудниковПериоды.ВидДоговора

 

Пояснение структуры запроса

1. Формирование кадровых периодов сотрудников

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

Ключевые моменты:

  • используется исполняемое представление регистра КадроваяИсторияСотрудников.Периоды;

  • возвращаются именно периоды, а не отдельные записи;

  • исключаются события увольнения;

  • таблица используется далее для отбора сотрудников и привязки аналитик.


2. Получение фактического рабочего времени

Фактическое рабочее время получается через исполняемое представление
ДанныеУчетаВремениСотрудников.

Здесь важно, что:

  • данные рассчитываются программным интерфейсом ЗУП;

  • учитываются все отклонения и виды учёта времени;

  • отбор сотрудников формируется на основе кадровых периодов.

3. Получение планового рабочего времени

Плановое время формируется через исполняемое представление
ПлановоеВремяСотрудников.

Этот блок:

  • рассчитывает план по графикам работы и индивидуальным графикам;

  • учитывает дату актуальности;

  • возвращает данные в том же формате, что и факт.

4. Привязка к кадровым данным

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

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

Настройки СКД

После того как запрос установлен и используется в качестве источника данных, дальнейшая работа с отчётом выполняется стандартными средствами системы компоновки данных. Это важный момент — несмотря на нетипичный источник данных, отчёт настраивается так же, как обычный универсальный отчёт.

Отбор данных

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



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

Пользовательские поля

Так как отчёт должен рассчитывать итоговые значения по группировкам, добавим пользовательские поля через механизм формул.


 

Структура отчёта

На завершающем этапе настраивается структура отчёта — группировки и порядок вывода данных.



 

Дополнительные возможности

Так как используется стандартная СКД, доступны и все остальные её возможности:

  • условное оформление;

  • сортировки;

  • дополнительные отборы;

  • быстрые настройки.

Таким образом, доработанный универсальный отчёт сочетает в себе гибкость SQL-запроса с полноценными возможностями СКД, не ограничивая пользователя в привычных сценариях работы.

 

Результат

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


 

На выходе получаем две таблицы. По подразделениям и по сотрудникам с тремя ключевыми показателями.

На скриншоте видно, что отклонения сразу выделяются визуально: отрицательные значения отображаются красным, положительные — зелёным. Это позволяет быстро находить сотрудников с переработками/недоработками и переходить к детальному анализу (по видам учёта времени, подразделениям и т.д.) за счёт группировок и отборов.

Дальше, меняя настройки структуры (например, группировку по организации/подразделению или добавляя другие разрезы), можно получить тот же отчёт в нужном формате без изменения запроса — только средствами СКД.

Настройки отчета можно скачать здесь.
 

Сохранение варианта отчёта

После настройки запроса и СКД отчёт можно сохранить типовым механизмом вариантов отчётов. При сохранении мы задаём наименование, настраиваем доступность (только автору или всем пользователям) и при необходимости выбираем, кому показать отчёт в панелях. Далее вариант можно разместить в нужных разделах приложения (например, «Учёт времени»), чтобы пользователи находили отчёт в привычном месте и использовали его как обычный типовой отчёт.


 

Итог

В результате мы получили полноценный отчёт для план-фактного анализа рабочего времени с отклонениями по часам (и при необходимости — по дням), с гибкими разрезами (сотрудник, подразделение, должность/позиция штатного расписания) и стандартными возможностями СКД: отборами, группировками, пользовательскими формулами и оформлением.

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

На практике настройка такого отчёта «с нуля» заняла 15–20 минут: установить запрос, задать отборы, настроить формулы и структуру, сохранить вариант и разместить его в нужном разделе.

 

Заглянем под капот: какой запрос уходит в движок исполняемых представлений

Теперь посмотрим, что происходит при выполнении отчёта «под капотом». В первую очередь нас интересует запрос формирования интервалов кадровой истории — именно он создаёт таблицу ВТПериодыКадровойИстории, от которой дальше зависит корректная привязка аналитик и производительность.

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

 

 

ВЫБРАТЬ
	КадроваяИсторияСотрудниковПериоды1.Сотрудник КАК Сотрудник,
	КадроваяИсторияСотрудниковПериоды1.НачалоПериода КАК НачалоПериода,
	КадроваяИсторияСотрудниковПериоды1.КонецПериода КАК КонецПериода,
	КадроваяИсторияСотрудниковПериоды1.Организация КАК Организация,
	КадроваяИсторияСотрудниковПериоды1.Подразделение КАК Подразделение
ПОМЕСТИТЬ ВТПериодыКадровойИстории
ИЗ
	ИсполняемоеПредставление.РегистрСведений.КадроваяИсторияСотрудников.Периоды(
		(ДатаНачала, ДатаОкончания) В 
		(ВЫБРАТЬ
			&ДатаНачала КАК ДатаНачала,
			&ДатаОкончания КАК ДатаОкончания),
		ВключатьЗаписиНаНачалоПериода = ИСТИНА) КАК КадроваяИсторияСотрудниковПериоды1
ГДЕ
	КадроваяИсторияСотрудниковПериоды1.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
	И КадроваяИсторияСотрудниковПериоды1.Организация = &П2

 

Здесь хорошо видно два важных момента.

1) Отбор из СКД “проталкивается” в самый первый запрос

Хотя СКД напрямую не работает с исполняемыми представлениями как с типовыми таблицами, оптимизатор СКД всё равно применяется. В результате отбор по организации не остаётся на уровне отчёта “после факта”, а попадает в ГДЕ уже на этапе формирования кадровых периодов:

  • в отчёте настроили отбор по Организация;

  • оптимизатор встроил это условие в первый запрос (...Организация = &П2).

2) Движок исполняемых представлений делегирует отбор дальше

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

 

 

ВЫБРАТЬ
 	...
ПОМЕСТИТЬ ВТКадроваяИсторияСотрудниковПериоды1
ИЗ
	ВТФильтрКадроваяИсторияСотрудниковПериоды1 КАК ИзмеренияДаты
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудниковИнтервальный КАК РегистрСведений
		ПО (РегистрСведений.ДатаНачала >= ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(ИзмеренияДаты.ДатаНачала, ДЕНЬ), ДЕНЬ, 1)
					И РегистрСведений.ДатаНачала <= ВЫБОР
						КОГДА ИзмеренияДаты.ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1)
							ТОГДА ДАТАВРЕМЯ(3999, 12, 31, 23, 59, 59)
						ИНАЧЕ КОНЕЦПЕРИОДА(ИзмеренияДаты.ДатаОкончания, ДЕНЬ)
					КОНЕЦ
				ИЛИ НАЧАЛОПЕРИОДА(РегистрСведений.ДатаНачала, ДЕНЬ) <= КОНЕЦПЕРИОДА(ИзмеренияДаты.ДатаНачала, ДЕНЬ)
					И РегистрСведений.ДатаОкончания >= КОНЕЦПЕРИОДА(ИзмеренияДаты.ДатаНачала, ДЕНЬ))
			И (РегистрСведений.ДатаОкончания >= КОНЕЦПЕРИОДА(РегистрСведений.ДатаНачала, ДЕНЬ))
ГДЕ
	РегистрСведений.Организация = &ВТКадроваяИсторияСотрудниковПериоды1_Параметр1

 


Дополнительно видно, что в запросе выбираются только поля, которые реально используются в отчёте. Это снижает объём передаваемых данных и ускоряет выполнение (особенно на больших базах).

 

Открытый исходный код и продолжение темы

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

Если тема интересна глубже — у меня есть отдельный доклад о следующем шаге развития: Как я заставил ИИ понимать ЗУП: современный RAG-pipeline для генерации корректных запросов (в том числе с учётом программного интерфейса и исполняемых представлений). В докладе расскажу про архитектуру, практические сценарии и то, как превратить «генерацию текста» в реально рабочий инструмент, который ускоряет разработку запросов и отчётов.

Проверено на следующих конфигурациях и релизах:

  • Зарплата и кадры государственного учреждения КОРП, редакция 3, релизы 3.1.36.41
  • Зарплата и кадры государственного учреждения, редакция 3, релизы 3.1.36.41
  • Зарплата и управление персоналом, редакция 3.1, релизы 3.1.36.41
  • Зарплата и управление персоналом КОРП, редакция 3.1, релизы 3.1.36.41
  • 1С:ERP Управление предприятием 2, релизы 2.5.25.83

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

ЗУП ЗКГУ Универсальный отчет представления ЗУП исполняемые представления

См. также

HighLoad оптимизация Программист 1С 8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Использование оператора «В» для полей или данных составного типа (например, Регистратор) может приводить к неочевидным проблемам.

10.11.2025    5855    ivanov660    48    

51

HighLoad оптимизация Программист 1С:Предприятие 8 1C:ERP Бесплатно (free)

Приведем примеры использования различных в динамических списках и посмотрим, почему это плохо.

18.02.2025    8485    ivanov660    39    

61

HighLoad оптимизация Технологический журнал Системный администратор Программист Бесплатно (free)

Обсудим поиск и разбор причин длительных серверных вызовов CALL, SCALL.

24.06.2024    10880    ivanov660    13    

64

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

Метод очень медленно работает, когда параметр приемник содержит намного меньше свойств, чем источник.

06.06.2024    16962    Evg-Lylyk    73    

46

HighLoad оптимизация Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Анализ простого плана запроса. Оптимизация нагрузки на ЦП сервера СУБД используя типовые индексы.

13.03.2024    8344    spyke    29    

54

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

Оказывается, в типовых конфигурациях 1С есть, что улучшить!

13.03.2024    11696    vasilev2015    22    

47
Для отправки сообщения требуется регистрация/авторизация