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