Почему при установке отбора в СКД пропадают данные из подчиненного набора данных?

Программист 1С v8.3 (Обычные формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

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

Причины пропадания данных при наложении отбора

Рассмотрим подробнее внутреннюю логику компоновщика данных, приводящую к данной проблеме:

  1. Трансформация соединения во внутреннее (INNER JOIN). По умолчанию механизм Связи наборов данных эмулирует левое соединение: родительский набор является ведущим, а зависимый набор присоединяется к нему. Однако если на уровне всего отчета устанавливается отбор по полю, присутствующему в подчиненном наборе данных с тем же именем, СКД автоматически превращает связь во внутреннее соединение.
  2. Автозаполнение условий в запросах. Если в подчиненном наборе включено свойство «Автозаполнение», платформа 1С пытается оптимизировать запрос и автоматически проталкивает общее условие отбора во все запросы схемы, где встречается поле с псевдонимом Номенклатура. Это приводит к преждевременной фильтрации строк до момента сопоставления результатов.
  3. Неявная передача параметров связи. Если подчиненный набор данных соединяется только по выражению связи без явной параметризации запроса списком значений, компоновщик может некорректно сопоставлять данные или выполнять избыточное количество одиночных запросов к СУБД.

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

Разберем по шагам наиболее быстрый способ устранения конфликта автозаполнения, основанный на переименовании полей:

  1. Откроем схему компоновки данных и перейдем в зависимый набор данных (например, «ДополнительныеДанные»).
  2. В тексте запроса или на вкладке настройки полей изменим псевдоним связующего поля. Вместо Номенклатура укажем, например, НоменклатураПриемник.
  3. Перейдем на закладку Связи наборов данных.
  4. Настроим связь заново: в колонке Источник связи укажем ПланФакт, в Приемник связи — ДополнительныеДанные. В колонке Выражение источник выберем поле Номенклатура, а в колонке Выражение приемник — НоменклатураПриемник.
  5. На закладке Наборы данных для поля НоменклатураПриемник установим флажок в колонке Ограничение условий, чтобы исключить возможность случайного наложения условий напрямую на зависимое поле.

В результате пользовательский отбор будет накладываться исключительно на основное поле Номенклатура главного набора, а подчиненный запрос получит нужные значения через механизм связи без сваливания во внутреннее соединение.

Способ 2. Параметризация подчиненного набора данных через список значений

Посмотрим на пример правильной передачи параметров в зависимый набор. Это не только решает проблему с отборами, но и существенно ускоряет выполнение отчета.

Модифицируем текст запроса набора «ДополнительныеДанные», добавив явный фильтр по массиву значений:


ВЫБРАТЬ
    РегистрСведений.Номенклатура КАК Номенклатура,
    РегистрСведений.ЗначениеРесурса КАК ДополнительныйПоказатель
ИЗ
    РегистрСведений.ДополнительныеСведения КАК РегистрСведений
ГДЕ
    РегистрСведений.Номенклатура В (&МассивНоменклатуры)

Далее настроим параметры связи:

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

Способ 3. Перенос отбора на уровень группировки отчета

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

  1. Откроем настройки варианта отчета и перейдем к структуре группировок.
  2. Исключим поле Номенклатура из общих отборов отчета (вкладка «Отбор» верхнего уровня).
  3. Выделим конкретную группировку (строку с группировкой по номенклатуре) и добавим условие отбора непосредственно в свойства этой группировки.

Отборы, установленные на уровне отдельных группировок структуры, применяются к уже рассчитанной таблице компоновки данных в оперативной памяти и не вмешиваются в логику SQL-запросов и соединений между наборами.

Способ 4. Объединение данных в рамках единого запроса (рекомендуемый подход)

Проанализируем архитектурную альтернативу. Практика разработки на платформе 1С показывает, что использование множественных связанных наборов данных в СКД уступает по скорости и надежности классическому запросу. Оптимальным решением для задач вида «План-Факт + Дополнительные данные» является объединение таблиц в одном наборе данных типа «Запрос»:


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

При таком подходе соединение данных полностью контролируется разработчиком в тексте запроса. Глобальный отбор СКД накладывается стандартным образом и не приводит к потере связанных числовых ресурсов.

← На главную