Как вывести всех партнеров и объединить данные встреч и звонков в 1С и СКД?

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

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

Причины ошибок при соединении подзапросов

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

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

Способ 1. Использование пакетного запроса и временных таблиц

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

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

  1. Выбираем данные по встречам и сохраняем их во временную таблицу ВТ_Встречи.
  2. Выбираем данные по звонкам и сохраняем их во временную таблицу ВТ_Звонки.
  3. Объединяем таблицы встреч и звонков во временную таблицу ВТ_Взаимодействия. При этом следим за строгим совпадением типов и порядка полей.
  4. Выполняем финальный запрос: соединяем Справочник.Партнеры с ВТ_Взаимодействия по полю Ссылка = Контрагент.

Пример реализации пакетного запроса:


ВЫБРАТЬ
	Встреча.Ссылка КАК Ссылка,
	Встреча.Описание КАК Описание,
	Встреча.Комментарий КАК Комментарий,
	Встреча.ИнтекоОбъект КАК ИнтекоОбъект,
	Встреча.ИнтекоПодразделение КАК ИнтекоПодразделение,
	Встреча.Автор КАК Автор,
	Встреча.Дата КАК Дата,
	ВЫБОР
		КОГДА ВстречаУчастники.Контакт ССЫЛКА Справочник.КонтактныеЛицаПартнеров
			ТОГДА ВЫРАЗИТЬ(ВстречаУчастники.Контакт КАК Справочник.КонтактныеЛицаПартнеров).Владелец
		ИНАЧЕ ВстречаУчастники.Контакт
	КОНЕЦ КАК Контрагент
ПОМЕСТИТЬ ВТ_Встречи
ИЗ
	Документ.Встреча КАК Встреча
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.Встреча.Участники КАК ВстречаУчастники
		ПО Встреча.Ссылка = ВстречаУчастники.Ссылка
ГДЕ
	&ВыводитьВстречи
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ТелефонныйЗвонок.Ссылка КАК Ссылка,
	ТелефонныйЗвонок.Описание КАК Описание,
	ТелефонныйЗвонок.Комментарий КАК Комментарий,
	ТелефонныйЗвонок.ИнтекоОбъект КАК ИнтекоОбъект,
	ТелефонныйЗвонок.ИнтекоПодразделение КАК ИнтекоПодразделение,
	ТелефонныйЗвонок.Автор КАК Автор,
	ТелефонныйЗвонок.Дата КАК Дата,
	ВЫБОР
		КОГДА ТелефонныйЗвонок.АбонентКонтакт ССЫЛКА Справочник.КонтактныеЛицаПартнеров
			ТОГДА ВЫРАЗИТЬ(ТелефонныйЗвонок.АбонентКонтакт КАК Справочник.КонтактныеЛицаПартнеров).Владелец
		ИНАЧЕ ТелефонныйЗвонок.АбонентКонтакт
	КОНЕЦ КАК Контрагент
ПОМЕСТИТЬ ВТ_Звонки
ИЗ
	Документ.ТелефонныйЗвонок КАК ТелефонныйЗвонок
ГДЕ
	&ВыводитьЗвонки
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВТ.Ссылка КАК Ссылка,
	ВТ.Описание КАК Описание,
	ВТ.Комментарий КАК Комментарий,
	ВТ.ИнтекоОбъект КАК ИнтекоОбъект,
	ВТ.ИнтекоПодразделение КАК ИнтекоПодразделение,
	ВТ.Автор КАК Автор,
	ВТ.Дата КАК Дата,
	ВТ.Контрагент КАК Контрагент
ПОМЕСТИТЬ ВТ_Взаимодействия
ИЗ
	ВТ_Встречи КАК ВТ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	ВТ.Ссылка,
	ВТ.Описание,
	ВТ.Комментарий,
	ВТ.ИнтекоОбъект,
	ВТ.ИнтекоПодразделение,
	ВТ.Автор,
	ВТ.Дата,
	ВТ.Контрагент
ИЗ
	ВТ_Звонки КАК ВТ
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Партнеры.Ссылка КАК Партнер,
	Партнеры.Наименование КАК ПартнерНаименование,
	Взаимодействия.Ссылка КАК Взаимодействие,
	Взаимодействия.Дата КАК Дата,
	Взаимодействия.Автор КАК Автор,
	Взаимодействия.Описание КАК Описание,
	Взаимодействия.Комментарий КАК Комментарий,
	Взаимодействия.ИнтекоОбъект КАК ИнтекоОбъект,
	Взаимодействия.ИнтекоПодразделение КАК ИнтекоПодразделение
ИЗ
	Справочник.Партнеры КАК Партнеры
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Взаимодействия КАК Взаимодействия
		ПО Партнеры.Ссылка = Взаимодействия.Контрагент

Способ 2. Левое соединение двух источников и функция ЕСТЬNULL

Если необходимо выполнять отдельные соединения для встреч и звонков, чтобы хранить их атрибуты независимо, объединение одноименных колонок (например, Описание из встреч и Описание1 из звонков) выполняется с помощью функции ЕСТЬNULL.

Проанализируем фрагмент запроса:


ВЫБРАТЬ
	Партнеры.Ссылка КАК Партнер,
	ЕСТЬNULL(ВТ_Встречи.Описание, ВТ_Звонки.Описание) КАК Описание,
	ЕСТЬNULL(ВТ_Встречи.Автор, ВТ_Звонки.Автор) КАК Автор,
	ЕСТЬNULL(ВТ_Встречи.Дата, ВТ_Звонки.Дата) КАК Дата
ИЗ
	Справочник.Партнеры КАК Партнеры
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Встречи КАК ВТ_Встречи
		ПО Партнеры.Ссылка = ВТ_Встречи.Контрагент
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Звонки КАК ВТ_Звонки
		ПО Партнеры.Ссылка = ВТ_Звонки.Контрагент

Функция ЕСТЬNULL проверяет значение первого выражения: если по встречам данные отсутствуют (значение NULL), возвращается значение из звонков.

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

В Системе компоновки данных вовсе не обязательно писать один громоздкий запрос с соединениями. Платформа 1С позволяет разделить логику на самостоятельные наборы данных и настроить связи между ними в интерфейсе схемы компоновки.

Проанализируем порядок действий:

  1. На вкладке «Наборы данных» создаем три набора данных типа «Запрос»:
    • НаборДанных_Партнеры — запрос выбора всех партнеров: ВЫБРАТЬ Партнеры.Ссылка КАК Партнер ИЗ Справочник.Партнеры КАК Партнеры.
    • НаборДанных_Встречи — запрос выборки встреч с нужными отборами и условиями.
    • НаборДанных_Звонки — запрос выборки звонков.
  2. Переходим на вкладку «Связи наборов данных».
  3. Добавляем новую связь:
    • Источник связи: НаборДанных_Партнеры
    • Приемник связи: НаборДанных_Встречи
    • Выражение источника: Партнер
    • Выражение приемника: Контрагент
  4. Добавляем аналогичную связь для второго набора:
    • Источник связи: НаборДанных_Партнеры
    • Приемник связи: НаборДанных_Звонки
    • Выражение источника: Партнер
    • Выражение приемника: Контрагент

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

← На главную