Как программно получить норму рабочего времени для сотрудника в 1С:ЗУП 3.1

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

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

Понимание структуры хранения данных о времени

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

  1. Графика работы сотрудника (основного или индивидуального).
  2. Производственного календаря (учитывающего праздники и переносы).
  3. Настроек самого графика (может ли норма рассчитываться по другому графику, например, при неполном рабочем времени).

Основным источником данных для запросов является регистр сведений ГрафикиРаботыПоВидамВремени или более современный и производительный регистр ДанныеГрафиковРаботы. Рассмотрим подробнее способы получения данных.

Способ 1: Использование программного интерфейса (Общие модули)

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

Рассмотрим пример использования метода СоздатьВТВремяПоГрафикамСотрудников. Важно понимать, что этот метод не возвращает таблицу значений напрямую, а наполняет менеджер временных таблиц, к которому затем нужно обратиться запросом.


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

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

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

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

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

Обратите внимание: если вы просто передадите таблицу в функцию, данные в ней не появятся (они будут равны нулю, как заметил автор вопроса на форуме). Данные нужно забирать именно из временной таблицы ВТВремяПоГрафикамСотрудников через запрос.

Способ 2: Прямой запрос к регистрам (для простых случаев)

Если нам нужно получить норму не для конкретного сотрудника (с учетом его перемещений), а просто по известному графику работы, мы можем обратиться к регистру ГрафикиРаботыПоВидамВремени. Это полезно, когда мы точно знаем, какой график использовать.

Разберем пример функции, возвращающей количество плановых часов по графику:


Функция ПолучитьНормуЧасовПоГрафику(График, НачДата, КонДата) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	СУММА(Графики.ДополнительноеЗначение) КАК НормаЧасов
        |ИЗ
        |	РегистрСведений.ГрафикиРаботыПоВидамВремени КАК Графики
        |ГДЕ
        |	Графики.ГрафикРаботы = &График
        |	И Графики.Дата МЕЖДУ &НачДата И &КонДата
        |	И Графики.ВидУчетаВремени = ЗНАЧЕНИЕ(Справочник.ВидыИспользованияРабочегоВремени.РабочееВремя)";
    
    Запрос.УстановитьПараметр("График", График);
    Запрос.УстановитьПараметр("НачДата", НачДата);
    Запрос.УстановитьПараметр("КонДата", КонДата);
    
    Результат = Запрос.Выполнить();
    Если Не Результат.Пустой() Тогда
        Выборка = Результат.Выбрать();
        Выборка.Следующий();
        Возврат Выборка.НормаЧасов;
    КонецЕсли;
    
    Возврат 0;
КонецФункции

Важный нюанс: Как справедливо отмечено в обсуждении, "Количество плановых часов" и "Норма" — это методологически разные вещи. У сотрудника может быть график неполного рабочего времени, где "Явка" составляет 4 часа, но при этом "Норма" для расчета оклада должна составлять 8 часов (согласно графику полной ставки). В таком случае в запросе нужно соединяться с полем ГрафикПолногоРабочегоВремени из справочника ГрафикиРаботыСотрудников.

Способ 3: Анализ плановых начислений (через регистр расчета)

Если необходимо получить норму так, как ее видит документ Начисление зарплаты, можно проанализировать запрос, используемый в типовых отчетах (например, "Анализ плановых начислений"). В ЗУП 3.1 норма часто определяется по данным регистра расчета Начисления.

Проанализируем ключевой фрагмент логики:

  1. Система ищет вид расчета, у которого установлен признак ТребуетсяРасчетНормыВремени.
  2. Определяется рабочий график. Если у графика заполнен ГрафикПолногоРабочегоВремени, то для нормы используется именно он.
  3. Данные суммируются из регистра ГрафикиРаботыПоВидамВремени с фильтром по виду учета времени Рабочее время.

Рекомендации по реализации в документе "Разовое начисление"

Автор темы столкнулся с проблемой при программном заполнении Разового начисления. Если в вашей формуле используются показатели НормаДней или НормаЧасов, помните следующее:

Выясним причину возможных ошибок: если функции возвращают 0, проверьте, заполнены ли графики работы на текущий год (записи в регистре ДанныеГрафиковРаботы). Без заполнения графиков (кнопка "Заполнить" в интерфейсе или регламентное задание) никакие программные методы норму не вернут.

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

← На главную