Как запросом 1С вывести список контрагентов, у которых количество договоров составляет от 2 до 3?

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

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

Основа решения: Использование группировки и секции ИМЕЮЩИЕ

Для того чтобы подсчитать количество подчиненных элементов (договоров) для каждого владельца (контрагента), нам необходимо обратиться к таблице справочника ДоговорыКонтрагентов. В языке запросов 1С для решения подобных задач используется агрегатная функция КОЛИЧЕСТВО в сочетании с предложением СГРУППИРОВАТЬ ПО.

Важно понимать различие между секциями ГДЕ и ИМЕЮЩИЕ. Условие ГДЕ фильтрует исходные записи до того, как они будут сгруппированы. Условие ИМЕЮЩИЕ накладывает фильтр уже на результат агрегации (после группировки). Рассмотрим пример кода, который решает поставленную задачу:


ВЫБРАТЬ
    ДоговораКонтрагентов.Владелец КАК Контрагент,
    КОЛИЧЕСТВО(ДоговораКонтрагентов.Ссылка) КАК КолВоДоговоров
ИЗ
    Справочник.ДоговораКонтрагентов КАК ДоговораКонтрагентов
СГРУППИРОВАТЬ ПО
    ДоговораКонтрагентов.Владелец
ИМЕЮЩИЕ
    КОЛИЧЕСТВО(ДоговораКонтрагентов.Ссылка) >= 2
    И КОЛИЧЕСТВО(ДоговораКонтрагентов.Ссылка) <= 3

В данном запросе мы выбираем поле Владелец, группируем по нему все записи и подсчитываем количество ссылок на договоры для каждого владельца. В секции ИМЕЮЩИЕ мы ограничиваем выборку только теми контрагентами, у которых счетчик договоров попал в диапазон от 2 до 3 включительно.

Оптимизация условия с помощью оператора МЕЖДУ

Для повышения читаемости кода и минимизации ошибок при указании границ диапазона, мы рекомендуем использовать оператор МЕЖДУ (в англоязычном варианте BETWEEN). Это делает логику запроса более прозрачной для других разработчиков. Проанализируем измененную секцию условий:


ИМЕЮЩИЕ
    КОЛИЧЕСТВО(ДоговораКонтрагентов.Ссылка) МЕЖДУ 2 И 3

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

Исключение "мусорных" данных: Пометка на удаление

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

Выясним, как правильно отсечь ненужные данные. Для этого добавим условие в секцию ГДЕ, которая выполняется до подсчета количества:


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

Обратите внимание: фильтрация по полю ПометкаУдаления должна происходить именно в секции ГДЕ. Это гарантирует, что агрегатная функция КОЛИЧЕСТВО будет работать только с актуальными записями.

Учет видов договоров и целостности данных

Зачастую бизнес-задача требует учета только определенных типов отношений. В типовых конфигурациях (БП, УТ, ERP) у договора есть реквизит ВидДоговора. Если вам нужно найти контрагентов, имеющих 2-3 договора именно как "Поставщик", необходимо добавить соответствующий фильтр.

Также разберем ситуацию с целостностью данных. В редких случаях в базе могут присутствовать "битые" записи, где ссылка на владельца пустая. Чтобы исключить их из отчета, добавим проверку на пустую ссылку. Итоговый структурированный запрос будет выглядеть так:


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

Использование вложенных запросов для получения детальной информации

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

Рассмотрим более правильный архитектурный подход: использование вложенного запроса или временной таблицы. Сначала мы определим список идентификаторов (ссылок) нужных нам контрагентов, а затем соединим этот список с основной таблицей справочника Контрагенты для получения детальной информации.


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

ВЫБРАТЬ
    Контрагенты.Наименование,
    Контрагенты.ИНН,
    Контрагенты.Телефон
ИЗ
    Справочник.Контрагенты КАК Контрагенты
ГДЕ
    Контрагенты.Ссылка В (ВЫБРАТЬ ВТ_ОтобранныеКонтрагенты.Контрагент ИЗ ВТ_ОтобранныеКонтрагенты)

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

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

Если ваша задача — создать пользовательский отчет, то писать сложный запрос с секцией ИМЕЮЩИЕ вовсе не обязательно. Платформа 1С предоставляет мощный инструмент — СКД.

Проанализируем шаги настройки в СКД:

  1. Создайте набор данных - запрос, который просто выбирает контрагентов и их договоры.
  2. В настройках отчета добавьте группировку по полю Контрагент.
  3. Перейдите на вкладку "Отбор" для этой группировки.
  4. Добавьте новое условие: выберите поле Количество(Договор), вид сравнения "В диапазоне" (или "Больше или равно" и "Меньше или равно"), и укажите значения 2 и 3.

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

Резюме

Мы рассмотрели несколько способов получения списка контрагентов по количеству договоров. Основной механизм — это группировка по владельцу в таблице договоров с использованием агрегатной функции КОЛИЧЕСТВО и фильтра ИМЕЮЩИЕ. Не забывайте проверять данные на пометку удаления и использовать временные таблицы для оптимизации запросов к большим справочникам. Эти методы позволят вам создавать надежные и быстрые отчеты в любой конфигурации на базе 1С.

← На главную