Разработка и Конфигурация · 11 мин
Как в 1С получить количество рабочих дней
Как в 1С посчитать количество рабочих дней между датами: производственный календарь, графики работы, запросы и функции встроенного языка.
Задача посчитать количество рабочих дней между двумя датами возникает в 1С постоянно: при расчёте отпусков и больничных, планировании сроков доставки, формировании графиков платежей и производственных заданий. Универсальной встроенной функции «количество рабочих дней» во встроенном языке нет — платформа оперирует календарными датами, а понятие рабочего дня определяется прикладной конфигурацией через календари и графики работы.
Поэтому способ решения зависит от того, в какой конфигурации вы работаете и что именно нужно: просто отбросить субботы и воскресенья, учесть праздники по производственному календарю или использовать индивидуальный график сотрудника. Ниже разобраны все основные подходы — от штатных механизмов типовых конфигураций до самостоятельного расчёта запросом и кодом.
Как 1С хранит информацию о рабочих и выходных днях
Платформа «1С:Предприятие» сама по себе не знает, какие дни рабочие. Эти данные хранятся в прикладных объектах конфигурации. В типовых решениях используются справочник «Производственные календари» и связанный с ним регистр сведений, где для каждой даты указан вид дня: рабочий, выходной, праздничный, предпраздничный. В конфигурациях линейки ЗУП и ERP регистр обычно называется «РегламентированныйПроизводственныйКалендарь» или «ДанныеПроизводственногоКалендаря».
Кроме общего календаря, существуют графики работы сотрудников (справочник «ГрафикиРаботыСотрудников» и регистр «ГрафикиРаботыПоВидамВремени»). Они нужны, когда у организации несколько режимов: пятидневка, шестидневка, сменные графики 2/2 и тому подобное. Расчёт по графику даёт более точный результат, чем расчёт по общему календарю.
Перед написанием собственного кода проверьте, какие объекты есть в вашей конфигурации: откройте конфигуратор и найдите в дереве метаданных справочники и регистры со словами «Календарь» и «График». От этого зависит, какой из способов ниже применим.
Способ 1. Штатные функции типовых конфигураций
В конфигурациях на базе БСП (библиотека стандартных подсистем) и в ЗУП уже есть готовые программные интерфейсы. Например, общий модуль «КалендарныеГрафики» предоставляет функции для работы с календарями: получение дат рабочих дней в периоде, разности дат по календарю. В ЗУП аналогичные задачи решают модули «УчетРабочегоВремени» и «КалендарныеГрафики».
Типичный вызов выглядит так: вы передаёте в функцию производственный календарь (или график), дату начала и дату окончания, а получаете таблицу дат с видами дней или сразу количество рабочих дней. Точные имена функций зависят от версии конфигурации, поэтому надёжнее всего найти их поиском по конфигуратору: откройте общие модули и выполните глобальный поиск по слову «Календарь».
Преимущество подхода — корректный учёт праздников и переносов выходных, которые уже заполнены в базе. Недостаток — привязка к конкретной конфигурации: код, написанный для ЗУП, не заработает в самописной конфигурации без доработки.
Способ 2. Запрос к регистру производственного календаря
Самый универсальный программный способ — запрос к регистру сведений, где хранятся виды дней. Идея проста: выбрать записи за период, отфильтровать рабочие дни и посчитать их количество. Такой запрос работает быстро даже на больших интервалах и легко встраивается в отчёты.
Пример запроса к типовому регистру:
ВЫБРАТЬ
КОЛИЧЕСТВО(РегламентированныйПроизводственныйКалендарь.ДатаКалендаря) КАК РабочихДней
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК РегламентированныйПроизводственныйКалендарь
ГДЕ
РегламентированныйПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &НачалоПериода И &КонецПериода
И РегламентированныйПроизводственныйКалендарь.ВидДня = ЗНАЧЕНИЕ(Перечисление.ВидыДнейПроизводственногоКалендаря.Рабочий)
Обратите внимание на детали. Во-первых, предпраздничные дни в типовых конфигурациях — это отдельный вид дня, но они остаются рабочими (сокращёнными на час). Если для вашей задачи важно количество дней, а не часов, включайте в условие и «Предпраздничный» вид. Во-вторых, параметры периода передавайте с учётом границ: конец периода обычно задают как конец дня — КонецДня(ДатаОкончания), иначе последний день может выпасть из выборки.
Если нужен расчёт по нескольким календарям или графикам сразу, добавьте в запрос измерение календаря и группировку по нему — получите количество рабочих дней по каждому графику одним запросом.
Способ 3. Расчёт встроенным языком без календаря
Если в конфигурации нет производственного календаря или требуется грубая оценка без учёта праздников, можно посчитать рабочие дни циклом, проверяя день недели каждой даты. Для этого используется функция ДеньНедели(Дата), которая возвращает число от 1 (понедельник) до 7 (воскресенье).
Функция КоличествоРабочихДней(ДатаНачала, ДатаОкончания)
РабочихДней = 0;
ТекущаяДата = НачалоДня(ДатаНачала);
Пока ТекущаяДата <= ДатаОкончания Цикл
Если ДеньНедели(ТекущаяДата) < 6 Тогда
РабочихДней = РабочихДней + 1;
КонецЕсли;
ТекущаяДата = ТекущаяДата + 86400; // сутки в секундах
КонецЦикла;
Возврат РабочихДней;
КонецФункции
Такой подход прост и не зависит от заполненности справочников, но у него есть принципиальное ограничение: праздничные дни и переносы выходных не учитываются. Для расчёта зарплаты, больничных или юридически значимых сроков этот способ не подходит — используйте его только для прикидочных вычислений, например в планировании.
Способ 4. Расчёт по графику работы сотрудника
Когда у сотрудников разные режимы работы, общий производственный календарь не подходит. В ЗУП и ERP для этого предназначены графики работы: каждому сотруднику назначается свой график, а данные о рабочих днях хранятся в регистрах учёта рабочего времени.
Программно количество рабочих дней сотрудника за период получают запросом к регистру графиков с отбором по конкретному графику, либо через штатные функции модуля учёта рабочего времени. В пользовательском режиме количество рабочих дней по графику видно в отчётах «Табель учёта рабочего времени (Т-13)» и в справочнике графиков — там отображается норма дней и часов за месяц.
Практический сценарий: нужно узнать, сколько рабочих дней у сотрудника в месяце для расчёта среднего заработка. Откройте его график работы, вызовите печать или отчёт по графику за нужный месяц — в итоговой строке будет количество рабочих дней по этому графику с учётом производственного календаря, на котором график основан.
- 1Убедитесь, что производственный календарь заполнен на нужный период (справочник «Производственные календари» → «Заполнить по умолчанию»).
- 2Определите имя регистра сведений с видами дней в вашей конфигурации через конфигуратор.
- 3Напишите запрос с отбором по периоду и виду дня «Рабочий» (при необходимости добавьте «Предпраздничный»).
- 4Передайте границы периода с НачалоДня() и КонецДня(), чтобы не потерять крайние даты.
- 5Выполните запрос и сверьте результат с известным месяцем, например с нормой дней из отчёта по графику.
Как проверить правильность результата
Любой расчёт рабочих дней стоит верифицировать, прежде чем использовать в документах. Самый надёжный эталон — штатный отчёт или печатная форма самой конфигурации: табель учёта рабочего времени, норма времени в графике работы, производственный календарь в пользовательском режиме с итогами по месяцу.
Сверьте результат вашей функции или запроса с этими данными на нескольких периодах: обычный месяц без праздников, месяц с праздниками (например, январь или май), период, содержащий перенесённый выходной. Если цифры совпали во всех трёх случаях — расчёт корректен. Расхождение в праздничном месяце почти всегда означает, что не учтён вид дня «Предпраздничный» или календарь не заполнен.
Как проверить результат
Количество рабочих дней совпадает с нормой в графике работы
Расхождение даже на один день — проверьте границы периода
Праздничные дни исключены из рабочих
Праздники посчитаны рабочими — календарь не заполнен или неверный фильтр по виду дня
Учтены как рабочие (если считаются дни, а не часы)
Предпраздничные дни выпали из расчёта
Типичные ошибки и ограничения
Чаще всего проблемы возникают не из-за кода, а из-за данных и нюансов периодов. Ниже — ошибки, которые встречаются регулярно.
Отдельное ограничение — производительность. Цикл по датам в коде на интервале в несколько лет выполняется медленно и грузит сервер при массовых расчётах. Для обработки больших периодов и пакетных операций всегда предпочтителен запрос к регистру: он выполняется на стороне СУБД и возвращает результат одним обращением.
Что важно запомнить
Количество рабочих дней в 1С определяется данными производственного календаря или графика работы, а не платформой. Оптимальный способ — запрос к регистру сведений с отбором по виду дня; расчёт по дням недели годится только для грубых прикидок. Перед использованием проверьте заполненность календаря и сверьте результат с табелем или нормой времени.
Частые вопросы
Есть ли в 1С готовая функция «количество рабочих дней между датами»?
В платформе такой функции нет. Готовые процедуры существуют в типовых конфигурациях: общие модули «КалендарныеГрафики» (в решениях на базе БСП) и модули учёта рабочего времени в ЗУП. Их точные имена зависят от версии — ищите глобальным поиском по слову «Календарь» в конфигураторе.
Почему запрос к календарю возвращает ноль рабочих дней?
Наиболее вероятная причина — производственный календарь не заполнен на запрошенный период. Откройте справочник «Производственные календари», выберите нужный календарь и выполните заполнение по умолчанию на соответствующий год. Вторая возможная причина — неверно указаны границы периода или отбор по виду дня.
Как учесть переносы выходных дней при расчёте?
Переносы учитываются автоматически, если производственный календарь заполнен корректно: перенесённый рабочий день в нём помечен как рабочий, а день, ставший выходным, — как выходной. При расчёте по дням недели без календаря переносы учесть невозможно.
Чем отличается расчёт по календарю от расчёта по графику сотрудника?
Производственный календарь описывает общероссийскую сетку рабочих и праздничных дней. График работы сотрудника строится на его основе, но отражает конкретный режим: пятидневку, сменный график, неполную неделю. Для кадровых расчётов по конкретному сотруднику всегда используйте его график, а не общий календарь.
Можно ли посчитать рабочие дни в отчёте на СКД без программирования?
Да. В схеме компоновки данных создайте набор данных — запрос к регистру календаря с полями даты и вида дня, затем в ресурсах вычислите количество записей с отбором по рабочим дням. Пользователь сможет задавать период параметрами отчёта без изменения кода.
Как посчитать дату, отстоящую на N рабочих дней от заданной?
Это обратная задача. В типовых конфигурациях для неё есть функции в общих модулях календарных графиков — они возвращают дату по календарю со смещением на заданное число рабочих дней. Вручную задачу решают выборкой рабочих дат из регистра запросом с сортировкой по дате и взятием N-й записи.