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

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

При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда выборка данных производится из табличных частей документов (например, РеализацияТоваровУслуг.Товары). Это приводит к тому, что в итоговую выборку попадает столько строк, сколько позиций номенклатуры указано в каждом документе. Если нам нужно посчитать общую сумму — проблем обычно не возникает, но как только встает задача посчитать количество уникальных документов, стандартная функция Количество() начинает выдавать неверный результат, суммируя все строки табличной части вместо самих ссылок на документы.

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

Причина возникновения проблемы: размножение строк

Рассмотрим типичную ситуацию. В запросе мы обращаемся к табличной части документа:


ВЫБРАТЬ
    РеализацияТоваровУслугТовары.Ссылка КАК ДокументСсылка,
    РеализацияТоваровУслугТовары.Номенклатура,
    РеализацияТоваровУслугТовары.Количество,
    РеализацияТоваровУслугТовары.Ссылка.Контрагент КАК Контрагент
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары
ГДЕ
    РеализацияТоваровУслугТовары.Ссылка.Проведен

Если у Контрагента "Альфа" есть один документ "Реализация" с пятью строками товаров, то результат запроса вернет 5 строк. При попытке вывести ресурс "Количество" по полю ДокументСсылка, система просто посчитает количество записей в выборке и выдаст цифру 5 вместо 1. Это происходит потому, что на уровне СУБД Ссылка в каждой строке — это значение, которое повторяется столько раз, сколько строк в документе.

Решение 1: Использование функции Количество(Различные ...) в ресурсах СКД

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

Разберем по шагам, как это настроить:

  1. Откройте схему компоновки данных и перейдите на закладку «Ресурсы».
  2. Выберите поле, по которому нужно считать количество (в нашем случае это поле Ссылка или ДокументСсылка).
  3. В колонке «Выражение» напишите: Количество(Различные Ссылка).
  4. В колонке «Рассчитывать по...» крайне важно указать те группировки, в которых этот итог должен отображаться. Обычно это группировка Контрагент и Общие итоги.

Почему это работает? Функция Различные внутри агрегатной функции Количество заставляет СКД при расчете итогов сначала собрать все уникальные идентификаторы (GUID) ссылок внутри текущей группировки и только потом подсчитать их количество. Таким образом, даже если документ содержит 100 строк товаров, в итог по контрагенту он попадет как 1 единица.

Решение 2: Подсчет через вычисляемые поля

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

  1. Создайте новое вычисляемое поле, например, с заголовком КолВоДокументов.
  2. В выражении оставьте поле пустым или укажите Ссылка.
  3. Перейдите на закладку «Ресурсы» и добавьте это поле.
  4. В выражении ресурса укажите: Количество(Различные Ссылка).

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

Решение 3: Использование функции ВычислитьВыражение

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

Выражение может выглядеть так:

ВычислитьВыражение("Количество(Различные Ссылка)", "Контрагент", "Группировка")

Эта конструкция говорит системе: "Возьми все записи в рамках текущего Контрагента, найди там уникальные Ссылки и посчитай их количество". Это очень мощный инструмент для создания сложных аналитических отчетов.

Решение 4: Оптимизация через использование нескольких наборов данных

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

Профессиональный подход заключается в разделении данных на два набора:

  1. НаборДанных1 (Запрос): Здесь мы выбираем данные о товарах (Номенклатура, Количество, Сумма).
  2. НаборДанных2 (Запрос): Здесь мы выбираем только уникальные документы и их владельцев:
    
    ВЫБРАТЬ РАЗЛИЧНЫЕ
        Реализация.Ссылка,
        Реализация.Контрагент,
        1 КАК ИндексДокумента
    ИЗ
        Документ.РеализацияТоваровУслуг КАК Реализация
    

Затем на закладке «Связи наборов данных» мы связываем их по полю Ссылка. В ресурсах для поля ИндексДокумента мы просто используем функцию Сумма(ИндексДокумента). Поскольку во втором наборе данных каждый документ встречается ровно один раз, обычная сумма даст нам точное количество документов без лишних затрат ресурсов на операцию Различные.

Важные нюансы и "подводные камни"

Разберем ситуацию, которая часто встречается при соединении таблиц. Если в исходном запросе используется ЛЕВОЕ СОЕДИНЕНИЕ (например, с регистром сведений «Цены номенклатуры»), и для одной строки товара находится несколько записей в регистре (ошибка в данных или не указан срез на дату), количество строк в результате запроса увеличится еще сильнее. Это исказит не только количество документов, но и суммовые показатели.

Рекомендации:

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

← На главную