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