Как в ЗУП 3.1 получить предыдущий и новый оклад сотрудника при кадровом переводе

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

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

В ЗУП 3.1 больше нет прямых срезов последних по регистрам сведений прежнего формата, а сами кадровые и плановые данные строятся на интервальных регистрах и периодических показателях расчета зарплаты. Проанализируем, почему прямые запросы к регистрам в ЗУП 3.1 считаются нежелательными, и рассмотрим надежные способы получения данных об изменении оклада.

Почему не рекомендуется писать прямые запросы к регистрам в ЗУП 3.1

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

Если написать прямой запрос к таблице РегистрСведений.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников или РегистрСведений.ПлановыйФОТ, высока вероятность того, что очередное обновление конфигурации нарушит работу алгоритма. Фирма «1С» рекомендует использовать штатные программные механизмы — общие модули КадровыйУчет и ЗарплатаКадрыПериодическиеРегистры, которые гарантируют корректную выборку данных независимо от внутренней структуры интервальных таблиц.

Способ 1. Получение данных через типовой программный интерфейс модуля КадровыйУчет

Наиболее универсальный и безопасный способ получения кадровых сведений на определенный момент времени — функция КадровыйУчет.КадровыеДанныеСотрудников. Разберем по шагам, как получить оклад сотрудника до даты кадрового перевода.

Важно помнить, что в ЗУП 3.1 показатель оплаты труда сотрудника может называться не только окладом (например, «Оплата по часовому тарифу», «Оплата по окладу (по часам)»). Поэтому типовой интерфейс возвращает унифицированное поле ТарифнаяСтавка, а не слово «Оклад».

Посмотрим на пример кода, позволяющего получить старый оклад на дату, предшествующую переводу:


// Определяем дату, на которую оклад еще не изменился
// Периодичность кадровых событий в ЗУП 3.1 посуточная, 
// поэтому берем предыдущий день до даты перевода:
ДатаДоПеревода = КонецДня(ДокументСсылка.ДатаНачала - 86400);

// Формируем список требуемых кадровых полей
Поля = Новый Массив;
Поля.Добавить("ТарифнаяСтавка");
Поля.Добавить("КоличествоСтавок");
Поля.Добавить("ВидТарифнойСтавки");

// Сотрудник может быть передан как единичная ссылка или массив
ТаблицаДанныхДоПеревода = КадровыйУчет.КадровыеДанныеСотрудников(
    Истина, 
    ДокументСсылка.Сотрудник, 
    Поля, 
    ДатаДоПеревода
);

СтарыйОклад = 0;
Если ТаблицаДанныхДоПеревода.Количество() > 0 Тогда
    СтрокаДанных = ТаблицаДанныхДоПеревода[0];
    СтарыйОклад = СтрокаДанных.ТарифнаяСтавка;
    
    // Если в печатной форме оклад должен отображаться с учетом неполной ставки:
    Если ЗначениеЗаполнено(СтрокаДанных.КоличествоСтавок) И СтрокаДанных.КоличествоСтавок <> 1 Тогда
        СтарыйОкладСУчетомСтавки = СтарыйОклад * СтрокаДанных.КоличествоСтавок;
    КонецЕсли;
КонецЕсли;

Способ 2. Получение среза через временные таблицы и ЗарплатаКадрыПериодическиеРегистры

Если необходимо включить расчет в сложный пакетный запрос внутри отчета или макета печати, можно воспользоваться штатным генератором временных таблиц ЗарплатаКадрыПериодическиеРегистры. Этот механизм самостоятельно формирует корректный срез с учетом всех служебных интервалов конфигурации.

Рассмотрим, как с его помощью получить значение показателя расчета зарплаты на нужную дату:


Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;

// 1. Создаем таблицу с датой актуальности и списком сотрудников
Запрос.УстановитьПараметр("ДатаАктуальности", КонецДня(ДокументСсылка.ДатаНачала - 86400));
Запрос.УстановитьПараметр("Сотрудник", ДокументСсылка.Сотрудник);

Запрос.Текст =
"ВЫБРАТЬ
|   &ДатаАктуальности КАК Период,
|   &Сотрудник КАК Сотрудник
|ПОМЕСТИТЬ ВТСотрудники";
Запрос.Выполнить();

// 2. Вызываем процедуру формирования временной таблицы среза последних
ЗарплатаКадрыПериодическиеРегистры.СоздатьВТИмяРегистраСрезПоследних(
    "ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников",
    Запрос.МенеджерВременныхТаблиц,
    Истина,
    ЗарплатаКадрыПериодическиеРегистры.ОписаниеФильтраДляСоздатьВТИмяРегистра("ВТСотрудники"),
    ЗарплатаКадрыПериодическиеРегистры.ПараметрыПостроенияДляСоздатьВТИмяРегистраСрез(),
    "ВТПоказателиНаПериод"
);

// 3. Выбираем значение нужного показателя из сформированной ВТ
Запрос.Текст =
"ВЫБРАТЬ
|   ВТ.Сотрудник КАК Сотрудник,
|   ВТ.Показатель КАК Показатель,
|   ВТ.Значение КАК ЗначениеОклада
|ИЗ
|   ВТПоказателиНаПериод КАК ВТ
|ГДЕ
|   ВТ.Показатель = ЗНАЧЕНИЕ(Справочник.ПоказателиРасчетаЗарплаты.Оклад)";

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    СтарыйОклад = Выборка.ЗначениеОклада;
КонецЕсли;

Как правильно получить новый оклад из документа перевода

Определение нового оклада зависит от того, в какой момент формируется печатная форма — до или после проведения документа.

  1. Документ не проведен: движений в регистрах еще нет. Читать регистры срезом на дату документа бессмысленно, данные необходимо извлекать непосредственно из самого документа.
  2. Флаг изменения начислений: в документе КадровыйПеревод присутствует реквизит ИзменитьНачисления. Если этот флаг снят, условия оплаты не менялись, и новый оклад сотрудника полностью равен старому.
  3. Чтение табличной части: если флаг установлен, размер нового оклада следует искать в табличной части Начисления документа, сопоставляя строку с показателями расчета зарплаты или основным начислением.

Разберем универсальный алгоритм вычисления нового оклада из данных документа:


НовыйОклад = СтарыйОклад; // По умолчанию оклад не меняется

// Проверяем, изменялась ли оплата труда в данном документе
Если ДокументОбъект.ИзменитьНачисления Тогда
    
    // Ищем начисление, относящееся к окладу
    Для Каждого СтрНачисление Из ДокументОбъект.Начисления Цикл
        // Проверяем признак отмены начисления
        Если СтрНачисление.Действие = Перечисления.ДействияСНачислениямиИУдержаниями.Отменить Тогда
            Продолжить;
        КонецЕсли;
        
        // Значение оклада в документе может храниться в реквизите Размер 
        // Либо определяться по ведущему показателю начисления
        Если СтрНачисление.Размер > 0 Тогда
            НовыйОклад = СтрНачисление.Размер;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
КонецЕсли;

Таким образом, сочетание штатного вызова КадровыйУчет.КадровыеДанныеСотрудников на дату накануне кадрового события и анализа реквизитов табличной части текущего документа позволяет получить корректные сведения о старом и новом окладе, сохранив полную устойчивость доработки к будущим обновлениям ЗУП 3.1.

← На главную