Вопрос расчета стажа в запросах 1С часто ставит разработчиков в тупик из-за разницы в подходах к округлению и учету високосных лет. Обычное деление разности дат в днях на 365 дает погрешность, которая со временем накапливается и приводит к неверным данным в кадровых отчетах. Разберем наиболее эффективные и точные способы решения этой задачи, ориентируясь на логику типовых конфигураций (ЗУП, ERP).
Если нам необходимо получить количество полных лет стажа (например, для определения права на надбавку или категорию), использование РАЗНОСТЬДАТ(..., ГОД) в чистом виде не подходит, так как эта функция считает просто количество пересечений границ календарного года. Рассмотрим правильную формулу, которая учитывает, наступил ли уже «день рождения» стажа в текущем году.
Проанализируем следующую конструкцию в запросе:
ВЫБРАТЬ
ГОД(&ДатаОтчета) - ГОД(&ДатаНачала)
+ ВЫБОР
КОГДА МЕСЯЦ(&ДатаНачала) > МЕСЯЦ(&ДатаОтчета) ТОГДА -1
КОГДА МЕСЯЦ(&ДатаНачала) = МЕСЯЦ(&ДатаОтчета) И ДЕНЬ(&ДатаНачала) > ДЕНЬ(&ДатаОтчета) ТОГДА -1
ИНАЧЕ 0
КОНЕЦ КАК ПолныхЛет
Разберем, как это работает. Мы вычитаем год начала из года отчета, а затем проверяем: если месяц начала больше месяца отчета, значит, полный год еще не прошел, и мы вычитаем единицу. Если месяцы равны, мы проверяем дни. Это классический алгоритм расчета возраста, который идеально подходит для определения стажа в полных годах.
Иногда стаж необходимо представить в виде десятичного числа (например, 25.5 лет) и затем округлить его по определенным правилам. В языке запросов 1С функция ВЫРАЗИТЬ выполняет математическое округление. Однако здесь есть нюанс: если результат 25.5, система может округлить его как до 25, так и до 26 в зависимости от реализации СУБД (часто используется банковское округление к ближайшему четному).
Для того чтобы гарантированно управлять направлением округления, проанализируем следующие приемы:
ВЫРАЗИТЬ(ПолеСтажа + 0.5 КАК ЧИСЛО(15, 0)) - 1 (в зависимости от логики может потребоваться корректировка).ВЫРАЗИТЬ(ПолеСтажа КАК ЧИСЛО(15, 0)).ВЫБОР.В типовых конфигурациях стаж сотрудника часто складывается из двух частей: стаж до приема на работу (введенный вручную) и стаж после приема (исчисляемый автоматически). Данные хранятся в регистре сведений СтажиФизическихЛиц.
Рассмотрим алгоритм получения актуального стажа в запросе:
ДОБАВИТЬКДАТЕ, чтобы вычислить виртуальную «дату начала стажа».&ДатаОтчета и этой виртуальной датой.Пример получения «виртуальной» даты начала в запросе:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(
ДОБАВИТЬКДАТЕ(
ДОБАВИТЬКДАТЕ(Стажи.ДатаОтсчета, ГОД, -Стажи.Лет),
МЕСЯЦ, -Стажи.Месяцев),
ДЕНЬ, -Стажи.Дней) КАК ВиртуальнаяДатаНачала
ИЗ
РегистрСведений.СтажиФизическихЛиц КАК Стажи
Согласно правилам кадрового учета, стаж часто считается по принципу: 30 дней — это месяц, 12 месяцев — это год. При этом важно помнить про правило «+1 день». Если сотрудник принят 1-го числа и уволен 30-го, РАЗНОСТЬДАТ вернет 29 дней, хотя фактически отработан полный месяц. Поэтому к разности дат в днях всегда нужно прибавлять 1.
Выясним причину расхождений с типовыми отчетами. Типовые отчеты в ЗУП часто суммируют все периоды работы в днях, а затем переводят их в годы и месяцы. В запросе это можно реализовать так:
ВЫБРАТЬ
СУММА(РАЗНОСТЬДАТ(Периоды.ДатаНачала, Периоды.ДатаОкончания, ДЕНЬ) + 1) КАК ВсегоДней
ПОМЕСТИТЬ ВТ_ОбщийСтаж
ИЗ
ВТ_ПериодыРаботы КАК Периоды;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ВЫРАЗИТЬ(ВсегоДней / 365.25 - 0.5 КАК ЧИСЛО(10, 0)) КАК ПолныхЛет
ИЗ
ВТ_ОбщийСтаж
Использование коэффициента 365.25 позволяет нивелировать влияние високосных лет при грубом расчете. Однако для юридически точного расчета рекомендуется использовать Метод 1, комбинируя его с проверкой периодов.
При работе со стажем в запросах всегда учитывайте следующие моменты:
ВЫРАЗИТЬ всегда указывайте достаточную разрядность ЧИСЛО(15, 2), если вам нужна дробная часть для дальнейших расчетов.Дата > ДАТАВРЕМЯ(1, 1, 1)), иначе результат РАЗНОСТЬДАТ будет непредсказуемым.Таким образом, для получения результата, максимально близкого к ЗУП, лучше всего использовать комбинацию из получения данных регистра СтажиФизическихЛиц и расчета разности дат с проверкой месяцев и дней (Метод 1). Это исключит ошибки округления и обеспечит корректное попадание сотрудника в нужные интервалы стажа (1-5 лет, 5-10 лет и т.д.).