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