Как получить норму рабочих часов за месяц по производственному календарю в 1С:ЗУП 3?

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

При разработке различных отчетов, доработке документов или создании механизмов расчета заработной платы в программе «1С:Зарплата и управление персоналом» (редакция 3) часто возникает необходимость оперативно получить норму рабочего времени за определенный месяц. Как правило, ориентироваться нужно на общегосударственный производственный календарь и стандартную 40-часовую рабочую неделю.

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

Особенности архитектуры хранения данных в 1С:ЗУП 3

Прежде чем переходить к написанию кода, проанализируем структуру метаданных конфигурации. Справочник ПроизводственныеКалендари сам по себе является лишь классификатором. Он хранит только названия календарей (например, «Российская Федерация», региональные календари или календари стран СНГ) и их базовые реквизиты. Непосредственно календарные данные — рабочие, выходные, праздничные и предпраздничные дни — хранятся в подчиненных регистрах сведений.

Для оптимизации расчетов и быстрого извлечения информации разработчики фирмы «1С» предусмотрели два регистра сведений:

  1. РегистрСведений.ДанныеПроизводственногоКалендаря — это подневный регистр. В нем хранится детальная информация по каждому дню каждого календаря (вид дня, перенос выходного и т. д.).
  2. РегистрСведений.ДанныеПроизводственногоКалендаряПомесячно — это агрегированный периодический регистр. В нем для каждого месяца уже рассчитаны и сохранены итоговые показатели: количество рабочих дней, а также норма рабочих часов для 40-часовой, 36-часовой и 24-часовой рабочих недель.

Давайте рассмотрим несколько практических способов получения нормы часов в зависимости от ваших задач.

Способ 1. Оптимальный запрос к помесячному регистру сведений

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

Рассмотрим структуру запроса, который выбирает норму времени для 40-часовой рабочей недели за конкретный месяц:


ВЫБРАТЬ
    КалендарьПомесячно.РабочихЧасовДлительностьНедели40Часов КАК Норма40Часов,
    КалендарьПомесячно.РабочихЧасовДлительностьНедели36Часов КАК Норма36Часов,
    КалендарьПомесячно.РабочихЧасовДлительностьНедели24Часа КАК Норма24Часа,
    КалендарьПомесячно.РабочихДней КАК РабочихДней
ИЗ
    РегистрСведений.ДанныеПроизводственногоКалендаряПомесячно КАК КалендарьПомесячно
ГДЕ
    КалендарьПомесячно.ПроизводственныйКалендарь = &ПроизводственныйКалендарь
    И КалендарьПомесячно.Год = &Год
    И КалендарьПомесячно.Месяц = &Месяц

Разберем параметры этого запроса подробнее:

Пример выполнения данного запроса во фрагменте кода на языке 1С:


Функция ПолучитьНормуЧасовЗаМесяц(ВыбранныйМесяц, ВыбранныйКалендарь) Экспорт

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

КонецФункции

Способ 2. Расчет нормы по подневному регистру за произвольный период

Иногда возникают ситуации, когда стандартный помесячный регистр не подходит. Например, если вам требуется рассчитать норму часов за нестандартный период (скажем, с 15 октября по 14 ноября) или если в вашей конфигурации по какой-то причине помесячный регистр не заполнен.

В этом случае мы можем самостоятельно рассчитать норму, обратившись к подневному регистру РегистрСведений.ДанныеПроизводственногоКалендаря. Логика расчета базируется на классификации дней в соответствии со значением перечисления Перечисления.ВидыДнейПроизводственногоКалендаря:

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


ВЫБРАТЬ
    СУММА(ВЫБОР
        КОГДА ДанныеКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий) 
            ТОГДА 8
        КОГДА ДанныеКалендаря.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Предпраздничный) 
            ТОГДА 7
        ИНАЧЕ 0
    КОНЕЦ) КАК НормаЧасов
ИЗ
    РегистрСведений.ДанныеПроизводственногоКалендаря КАК ДанныеКалендаря
ГДЕ
    ДанныеКалендаря.ПроизводственныйКалендарь = &ПроизводственныйКалендарь
    И ДанныеКалендаря.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания

Этот способ более гибкий, так как позволяет уйти от жесткой привязки к границам календарного месяца и корректно рассчитывает норму даже для интервалов в несколько дней.

Способ 3. Получение данных через программный интерфейс БСП (рекомендуется)

Современные версии 1С:ЗУП 3 построены на базе Библиотеки стандартных подсистем (БСП). Разработчики БСП настоятельно рекомендуют минимизировать количество прямых запросов к системным регистрам и использовать готовые методы общего модуля КалендарныеГрафики. Это гарантирует, что ваш код не сломается при очередном обновлении конфигурации, если фирма «1С» решит изменить структуру или названия регистров.

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


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

// Теперь мы можем программно обойти таблицу и рассчитать норму
НормаЧасов = 0;
Для Каждого СтрокаДня Из ТаблицаДней Цикл
    Если СтрокаДня.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий Тогда
        НормаЧасов = НормаЧасов + 8;
    ИначеЕсли СтрокаДня.ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный  Тогда
        НормаЧасов = НормаЧасов + 7;
    КонецЕсли;
КонецЦикла;

Использование методов БСП делает программный код чистым, понятным и значительно упрощает последующую поддержку и обновление программного продукта.

Важно: учитывайте региональную специфику

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

В этих регионах объявляются дополнительные нерабочие праздничные дни (например, Ураза-Байрам, Курбан-Байрам, День Республики), из-за чего месячная норма часов будет отличаться от общероссийской.

Поэтому золотое правило разработчика в ЗУП 3: никогда не зашивайте в код жесткий поиск календаря по коду «РФ» или «Российская Федерация», если вы разрабатываете тиражное решение. Всегда получайте производственный календарь динамически:

Настройка использования нормы времени в пользовательском режиме

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

Выполним настройку по шагам в пользовательском интерфейсе:

  1. Перейдите в раздел «Настройка» и выберите пункт «Расчет зарплаты».
  2. Найдите блок настроек «Порядок пересчета тарифной ставки сотрудника в стоимость часа (день)».
  3. Установите переключатель в положение «По месячной норме по производственному календарю».

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

← На главную