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