При разработке или модификации печатных форм в современных конфигурациях на базе 1С:Предприятие 8.3 (таких как УТ 11, ERP 2.x или КА 2.x) разработчики часто сталкиваются с трудностями при получении контактной информации. В отличие от старых версий, где данные хранились в отдельном регистре сведений, в актуальных релизах контактная информация (КИ) хранится непосредственно в табличных частях объектов. Разберем подробно, как правильно извлечь телефон контактного лица и вывести его в макет.
Самый надежный и "правильный" с точки зрения архитектуры 1С способ — использование функций общего модуля УправлениеКонтактнойИнформацией. Этот модуль входит в состав Библиотеки Стандартных Подсистем (БСП) и берет на себя все сложности по поиску актуальных записей, проверке типов и видов КИ.
Рассмотрим ситуацию, когда у нас есть ссылка на документ ЗаказКлиента, и нам нужно получить строковое представление телефона его контактного лица. Для этого воспользуемся функцией КонтактнаяИнформацияОбъекта. Проанализируем пример кода:
// Определяем ссылку на контактное лицо из документа
КонтактноеЛицоСсылка = СсылкаНаОбъект.КонтактноеЛицо;
// Если контактное лицо заполнено, получаем его телефон
Если ЗначениеЗаполнено(КонтактноеЛицоСсылка) Тогда
// Получаем вид контактной информации (обычно это предопределенный элемент)
ВидКИ = Справочники.ВидыКонтактнойИнформации.ТелефонКонтактногоЛица;
// Вызываем функцию БСП для получения представления КИ
ТелефонПредставление = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
КонтактноеЛицоСсылка,
ВидКИ,
ТекущаяДата()
);
// Заполняем параметр в области макета
ОбластьПодвал.Параметры.Телефон = ТелефонПредставление;
КонецЕсли;
Этот метод хорош тем, что он автоматически обрабатывает ситуацию, если у объекта несколько телефонов или если структура хранения данных изменится в будущих обновлениях платформы. Мы просто передаем ссылку на объект и нужный вид информации, а на выходе получаем готовую строку для печати.
Иногда требуется получить данные массово для списка документов или в рамках одного сложного запроса для оптимизации производительности. В этом случае нам нужно обратиться к табличной части КонтактнаяИнформация справочника КонтактныеЛицаПартнеров.
Выясним причину, по которой простые запросы через точку (например, ЗаказКлиента.КонтактноеЛицо.КонтактнаяИнформация.Представление) часто работают некорректно. Дело в том, что такое обращение возвращает вложенную таблицу в результате запроса, которую неудобно обрабатывать при выводе в ТабличныйДокумент.
Рассмотрим правильную структуру запроса с использованием соединения таблиц:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказКлиента.Ссылка КАК Ссылка,
| КИ_Телефоны.Представление КАК ТелефонКонтактногоЛица
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КонтактныеЛицаПартнеров.КонтактнаяИнформация КАК КИ_Телефоны
| ПО ЗаказКлиента.КонтактноеЛицо = КИ_Телефоны.Ссылка
| И (КИ_Телефоны.Вид = &ВидТелефона)
|ГДЕ
| ЗаказКлиента.Ссылка = &СсылкаНаДокумент";
// Устанавливаем параметры
Запрос.УстановитьПараметр("СсылкаНаДокумент", СсылкаНаДокумент);
Запрос.УстановитьПараметр("ВидТелефона", Справочники.ВидыКонтактнойИнформации.ТелефонКонтактногоЛица);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
ОбластьПодвал.Параметры.Телефон = Выборка.ТелефонКонтактногоЛица;
КонецЕсли;
Важные моменты при составлении запроса:
ЛЕВОЕ СОЕДИНЕНИЕ. Если использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ, то в случае отсутствия телефона у контактного лица, сам документ "исчезнет" из выборки, и печатная форма не сформируется.КонтактнаяИнформация могут храниться и адреса, и телефоны, и email. Без условия КИ_Телефоны.Вид = &ВидТелефона запрос вернет несколько строк на одного человека, что приведет к дублированию данных в печатной форме.Представление, так как именно в нем хранится отформатированный номер телефона (с маской, кодом города и добавочным номером). Поле НомерТелефона обычно содержит только очищенные цифры.Проанализируем ситуацию, когда запрос в консоли возвращает данные, а в коде печатной формы — нет. Рассмотрим основные причины:
1. Ошибка обращения к полям выборки. Если вы в запросе написали КИ_Телефоны.Представление КАК Телефон, то и в коде нужно писать Выборка.Телефон. Программисты часто забывают назначить псевдоним полю или ошибаются в его написании.
2. Несоответствие видов контактной информации. В базе может быть создано несколько видов телефонов (например, "Личный телефон", "Рабочий телефон"). Убедитесь, что вы запрашиваете именно тот вид КИ, который заполнен у ваших контактных лиц. Проверить это можно, открыв карточку контактного лица и посмотрев заголовок поля телефона.
3. Использование устаревших регистров. Попытка найти данные в РегистрСведений.КонтактнаяИнформация в УТ 11.4 часто заканчивается неудачей, так как этот регистр является вспомогательным или вовсе не используется для хранения КИ справочников. Основные данные всегда находятся в табличных частях.
После того как мы получили данные (одним из описанных выше способов), нам необходимо правильно передать их в ТабличныйДокумент. Разберем по шагам процесс вывода:
// 1. Получаем макет
Макет = ПолучитьМакет("ПФ_MXL_МояПечатнаяФорма");
// 2. Получаем область (например, Подвал)
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
// 3. Заполняем параметры из нашей выборки
// Предположим, ВыборкаДетальныеЗаписи — это результат выполнения нашего запроса
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
// Обращаемся к параметру "Телефон", который должен быть создан в макете
ОбластьПодвал.Параметры.Телефон = ВыборкаДетальныеЗаписи.ТелефонКонтактногоЛица;
КонецЕсли;
// 4. Выводим область в результирующий табличный документ
ТабДок.Вывести(ОбластьПодвал);
Помните, что в макете ячейка, в которую выводится телефон, должна иметь тип Параметр, а её имя должно строго совпадать с тем, что вы пишете в коде после ОбластьПодвал.Параметры....
Таким образом, мы рассмотрели два основных способа получения телефона контактного лица. Для разовых задач и простых доработок лучше использовать Метод 1 (функции БСП), так как он минимизирует количество ошибок и делает код более читаемым.