При разработке отчетов в системе компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда данные из двух наборов данных необходимо связать не по жесткому ключу, а по определенному логическому условию. Например, если в наборе-источнике булево поле принимает значение Истина, связывание должно происходить по одной паре полей, а если Ложь — по другой.
Попытка реализовать такую конструкцию напрямую на вкладке Связи наборов данных стандартным добавлением двух строк с условиями связи обычно приводит к тому, что соединение перестает возвращать данные. Разберем по шагам, почему так происходит, как работает механизм связей платформы 1С и какими способами можно корректно решить эту задачу.
Проанализируем типичную ошибку. Разработчик добавляет две строки связей между таблицами Таблица1 (источник) и Таблица2 (приемник):
Поле1, Приемник: Поле1, Условие связи: Поле3 = ИстинаПоле1, Приемник: Поле2, Условие связи: Поле3 = ЛожьОжидается, что платформа применит логику ветвления (ИЛИ), однако в результате связь вообще не срабатывает. Выясним причину такого поведения платформы 1С:
Таблица1.Поле1 = Таблица2.Поле1 И Таблица1.Поле1 = Таблица2.Поле2.Ложь, компоновщик данных просто не пытается связывать эту строку с приемником (все поля набора-приемника для нее примут значение NULL).ВЫБОР КОГДА Таблица1.Поле3... непосредственно в выражении приемника невозможно.Если оба набора данных представляют собой запросы к базе данных, наиболее производительным и архитектурно правильным решением будет объединение их в один общий запрос с явным соединением таблиц. Это позволяет перенести всю вычислительную нагрузку на СУБД и избежать избыточной обработки данных в оперативной памяти компоновщика.
Посмотрим на пример запроса:
ВЫБРАТЬ
Табл1.Поле1 КАК Поле1,
Табл1.Поле3 КАК Поле3,
Табл2.Данные КАК Данные
ИЗ
Таблица1 КАК Табл1
ЛЕВОЕ СОЕДИНЕНИЕ Таблица2 КАК Табл2
ПО (ВЫБОР
КОГДА Табл1.Поле3 = ИСТИНА
ТОГДА Табл2.Поле1
ИНАЧЕ Табл2.Поле2
КОНЕЦ = Табл1.Поле1)
Такой подход гарантирует быстрое выполнение, исключает проблему неработающих условий связи и значительно упрощает структуру схемы компоновки данных.
Если наборы данных необходимо оставить разделенными (например, подчиненный запрос должен исполняться для каждой группировки или зависит от итогов верхнего уровня), перенесем логику условного выбора в секцию ГДЕ подчиненного набора данных через параметры.
Разберем по шагам, как настроить этот вариант:
Таблица2) пропишем условие фильтрации по параметрам:
ВЫБРАТЬ
Таблица2.Поле1 КАК Поле1,
Таблица2.Поле2 КАК Поле2,
Таблица2.Данные КАК Данные
ИЗ
Таблица2 КАК Таблица2
ГДЕ
(&ПараметрПоле3 = ИСТИНА И Таблица2.Поле1 = &ПараметрПоле1)
ИЛИ (&ПараметрПоле3 = ЛОЖЬ И Таблица2.Поле2 = &ПараметрПоле1)
НаборДанных1, Приемник: НаборДанных2, Выражение источник: Поле1, Параметр: ПараметрПоле1.НаборДанных1, Приемник: НаборДанных2, Выражение источник: Поле3, Параметр: ПараметрПоле3.В (&ПараметрПоле1).Если набор-приемник является таблицей значений (тип Набор данных - объект), использование параметров запроса невозможно. В таком случае необходимо заранее нормализовать данные и сформировать единое ключевое поле для связи.
Рассмотрим, как это реализовать: