Как настроить связь наборов данных в СКД по определенному типу документа?

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

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

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

Выясняем причину: почему не работает оператор ССЫЛКА в связях СКД?

Разберем типичную ошибку начинающих разработчиков. Пытаясь наложить условие связи по типу документа в поле «Условие связи», программисты часто пишут выражения вида:

Док ССЫЛКА Документ.ЗаказПокупателя

Или пытаются применить функции работы с типами:

ТипЗначения(Док) = Тип("ДокументСсылка.ЗаказПокупателя")

При выполнении отчета система выдает синтаксическую ошибку. Происходит это из-за смешивания двух разных языков:

  1. Язык запросов 1С — используется внутри схем запросов наборов данных. В нем оператор ССЫЛКА работает отлично.
  2. Язык выражений СКД — специальный синтаксис, на котором пишутся формулы вычисляемых полей, ресурсов и условий связи. В этом языке оператора ССЫЛКА в его классическом виде просто нет.

Кроме того, в поле «Условие связи» категорически запрещено использовать поля набора-приемника. Написание условий, сравнивающих поля источника и приемника в этой колонке, вызовет ошибку «Поле не найдено».

Ниже мы подробно проанализируем работающие способы обхода этих ограничений.

Решение 1. Использование условных выражений в полях «Выражение источник» и «Выражение приемник»

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

Суть метода заключается в том, что условную конструкцию ВЫБОР... мы переносим непосредственно в определение связующих полей. Язык выражений СКД прекрасно понимает эту конструкцию внутри полей источника и приемника.

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

  1. Переходим на вкладку «Связи наборов данных».
  2. В поле «Выражение источник» пишем условие, которое будет возвращать контрагента только для Заказа покупателя, а для всех остальных типов документов вернет NULL:
    
    ВЫБОР 
        КОГДА ВЫРАЗИТЬ(Док, "Документ.ЗаказПокупателя") ЕСТЬ НЕ NULL 
        ТОГДА Контрагент 
        ИНАЧЕ NULL 
    КОНЕЦ
    
  3. В поле «Выражение приемник» указываем простое связующее поле из подчиненного набора данных (например, Контрагент).

Поскольку значение NULL, полученное из выражения-источника для других документов, никогда не совпадет с конкретным контрагентом в приемнике, связь для лишних типов документов физически не установится.

Решение 2. Корректное написание типов в поле «Условие связи»

Если мы хотим использовать именно колонку «Условие связи», нам необходимо применять функции, которые поддерживаются Языком выражений СКД. Нам доступны два основных варианта.

Вариант А. Через функцию ВЫРАЗИТЬ

Функция ВЫРАЗИТЬ в СКД имеет важную особенность: если тип объекта не соответствует указанному, она не вызывает ошибку, а возвращает пустое значение NULL. Мы можем использовать это свойство в условии связи:

ВЫРАЗИТЬ(Док, "Документ.ЗаказПокупателя") ЕСТЬ НЕ NULL

Обратите внимание, что имя типа в СКД обязательно передается в виде строки в кавычках.

Вариант Б. Через ТипЗначения и Тип (для новых версий платформы)

Если вы работаете на современной версии платформы 1С:Предприятие 8.3, компоновщик поддерживает функции работы с типами. Конструкция в условии связи должна выглядеть так:

ТипЗначения(Док) = Тип("ДокументСсылка.ЗаказПокупателя")

Здесь важно использовать точный строковый литерал типа "ДокументСсылка.[ИмяДокумента]".

Решение 3. Подготовка данных на уровне запроса (План Б)

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

Рассмотрим этот вариант подробнее:

  1. Открываем конструктор запроса первого набора данных.
  2. Добавляем в список выбора новое вычисляемое поле, определяющее применимость связи. Например:
    
    ВЫБОР
        КОГДА Док ССЫЛКА Документ.ЗаказПокупателя 
            ТОГДА Контрагент
        ИНАЧЕ NULL
    КОНЕЦ КАК КонтрагентДляСвязи
    
  3. В настройках связей наборов данных в качестве источника выбираем наше новое поле КонтрагентДляСвязи, а в качестве приемника — поле Контрагент из второго набора.

Этот способ разгружает процессор компоновки данных, перенося логику отбора типов на уровень СУБД, что положительно сказывается на скорости формирования сложных отчетов.

Важная деталь: флаг «Обязательная связь»

При настройке связи наборов данных обратите особое внимание на последнюю колонку в таблице настроек — флаг «Обязательная связь». Поведение отчета кардинально меняется в зависимости от его состояния:

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

← На главную