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