Как в запросе 1С подсчитать количество уникальных комбинаций полей для номенклатуры?

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

При разработке отчетов и аналитических алгоритмов в 1С часто возникает задача агрегации данных по составным ключам. Рассмотрим типовую ситуацию: в справочнике форм (оснастки) в табличной части хранятся номера отсеков и номенклатура, которую в них можно изготавливать. Поскольку номер отсека является числом (например, 1, 2, 3) и повторяется в разных формах, каждый физический отсек однозначно определяется парой значений Ссылка (Форма) + Номер отсека. Нам необходимо выяснить, в каком количестве уникальных отсеков может производиться каждая номенклатурная позиция.

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

Ограничения языка запросов 1С при подсчете составных ключей

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

  1. Передача нескольких полей в агрегатную функцию: в языке запросов 1С функция КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ...) принимает ровно одно выражение. Конструкция вида КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Ссылка, Отсек) вызовет синтаксическую ошибку.
  2. Подсчет только по полю отсека: вызов КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Отсек) посчитает только уникальные номера (1, 2, 3), проигнорировав тот факт, что отсек №1 в «Форме 1» и отсек №1 в «Форме 2» — это два разных физических места.
  3. Попытка конкатенации ссылок со строками: выражение вида ВЫРАЗИТЬ(Формы.Ссылка КАК Строка) не поддерживается платформой 1С. Функция ВЫРАЗИТЬ предназначена только для ограничения длины строковых полей, приведения чисел или сужения составных типов, но не для получения строкового представления ссылочных данных.

Способ 1. Использование вложенного запроса с ВЫБРАТЬ РАЗЛИЧНЫЕ

Рассмотрим наиболее простое и универсальное решение. Чтобы корректно сосчитать количество отсеков, разделим задачу на два шага:

  1. Во вложенном запросе получим уникальные строки сочетаний Форма + Отсек + Номенклатура с помощью ключевого слова РАЗЛИЧНЫЕ. Это исключит возможные дубликаты, если одна и та же номенклатура по ошибке указана для одного отсека дважды.
  2. Во внешнем запросе выполним группировку по номенклатуре и подсчитаем число уникальных строк с помощью функции КОЛИЧЕСТВО(1).

Посмотрим на пример текста запроса:


ВЫБРАТЬ
    ВложенныйЗапрос.Номенклатура КАК Номенклатура,
    КОЛИЧЕСТВО(1) КАК КоличествоОтсеков
ИЗ
    (ВЫБРАТЬ РАЗЛИЧНЫЕ
        Формы.Ссылка КАК Форма,
        Формы.Отсек КАК Отсек,
        Формы.Номенклатура КАК Номенклатура
    ИЗ
        Справочник.Формы.ТабличнаяЧасть КАК Формы) КАК ВложенныйЗапрос
СГРУППИРОВАТЬ ПО
    ВложенныйЗапрос.Номенклатура

Способ 2. Использование временной таблицы для больших объемов данных

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

Разберем реализацию пакета запросов:


ВЫБРАТЬ РАЗЛИЧНЫЕ
    Формы.Ссылка КАК Форма,
    Формы.Отсек КАК Отсек,
    Формы.Номенклатура КАК Номенклатура
ПОМЕСТИТЬ ВТ_УникальныеОтсеки
ИЗ
    Справочник.Формы.ТабличнаяЧасть КАК Формы
ИНДЕКСИРОВАТЬ ПО
    Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ.Номенклатура КАК Номенклатура,
    КОЛИЧЕСТВО(1) КАК КоличествоОтсеков
ИЗ
    ВТ_УникальныеОтсеки КАК ВТ
СГРУППИРОВАТЬ ПО
    ВТ.Номенклатура

В этом варианте первая часть запроса отбирает уникальные тройки значений и сохраняет их во временную таблицу ВТ_УникальныеОтсеки, создавая индекс по полю Номенклатура. Второй запрос быстро выполняет группировку и расчет итогового количества отсеков.

Рекомендации по оптимизации структуры метаданных

Если подобные выборки и расчеты выполняются в системе на регулярной основе, имеет смысл проанализировать саму модель данных:

  1. Использование регистра сведений: создание непериодического регистра сведений с измерениями Форма, Отсек и Номенклатура гарантирует уникальность записей на уровне платформы и значительно ускоряет выполнение запросов.
  2. Подчиненный справочник: если отсек представляет собой объект со своими свойствами (габариты, износ), логично выделить его в отдельный справочник ОтсекиФорм, подчиненный справочнику Формы. Тогда отсек станет ссылочным типом, и в запросе можно будет напрямую применять стандартную функцию КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Отсек).
← На главную