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