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

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

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

Особенности кадровой структуры и определение графика работы

Проанализируем распространенную ошибку: попытку обратиться к реквизитам сотрудника напрямую или связать сотрудника с учетной записью пользователя базы. Пользователь информационной базы — это объект административного доступа, в то время как сотрудник — объект кадрового учета. У большинства линейных сотрудников учетных записей в 1С нет вовсе.

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

Рассмотрим пример запроса для получения актуального графика и ставки сотрудника:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Срез.ГрафикРаботы КАК ГрафикРаботы,
    |	Срез.ЗанимаемыхСтавок КАК ЗанимаемыхСтавок
    |ИЗ
    |	РегистрСведений.РаботникиОрганизаций.СрезПоследних(&Период, Сотрудник = &СсылкаНаСотрудника) КАК Срез";

Запрос.УстановитьПараметр("СсылкаНаСотрудника", СсылкаНаСотрудника);
Запрос.УстановитьПараметр("Период", ДатаФормирования);

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    ГрафикРаботы = Выборка.ГрафикРаботы;
    Ставка = Выборка.ЗанимаемыхСтавок;
КонецЕсли;

Способ 1. Определение продолжительности из регистра «ГрафикиРаботыПоВидамВремени»

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

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


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

ВидыВремени = Новый Массив;
ВидыВремени.Добавить(Справочники.ВидыИспользованияРабочегоВремени.ПоРабочимДням); // Основная явка
// При необходимости добавляются ночные часы:
// ВидыВремени.Добавить(Справочники.ВидыИспользованияРабочегоВремени.НочныеЧасы);

ЗапросВремени.УстановитьПараметр("ГрафикРаботы", ГрафикРаботы);
ЗапросВремени.УстановитьПараметр("ДатаДня", ДатаСмены);
ЗапросВремени.УстановитьПараметр("ВидыВремени", ВидыВремени);

Результат = ЗапросВремени.Выполнить().Выгрузить();
Если Результат.Количество() > 0 Тогда
    ЧасовВДень = Результат[0].ЧасовЗаДень * Ставка;
КонецЕсли;

Способ 2. Расчет нормальной продолжительности для стандартных графиков (пятидневка)

Для печатных форм трудовых договоров чаще требуется не календарная длительность конкретной смены, а базовая норма дня (например, стандартные 8 часов при 40-часовой рабочей неделе). Если брать конкретный день из регистра, можно случайно попасть на сокращенный предпраздничный день или выходной.

Разберем по шагам расчет нормы дня через реквизиты самого графика:

  1. Обратимся к реквизиту ДлительностьРабочейНедели в справочнике ГрафикиРаботы.
  2. Определим тип графика (пятидневка, шестидневка). Для пятидневки делим значение на 5, для шестидневки — вычисляем среднюю норму.
  3. Умножим полученное значение на ЗанимаемыхСтавок.

// Пример для пятидневной рабочей недели
НормаЧасовВНеделю = ГрафикРаботы.ДлительностьРабочейНедели;
Если НормаЧасовВНеделю > 0 Тогда
    ДлительностьДня = (НормаЧасовВНеделю / 5) * Ставка;
КонецЕсли;

Способ 3. Получение данных из справочника «Смены» для сменного графика

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

Выясним причину частой ошибки при расчете времени смены: переходящие через полночь смены. Если смена начинается в 20:00, а заканчивается в 08:00 следующего дня, простое вычитание времени начала из времени окончания вернет отрицательное число.

Разберем корректный алгоритм вычисления длительности интервала смены:


ВремяНачала = Смена.ВремяНачала;
ВремяОкончания = Смена.ВремяОкончания;

// Разница во времени в секундах
РазницаСекунд = ВремяОкончания - ВремяНачала;

Если РазницаСекунд < 0 Тогда
    // Смена переходит через полночь, добавляем сутки (86400 секунд)
    РазницаСекунд = РазницаСекунд + 86400;
КонецЕсли;

ДлительностьСменыВЧасах = РазницаСекунд / 3600;

// Если в смене предусмотрены неоплачиваемые перерывы,
// обходим табличную часть ПериодыСмены и суммируем только рабочие интервалы

Важные практические нюансы

  1. Индивидуальные графики: если на предприятии введен документ Ввод индивидуальных графиков работы организации, плановые данные берутся именно из него, так как индивидуальный график полностью перекрывает общий график сотрудника на расчетный месяц.
  2. Праздничные дни: при выборке часов из регистра на определенный календарный день всегда проверяйте дату на принадлежность к предпраздничным дням, чтобы в печатную форму договора не попали сокращенные часы (например, 7 часов вместо 8).
← На главную