При разработке на платформе 1С:Предприятие 8.3 часто возникает задача отображения в списке основного документа некоего результирующего статуса, который зависит от состояния множества подчиненных документов. Рассмотрим, как эффективно решить эту задачу, избегая распространенных проблем с производительностью.
Когда мы пытаемся использовать сложные группировки или вложенные запросы прямо в Динамическом списке, мы сталкиваемся с тем, что система выполняет тяжелые вычисления для каждой строки списка при каждом обновлении или прокрутке. Это приводит к значительному замедлению интерфейса. Рассмотрим два основных способа решения этой задачи.
Если объем данных небольшой, мы можем использовать конструкцию ВЫБОР КОГДА с проверкой существования подчиненных документов. Чтобы запрос работал быстрее, вместо сложных агрегаций используем проверку ВЫБРАТЬ ПЕРВЫЕ 1 1. Это позволит системе быстро определить наличие хотя бы одного документа с заданным статусом.
Рассмотрим пример кода для произвольного запроса:
ВЫБРАТЬ
ДокА.Ссылка,
ВЫБОР
КОГДА 1 В (ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ Документы.ДокБ КАК ДокБ
ГДЕ ДокА.Ссылка = ДокБ.ДокументОснование
И ДокБ.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.ВРаботе))
ТОГДА ЗНАЧЕНИЕ(Перечисление.Статусы.ВРаботе)
КОГДА 1 В (ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ Документы.ДокБ КАК ДокБ
ГДЕ ДокА.Ссылка = ДокБ.ДокументОснование
И ДокБ.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.СОшибкой))
ТОГДА ЗНАЧЕНИЕ(Перечисление.Статусы.СОшибкой)
КОГДА 1 В (ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ Документы.ДокБ КАК ДокБ
ГДЕ ДокА.Ссылка = ДокБ.ДокументОснование
И ДокБ.Статус = ЗНАЧЕНИЕ(Перечисление.Статусы.БезОшибок))
ТОГДА ЗНАЧЕНИЕ(Перечисление.Статусы.БезОшибок)
ИНАЧЕ ЗНАЧЕНИЕ(Перечисление.Статусы.ПустаяСсылка)
КОНЕЦ КАК Статус
ИЗ
Документы.ДокА КАК ДокА
Важно: Данный метод хорош для небольших списков, однако при работе с большими объемами данных он может снижать отзывчивость системы.
Для профессиональной разработки с расчетом на высокую производительность рекомендуется использовать Регистр сведений. Это переносит нагрузку с момента отображения списка на момент записи документа.
Разберем этапы реализации:
Регистр сведений (например, СтатусыДокументов), где измерением будет ДокументА, а ресурсом — Статус.ДокументБ или в Подписке на событие при записи/проведении документа организуйте процедуру пересчета статуса для родительского ДокументаА.Динамическом списке сделайте левое соединение (LEFT JOIN) с этим регистром.Почему это решение лучше:
Если вам необходимо выводить статус на основе количественных показателей (например, количество ошибок), можно использовать СУММА и ВЫБОР:
ВЫБРАТЬ
ДокА.Ссылка,
СУММА(ВЫБОР КОГДА ДокБ.Статус = &СтатусОшибка ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоОшибок,
СУММА(ВЫБОР КОГДА ДокБ.Статус = &СтатусБезОшибок ТОГДА 1 ИНАЧЕ 0 КОНЕЦ) КАК КоличествоБезОшибок
ИЗ
Документы.ДокА КАК ДокА
ЛЕВОЕ СОЕДИНЕНИЕ Документы.ДокБ КАК ДокБ ПО ДокА.Ссылка = ДокБ.ДокументОснование
СГРУППИРОВАТЬ ПО
ДокА.Ссылка
Помните, что использование СГРУППИРОВАТЬ ПО в динамическом списке отключает стандартные функции сортировки и фильтрации, предоставляемые платформой для динамических списков, поэтому используйте этот метод осознанно.
Если вы хотите создать надежное и масштабируемое решение, всегда стремитесь к выносу сложной логики в Регистр сведений. Это «золотой стандарт» платформы 1С, позволяющий избежать проблем с производительностью при росте базы данных. Если же задача разовая или объем данных минимален — используйте оптимизированный произвольный запрос с ВЫБОР КОГДА.