Как правильно получить данные из табличной части контактной информации в запросе 1С

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

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

Выясним причину ошибки при обращении к табличной части

Рассмотрим две ключевые причины, из-за которых возникают сложности при выборке данных контактной информации:

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

Важно также помнить, что реквизит Ссылка внутри табличной части хранит ссылку на объект-владелец этой табличной части (например, на справочник Контрагенты или КонтактныеЛица).

Решение 1: Запрос к табличной части с группировкой и функцией МАКСИМУМ

Наиболее эффективным и простым способом свернуть несколько строк табличной части в одну строку результата является прямой запрос к табличной части с применением агрегатной функции МАКСИМУМ и группировкой по объекту-владельцу.

Разберем по шагам создание такого запроса для получения телефона и email контактного лица контрагента:


Запрос1 = Новый Запрос;
Запрос1.УстановитьПараметр("Ссылка", ТекущийДокумент.Контрагент.КонтактноеЛицо);

Запрос1.Текст = 
"ВЫБРАТЬ
|	КонтактнаяИнформация.Ссылка.Представление КАК Представление,
|	МАКСИМУМ(КонтактнаяИнформация.АдресЭП) КАК АдресЭП,
|	МАКСИМУМ(КонтактнаяИнформация.НомерТелефона) КАК НомерТелефона
|ИЗ
|	Справочник.КонтактныеЛица.КонтактнаяИнформация КАК КонтактнаяИнформация
|ГДЕ
|	КонтактнаяИнформация.Ссылка = &Ссылка
|СГРУППИРОВАТЬ ПО
|	КонтактнаяИнформация.Ссылка.Представление";

Выборка = Запрос1.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда
	ОбластьМакета.Параметры.Контрагент = Выборка.Представление;
	ОбластьМакета.Параметры.ТелефонКонтрагента = Выборка.НомерТелефона;
	ОбластьМакета.Параметры.EmailКонтрагента = Выборка.АдресЭП;
КонецЕсли;

Посмотрим, как работает данный механизм: так как телефон и email хранятся в разных строках табличной части, функция МАКСИМУМ отбрасывает пустые значения в каждой из колонок и сводит непустые строки в одну итоговую запись для каждого владельца.

Решение 2: Использование соединения таблиц

Если необходимо сформировать один общий запрос, получающий данные документа и связанные контакты контрагента, лучше всего применить ЛЕВОЕ СОЕДИНЕНИЕ таблицы документа с табличной частью справочника.

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


Запрос1 = Новый Запрос;
Запрос1.УстановитьПараметр("ТекущийДокумент", ТекущийДокумент);

Запрос1.Текст = 
"ВЫБРАТЬ
|	ПриемИПередачаВРемонт.Ссылка КАК ДокументСсылка,
|	МАКСИМУМ(КонтактныеЛицаКИ.АдресЭП) КАК АдресЭП,
|	МАКСИМУМ(КонтактныеЛицаКИ.НомерТелефона) КАК НомерТелефона
|ИЗ
|	Документ.ПриемИПередачаВРемонт КАК ПриемИПередачаВРемонт
|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КонтактныеЛица.КонтактнаяИнформация КАК КонтактныеЛицаКИ
|		ПО ПриемИПередачаВРемонт.Контрагент.КонтактноеЛицо = КонтактныеЛицаКИ.Ссылка
|ГДЕ
|	ПриемИПередачаВРемонт.Ссылка = &ТекущийДокумент
|СГРУППИРОВАТЬ ПО
|	ПриемИПередачаВРемонт.Ссылка";

Выборка = Запрос1.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
	ОбластьМакета.Параметры.ТелефонКонтрагента = Выборка.НомерТелефона;
	ОбластьМакета.Параметры.EmailКонтрагента = Выборка.АдресЭП;
КонецЕсли;

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

Рекомендации по отладке запросов

При отладке сложных запросов к табличным частям рекомендуется использовать следующие приемы:

← На главную