В конфигурации 1С:Зарплата и управление персоналом 3.1 (ЗУП) разработчики реализовали сложную структуру хранения данных. Вместо привычных срезов последних в регистрах сведений, данные о плановых начислениях разнесены по множеству таблиц: интервальные регистры, регистры исправлений и таблицы периодических показателей. Часто перед программистом стоит задача получить не просто срез на конкретную дату, а таблицу начислений за период (например, с 10 по 20 число месяца) с учетом всех изменений показателей внутри этого периода.
В этой статье мы рассмотрим, почему стандартные функции на дату не подходят, и разберем два основных способа решения задачи: использование профессионального Менеджера расчета и механизм построения запросов через Представления.
Типовая функция КадровыйУчетРасширенный.ТекущиеНачисленияСотрудника возвращает данные строго на одну дату. Если внутри месяца у сотрудника изменился оклад или добавилась надбавка, нам придется вызывать эту функцию многократно для каждой даты, что крайне неэффективно. Нам же требуется получить таблицу вида: Сотрудник — Вид Расчета — Дата Начала — Дата Окончания — Значение Показателя. При необходимости получить готовые сведения на конкретный день можно использовать отчет для вывода показателей плановых начислений сотрудников на дату.
Сложность заключается в том, что значения показателей (например, размер оклада или процент премии) хранятся отдельно от самих фактов назначения начисления. Связь между ними осуществляется через уникальный ИдентификаторСтрокиВидаРасчета. Чтобы собрать эти данные вручную, пришлось бы писать громоздкие запросы к 5-6 регистрам сразу. Рассмотрим более элегантные способы. Для формирования данных без самостоятельной разработки можно использовать отчет для анализа плановых начислений сотрудников.
Этот способ является наиболее надежным, так как он использует те же алгоритмы, которыми заполняется документ «Начисление зарплаты и взносов». Система сама проанализирует все кадровые изменения, плановые назначения и значения показателей за указанный интервал.
Разберем алгоритм реализации этого метода по шагам:
Рассмотрим пример кода:
// Установим параметры поиска
Сотрудник = Справочники.Сотрудники.НайтиПоНаименованию("Иванов Иван Иванович");
ДатаС = Дата(2023, 10, 01);
ДатаПо = Дата(2023, 10, 15);
// Создаем менеджер расчета для организации сотрудника
МенеджерРасчета = РасчетЗарплатыРасширенный.СоздатьМенеджерРасчета(НачалоМесяца(ДатаС), Сотрудник.ГоловнаяОрганизация);
// Формируем таблицу сотрудников, по которым нужны данные
СотрудникиДляНачислений = МенеджерРасчета.ТаблицаСотрудников();
НоваяСтрока = СотрудникиДляНачислений.Добавить();
НоваяСтрока.Сотрудник = Сотрудник;
НоваяСтрока.ДатаНачала = ДатаС;
НоваяСтрока.ДатаОкончания = ДатаПо;
// Важно: отключаем лишние проверки, чтобы получить данные "как есть"
НоваяСтрока.БезусловноСоответствуетКадровымДанным = Истина;
НоваяСтрока.Вычеркивать = Ложь;
// Настраиваем менеджер на получение плановых начислений
МенеджерРасчета.НастройкиРасчета.РассчитыватьНачисления = Истина;
МенеджерРасчета.НастройкиРасчета.ОкончательныйРасчет = Истина;
// Пустой отбор по подразделению (если нужно по всем)
ОтборМенеджераРасчета = МенеджерРасчета.СоздатьОтборы();
// Запускаем сбор данных
МенеджерРасчета.ЗаполнитьНачислениеЗарплаты(СотрудникиДляНачислений, ОтборМенеджераРасчета);
// Теперь данные доступны в коллекции МенеджерРасчета.Зарплата.Начисления
Для Каждого СтрокаНачисления Из МенеджерРасчета.Зарплата.Начисления Цикл
Сообщить("Начисление: " + СтрокаНачисления.ВидРасчета + " с " + СтрокаНачисления.ДатаНачала + " по " + СтрокаНачисления.ДатаОкончания);
// В каждой строке начисления есть вложенная коллекция показателей
Для Каждого СтрокаПоказателя Из СтрокаНачисления.Показатели Цикл
Сообщить(" Показатель: " + СтрокаПоказателя.Показатель + " = " + СтрокаПоказателя.Значение);
КонецЦикла;
КонецЦикла;
Преимущество этого метода: он абсолютно "честный". Если 1С изменит структуру регистров (что случается часто), МенеджерРасчета внутри себя будет обновлен разработчиками, а ваш код продолжит работать корректно.
Если вам нужно получить данные по большому количеству сотрудников сразу и использование Менеджера расчета кажется слишком тяжелым, можно воспользоваться механизмом программного формирования запросов через Представления.
Представления — это виртуальные таблицы, которые программный интерфейс ЗУП 3.1 разворачивает в реальные SQL-запросы к нужным регистрам в зависимости от версии конфигурации. Для получения плановых начислений используется метод ЗарплатаКадрыОтчеты.ДобавитьВЗапросПредставлениеПлановыеНачисления.
Проанализируем ситуацию: нам нужно создать запрос, в тексте которого будет обращение к виртуальной таблице. Система сама подменит это обращение на сложный UNION ALL из нужных регистров.
Пример построения такого запроса:
Запрос = Новый Запрос;
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
// Шаг 1: Подготовка параметров для формирования представлений
ПараметрыПостроения = ЗарплатаКадрыОтчеты.ПараметрыПостроенияПредставлений();
ПараметрыПостроения.Период = КонецДня(ТекущаяДата()); // Дата, на которую анализируем структуру
// Шаг 2: Добавляем описание виртуальной таблицы в запрос
ЗарплатаКадрыОтчеты.ДобавитьВЗапросПредставлениеПлановыеНачисления(Запрос, Истина, ПараметрыПостроения);
// Шаг 3: Теперь мы можем обращаться к ВТПредставление_ПлановыеНачисления
Запрос.Текст =
"ВЫБРАТЬ
| ПлановыеНачисления.Сотрудник КАК Сотрудник,
| ПлановыеНачисления.ВидРасчета КАК ВидРасчета,
| ПлановыеНачисления.ДатаНачала КАК ДатаНачала,
| ПлановыеНачисления.ДатаОкончания КАК ДатаОкончания,
| ПлановыеНачисления.Показатель1 КАК ЗначениеОклада
|ИЗ
| ВТПредставление_ПлановыеНачисления КАК ПлановыеНачисления";
Результат = Запрос.Выполнить().Выгрузить();
Обратите внимание, что поля Показатель1, Показатель2 и так далее в представлении соответствуют основным показателям вида расчета. Это наиболее быстрый способ получения данных для отчетов или массовых обработок.
Выясним причину, почему иногда в таблице начислений значения показателей оказываются пустыми. В ЗУП 3.1 существует концепция периодических показателей. Если оклад сотрудника не менялся год, а надбавка меняется ежемесячно, то в интервальном регистре начислений будет много строк для надбавки и одна для оклада.
При использовании Менеджера расчета система автоматически сопоставляет их. Если же вы решите самостоятельно читать регистр ПлановыеНачисленияИнтервальный, помните:
ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудниковИнтервальный.ИдентификаторСтрокиВидаРасчета (тип УникальныйИдентификатор).Выбор метода зависит от вашей конкретной задачи:
СрезПоследних, так как вы пропустите данные, внесенные документами-исправлениями или изменениями, действующими "внутри" месяца.Рассмотренные подходы позволяют корректно работать с "хрупкой" расчетной подсистемой ЗУП 3.1, сохраняя работоспособность программного кода даже после серьезных обновлений конфигурации от фирмы 1С.