Как реализовать неэквивалентные условия связи между наборами данных в СКД 1С (например, по условию «больше» или «меньше»)?

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

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

Суть проблемы: ограничение поля «Условие связи»

При попытке установить связь между наборами данных, например, «НаборДанных1» (источник) и «НаборДанных2» (приемник), и задать условие вида ДатаВозникновенияДолга <= ДатаДвижений непосредственно в поле «Условие связи» для связи наборов, система компоновки данных выдает ошибку «Поле не найдено 'ДатаДвижений'». Это происходит потому, что поле «Условие связи» предназначено для выражений, которые могут содержать только поля из набора данных, указанного в качестве источника связи. Оно служит для предварительной фильтрации строк источника до того, как будет предпринята попытка установить связь с приемником. Поля из набора-приемника в этом поле недоступны.

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

Основной подход: использование параметров связи в запросе приемника

Наиболее эффективный и стандартный способ решения этой задачи в СКД — это использование механизма передачи значений через параметры связи. Мы передадим значение из набора-источника в набор-приемник через специально созданный параметр, а затем используем этот параметр непосредственно в запросе набора-приемника для построения нужного условия.

Разберем по шагам, как это реализовать:

  1. Настройка запроса набора данных — Источника связи

    В запросе первого набора данных (источника связи) мы просто выбираем все необходимые поля, включая то поле, значение которого мы хотим использовать для сравнения. В нашем примере это будет ДатаВозникновенияДолга.

    Например:

    
    ВЫБРАТЬ
        ТаблицаДолгов.ДокументОснование,
        ТаблицаДолгов.СуммаДолга,
        ТаблицаДолгов.ДатаВозникновенияДолга
    ИЗ
        РегистрНакопления.Долги КАК ТаблицаДолгов
    
  2. Настройка запроса набора данных — Приемника связи

    В запросе второго набора данных (приемника связи) мы должны добавить параметр, который будет принимать значение из набора-источника. Этот параметр будет использоваться в условии ГДЕ для фильтрации данных по нужному условию.

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

    
    ВЫБРАТЬ
        ТаблицаДвижений.ДокументДвижения,
        ТаблицаДвижений.СуммаДвижения,
        ТаблицаДвижений.ДатаДвижений
    ИЗ
        РегистрНакопления.Движения КАК ТаблицаДвижений
    ГДЕ
        ТаблицаДвижений.ДатаДвижений >= &ДатаДолгаИзИсточника
    

    Обратите внимание на строку ГДЕ ТаблицаДвижений.ДатаДвижений >= &ДатаДолгаИзИсточника. Здесь мы используем параметр &ДатаДолгаИзИсточника.

  3. Настройка связи наборов данных в СКД

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

    1. Выражение источник: Укажите поле из набора-источника, значение которого мы будем передавать. В нашем примере это будет ДатаВозникновенияДолга.

      ДатаВозникновенияДолга

    2. Выражение приемник: Это поле из набора-приемника, которое логически связывается с выражением источника. Оно может быть тем же полем, что и в условии, или другим полем, которое вы хотите связать. В нашем случае, это ДатаДвижений.

      ДатаДвижений

    3. Параметр: Это ключевое поле для нашего решения. Здесь мы указываем имя параметра, который мы создали в запросе набора-приемника. В нашем примере это ДатаДолгаИзИсточника.

      ДатаДолгаИзИсточника

      СКД автоматически свяжет значение из «Выражения источник» с этим параметром.

    4. Условие связи: Это поле оставляем пустым, поскольку наша неэквивалентная логика уже реализована в запросе приемника через параметр.

    5. Обязательная связь: Мы рекомендуем снять флаг «Обязательная связь». Это позволит показывать все записи из набора-источника, даже если для них не найдется соответствующих записей в наборе-приемнике по установленному условию. Если флаг установлен, будут выведены только те записи источника, для которых найдутся соответствия в приемнике. В контексте расшифровки или детализации чаще требуется видеть все записи источника.

После этих настроек, при компоновке отчета, для каждой строки из набора-источника, значение поля ДатаВозникновенияДолга будет передаваться в параметр &ДатаДолгаИзИсточника запроса второго набора. Запрос второго набора будет фильтровать свои данные, оставляя только те, где ДатаДвижений >= ДатаДолгаИзИсточника, и уже эти отфильтрованные данные будут связаны с соответствующей строкой источника.

Пример полного запроса для набора-приемника с параметром:


ВЫБРАТЬ
    ТаблицаДвижений.ДокументДвижения КАК ДокументДвижения,
    ТаблицаДвижений.СуммаДвижения КАК СуммаДвижения,
    ТаблицаДвижений.ДатаДвижений КАК ДатаДвижений
ИЗ
    РегистрНакопления.Движения КАК ТаблицаДвижений
ГДЕ
    ТаблицаДвижений.ДатаДвижений >= &ДатаДолгаИзИсточника

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

Дополнительные обходные пути и соображения

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

Использование вычисляемых полей

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

Изменение запросов самих наборов данных

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


ВЫБРАТЬ
    ТаблицаДолгов.ДокументОснование,
    ТаблицаДолгов.СуммаДолга,
    ТаблицаДолгов.ДатаВозникновенияДолга,
    ТаблицаДвижений.ДокументДвижения,
    ТаблицаДвижений.СуммаДвижения,
    ТаблицаДвижений.ДатаДвижений
ИЗ
    РегистрНакопления.Долги КАК ТаблицаДолгов
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Движения КАК ТаблицаДвижений
        ПО ТаблицаДолгов.ДатаВозникновенияДолга <= ТаблицаДвижений.ДатаДвижений

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

Объединение (UNION ALL) наборов данных

Если ваша задача не столько связать данные, сколько получить единый список записей из двух разных источников и затем работать с ними в отчете, можно использовать объединение наборов данных (UNION ALL). Это позволит получить все записи из обоих наборов, а затем уже средствами СКД или вычисляемыми полями анализировать их взаимодействие. Однако это не является прямым решением для реализации неэквивалентной связи, а скорее альтернативным способом комбинирования данных.

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

Мы уже упомянули о важности флага «Обязательная связь». Давайте проанализируем его роль более детально:

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

Работа с параметрами-списками

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


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

И в настройках связи: «Параметр» — СписокДатИзИсточника, а также установленный флаг «Список параметров».

Резюмируя:

Хотя СКД и имеет свои особенности в работе с условиями связи, метод использования параметров в запросе набора-приемника является надежным и гибким решением для реализации неэквивалентных связей между наборами данных. Он позволяет обойти ограничения поля «Условие связи» и построить сложные условия фильтрации, сохраняя при этом удобство работы с отчетами СКД.

← На главную