Как составить запрос для поиска сотрудников, у которых день рождения или юбилей в ближайший месяц?

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

При разработке отчетов или систем оповещения в 1С часто возникает задача: выбрать сотрудников, чей день рождения или юбилей наступает в ближайшее время. Эта задача кажется простой, но требует внимательного подхода к работе с датами, так как мы должны игнорировать год рождения, фокусируясь только на дне и месяце.

Разберем задачу поиска дней рождения

Основная сложность заключается в том, что поле ДатаРождения содержит год. Если мы будем сравнивать его напрямую, запрос вернет данные только для тех, кто родился в конкретном году. Для решения этой проблемы мы приведем дату рождения к текущему году.

Рассмотрим вариант запроса, который позволяет найти сотрудников, чей день рождения попадает в интервал 30 дней от текущей даты:


ВЫБРАТЬ
    Сотрудники.Ссылка КАК Ссылка,
    Сотрудники.ДатаРождения КАК ДатаРождения
ИЗ
    Справочник.Сотрудники КАК Сотрудники
ГДЕ
    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&ТекДата, ГОД), ДЕНЬ, 
        РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Сотрудники.ДатаРождения, ГОД), Сотрудники.ДатаРождения, ДЕНЬ)) 
    МЕЖДУ &ТекДата И ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, 30)

В этом примере мы используем функцию РАЗНОСТЬДАТ, чтобы вычислить порядковый номер дня в году для даты рождения, а затем прибавляем это количество дней к НАЧАЛОПЕРИОДА текущего года. Это позволяет нам эффективно «перенести» дату рождения на текущий год и провести корректное сравнение в рамках интервала.

Реализация поиска юбилеев

Юбилей — это особый день рождения, когда человеку исполняется количество лет, кратное 10 (30, 40, 50 и т.д.). Для поиска таких сотрудников мы можем расширить условие запроса, добавив проверку возраста.

Рассмотрим подход, объединяющий поиск по периоду и проверку кратности возраста 10 годам:


ВЫБРАТЬ
    Сотрудники.Ссылка КАК Ссылка,
    Сотрудники.ДатаРождения КАК ДатаРождения
ИЗ
    Справочник.Сотрудники КАК Сотрудники
ГДЕ
    ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&ТекДата, ГОД), ДЕНЬ, 
        РАЗНОСТЬДАТ(НАЧАЛОПЕРИОДА(Сотрудники.ДатаРождения, ГОД), Сотрудники.ДатаРождения, ДЕНЬ)) 
    МЕЖДУ &ТекДата И ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, 30)
    И (ГОД(&ТекДата) - ГОД(Сотрудники.ДатаРождения)) / 10 = 
        (ВЫРАЗИТЬ((ГОД(&ТекДата) - ГОД(Сотрудники.ДатаРождения)) / 10 КАК ЧИСЛО(10, 0)))

Здесь мы используем математическое деление для проверки кратности. Если возраст, деленный на 10, равен целому числу, значит, текущий год для сотрудника является юбилейным.

Рекомендации по улучшению кода

  1. Гибкость настроек: Жесткое кодирование условий «10, 20, 30» в коде запроса считается плохой практикой. Если бизнес захочет включить в список юбилеев 55 лет или иные даты, вам придется менять программный код. Лучше вынести перечень юбилейных возрастов в константы или настройки пользователя.
  2. Производительность: Использование множественных операторов ИЛИ в запросах может замедлить их выполнение на больших объемах данных. Старайтесь вычислять даты начала и окончания периода в коде 1С, а в запрос передавать уже готовые параметры &ДатаНачала и &ДатаОкончания.
  3. Корректность дат: При расчете «ближайших 30 дней» всегда учитывайте переход через конец года. Вычисление параметров в коде 1С (на сервере) до вызова запроса — самый надежный способ избежать ошибок с февралем или високосными годами.

Работая с подобными задачами, всегда анализируйте, насколько архитектура вашего решения устойчива к изменениям требований бизнеса. Помните, что чистота кода и его легкость в поддержке важнее, чем попытка уместить всю логику в один громоздкий запрос.

← На главную