Почему при расшифровке в отчете СКД выводятся все строки и как это исправить?

Программист 1С v8.3 (Обычные формы)
← На главную

При разработке отчетов на Системе компоновки данных (СКД) программисты часто сталкиваются с неприятной особенностью: при попытке расшифровать (сделать drill-down) конкретную ячейку, вместо ожидаемого списка детальных записей отчет выводит абсолютно все строки, игнорируя фильтр расшифровки. Особенно часто это проявляется в отчетах, где используется левое соединение (LEFT JOIN) и обработка пустых значений через ЕСТЬNULL. В данной статье мы подробно разберем причины такого поведения и рассмотрим несколько способов решения этой проблемы.

Проанализируем причину возникновения проблемы

Рассмотрим типичную ситуацию. У нас есть основной набор данных (например, список сотрудников) и мы присоединяем к нему данные из регистра сведений (например, заметки или дополнительные свойства) с помощью левого соединения. Для красоты вывода мы преобразуем неопределенные значения (NULL) в читаемый текст, например, "Отсутствие записи". В тексте запроса это выглядит примерно так:


ВЫБРАТЬ
    Работники.Сотрудник,
    ВЫРАЗИТЬ(ЕСТЬNULL(втЗаметки.Содержание, "Отсутствие записи") КАК СТРОКА(50)) КАК Содержание
ИЗ
    ВТ_КадровыеДанные КАК Работники
ЛЕВОЕ СОЕДИНЕНИЕ втАктуальныеЗаметки КАК втЗаметки
    ПО Работники.Физлицо = втЗаметки.Объект

Проблема заключается в том, как механизм расшифровки 1С генерирует фоновый запрос. Когда вы нажимаете на ячейку со значением "Отсутствие записи", СКД пытается применить фильтр ГДЕ Содержание = "Отсутствие записи" к исходному запросу.

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

Способ 1. Модификация запроса с использованием ОБЪЕДИНИТЬ ВСЕ

Один из надежных, хотя и трудоемких способов — переписать запрос таким образом, чтобы избавиться от левого соединения, при котором возникают NULL значения, заменяемые текстом. Мы можем разделить получение данных на две части и объединить их. Рассмотрим этот алгоритм подробнее:

  1. Сначала получим всех сотрудников, по которым есть записи в регистре, используя внутреннее соединение (INNER JOIN).
  2. Затем получим сотрудников, по которым нет записей, используя полное соединение с проверкой на NULL в правой таблице.
  3. Объединим результаты.

Пример реализации такого запроса:


ВЫБРАТЬ
    ВТ_КадровыеДанные.Сотрудник,
    ВТ_КадровыеДанные.Физлицо,
    ВЫРАЗИТЬ(втАктуальныеЗаметки.Содержание КАК СТРОКА(50)) КАК Содержание
ИЗ
    ВТ_КадровыеДанные КАК ВТ_КадровыеДанные
ВНУТРЕННЕЕ СОЕДИНЕНИЕ втАктуальныеЗаметки КАК втАктуальныеЗаметки
    ПО ВТ_КадровыеДанные.Физлицо = втАктуальныеЗаметки.Объект

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

ВЫБРАТЬ
    ВТ_КадровыеДанные.Сотрудник,
    ВТ_КадровыеДанные.Физлицо,
    "Отсутствие записи"
ИЗ
    ВТ_КадровыеДанные КАК ВТ_КадровыеДанные
ЛЕВОЕ СОЕДИНЕНИЕ втАктуальныеЗаметки КАК втАктуальныеЗаметки
    ПО ВТ_КадровыеДанные.Физлицо = втАктуальныеЗаметки.Объект
ГДЕ
    втАктуальныеЗаметки.Объект ЕСТЬ NULL

В этом случае при расшифровке строки "Отсутствие записи" СКД будет работать со второй частью объединения, где это значение прописано явно, и фильтрация отработает корректно.

Способ 2. Использование вычисляемых полей СКД

Это более элегантный способ, который позволяет оставить запрос простым. Мы переносим логику замены NULL из SQL-запроса в саму схему компоновки данных. Проанализируем шаги:

  1. В тексте запроса оставим поле как есть, без ЕСТЬNULL. В результате в поле Содержание будут приходить либо реальные строки, либо NULL.
  2. Перейдем на вкладку "Вычисляемые поля" в СКД.
  3. Создадим новое поле (например, СодержаниеПредставление) и в колонке "Выражение" напишем: ЕстьNULL(Содержание, "Отсутствие записи").
  4. В настройках отчета (вкладка "Выбранные поля") заменим исходное поле Содержание на наше вычисляемое поле.

Почему это работает: При такой настройке СКД понимает структуру данных. При расшифровке система будет накладывать фильтр на исходное поле Содержание с условием НЕ ЗАПОЛНЕНО (или проверкой на NULL), что является стандартной операцией для платформы и не вызывает сбоев оптимизатора.

Способ 3. Настройка выражения представления

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

  1. На вкладке "Наборы данных" найдем наше поле Содержание.
  2. В колонке "Выражение представления" напишем код:
    Выбор Когда Содержание Есть NULL Тогда "Отсутствие записи" Иначе Содержание Конец.

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

Дополнительные рекомендации по настройке полей

Рассмотрим еще несколько важных моментов, которые влияют на корректность расшифровки в сложных отчетах:

Таким образом, мы выяснили, что проблема расшифровки чаще всего кроется в попытке СКД отфильтровать данные по "виртуальному" значению, созданному внутри запроса. Используя вычисляемые поля или выражения представления, вы сохраните чистоту кода и обеспечите пользователям корректную работу с отчетами.

← На главную