Как вывести сотрудников, у которых отсутствует документ Договор МОЛ

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

В процессе кадрового учета и контроля материальной ответственности часто возникает задача выявить список сотрудников, с которыми по какой-то причине еще не заключен договор о материальной ответственности (МОЛ). В системе 1С эта задача решается с помощью механизма запросов. Рассмотрим подробно, как правильно составить такой запрос, какие методы существуют и какие нюансы следует учитывать, чтобы отчет был точным и производительным.

Метод 1: Использование левого соединения и проверки на NULL

Это классический и наиболее производительный способ решения задачи. Основная идея заключается в том, чтобы взять полный список сотрудников и попытаться «присоединить» к нему документы. Если документ не найден, в соответствующих полях запроса возникнет значение NULL, которое мы и отфильтруем.

Проанализируем шаги построения такого запроса:

  1. Выбираем основную таблицу — Справочник.Сотрудники.
  2. Присоединяем таблицу документов (например, Документ.СЭ_ДоговорМОЛ_Индивидуальный) по полю Сотрудник.
  3. Указываем тип соединения — ЛЕВОЕ. Это гарантирует, что все записи из справочника сотрудников попадут в результат, даже если для них нет документа.
  4. В условии ГДЕ устанавливаем фильтр по отсутствующей ссылке документа.

Разберем пример кода запроса:


ВЫБРАТЬ
    Сотрудники.Ссылка КАК Сотрудник,
    Сотрудники.Наименование КАК ФИО
ИЗ
    Справочник.Сотрудники КАК Сотрудники
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.СЭ_ДоговорМОЛ_Индивидуальный КАК ДоговорыМОЛ
        ПО Сотрудники.Ссылка = ДоговорыМОЛ.Сотрудник
ГДЕ
    ДоговорыМОЛ.Ссылка ЕСТЬ NULL

Важный технический момент: Обратите внимание на условие ЕСТЬ NULL. В языке запросов 1С использование конструкции = NULL является ошибкой, так как сравнение с неопределенностью (NULL) всегда дает ложь. Чтобы система правильно идентифицировала пустые записи, возникшие в результате левого соединения, необходимо использовать именно оператор ЕСТЬ NULL.

Метод 2: Использование оператора НЕ В с подзапросом

Этот метод считается более интуитивно понятным для начинающих разработчиков. Мы сначала получаем список всех сотрудников, у которых есть документ, а затем исключаем их из общего списка сотрудников предприятия.

Рассмотрим реализацию этого подхода:


ВЫБРАТЬ
    Сотрудники.Ссылка КАК Сотрудник,
    Сотрудники.Наименование КАК ФИО
ИЗ
    Справочник.Сотрудники КАК Сотрудники
ГДЕ
    Сотрудники.Ссылка НЕ В
        (ВЫБРАТЬ
            ДоговорыМОЛ.Сотрудник
        ИЗ
            Документ.СЭ_ДоговорМОЛ_Индивидуальный КАК ДоговорыМОЛ)

Проанализируем ситуацию с точки зрения производительности. Если в справочнике сотрудников десятки тысяч записей, подзапрос с оператором НЕ В может работать медленнее, чем левое соединение, особенно на СУБД PostgreSQL. Однако для небольших баз этот вариант вполне допустим и легко читается.

Определение актуальности сотрудников

Просто выбрать всех сотрудников из справочника Сотрудники часто недостаточно. В справочнике могут храниться архивные записи, уволенные сотрудники или дубли. Чтобы отчет был полезен бизнесу, нам нужно ограничить выборку только «актуальными» работниками.

Выясним, откуда лучше брать список работающих сотрудников:

  1. Регистр сведений «Текущие кадровые данные сотрудников»: Это самый оптимальный источник в современных конфигурациях (ЗУП 3.1, ERP). В нем уже содержатся флаги увольнения.
  2. Срез последних регистра «Кадровая история сотрудников»: Позволяет получить состояние сотрудника на конкретную дату (например, на сегодня).
  3. Флаг «В архиве»: В самом справочнике Сотрудники есть реквизит ВАрхиве. Если мы используем справочник напрямую, обязательно добавляем условие ГДЕ Сотрудники.ВАрхиве = ЛОЖЬ.

Посмотрим на пример запроса с учетом актуальности через проверку архива:


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

Учет состояния документа

Часто в системе могут быть созданы «черновики» документов или документы, помеченные на удаление. Если документ помечен на удаление, мы должны считать, что договора у сотрудника нет. Также может быть важно проверять флаг Проведен.

Разберем, как модифицировать соединение для учета этих условий. Важно накладывать условия на документ внутри параметров соединения или использовать временные таблицы, чтобы не «отрезать» сотрудников без документов в блоке ГДЕ.

Правильный пример с использованием временной таблицы (ВТ):


// Сначала соберем все действующие договоры во временную таблицу
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ДоговорыМОЛ.Сотрудник КАК Сотрудник
ПОМЕСТИТЬ ВТ_ЕстьДоговоры
ИЗ
    Документ.СЭ_ДоговорМОЛ_Индивидуальный КАК ДоговорыМОЛ
ГДЕ
    ДоговорыМОЛ.Проведен = ИСТИНА
;

// Теперь выбираем сотрудников, которых нет в этой таблице
ВЫБРАТЬ
    Сотрудники.Ссылка КАК Сотрудник
ИЗ
    Справочник.Сотрудники КАК Сотрудники
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ЕстьДоговоры КАК ВТ_ЕстьДоговоры
        ПО Сотрудники.Ссылка = ВТ_ЕстьДоговоры.Сотрудник
ГДЕ
    Сотрудники.ВАрхиве = ЛОЖЬ
    И ВТ_ЕстьДоговоры.Сотрудник ЕСТЬ NULL

Работа с коллективными договорами

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

Например: Документ.ДоговорОКоллективнойМатериальнойОтветственности.СоставБригады. Логика поиска (левое соединение или подзапрос) останется прежней, но источником данных о наличии договора станет именно табличная часть.

Реализация через СКД (Система компоновки данных)

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

  1. Создаем Набор данных 1: выбираем всех актуальных сотрудников.
  2. Создаем Набор данных 2: выбираем сотрудников из существующих документов МОЛ.
  3. На вкладке Связи наборов данных связываем их по полю Сотрудник.
  4. В настройках отчета добавляем отбор: Поле_Из_Набора2 Не заполнено.

Этот способ удобен тем, что пользователь сможет самостоятельно добавлять фильтры по подразделениям, должностям или организациям, не меняя текст запроса.

Заключение

Мы проанализировали основные подходы к поиску сотрудников без документов. Наиболее гибким и профессиональным методом является использование временных таблиц и левого соединения с проверкой на ЕСТЬ NULL. Не забывайте всегда проверять статус сотрудника (рабочий или архивный) и статус документа (проведен или помечен на удаление), чтобы предоставлять руководству только достоверные данные.

← На главную