Как определить количество дней в году, если год задан числом в запросе или СКД?

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

При разработке отчетов и доработке зарплатных алгоритмов в 1С часто возникает задача расчета показателей за календарный год. Нередко в табличных частях документов (например, при расчете среднего заработка) или параметрах год хранится в виде обычного числа (например, 2023 или 2024), а не даты.

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

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

Прежде чем перейти к рабочим решениям, проанализируем частые ошибки и синтаксические ограничения платформы:

  1. Литерал ДАТАВРЕМЯ не принимает поля и параметры. Конструкция вида ДАТАВРЕМЯ(Год, 12, 31) не скомпилируется, так как ключевое слово ДАТАВРЕМЯ в запросе является литералом константы и принимает исключительно фиксированные целые числа, записанные вручную в тексте запроса.
  2. Отсутствие оператора остатка от деления (%) в запросах. В отличие от классического SQL, в языке запросов 1С нет встроенной операции нахождения остатка от деления через знак процента %.
  3. Отсутствие конструктора ДАТА() в запросе. Функция создания даты по отдельным составляющим Дата(Год, Месяц, День) существует исключительно во встроенном языке BSL. В языке запросов и стандартных выражениях схемы компоновки данных такой функции нет.

Способ 1. Смещение опорной даты через функцию ДОБАВИТЬКДАТЕ

Рассмотрим элегантный способ получить дату последнего дня нужного года средствами чистого языка запросов. Для этого мы берем заранее известную дату-константу и сдвигаем ее на требуемое число лет с помощью функции ДОБАВИТЬКДАТЕ, после чего получаем номер дня с помощью ДЕНЬГОДА.

В качестве опорной точки лучше всего использовать начало современного летоисчисления (например, 2000 год), чтобы избежать ошибок переполнения дат в СУБД (например, в Microsoft SQL Server при старом формате хранения дат значения до 1753 года недопустимы):


ВЫБРАТЬ
    ДЕНЬГОДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(2000, 12, 31, 0, 0, 0), ГОД, Таблица.РасчетныйГод - 2000)) КАК ДнейВГоду
ИЗ
    Документ.БольничныйЛист.Начисления КАК Таблица

Разберем логику работы этого выражения:

  1. Мы берем литерал последнего дня опорного года: 31.12.2000.
  2. Прибавляем к нему разницу в годах между целевым годом и базовым: Таблица.РасчетныйГод - 2000. В результате получаем дату 31.12.ЦелевойГод.
  3. Функция ДЕНЬГОДА возвращает порядковый номер этого дня с начала года, что в последний день года точно равно общему числу дней (365 или 366).

Способ 2. Проверка кратности через оператор ВЫРАЗИТЬ (для диапазона 1901–2099 годов)

Посмотрим на математический подход. Год является високосным, если он делится на 4 без остатка (с учетом того, что в диапазоне с 1901 по 2099 год вековой 2000 год также был високосным). Чтобы проверить делимость нацело без оператора %, сравним результат обычного деления с результатом целочисленного приведения через ВЫРАЗИТЬ:


ВЫБРАТЬ
    ВЫБОР
        КОГДА Таблица.РасчетныйГод / 4 = ВЫРАЗИТЬ(Таблица.РасчетныйГод / 4 КАК ЧИСЛО(15, 0))
            ТОГДА 366
        ИНАЧЕ 365
    КОНЕЦ КАК ДнейВГоду
ИЗ
    Документ.БольничныйЛист.Начисления КАК Таблица

Если год делится на 4 нацело, то дробная часть равна нулю, и равенство выполняется. Если год невисокосный (например, 2023 / 4 = 505.75), то после приведения к целому значению произойдет округление, равенство будет нарушено, и запрос вернет 365 дней.

Способ 3. Вычисление в выражениях полей СКД

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

Выясним, как составить выражение для вычисляемого поля:


ВЫБОР 
    КОГДА РасчетныйГод / 4 = Окр(РасчетныйГод / 4, 0) ТОГДА 366 
    ИНАЧЕ 365 
КОНЕЦ

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


Функция ПолучитьКоличествоДнейВГоду(ГодЧислом) Экспорт
    Возврат ДеньГода(КонецГода(Дата(ГодЧислом, 1, 1)));
КонецФункции

После этого в выражении поля СКД достаточно написать: ИмяОбщегоМодуля.ПолучитьКоличествоДнейВГоду(РасчетныйГод).

Важное замечание о расчете пособий

Обратите внимание на законодательный контекст: если расчет дней выполняется в рамках начисления стандартных пособий по временной нетрудоспособности (обычный больничный лист), законодательство РФ (255-ФЗ) жестко фиксирует базовый делитель заработка — строго 730 дней за два расчетных года, независимо от високосности. Реальное количество календарных дней (365 или 366) за вычетом исключаемых периодов учитывается только при расчете пособий по беременности и родам, а также по уходу за ребенком.

← На главную