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