При разработке отчетов и доработке зарплатных алгоритмов в 1С часто возникает задача расчета показателей за календарный год. Нередко в табличных частях документов (например, при расчете среднего заработка) или параметрах год хранится в виде обычного числа (например, 2023 или 2024), а не даты.
Если мы попытаемся применить стандартные функции для работы с датами напрямую к числу, платформа выдаст синтаксическую ошибку. Разберем особенности платформы 1С и несколько надежных способов, как узнать точное количество дней в году (365 или 366).
Прежде чем перейти к рабочим решениям, проанализируем частые ошибки и синтаксические ограничения платформы:
ДАТАВРЕМЯ(Год, 12, 31) не скомпилируется, так как ключевое слово ДАТАВРЕМЯ в запросе является литералом константы и принимает исключительно фиксированные целые числа, записанные вручную в тексте запроса.%.Дата(Год, Месяц, День) существует исключительно во встроенном языке BSL. В языке запросов и стандартных выражениях схемы компоновки данных такой функции нет.Рассмотрим элегантный способ получить дату последнего дня нужного года средствами чистого языка запросов. Для этого мы берем заранее известную дату-константу и сдвигаем ее на требуемое число лет с помощью функции ДОБАВИТЬКДАТЕ, после чего получаем номер дня с помощью ДЕНЬГОДА.
В качестве опорной точки лучше всего использовать начало современного летоисчисления (например, 2000 год), чтобы избежать ошибок переполнения дат в СУБД (например, в Microsoft SQL Server при старом формате хранения дат значения до 1753 года недопустимы):
ВЫБРАТЬ
ДЕНЬГОДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(2000, 12, 31, 0, 0, 0), ГОД, Таблица.РасчетныйГод - 2000)) КАК ДнейВГоду
ИЗ
Документ.БольничныйЛист.Начисления КАК Таблица
Разберем логику работы этого выражения:
31.12.2000.Таблица.РасчетныйГод - 2000. В результате получаем дату 31.12.ЦелевойГод.ДЕНЬГОДА возвращает порядковый номер этого дня с начала года, что в последний день года точно равно общему числу дней (365 или 366).Посмотрим на математический подход. Год является високосным, если он делится на 4 без остатка (с учетом того, что в диапазоне с 1901 по 2099 год вековой 2000 год также был високосным). Чтобы проверить делимость нацело без оператора %, сравним результат обычного деления с результатом целочисленного приведения через ВЫРАЗИТЬ:
ВЫБРАТЬ
ВЫБОР
КОГДА Таблица.РасчетныйГод / 4 = ВЫРАЗИТЬ(Таблица.РасчетныйГод / 4 КАК ЧИСЛО(15, 0))
ТОГДА 366
ИНАЧЕ 365
КОНЕЦ КАК ДнейВГоду
ИЗ
Документ.БольничныйЛист.Начисления КАК Таблица
Если год делится на 4 нацело, то дробная часть равна нулю, и равенство выполняется. Если год невисокосный (например, 2023 / 4 = 505.75), то после приведения к целому значению произойдет округление, равенство будет нарушено, и запрос вернет 365 дней.
Если задача решается непосредственно в схеме компоновки данных на вкладке Вычисляемые поля, нам доступны функции языка выражений СКД, которых нет в обычном запросе, например функция округления Окр().
Выясним, как составить выражение для вычисляемого поля:
ВЫБОР
КОГДА РасчетныйГод / 4 = Окр(РасчетныйГод / 4, 0) ТОГДА 366
ИНАЧЕ 365
КОНЕЦ
Кроме того, в выражениях СКД поддерживается прямой вызов экспортных методов общих модулей конфигурации. Если у вас есть общий модуль с признаком Сервер, можно объявить функцию:
Функция ПолучитьКоличествоДнейВГоду(ГодЧислом) Экспорт
Возврат ДеньГода(КонецГода(Дата(ГодЧислом, 1, 1)));
КонецФункции
После этого в выражении поля СКД достаточно написать: ИмяОбщегоМодуля.ПолучитьКоличествоДнейВГоду(РасчетныйГод).
Обратите внимание на законодательный контекст: если расчет дней выполняется в рамках начисления стандартных пособий по временной нетрудоспособности (обычный больничный лист), законодательство РФ (255-ФЗ) жестко фиксирует базовый делитель заработка — строго 730 дней за два расчетных года, независимо от високосности. Реальное количество календарных дней (365 или 366) за вычетом исключаемых периодов учитывается только при расчете пособий по беременности и родам, а также по уходу за ребенком.