Почему в отчете СКД не работает расшифровка и отбор по соединенной таблице?

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

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

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

Причины некорректной работы расшифровки и отборов

Проанализируем механику работы СКД при формировании итогового запроса:

  1. Оптимизация и автоматическое «проталкивание» условий. При включенном механизме автозаполнения СКД стремится оптимизировать исполнение запроса на уровне СУБД. Платформа пытается перенести пользовательские отборы, а также фильтры контекста расшифровки непосредственно в параметры виртуальной таблицы (в четвертый параметр — «Условие») либо в секции ГДЕ исходных подзапросов пакета. Если отбор наложен на поле присоединенной таблицы, СКД может применить условие еще до выполнения соединения, что приводит к пустой выборке.
  2. Сбор контекста расшифровки. Когда пользователь дважды щелкает по ячейке для расшифровки, стандартный механизм СКД считывает значения всех измерений и реквизитов текущей строки отчета и формирует массив отборов для нового расшифровывающего отчета. Если в строку выведено поле из временной таблицы, СКД накладывает отбор по этому полю на весь результирующий набор, ломая логику внутреннего соединения.
  3. Определение ролей полей. При соединении таблиц в тексте одного запроса СКД не всегда автоматически распознает роль поля Регистратор как составного периода или ключевого поля, из-за чего связь группировок с первичным документом теряется.

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

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

  1. В запросе набора данных оставляем выборку поля со своим псевдонимом (например, втМепингСтатьи.СтатьяБюджета КАК СтатьяБюджетаИсходная).
  2. На вкладке Вычисляемые поля добавляем новое поле с именем СтатьяБюджета и в колонке Выражение указываем СтатьяБюджетаИсходная.
  3. На вкладке Настройки выводим в отчет и накладываем пользовательские отборы именно на созданное вычисляемое поле.

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

Способ 2. Явное управление отборами через расширение языка запросов СКД

Разберем профессиональный подход с точки зрения языка СКД. Чтобы жестко указать платформе, где именно должно применяться пользовательское условие и контекст расшифровки, используем секцию расширения {ГДЕ ...}:


ВЫБРАТЬ
    БюджетОбороты.Регистратор КАК Регистратор,
    БюджетОбороты.СтатьяДДС КАК СтатьяДДС,
    БюджетОбороты.СуммаОборот КАК СуммаОборот,
    втМепингСтатьи.СтатьяБюджета КАК СтатьяБюджета
ИЗ
    РегистрНакопления.Бюджет.Обороты(, , Авто, ) КАК БюджетОбороты
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ втМепингСтатьи КАК втМепингСтатьи
        ПО БюджетОбороты.СтатьяДДС = втМепингСтатьи.СтатьяДДС
{ГДЕ
    втМепингСтатьи.СтатьяБюджета.* КАК СтатьяБюджета}

Такая конструкция запрещает СКД переносить отборы по полю СтатьяБюджета в параметры виртуальной таблицы оборотов или в тело формирования временной таблицы втМепингСтатьи.

Способ 3. Разделение на независимые наборы данных

Рассмотрим еще один архитектурно правильный вариант, исключающий конфликты при расшифровке — использование функционала связей наборов данных в СКД:

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

При такой схеме компоновщик выполняет запросы изолированно. Отборы по полям второго набора накладываются на этапе постобработки в памяти, сохраняя доступ к документу-регистратору из первого набора.

Способ 4. Проверка назначения ролей полей и индексация

Для гарантированной работы расшифровки по регистратору выполним следующие шаги:

  1. На вкладке Наборы данных в колонке Роль для поля Регистратор проверим признак типа роли: он должен быть отмечен как период с порядковым номером (или включен флаг Обязательное).
  2. Во временной таблице втМепингСтатьи обязательно добавляем директиву индексирования по полям соединения:
    
    ИНДЕКСИРОВАТЬ ПО
        СтатьяДДС
    

Если требуется проанализировать, какой именно итоговый SQL-запрос генерирует платформа, используем встроенную процедуру ПриКомпоновкеРезультата в модуле объекта отчета, либо открываем консоль компоновки данных для просмотра реального текста с учетом переданных отборов расшифровки.

← На главную