Как в 1С вывести список подразделений, в которых нет сотрудников в декретном отпуске?

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

При работе с кадровой отчетностью в конфигурациях «1С:Зарплата и управление персоналом» часто возникает задача проанализировать подразделения не только по наличию в них определенных сотрудников, но и по их отсутствию. Типичный пример — вывод списка подразделений, где на данный момент никто не находится в декретном отпуске (отпуске по уходу за ребенком). Сложность здесь заключается в том, что стандартные запросы к регистрам сведений выдают только те подразделения, по которым есть движения. Если сотрудников в декрете нет, подразделение просто не попадет в выборку.

В этой статье мы подробно разберем, как правильно составить запрос, чтобы получить полную картину, включая подразделения с нулевым количеством декретников.

Анализ исходной проблемы и выбор стратегии

Рассмотрим ситуацию: если мы будем строить запрос напрямую от регистра РегистрСведений.СостоянияСотрудников или РегистрСведений.КадроваяИсторияСотрудников, мы получим список тех, кто числится в системе. Если в подразделении «Отдел маркетинга» нет ни одного человека в декрете, в этих регистрах просто не будет записей с соответствующим состоянием для этого подразделения.

Для решения этой задачи мы применим классический метод «Левого соединения со справочником». Суть метода заключается в следующем:

  1. Сначала мы соберем список всех сотрудников, которые находятся в декретном отпуске на выбранную дату, и определим их подразделения.
  2. Поместим этот список во временную таблицу.
  3. Выполним основной запрос к справочнику Подразделения (или ПодразделенияОрганизаций), присоединив к нему нашу временную таблицу.
  4. Те подразделения, для которых во временной таблице не нашлось соответствия (значение будет NULL), и есть искомые нами подразделения.

Шаг 1: Получаем список «декретников» во временную таблицу

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

Посмотрим на пример формирования временной таблицы:


ВЫБРАТЬ
    СостоянияСотрудниковСрезПоследних.Сотрудник КАК Сотрудник,
    КадроваяИсторияСотрудниковСрезПоследних.Подразделение КАК Подразделение
ПОМЕСТИТЬ ВТ_СотрудникиВДекрете
ИЗ
    РегистрСведений.СостоянияСотрудников.СрезПоследних(&ДатаОтчета, ) КАК СостоянияСотрудниковСрезПоследних
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&ДатаОтчета, ) КАК КадроваяИсторияСотрудниковСрезПоследних
        ПО СостоянияСотрудниковСрезПоследних.Сотрудник = КадроваяИсторияСотрудниковСрезПоследних.Сотрудник
ГДЕ
    СостоянияСотрудниковСрезПоследних.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияСотрудника.ОтпускПоУходуЗаРебенком)
;

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

Шаг 2: Вывод всех подразделений и поиск отсутствующих

Теперь рассмотрим основную часть запроса. Нам нужно взять все подразделения из справочника и «наложить» на них данные из нашей временной таблицы ВТ_СотрудникиВДекрете.


ВЫБРАТЬ
    Подразделения.Ссылка КАК Подразделение,
    ЕСТЬNULL(ВТ_Декретники.Количество, 0) КАК КоличествоДекретников
ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
        ЛЕВОЕ СОЕДИНЕНИЕ (
            ВЫБРАТЬ
                ВТ.Подразделение КАК Подразделение,
                КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ.Сотрудник) КАК Количество
            ИЗ
                ВТ_СотрудникиВДекрете КАК ВТ
            СГРУППИРОВАТЬ ПО
                ВТ.Подразделение
        ) КАК ВТ_Декретники
        ПО Подразделения.Ссылка = ВТ_Декретники.Подразделение
ГДЕ
    НЕ Подразделения.ЭтоГруппа
    И (Подразделения.Расформировано = ЛОЖЬ ИЛИ Подразделения.Расформировано ЕСТЬ NULL)
    И ВТ_Декретники.Подразделение ЕСТЬ NULL

Разберем подробнее, что происходит в этом запросе:

Шаг 3: Тонкости работы с регистрами состояний

Проанализируем ситуацию с выбором регистров. В современных конфигурациях (например, ЗУП 3.1) существует несколько способов получить состояние сотрудника. Один из наиболее эффективных — использование вспомогательного регистра ДанныеСостоянийСотрудников. В нем информация зачастую представлена в более развернутом и удобном для запросов виде.

Если вы используете РегистрСведений.СостоянияСотрудников.СрезПоследних, обязательно передавайте в параметры метода дату отчета (&Дата). Без этого 1С вернет срез на текущий момент времени (на «сейчас»), что может не соответствовать периоду, за который вы строите отчет.

Вариант с выводом всех подразделений и счетчиком «0»

Иногда пользователю требуется видеть не только пустые подразделения, но и полный список отделов с указанием количества декретников (где-то 5, где-то 0). В таком случае мы просто убираем условие ЕСТЬ NULL и используем функцию ЕСТЬNULL для вывода красивого нуля в отчете.


ВЫБРАТЬ
    Подразделения.Наименование КАК ПодразделениеНаименование,
    ЕСТЬNULL(ВТ_Декретники.Количество, 0) КАК Количество
ИЗ
    Справочник.ПодразделенияОрганизаций КАК Подразделения
        ЛЕВОЕ СОЕДИНЕНИЕ (
            ВЫБРАТЬ
                Подразделение КАК Подразделение,
                КОЛИЧЕСТВО(Сотрудник) КАК Количество
            ИЗ
                ВТ_СотрудникиВДекрете
            СГРУППИРОВАТЬ ПО
                Подразделение
        ) КАК ВТ_Декретники
        ПО Подразделения.Ссылка = ВТ_Декретники.Подразделение
ГДЕ
    Подразделения.ЭтоГруппа = ЛОЖЬ

Важный совет: При работе с подразделениями всегда помните об иерархии. Если вам нужно проверить отсутствие декретников не только в конкретном отделе, но и во всей его «ветке» (включая подотделы), логика запроса усложнится. Потребуется использование оператора В ИЕРАРХИИ или предварительный обход дерева подразделений.

Заключение

Мы выяснили, что для решения задачи вывода «пустых» подразделений нельзя ограничиваться только регистрами сведений. Основным ключом к решению является справочник Подразделений как ведущая таблица запроса. Комбинируя ЛЕВОЕ СОЕДИНЕНИЕ с проверкой на NULL, мы получаем надежный инструмент для поиска любых отсутствующих данных в системе, будь то подразделения без сотрудников в декрете, склады без остатков или клиенты без заказов.

← На главную