Как устроен отчет Анализ начислений и удержаний в ЗУП 3.1 и где формируется его запрос?

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При попытке доработать или исследовать типовой отчет АнализНачисленийИУдержаний (а также многие производные варианты, такие как расчетные листки) в конфигурации 1С:Зарплата и управление персоналом 3.1 разработчики часто сталкиваются с неожиданным поведением. Открыв схему компоновки данных (СКД), мы видим лишь пустой набор полей или лаконичный запрос-заглушку, тогда как реальный отчет оперирует десятками временных таблиц и собирает данные из множества кадровых и расчетных регистров.

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

Где находится процедура генерации текста запроса

Выясним точное место формирования итогового запроса. В типовых зарплатных решениях формирование текста вынесено в специализированные общие модули подсистемы общих наборов данных. Основная точка входа для отчета АнализНачисленийИУдержаний расположена в процедуре:

ЗарплатаКадрыОбщиеНаборыДанныхРасширенный.ПолучитьТекстОбщегоЗапроса(ИсточникДанных)

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

Почему 1С формирует запросы программно, а не через стандартный текст СКД

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

  1. Переиспользование бизнес-логики и единая точка правды: Получение данных по начислениям, удержаниям, кадровой истории и отработанному времени требуется не только в одном отчете, но и в документах расчета, межрасчетных выплатах, аналитических справках и регламентированных формах. Если бы запрос писался в каждом отчете отдельно, любая доработка алгоритма расчета требовала бы синхронной правки десятков объектов. Использование единых методов генерации гарантирует одинаковый результат во всех подсистемах.
  2. Изоляция от изменений структуры метаданных: При переработке структуры регистров (например, при оптимизации индексов или изменении состава измерений) СКД-представление набора данных остается неизменным. Разработчикам типовой конфигурации достаточно изменить логику генерации в общем модуле, не переписывая все схемы компоновки данных.
  3. Механизм представлений и динамическая оптимизация: В СКД зарплатных отчетов наборы данных обращаются к виртуальным таблицам-шаблонам. Специальный механизм анализирует реальные потребности пользователя: какие поля выбраны в отчете, какие установлены группировки и отборы. С помощью объекта СхемаЗапроса неиспользуемые временные таблицы просто исключаются из итогового текста. Если пользователю не нужны данные по плановым авансам или определенным видам времени, соответствующие таблицы не создаются, что кардинально снижает нагрузку на СУБД.
  4. Сложная работа с интервальными данными: Зарплатный учет базируется на срезах на произвольные интервалы, соединениях графиков работы, периодов действия и перерасчетов. Построить такую логику одним статическим запросом в СКД без просадки производительности и риска дублирования строк практически невозможно.
  5. Централизованный контроль прав доступа (RLS): Ограничения на уровне записей по организациям, подразделениям и группам физических лиц внедряются непосредственно в создаваемые временные таблицы, исключая утечку данных при сложных многоуровневых соединениях.

Особенности поиска вариантов: связь с расчетными листками

Рассмотрим структуру самого отчета АнализНачисленийИУдержаний. В конфигурации 1С:ЗУП 3.1 он выполняет роль универсального комбайна данных. Например, привычный пользователям отчет Расчетный листок не является отдельным объектом метаданных — это предопределенный вариант отчета АнализНачисленийИУдержаний с именем РасчетныйЛисток. Соответственно, вся расчетная база для листков извлекается через тот же самый универсальный механизм общих наборов данных.

Как увидеть и отладить итоговый запрос

Поскольку отчеты на базе Библиотеки стандартных подсистем (БСП) формируются в фоновом режиме, разработчик при попытке отладки может столкнуться с тем, что точки останова в модулях не срабатывают. Разберем по шагам, как добраться до реального текста запроса:

  1. Убедимся, что в среде разработки включена автоматическая отладка фоновых заданий, а сервер 1С запущен с ключом отладки.
  2. Установим точку останова в процедуре ПриКомпоновкеРезультата модуля объекта отчета или непосредственно в методе ЗарплатаКадрыОбщиеНаборыДанныхРасширенный.ПолучитьТекстОбщегоЗапроса.
  3. После выполнения процедур инициализации отчета и подмены запроса откроем табло и вычислим выражение: СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос Здесь будет доступен полный сгенерированный SQL-пакет со всеми временными таблицами, адаптированный под текущие настройки пользователя.

Как программно получить данные отчета в коллекцию значений

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


ОтчетОбъект = Отчеты.АнализНачисленийИУдержаний.Создать();
ОтчетОбъект.ИнициализироватьОтчет();

КомпоновщикНастроек = ОтчетОбъект.КомпоновщикНастроек;
Настройки = КомпоновщикНастроек.ПолучитьНастройки();

// При необходимости настраиваем параметры и отборы
ПараметрПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период");
Если ПараметрПериод <> Неопределено Тогда
    ПараметрПериод.Значение = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
    ПараметрПериод.Использование = Истина;
КонецЕсли;

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(ОтчетОбъект.СхемаКомпоновкиДанных, Настройки,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

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

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

← На главную