Как вывести агрегированный статус документа в динамическом списке?

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

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

Почему простые решения не всегда работают

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

Способ №1: Оптимизированный запрос с использованием конструкции ВЫБОР

Если объем данных небольшой, мы можем использовать конструкцию ВЫБОР КОГДА с проверкой существования подчиненных документов. Чтобы запрос работал быстрее, вместо сложных агрегаций используем проверку ВЫБРАТЬ ПЕРВЫЕ 1 1. Это позволит системе быстро определить наличие хотя бы одного документа с заданным статусом.

Рассмотрим пример кода для произвольного запроса:


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

Важно: Данный метод хорош для небольших списков, однако при работе с большими объемами данных он может снижать отзывчивость системы.

Способ №2: Использование регистра сведений (Рекомендуемый подход)

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

Разберем этапы реализации:

  1. Создайте Регистр сведений (например, СтатусыДокументов), где измерением будет ДокументА, а ресурсом — Статус.
  2. В модуле объекта ДокументБ или в Подписке на событие при записи/проведении документа организуйте процедуру пересчета статуса для родительского ДокументаА.
  3. В Динамическом списке сделайте левое соединение (LEFT JOIN) с этим регистром.

Почему это решение лучше:

Альтернатива: Расчет через агрегатные функции

Если вам необходимо выводить статус на основе количественных показателей (например, количество ошибок), можно использовать СУММА и ВЫБОР:


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

Помните, что использование СГРУППИРОВАТЬ ПО в динамическом списке отключает стандартные функции сортировки и фильтрации, предоставляемые платформой для динамических списков, поэтому используйте этот метод осознанно.

Заключение: какой подход выбрать?

Если вы хотите создать надежное и масштабируемое решение, всегда стремитесь к выносу сложной логики в Регистр сведений. Это «золотой стандарт» платформы 1С, позволяющий избежать проблем с производительностью при росте базы данных. Если же задача разовая или объем данных минимален — используйте оптимизированный произвольный запрос с ВЫБОР КОГДА.

← На главную