Как правильно выбрать последнее значение периодического показателя расчета зарплаты в 1С:ЗУП 3.1?

Программист 1С:Зарплата и Управление Персоналом
← На главную

При разработке отчетов в конфигурации 1С:Зарплата и управление персоналом 3.1 программисты часто сталкиваются с необходимостью получить актуальное значение периодического показателя (например, оклада, тарифной ставки или процента надбавки) на определенную дату или для конкретной строки начисления. Регистр сведений ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников имеет свои особенности, которые не позволяют использовать стандартную виртуальную таблицу "СрезПоследних" в обычном понимании. Разберем подробно, почему возникают ошибки при выборке данных и как составить корректный запрос.

Почему не работает простая группировка по периоду?

Рассмотрим типичную ошибку, которую совершают начинающие разработчики. При попытке получить последнюю запись через функцию МАКСИМУМ(Период), в список полей группировки часто включают и само поле Значение. Выясним причину, по которой это приводит к дублированию строк. В языке запросов 1С механизм СГРУППИРОВАТЬ ПО работает таким образом, что система ищет уникальные комбинации всех указанных полей.

Если у сотрудника показатель менялся (например, сначала был 8, а потом стал 11), то строки в базе данных будут иметь разные значения в поле Значение. Когда вы добавляете это поле в группировку, запрос вернет обе строки, так как комбинации "Значение 8 + Дата1" и "Значение 11 + Дата2" являются разными с точки зрения СУБД. Функция МАКСИМУМ просто выберет наибольшую дату для каждой из этих уникальных пар, но не отсеет старое значение.

Классический способ получения актуального значения (Срез последних вручную)

Поскольку мы работаем с физической таблицей регистра, нам необходимо выполнить задачу в два этапа. Проанализируем ситуацию: сначала нам нужно найти момент времени, когда показатель изменился в последний раз, а уже затем узнать, какое именно значение было установлено в этот момент.

Шаг 1: Подготовка временной таблицы с максимальными датами. На этом этапе мы выбираем только ключевые измерения (Сотрудник, Показатель) и находим для них максимальный период. Обратите внимание, что поле Значение здесь использовать нельзя.


ВЫБРАТЬ
    ЗначенияПоказателей.Сотрудник КАК Сотрудник,
    ЗначенияПоказателей.Показатель КАК Показатель,
    МАКСИМУМ(ЗначенияПоказателей.Период) КАК МаксПериод
ПОМЕСТИТЬ ВТ_МаксимальныеДаты
ИЗ
    РегистрСведений.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников КАК ЗначенияПоказателей
ГДЕ
    ЗначенияПоказателей.Период <= &ПериодРегистрации
СГРУППИРОВАТЬ ПО
    ЗначенияПоказателей.Сотрудник,
    ЗначенияПоказателей.Показатель
;

Шаг 2: Получение значений путем соединения. Теперь мы соединяем полученную временную таблицу с исходным регистром, чтобы "подтянуть" значение показателя, соответствующее найденному периоду.


ВЫБРАТЬ
    Т1.Сотрудник,
    Т1.Показатель,
    РегистрЗначения.Значение
ИЗ
    ВТ_МаксимальныеДаты КАК Т1
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников КАК РегистрЗначения
    ПО Т1.Сотрудник = РегистрЗначения.Сотрудник
    И Т1.Показатель = РегистрЗначения.Показатель
    И Т1.МаксПериод = РегистрЗначения.Период

Соединение с регистром расчета (Начислениями)

Сложность задачи возрастает, когда показатели нужно вывести рядом с данными о начислениях. В регистре расчета Начисления период регистрации обычно кратен месяцу, а в регистре показателей Период — это точная дата изменения (например, 15-е число месяца). Соединение "лоб в лоб" по периоду здесь не сработает.

Рассмотрим правильную логику соединения. Для каждой строки начисления нам нужно найти показатель, у которого Период меньше или равен дате начала начисления (ПериодДействияНачало). Посмотрим на пример реализации такого условия в связи таблиц:

Нужно использовать условие связи ПО Начисления.Сотрудник = Показатели.Сотрудник И Показатели.Период <= Начисления.ПериодДействияНачало. Однако такое соединение создаст "множество" строк (все исторические записи показателя до даты начисления). Чтобы оставить одну, в итоговой выборке снова придется использовать МАКСИМУМ(Показатели.Период) и группировать по всем полям начисления.

Использование механизма представлений ЗУП 3.1

В современных конфигурациях на базе 1С:ЗУП 3.1 разработчики фирмы "1С" предусмотрели специальный механизм — виртуальные таблицы представлений. Это наиболее профессиональный и эффективный способ получения данных, так как он автоматически учитывает приоритеты документов, исправления и корректные срезы данных.

В тексте запроса используются специальные конструкции, которые программно заменяются на сложные оптимизированные запросы. Рассмотрим пример использования такого подхода для получения плановых начислений и показателей:


// В тексте запроса СКД или обработки пишем заглушку:
ВЫБРАТЬ
    Представления.Сотрудник,
    Представления.Показатель,
    Представления.Значение
ПОМЕСТИТЬ ВТ_ДанныеПоказателей
ИЗ
    Представления_ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников КАК Представления
ГДЕ
    "ТолькоРазрешенные" = ИСТИНА

Чтобы этот код заработал, перед выполнением запроса в коде на языке 1С необходимо вызвать специальную процедуру:


ТекстЗапроса = СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Запрос;
ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц(ТекстЗапроса);

Этот метод позволяет избежать написания громоздких конструкций со вложенными запросами и гарантирует, что вы получите именно те цифры, которые пользователь видит в экранных формах документов "Изменение оплаты труда" или "Назначение планового начисления".

Важные нюансы с полем "ДействуетДо"

Проанализируем ситуацию с полем ДействуетДо. В рассматриваемом регистре пустое значение этой даты (01.01.0001) означает, что показатель установлен бессрочно. Если же в поле стоит конкретная дата, значит, после этого момента показатель перестает действовать (если не было новых записей). При ручном написании запросов важно учитывать:

  1. Если вы ищете текущее значение, нужно фильтровать записи, где ДействуетДо либо пустое, либо больше текущей даты.
  2. Если показатель менялся несколько раз внутри одного месяца, ориентироваться нужно не только на дату, но и на поле Регистратор (или МоментВремени), чтобы корректно определить последовательность изменений.

Подводя итог, можно сказать: для простых отчетов используйте метод с временной таблицей МАКСИМУМ(Период), исключая значение из группировки. Для сложных архитектурных решений в рамках ЗУП 3.1 всегда отдавайте предпочтение механизму Представления_..., так как он минимизирует риск возникновения ошибок при расчете сложных схем начислений.

← На главную