Как программно получить районный коэффициент сотрудника на дату в 1С:ЗУП 3.1

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

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

В этой статье мы подробно разберем, как решить эту задачу правильно. Мы проанализируем «кустарный» метод, к которому пришли разработчики на форумах, выясним его недостатки и рассмотрим наиболее элегантные, быстрые и штатные программные методы, заложенные в библиотеку зарплаты и кадров (БЗК) фирмы 1С.

Анализ проблемы и «самописного» решения

В процессе обсуждения на форуме разработчики столкнулись со сложностью прямой адресации к районному коэффициенту. На первый взгляд кажется, что РК — это просто плановый показатель расчета зарплаты, который можно вытащить срезом последних из соответствующего регистра сведений. Однако при использовании механизма территорий (справочник Территории) РК привязывается к рабочему месту, а не к сотруднику напрямую. В плановых начислениях сотрудника этот показатель может вообще не фигурировать в явном виде.

В итоге участники форума пришли к следующему рабочему, но громоздкому алгоритму (так называемому «колхозному» подходу):

  1. Сначала запросить кадровые данные сотрудника на нужную дату, чтобы узнать его текущую Территорию.
  2. Если территория заполнена, то взять коэффициент напрямую из реквизитов справочника территории и пересчитать его в проценты по формуле: (РайонныйКоэффициент - 1) * 100.
  3. Если территория не заполнена (или не используется), написать прямой запрос к регистру сведений ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.СрезПоследних для получения значения показателя РайонныйКоэффициент.

Посмотрим на код, который был предложен на форуме:


КадровыеДанныеСотрудников = КадровыйУчет.КадровыеДанныеСотрудников(Истина, Сотрудник, "Территория", Дата);
РК = 0;
РассчитыватьРКПоПоказателям = Истина;
Если КадровыеДанныеСотрудников.Количество() > 0 Тогда
    ТерриторияСотрудника = КадровыеДанныеСотрудников[0].Территория;
    Если ТерриторияСотрудника = NULL Тогда
        // Территория не задана
    ИначеЕсли НЕ ТерриторияСотрудника.Пустая() Тогда
        РК = (ТерриторияСотрудника.РайонныйКоэффициент - 1)*100;
        РассчитыватьРКПоПоказателям = Ложь;
    КонецЕсли;    
КонецЕсли;        
Если РассчитыватьРКПоПоказателям Тогда 
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗЛИЧНЫЕ
        |    ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудниковСрезПоследних.Значение КАК Значение
        |ИЗ
        |    РегистрСведений.ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников.СрезПоследних(
        |        &ТекДата,
        |        Сотрудник = &Сотрудник
        |            И Показатель = &Показатель
        |            И (ДействуетДо = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
        |                ИЛИ ДействуетДо > &ТекДата)) КАК ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудниковСрезПоследних";
    
    Запрос.УстановитьПараметр("Сотрудник", Сотрудник);
    Запрос.УстановитьПараметр("Показатель", Справочники.ПоказателиРасчетаЗарплаты.РайонныйКоэффициент);
    Запрос.УстановитьПараметр("ТекДата", КонецДня(Дата));
    
    РезультатЗапросаВыборка = Запрос.Выполнить().Выбрать();
    Если РезультатЗапросаВыборка.Следующий() Тогда
        РК = (РезультатЗапросаВыборка.Значение - 1)*100;
    КонецЕсли;
КонецЕсли;

Почему этот подход неоптимален и опасен:

Давайте разберем, как сделать то же самое штатными методами ЗУП 3.1 гораздо быстрее и надежнее.

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

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

В функцию КадровыйУчет.КадровыеДанныеСотрудников() достаточно передать предопределенные поля:

Проанализируем пример лаконичного и полностью безопасного кода:


// Формируем массив сотрудников (метод принимает коллекцию)
МассивСотрудников = Новый Массив;
МассивСотрудников.Добавить(ВыбранныйСотрудник);

// Запрашиваем готовые кадровые данные напрямую через БСП
КадровыеДанные = КадровыйУчет.КадровыеДанныеСотрудников(Истина, МассивСотрудников, "РайонныйКоэффициент, РайонныйКоэффициентРФ", РабочаяДата);

Если КадровыеДанные.Количество() > 0 Тогда
    ТекущийРК = КадровыеДанные[0].РайонныйКоэффициент;
    ФедеральныйРК = КадровыеДанные[0].РайонныйКоэффициентРФ;
    
    // ТекущийРК вернет готовое числовое значение, например, 1.3
    // Никаких дополнительных запросов писать не нужно!
КонецЕсли;

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

Способ 2. Получение действующих показателей расчета зарплаты

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

Для этого в ЗУП 3.1 существует специализированный модуль ЗарплатаКадрыРасширенный. Мы можем использовать метод получения показателей действующих начислений:


МассивСотрудников = Новый Массив;
МассивСотрудников.Добавить(ВыбранныйСотрудник);

// Получаем таблицу действующих показателей для сотрудников на дату
ТаблицаПоказателей = ЗарплатаКадрыРасширенный.ЗначенияПоказателейДействующихНачисленийСотрудников(МассивСотрудников, РабочаяДата);

// Найдем в таблице показатель районного коэффициента
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Показатель", Справочники.ПоказателиРасчетаЗарплаты.РайонныйКоэффициент);

СтрокиПоказателя = ТаблицаПоказателей.НайтиСтроки(ПараметрыОтбора);
Если СтрокиПоказателя.Количество() > 0 Тогда
    РКПоказатель = СтрокиПоказателя[0].Значение; // Получаем значение показателя из плановых начислений
КонецЕсли;

Этот способ незаменим, если вы анализируете плановый ФОТ сотрудников или хотите проверить, зафиксирован ли данный показатель в их трудовых договорах и кадровых приказах.

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

Что делать, если вам нужно получить районный коэффициент не для одного сотрудника в кодовой процедуре, а для целого списка в сложном запросе (например, при компоновке данных для отчета)? Писать прямые соединения с регистрами сведений по-прежнему не рекомендуется.

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


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

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

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

КадровыйУчет.СоздатьНаДатуВТКадровыеДанныеСотрудников(Запрос.МенеджерВременныхТаблиц, Истина, ОписательВременнойТаблицы);

// Шаг 3. Теперь мы можем спокойно соединять готовую ВТ_КадровыеДанныеСотрудников в своем запросе
Запрос.Текст = 
    "ВЫБРАТЬ
    |    КадровыеДанные.Сотрудник КАК Сотрудник,
    |    КадровыеДанные.РайонныйКоэффициент КАК РайонныйКоэффициент,
    |    КадровыеДанные.РайонныйКоэффициентРФ КАК РайонныйКоэффициентРФ
    |ИЗ
    |    ВТ_КадровыеДанныеСотрудников КАК КадровыеДанные";

Результат = Запрос.Выполнить().Выгрузить();

Почему это важно: Метод КадровыйУчет.СоздатьНаДатуВТКадровыеДанныеСотрудников самостоятельно сформирует наиболее производительный и оптимизированный SQL-запрос с учетом индексации таблиц. Это исключит зависания базы данных при работе с большими объемами информации.

Резюме и рекомендации

Подведем итоги анализа способов получения районного коэффициента в 1С:ЗУП 3.1:

  1. Для решения большинства повседневных задач разработки используйте метод КадровыйУчет.КадровыеДанныеСотрудников() с передачей поля "РайонныйКоэффициент". Это самый быстрый и безотказный вариант.
  2. Если вы пишете сложный отчет или обработку с пакетными запросами к базе данных, используйте построение временных таблиц через КадровыйУчет.СоздатьНаДатуВТКадровыеДанныеСотрудников(). Это гарантирует максимальное быстродействие вашей программы.
  3. Избегайте прямых запросов к регистру показателей ЗначенияПериодическихПоказателейРасчетаЗарплатыСотрудников, так как они не учитывают динамически меняющиеся территории выполнения работ сотрудников и иерархию наследования коэффициентов в системе.
← На главную