Разработка отчетов в конфигурации «Зарплата и управление персоналом 3.1» (ЗУП) существенно отличается от создания обычных отчетов на СКД в других конфигурациях. Здесь разработчики сталкиваются с мощным, но сложным механизмом виртуальных таблиц (представлений). В этой статье мы подробно разберем, как устроена эта подсистема, как программно подготовить данные и «подружить» их с Системой компоновки данных.
В ЗУП 3.1 большинство типовых отчетов строятся не на прямых запросах к регистрам, а на использовании специальных конструкций в тексте запроса СКД. Рассмотрим пример: вместо выбора из РегистрСведений.КадроваяИсторияСотрудников, в запросе указывается источник ИЗ Представления_КадровыеДанныеСотрудников КАК КадровыеДанные.
Выясним причину такого подхода: учет в ЗУП крайне сложен из-за необходимости учитывать срезы данных на разные даты, наличие внутренних совместительств, разные состояния сотрудников (отпуска, больничные) и права доступа (RLS). Чтобы программисту каждый раз не писать запросы на 500 строк с учетом всех нюансов, разработчики фирмы «1С» вынесли эту логику в общие модули. Система сама «на лету» заменяет префикс Представления_ на реальные временные таблицы с уже рассчитанными данными.
Прежде чем приступать к написанию своего кода, проанализируем, как это реализовано в стандартных отчетах. Рекомендуем рассмотреть структуру следующих объектов:
ОтчетыПоСотрудникам — базовый каркас для большинства кадровых отчетов.КадроваяИсторияСотрудников — отличный пример того, как система работает с периодами и срезами данных.Обратите внимание на модуль объекта этих отчетов, особенно на процедуру ПриКомпоновкеРезультата. Именно там происходит магия подготовки данных.
Рассмотрим ситуацию, когда нам нужно получить кадровые данные и данные об учете времени сотрудников программно, чтобы затем использовать их в своем отчете. Для этого мы будем использовать МенеджерВременныхТаблиц и типовые функции из модулей КадровыйУчет и УчетРабочегоВремениРасширенный.
Разберем по шагам пример кода для получения данных:
// 1. Инициализируем менеджер и запрос
Менеджер = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Менеджер;
// 2. Настраиваем параметры получения кадровых данных
ПараметрыПолученияДанных = КадровыйУчет.ПараметрыПолученияСотрудниковОрганизацийПоСпискуФизическихЛиц();
ПараметрыПолученияДанных.Организация = Организация;
ПараметрыПолученияДанных.НачалоПериода = Период.ДатаОкончания;
ПараметрыПолученияДанных.ОкончаниеПериода = Период.ДатаОкончания;
// 3. Формируем ВТ сотрудников (ВТСотрудникиОрганизации)
КадровыйУчет.СоздатьВТСотрудникиОрганизации(Менеджер, ИСТИНА, ПараметрыПолученияДанных);
// 4. Подготавливаем данные для учета рабочего времени
ПараметрыЗаполнения = УчетРабочегоВремениРасширенный.ПараметрыДляЗапросВТДанныеУчетаВремениИСостоянийСотрудников();
ПараметрыЗаполнения.ИмяВТСотрудники = "ВТСотрудникиОрганизации";
ПараметрыЗаполнения.ИмяВТРезультат = "ВТУчетРабочегоВремениПолный";
ПараметрыЗаполнения.РассчитыватьПлановоеВремя = Истина;
ПараметрыЗаполнения.ДатаНачала = Период.ДатаНачала;
ПараметрыЗаполнения.ДатаОкончания = Период.ДатаОкончания;
// 5. Вызываем функцию создания ВТ данных учета времени
УчетРабочегоВремениРасширенный.СоздатьВТДанныеУчетаВремениИСостоянийСотрудников(Менеджер, ИСТИНА, ПараметрыЗаполнения);
// 6. Теперь мы можем выбрать данные из сформированной ВТ
Запрос.Текст = "ВЫБРАТЬ * ИЗ ВТУчетРабочегоВремениПолный";
Результат = Запрос.Выполнить().Выгрузить();
В данном примере мы использовали функцию СоздатьВТСотрудникиОрганизации, которая автоматически учитывает все кадровые изменения на указанную дату. Это гораздо надежнее, чем писать запрос к регистру КадроваяИсторияСотрудников вручную.
Теперь разберем ситуацию, когда данные подготовлены в МенеджереВременныхТаблиц, и нам нужно передать их в СКД. Рассмотрим подробнее, как связать наш менеджер с процессором компоновки.
Для того чтобы СКД «увидела» ваши временные таблицы, необходимо выполнить следующие действия в процедуре ПриКомпоновкеРезультата:
ВТУчетРабочегоВремениПолный).ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект);.МенеджерВременныхТаблиц, его нужно установить в свойство запроса, который будет исполняться внутри СКД. Это делается через установку параметра МенеджерВременныхТаблиц в объекте Запрос при выполнении компоновки макета.Важный момент: Если вы используете механизм представлений (префикс Представления_), то вам не нужно вручную создавать менеджер ВТ. Достаточно вызвать процедуру:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// Отключаем стандартную обработку, чтобы управлять процессом программно
СтандартнаяОбработка = Ложь;
// Позволяем системе ЗУП проанализировать запрос и подставить реальные таблицы вместо "Представления_"
ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(ЭтотОбъект);
// Далее следует стандартный вывод отчета через ПроцессорКомпоновкиДанных
// ...
КонецПроцедуры
Посмотрим на ситуацию глубже. Когда вы вызываете ЗаполнитьОбщиеИсточникиДанныхОтчета, система обращается к общим модулям описания представлений (например, ОписанияПредставленийЗарплатаКадры). Там программно описаны все доступные поля: ФИО, Должность, Табельный номер и т.д.
Проанализируем алгоритм работы системы:
Представления_.Поскольку финальный запрос формируется динамически, обычная консоль запросов вам не поможет. Чтобы увидеть реальный текст запроса, который уходит на сервер СУБД, рассмотрите возможность использования консоли компоновки данных, которая позволяет просматривать макет после его генерации процессором компоновки.
Также полезно в момент отладки в процедуре ПриКомпоновкеРезультата поставить точку останова после вызова ЗаполнитьОбщиеИсточникиДанныхОтчета и изучить содержимое переменной ЭтотОбъект.СхемаКомпоновкиДанных. Там вы увидите, как изменился текст запроса в наборах данных.
Никогда не пишите запросы к регистрам ЗУП «в лоб», если отчет должен возвращать актуальные кадровые сведения. Используйте функции КадровыйУчет.СоздатьВТСотрудникиОрганизации. Это единственный легитимный способ получить корректные данные с учетом всех разрезов учета и прав доступа.
Если отчет работает медленно, проверьте список запрашиваемых полей. В механизме представлений ВЫБРАТЬ * может привести к значительным задержкам, так как система будет вынуждена собирать все возможные данные о сотруднике (от образования до паспортных данных).
Разберем типичную ошибку: попытка использовать МенеджерВременныхТаблиц без явной передачи его в ПроцессорКомпоновки. Помните, что СКД создает свой собственный контекст выполнения. Чтобы ваши таблицы были видны, они должны быть помещены в менеджер, который «привязан» к запросу внутри компоновщика.