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