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