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

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

При разработке отчетов и аналитических выборок в среде 1С программисты часто сталкиваются с задачей подсчета количества документов на основе определенных условий в их табличных частях. Например, нам необходимо узнать, сколько документов Заказ клиента содержат в строках товаров определенные варианты обеспечения (такие как "Отгрузить", "К обеспечению" и т.д.), а также получить общую статистику по всей базе данных.

Начинающие разработчики часто совершают в этой задаче критические ошибки, которые приводят либо к неверным результатам, либо к катастрофическому падению производительности системы. В этой статье мы подробно разберем типичные ошибки, проанализируем причины их возникновения и рассмотрим правильные, оптимизированные способы решения задачи с помощью языка запросов и Системы компоновки данных (СКД).

Типичные ошибки при подсчете документов по табличным частям

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

Ошибка №1: Использование простых функций СУММА(1) или КОЛИЧЕСТВО() без учета уникальности

Если мы напишем простой запрос к табличной части Документ.ЗаказКлиента.Товары и применим группировку по варианту обеспечения с подсчетом количества строк, СУБД вернет нам количество строк табличной части, а не количество документов. Если в одном заказе клиента добавлено 5 разных товаров с действием "Отгрузить", то система посчитает этот документ 5 раз. В результате итоговые цифры в отчете будут завышены в несколько раз.

Ошибка №2: Получение вложенных таблиц в запросе

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

Ошибка №3: Избыточные соединения (JOIN) в запросе

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

---

Решение №1: Простой подсчет уникальных документов по действиям

Рассмотрим ситуацию, когда нам необходимо быстро получить количество уникальных заказов клиентов в разрезе каждого варианта обеспечения, исключая при этом документы с определенным статусом (например, "Закрыт").

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


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

Как это работает:

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

---

Решение №2: Комплексный подсчет с использованием Временных Таблиц

Что делать, если задача сложнее? Например, нам нужно вывести единую таблицу со следующей статистикой:

Для решения такой задачи оптимально использовать механизм Временных Таблиц (ВТ). Это позволит разбить сложный алгоритм на простые шаги, распределить нагрузку на сервер и получить гарантированно точный результат на больших базах данных.

Проанализируем пошагово структуру такого запроса:


// ШАГ 1: Отбираем все уникальные заказы по нужному фильтру во временную таблицу
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ЗаказКлиента.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_ВсеЗаказы
ИЗ
    Документ.ЗаказКлиента КАК ЗаказКлиента
ГДЕ
    НЕ ЗаказКлиента.Статус = &Статус
;

// ШАГ 2: Собираем уникальные заказы, в которых заполнены варианты обеспечения
ВЫБРАТЬ РАЗЛИЧНЫЕ
    ЗаказКлиентаТовары.Ссылка КАК Ссылка,
    ЗаказКлиентаТовары.ВариантОбеспечения КАК Действие
ПОМЕСТИТЬ ВТ_ЗаказыСДействиями
ИЗ
    Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
ГДЕ
    НЕ ЗаказКлиентаТовары.Ссылка.Статус = &Статус
    И НЕ ЗаказКлиентаТовары.ВариантОбеспечения ЕСТЬ NULL
;

// ШАГ 3: Получаем итоговые агрегированные показатели совмещением данных
ВЫБРАТЬ
    (ВЫБРАТЬ КОЛИЧЕСТВО(Ссылка) ИЗ ВТ_ВсеЗаказы) КАК ОбщееКоличествоДокументов,
    (ВЫБРАТЬ КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Ссылка) ИЗ ВТ_ЗаказыСДействиями) КАК ДокументовСДействиями,
    ДействияДокументов.Действие КАК Действие,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДействияДокументов.Ссылка) КАК КоличествоПоДействию
ИЗ
    ВТ_ЗаказыСДействиями КАК ДействияДокументов

СГРУППИРОВАТЬ ПО
    ДействияДокументов.Действие

Преимущества данного подхода:

---

Решение №3: Реализация задачи в СКД (Система компоновки данных)

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

Выясним, как настроить такую схему за 3 простых шага:

Шаг 1. Пишем максимально простой запрос для получения детальных записей:


ВЫБРАТЬ
    ЗаказКлиентаТовары.Ссылка КАК Заказ,
    ЗаказКлиентаТовары.ВариантОбеспечения КАК ВариантОбеспечения
ИЗ
    Документ.ЗаказКлиента.Товары КАК ЗаказКлиентаТовары
ГДЕ
    НЕ ЗаказКлиентаТовары.Ссылка.Статус = &Статус

Шаг 2. Настраиваем вкладку "Ресурсы":

Переходим на вкладку "Ресурсы" в конструкторе схемы компоновки данных. Добавляем поле Заказ в список ресурсов. В колонке "Выражение" пишем строго следующую формулу:

Количество(Различные Заказ)

Это заставит СКД на всех уровнях группировок производить вычисление только по уникальным ссылкам документов.

Шаг 3. Настраиваем структуру отчета:

В настройках компоновки добавляем группировку по полю ВариантОбеспечения. При формировании отчета СКД автоматически:

Таким образом, использование возможностей СКД — это самый надежный, быстрый и гибкий метод разработки подобных отчетов в 1С.

← На главную