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