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

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

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

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

Базовый вариант: объединение запросов с функцией ТИПЗНАЧЕНИЯ

Для того чтобы в результирующей таблице отчет мог разделить документы по их видам, запрос должен возвращать как минимум два поля: само количество и классификатор типа документа. Если выбирать только количественные показатели, система при объединении через ОБЪЕДИНИТЬ или в группировках СКД не сможет определить, к какому именно метаданному относится строка.

Для определения типа документа в тексте запроса применяется функция ТИПЗНАЧЕНИЯ(). Посмотрим на пример рабочего запроса, объединяющего данные по двум видам документов с условием выборки только проведенных документов:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ТИПЗНАЧЕНИЯ(ПриходДенежныхСредств.Ссылка) КАК ВидДокумента,
    КОЛИЧЕСТВО(ПриходДенежныхСредств.Ссылка) КАК Количество
ИЗ
    Документ.ПриходДенежныхСредств КАК ПриходДенежныхСредств
ГДЕ
    ПриходДенежныхСредств.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    ТИПЗНАЧЕНИЯ(ПриходДенежныхСредств.Ссылка)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ТИПЗНАЧЕНИЯ(РасходДенежныхСредств.Ссылка),
    КОЛИЧЕСТВО(РасходДенежныхСредств.Ссылка)
ИЗ
    Документ.РасходДенежныхСредств КАК РасходДенежныхСредств
ГДЕ
    РасходДенежныхСредств.Проведен = ИСТИНА
СГРУППИРОВАТЬ ПО
    ТИПЗНАЧЕНИЯ(РасходДенежныхСредств.Ссылка)

Ошибки при фильтрации по реквизиту «Проведен»

Частая ошибка при наложении условия на признак проведения — попытка передать булево значение как параметр: ГДЕ Документ.Проведен = &Истина. В языке запросов 1С булевы литералы являются зарезервированными словами. Правильно указывать условие напрямую в тексте запроса:


ГДЕ
    ТаблицаДокумента.Проведен = ИСТИНА

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


ГДЕ
    (&ТолькоПроведенные = ЛОЖЬ ИЛИ ТаблицаДокумента.Проведен = ИСТИНА)

Оптимизация производительности запроса

Проанализируем ключевые моменты, позволяющие сделать запрос быстрее и снизить нагрузку на СУБД:

  1. Замена КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Ссылка) на КОЛИЧЕСТВО(Ссылка): Ссылка на документ уникальна внутри таблицы базы данных. Конструкция РАЗЛИЧНЫЕ заставляет сервер СУБД выполнять дополнительную проверку уникальности, создавая бесполезную нагрузку.
  2. Использование ОБЪЕДИНИТЬ ВСЕ вместо ОБЪЕДИНИТЬ: Ключевое слово ОБЪЕДИНИТЬ без модификатора ВСЕ инициирует проверку на дубликаты и неявную сортировку всех строк результирующей выборки на стороне СУБД. Поскольку в каждой ветке выбирается свой уникальный тип документа, пересечений строк быть не может, поэтому всегда следует использовать ОБЪЕДИНИТЬ ВСЕ.
  3. Замена функции ТИПЗНАЧЕНИЯ на литерал типа: Вызов функции ТИПЗНАЧЕНИЯ(Ссылка) для каждой строки таблицы увеличивает время выборки. Вместо этого в секции ВЫБРАТЬ можно сразу указать тип метаданных: ТИП(Документ.ПриходДенежныхСредств) КАК ВидДокумента. В таком случае группировку по этому полю в ветках объединения выполнять не потребуется.
  4. Использование ВЫБРАТЬ РАЗРЕШЕННЫЕ: Если у пользователя ограничены права доступа на уровне записей (RLS) или нет прав на просмотр одного из документов, отсутствие этой конструкции приведет к аварийному завершению отчета.

Оптимизированный текст запроса

С учетом вышеописанных рекомендаций запрос приобретает следующий вид:


ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ТИП(Документ.ПриходДенежныхСредств) КАК ВидДокумента,
    КОЛИЧЕСТВО(ПриходДенежныхСредств.Ссылка) КАК Количество
ИЗ
    Документ.ПриходДенежныхСредств КАК ПриходДенежныхСредств
ГДЕ
    ПриходДенежныхСредств.Проведен = ИСТИНА

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ТИП(Документ.РасходДенежныхСредств),
    КОЛИЧЕСТВО(РасходДенежныхСредств.Ссылка)
ИЗ
    Документ.РасходДенежныхСредств КАК РасходДенежныхСредств
ГДЕ
    РасходДенежныхСредств.Проведен = ИСТИНА

Настройка ресурсов в Системе компоновки данных (СКД)

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

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

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

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

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