При разработке внешних отчетов в системе 1С часто возникает задача отфильтровать элементы справочника по количеству записей в их табличных частях. Например, требуется получить только те элементы, у которых табличная часть содержит более одной строки, и при этом вывести в отчет основной реквизитный состав элемента вместе с порядковой нумерацией выведенных строк.
Рассмотри по шагам, как правильно составить запрос для отбора таких элементов и как средствами Системы компоновки данных (СКД) автоматически проставить порядковые номера строк.
Наиболее быстрый и эффективный способ решить эту задачу на больших объемах данных — использовать внутреннее соединение основной таблицы справочника с его табличной частью по условию НомерСтроки = 2. Если в табличной части элемента существует вторая строка, это автоматически означает, что общее количество строк в ней больше единицы.
В СУБД первичный ключ табличной части справочника является составным и состоит из полей (Ссылка, НомерСтроки). Точное условие НомерСтроки = 2 позволяет СУБД выполнять точечный поиск по существующему кластерному индексу, избегая сканирования всех строк табличной части и выполнения ресурсоемкой группировки.
Разберем пример запроса:
ВЫБРАТЬ
СправочникНоменклатура.Ссылка КАК Ссылка,
СправочникНоменклатура.Наименование КАК Наименование,
СправочникНоменклатура.Код КАК Код
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура.ДополнительныеРеквизиты КАК СправочникТЧ
ПО СправочникТЧ.Ссылка = СправочникНоменклатура.Ссылка
И СправочникТЧ.НомерСтроки = 2
ГДЕ
НЕ СправочникНоменклатура.ПометкаУдаления
Важное примечание: при обращении к табличной части справочника в выборку по умолчанию могут попадать элементы, помеченные на удаление. Если такие элементы не должны выводиться в отчет, обязательно добавляем условие ГДЕ НЕ СправочникНоменклатура.ПометкаУдаления.
Альтернативный классический вариант — использование предложения СГРУППИРОВАТЬ ПО и условия ИМЕЮЩИЕ. Однако здесь важно учитывать нюанс работы с реквизитами табличной части.
Если применить подсчет по уникальным значениям конкретного реквизита, например КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ТЧ.Реквизит), отчет сработает некорректно в случае, если в двух разных строках табличной части значения этого реквизита совпадают. В таком случае платформа посчитает их как одну запись и элемент не попадет в выборку. Для правильного подсчета физических строк следует использовать КОЛИЧЕСТВО(СправочникТЧ.НомерСтроки) или КОЛИЧЕСТВО(*).
Посмотрим на пример запроса с группировкой:
ВЫБРАТЬ
СправочникТЧ.Ссылка КАК Ссылка,
КОЛИЧЕСТВО(СправочникТЧ.НомерСтроки) КАК КоличествоСтрок
ИЗ
Справочник.Номенклатура.ДополнительныеРеквизиты КАК СправочникТЧ
ГДЕ
НЕ СправочникТЧ.Ссылка.ПометкаУдаления
СГРУППИРОВАТЬ ПО
СправочникТЧ.Ссылка
ИМЕЮЩИЕ
КОЛИЧЕСТВО(СправочникТЧ.НомерСтроки) > 1
Этот способ уступает первому по производительности, так как требует полного обхода строк табличных частей и выполнения группировки на стороне СУБД.
Выясним, как вывести порядковые номера для строк отчета. Писать программный код или изменять текст запроса для этого не требуется — в СКД предусмотрена встроенная поддержка системных полей нумерации.
Проанализируем процесс настройки нумерации по шагам:
СистемныеПоля.НомерПоПорядку — формирует сквозную нумерацию всех выводимых строк отчета;СистемныеПоля.НомерПоПорядкуВГруппировке — формирует нумерацию, которая сбрасывается в 1 при смене родительской группировки.Если отчёт формируется с использованием собственных макетов оформления СКД, для получения порядкового номера элемента в вычисляемых выражениях макета применяется функция языка выражений НомерПоПорядку().