При попытке доработать или исследовать типовой отчет АнализНачисленийИУдержаний (а также многие производные варианты, такие как расчетные листки) в конфигурации 1С:Зарплата и управление персоналом 3.1 разработчики часто сталкиваются с неожиданным поведением. Открыв схему компоновки данных (СКД), мы видим лишь пустой набор полей или лаконичный запрос-заглушку, тогда как реальный отчет оперирует десятками временных таблиц и собирает данные из множества кадровых и расчетных регистров.
Разберем детально, где физически генерируется этот массивный пакет запросов, почему разработчики 1С отказались от классического статичного текста в СКД и как правильно отлаживать подобные отчеты.
Выясним точное место формирования итогового запроса. В типовых зарплатных решениях формирование текста вынесено в специализированные общие модули подсистемы общих наборов данных. Основная точка входа для отчета АнализНачисленийИУдержаний расположена в процедуре:
ЗарплатаКадрыОбщиеНаборыДанныхРасширенный.ПолучитьТекстОбщегоЗапроса(ИсточникДанных)
Именно этот метод отвечает за компоновку пакета из нескольких десятков временных таблиц. При формировании отчета система анализирует переданный ИсточникДанных, структуру полей и динамически подставляет собранный текст в схему компоновки данных перед непосредственным выполнением макета.
Проанализируем архитектурные причины, по которым разработчики типовых решений используют динамическую сборку запросов вместо классического описания в СКД:
СхемаЗапроса неиспользуемые временные таблицы просто исключаются из итогового текста. Если пользователю не нужны данные по плановым авансам или определенным видам времени, соответствующие таблицы не создаются, что кардинально снижает нагрузку на СУБД.Рассмотрим структуру самого отчета АнализНачисленийИУдержаний. В конфигурации 1С:ЗУП 3.1 он выполняет роль универсального комбайна данных. Например, привычный пользователям отчет Расчетный листок не является отдельным объектом метаданных — это предопределенный вариант отчета АнализНачисленийИУдержаний с именем РасчетныйЛисток. Соответственно, вся расчетная база для листков извлекается через тот же самый универсальный механизм общих наборов данных.
Поскольку отчеты на базе Библиотеки стандартных подсистем (БСП) формируются в фоновом режиме, разработчик при попытке отладки может столкнуться с тем, что точки останова в модулях не срабатывают. Разберем по шагам, как добраться до реального текста запроса:
ПриКомпоновкеРезультата модуля объекта отчета или непосредственно в методе ЗарплатаКадрыОбщиеНаборыДанныхРасширенный.ПолучитьТекстОбщегоЗапроса.
СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос
Здесь будет доступен полный сгенерированный SQL-пакет со всеми временными таблицами, адаптированный под текущие настройки пользователя.Копировать многостраничный сгенерированный запрос в свои внешние обработки не рекомендуется: при очередном релизе конфигурации структура временных таблиц изменится, и код перестанет работать. Если перед нами стоит задача программно получить данные начислений и удержаний, правильнее использовать программный запуск схемы компоновки данных напрямую в коллекцию значений:
ОтчетОбъект = Отчеты.АнализНачисленийИУдержаний.Создать();
ОтчетОбъект.ИнициализироватьОтчет();
КомпоновщикНастроек = ОтчетОбъект.КомпоновщикНастроек;
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// При необходимости настраиваем параметры и отборы
ПараметрПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период");
Если ПараметрПериод <> Неопределено Тогда
ПараметрПериод.Значение = Новый СтандартныйПериод(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
ПараметрПериод.Использование = Истина;
КонецЕсли;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(ОтчетОбъект.СхемаКомпоновкиДанных, Настройки,,, Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТаблицаРезультат = Новый ТаблицаЗначений;
ПроцессорВывода.УстановитьОбъект(ТаблицаРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Такой подход позволяет использовать всю мощь встроенной типовой оптимизации, корректно рассчитывает начисления с учетом RLS и защищает разработку от ошибок при последующих обновлениях конфигурации 1С:ЗУП 3.1.