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