К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как в 1С получить количество рабочих дней

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

Задача посчитать количество рабочих дней между двумя датами возникает в 1С постоянно: при расчёте отпусков и больничных, планировании сроков доставки, формировании графиков платежей и производственных заданий. Универсальной встроенной функции «количество рабочих дней» во встроенном языке нет — платформа оперирует календарными датами, а понятие рабочего дня определяется прикладной конфигурацией через календари и графики работы.

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

Как 1С хранит информацию о рабочих и выходных днях

Платформа «1С:Предприятие» сама по себе не знает, какие дни рабочие. Эти данные хранятся в прикладных объектах конфигурации. В типовых решениях используются справочник «Производственные календари» и связанный с ним регистр сведений, где для каждой даты указан вид дня: рабочий, выходной, праздничный, предпраздничный. В конфигурациях линейки ЗУП и ERP регистр обычно называется «РегламентированныйПроизводственныйКалендарь» или «ДанныеПроизводственногоКалендаря».

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

Перед написанием собственного кода проверьте, какие объекты есть в вашей конфигурации: откройте конфигуратор и найдите в дереве метаданных справочники и регистры со словами «Календарь» и «График». От этого зависит, какой из способов ниже применим.

Способ 1. Штатные функции типовых конфигураций

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

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

Преимущество подхода — корректный учёт праздников и переносов выходных, которые уже заполнены в базе. Недостаток — привязка к конкретной конфигурации: код, написанный для ЗУП, не заработает в самописной конфигурации без доработки.

Способ 2. Запрос к регистру производственного календаря

Самый универсальный программный способ — запрос к регистру сведений, где хранятся виды дней. Идея проста: выбрать записи за период, отфильтровать рабочие дни и посчитать их количество. Такой запрос работает быстро даже на больших интервалах и легко встраивается в отчёты.

Пример запроса к типовому регистру:

ВЫБРАТЬ

КОЛИЧЕСТВО(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) КАК РабочихДней

ИЗ

РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь

ГДЕ

РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода

И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)

Обратите внимание на детали. Во-первых, предпраздничные дни в типовых конфигурациях — это отдельный вид дня, но они остаются рабочими (сокращёнными на час). Если для вашей задачи важно количество дней, а не часов, включайте в условие и «Предпраздничный» вид. Во-вторых, параметры периода передавайте с учётом границ: конец периода обычно задают как конец дня — КонецДня(ДатаОкончания), иначе последний день может выпасть из выборки.

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

Способ 3. Расчёт встроенным языком без календаря

Если в конфигурации нет производственного календаря или требуется грубая оценка без учёта праздников, можно посчитать рабочие дни циклом, проверяя день недели каждой даты. Для этого используется функция ДеньНедели(Дата), которая возвращает число от 1 (понедельник) до 7 (воскресенье).

Функция КоличествоРабочихДней(ДатаНачала, ДатаОкончания)

РабочихДней = 0;

ТекущаяДата = НачалоДня(ДатаНачала);

Пока ТекущаяДата <= ДатаОкончания Цикл

Если ДеньНедели(ТекущаяДата) < 6 Тогда

РабочихДней = РабочихДней + 1;

КонецЕсли;

ТекущаяДата = ТекущаяДата + 86400; // сутки в секундах

КонецЦикла;

Возврат РабочихДней;

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

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

Способ 4. Расчёт по графику работы сотрудника

Когда у сотрудников разные режимы работы, общий производственный календарь не подходит. В ЗУП и ERP для этого предназначены графики работы: каждому сотруднику назначается свой график, а данные о рабочих днях хранятся в регистрах учёта рабочего времени.

Программно количество рабочих дней сотрудника за период получают запросом к регистру графиков с отбором по конкретному графику, либо через штатные функции модуля учёта рабочего времени. В пользовательском режиме количество рабочих дней по графику видно в отчётах «Табель учёта рабочего времени (Т-13)» и в справочнике графиков — там отображается норма дней и часов за месяц.

Практический сценарий: нужно узнать, сколько рабочих дней у сотрудника в месяце для расчёта среднего заработка. Откройте его график работы, вызовите печать или отчёт по графику за нужный месяц — в итоговой строке будет количество рабочих дней по этому графику с учётом производственного календаря, на котором график основан.

Порядок действий для расчёта запросом
  1. 1
    Убедитесь, что производственный календарь заполнен на нужный период (справочник «Производственные календари» → «Заполнить по умолчанию»).
  2. 2
    Определите имя регистра сведений с видами дней в вашей конфигурации через конфигуратор.
  3. 3
    Напишите запрос с отбором по периоду и виду дня «Рабочий» (при необходимости добавьте «Предпраздничный»).
  4. 4
    Передайте границы периода с НачалоДня() и КонецДня(), чтобы не потерять крайние даты.
  5. 5
    Выполните запрос и сверьте результат с известным месяцем, например с нормой дней из отчёта по графику.

Как проверить правильность результата

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

Сверьте результат вашей функции или запроса с этими данными на нескольких периодах: обычный месяц без праздников, месяц с праздниками (например, январь или май), период, содержащий перенесённый выходной. Если цифры совпали во всех трёх случаях — расчёт корректен. Расхождение в праздничном месяце почти всегда означает, что не учтён вид дня «Предпраздничный» или календарь не заполнен.

Контрольные точки

Как проверить результат

Месяц без праздников
Норма

Количество рабочих дней совпадает с нормой в графике работы

Тревожный признак

Расхождение даже на один день — проверьте границы периода

Месяц с праздниками (январь, май)
Норма

Праздничные дни исключены из рабочих

Тревожный признак

Праздники посчитаны рабочими — календарь не заполнен или неверный фильтр по виду дня

Предпраздничные дни
Норма

Учтены как рабочие (если считаются дни, а не часы)

Тревожный признак

Предпраздничные дни выпали из расчёта

Типичные ошибки и ограничения

Чаще всего проблемы возникают не из-за кода, а из-за данных и нюансов периодов. Ниже — ошибки, которые встречаются регулярно.

Типичные ошибки
01
Расчёт по незаполненному календарю: на новый год календарь не заполнили, и запрос возвращает ноль или заниженное число. Решение — заполнить календарь по умолчанию и добавить в код проверку наличия данных за период.
02
Потеря последнего дня периода: дата окончания передана как начало дня, и условие «меньше или равно» её не захватывает. Используйте КонецДня() для правой границы.
03
Игнорирование вида дня «Предпраздничный»: дни перед праздниками ошибочно исключаются из рабочих, хотя по ТК они рабочие.
04
Прибавление суток как 86400 секунд без учёта перехода на другое время суток — в российских реалиях безопасно, но надёжнее использовать функции работы с датами конфигурации.
05
Использование общего календаря вместо графика сотрудника при сменных режимах работы — результат не совпадает с табелем.

Отдельное ограничение — производительность. Цикл по датам в коде на интервале в несколько лет выполняется медленно и грузит сервер при массовых расчётах. Для обработки больших периодов и пакетных операций всегда предпочтителен запрос к регистру: он выполняется на стороне СУБД и возвращает результат одним обращением.

Итог

Что важно запомнить

Количество рабочих дней в 1С определяется данными производственного календаря или графика работы, а не платформой. Оптимальный способ — запрос к регистру сведений с отбором по виду дня; расчёт по дням недели годится только для грубых прикидок. Перед использованием проверьте заполненность календаря и сверьте результат с табелем или нормой времени.

Частые вопросы

Есть ли в 1С готовая функция «количество рабочих дней между датами»?

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

Почему запрос к календарю возвращает ноль рабочих дней?

Наиболее вероятная причина — производственный календарь не заполнен на запрошенный период. Откройте справочник «Производственные календари», выберите нужный календарь и выполните заполнение по умолчанию на соответствующий год. Вторая возможная причина — неверно указаны границы периода или отбор по виду дня.

Как учесть переносы выходных дней при расчёте?

Переносы учитываются автоматически, если производственный календарь заполнен корректно: перенесённый рабочий день в нём помечен как рабочий, а день, ставший выходным, — как выходной. При расчёте по дням недели без календаря переносы учесть невозможно.

Чем отличается расчёт по календарю от расчёта по графику сотрудника?

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

Можно ли посчитать рабочие дни в отчёте на СКД без программирования?

Да. В схеме компоновки данных создайте набор данных — запрос к регистру календаря с полями даты и вида дня, затем в ресурсах вычислите количество записей с отбором по рабочим дням. Пользователь сможет задавать период параметрами отчёта без изменения кода.

Как посчитать дату, отстоящую на N рабочих дней от заданной?

Это обратная задача. В типовых конфигурациях для неё есть функции в общих модулях календарных графиков — они возвращают дату по календарю со смещением на заданное число рабочих дней. Вручную задачу решают выборкой рабочих дат из регистра запросом с сортировкой по дате и взятием N-й записи.