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

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

Зачастую при работе со справочниками в 1С возникает задача отобрать объекты (в нашем случае — Номенклатура), связанные с дочерними элементами в табличной части, которые удовлетворяют сразу нескольким условиям одновременно. Например, нам нужно найти только те медицинские услуги, в спецификациях которых обязательно присутствуют сразу все три выбранных рабочих места. Рассмотрим, как решить эту задачу правильно с помощью языка запросов 1С.

Разбор типичной ошибки в запросе

Начинающие разработчики часто пытаются решить эту задачу через простое условие ГДЕ, перечисляя параметры через И, как это сделал автор вопроса: МестоВыполнения = &РабочееМесто1 И МестоВыполнения = &РабочееМесто2. Почему это не работает? Потому что одна строка табличной части физически не может содержать сразу три разных значения в одном поле МестоВыполнения. Запрос пытается найти одну запись, где значение равно одновременно всем трем параметрам, что математически невозможно.

Решение задачи с использованием группировки и функции ИМЕЮЩИЕ

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

Разберем это по шагам:

  1. Отбираем записи табличной части МестаВыполненияЭтапов, где МестоВыполнения соответствует списку нужных нам мест.
  2. Группируем результат по номенклатуре (или ссылке на спецификацию).
  3. Используем конструкцию ИМЕЮЩИЕ (HAVING), чтобы отсеять те номенклатуры, у которых количество найденных уникальных рабочих мест меньше, чем общее количество условий, заданных пользователем.

Посмотрим на итоговый код запроса:


ВЫБРАТЬ
    СпецификацииМедУслугРабочиеМеста.Ссылка.Номенклатура КАК Номенклатура
ИЗ
    Справочник.СпецификацииМедицинскихУслуг.МестаВыполненияЭтапов КАК СпецификацииМедУслугРабочиеМеста
ГДЕ
    СпецификацииМедУслугРабочиеМеста.Ссылка.Активная = ИСТИНА
    И (СпецификацииМедУслугРабочиеМеста.МестоВыполнения = &РабочееМесто1
       ИЛИ СпецификацииМедУслугРабочиеМеста.МестоВыполнения = &РабочееМесто2
       ИЛИ СпецификацииМедУслугРабочиеМеста.МестоВыполнения = &РабочееМесто3)
СГРУППИРОВАТЬ ПО
    СпецификацииМедУслугРабочиеМеста.Ссылка.Номенклатура
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ СпецификацииМедУслугРабочиеМеста.МестоВыполнения) = &КоличествоРабочихМест

Важные рекомендации по оптимизации

Рассмотрим несколько советов, которые помогут сделать этот запрос более производительным и профессиональным:

Использование конструкции КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...) в связке с ИМЕЮЩИЕ — это классический и наиболее надежный способ решения задач на \"наличие всех элементов множества\" в SQL-подобных языках, к которым относится и язык запросов 1С.

← На главную