При разработке печатных форм в среде 1С:Предприятие 8.3 одной из наиболее частых задач является вывод контактной информации, в частности — адреса по прописке. Несмотря на кажущуюся простоту, начинающие разработчики часто сталкиваются с трудностями: от пустых результатов в запросах до ошибок обращения к предопределенным элементам. В этой статье мы подробно разберем, как правильно извлекать данные о прописке, используя как прямые запросы к базе данных, так и мощные механизмы Библиотеки стандартных подсистем (БСП).
Рассмотрим ситуацию, с которой часто начинают программисты: попытка написать запрос к табличной части контактной информации. Основная проблема здесь кроется в обращении к видам контактной информации. В конфигурациях, построенных на БСП (таких как ЗУП 3.1, БП 3.0, ERP 2), виды контактной информации разделены по группам. Для справочника ФизическиеЛица вид адреса называется не просто АдресПоПрописке, а АдресПоПропискеФизическиеЛица.
Проанализируем еще одну критическую ошибку в запросе: сравнение ссылки с представлением. Попытка установить фильтр ГДЕ АдресПоПрописке.Представление = &Представление, где в параметр передается ссылка на справочник, заведомо обречена на провал. Программа пытается сравнить уникальный идентификатор (ссылку) со строкой адреса, что всегда возвращает «Ложь».
Если вам необходимо получить адрес в рамках сложного запроса (например, при формировании реестра сотрудников), следует использовать соединение с таблицей контактной информации. Разберем правильный вариант построения запроса, который учитывает связь сотрудника с физическим лицом.
Важный нюанс: Контактная информация в современных конфигурациях может храниться либо в табличной части КонтактнаяИнформация справочника ФизическиеЛица, либо в одноименном регистре сведений. Рассмотрим классический вариант с табличной частью:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сотрудники.Ссылка КАК Сотрудник,
| АдресПоПрописке.Представление КАК Прописка
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
| ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК АдресПоПрописке
| ПО Сотрудники.ФизическоеЛицо = АдресПоПрописке.Ссылка
| И (АдресПоПрописке.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица))
|ГДЕ
| Сотрудники.Ссылка = &Сотрудник";
Запрос.УстановитьПараметр("Сотрудник", Объект.СсылкаНаСотрудника);
Результат = Запрос.Выполнить();
В данном примере мы используем ЛЕВОЕ СОЕДИНЕНИЕ, чтобы сотрудник попал в выборку даже в том случае, если адрес у него не заполнен. Обратите внимание на условие связи по виду: мы обращаемся к ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица). Это гарантирует, что мы получим именно адрес прописки, а не фактический адрес или номер телефона.
Если вам нужно получить адрес только для одного физического лица, нет необходимости писать громоздкие запросы. В составе БСП есть специализированный общий модуль УправлениеКонтактнойИнформацией, который берет на себя всю работу по поиску данных в нужных таблицах.
Разберем, как правильно вызвать функцию получения представления адреса. Посмотрим на пример кода:
ФизЛицо = Объект.Сотрудник.ФизическоеЛицо;
ВидАдреса = Справочники.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица;
// Получаем строковое представление адреса
АдресПрописки = УправлениеКонтактнойИнформацией.ПредставлениеКонтактнойИнформацииОбъекта(ФизЛицо, ВидАдреса);
Если ПустаяСтрока(АдресПрописки) Тогда
АдресПрописки = "Адрес не указан";
КонецЕсли;
ДанныеЗаголовка.Вставить("АдресПр", АдресПрописки);
Этот метод гораздо надежнее, так как он автоматически учитывает настройки системы: хранятся ли данные в табличной части или в регистре сведений. Проанализируем типичную ошибку: если при вызове этой функции вы получаете сообщение «Поле объекта не обнаружено (АдресПоПрописке)», значит, вы пытаетесь обратиться к предопределенному элементу, имя которого в метаданных отличается. Всегда проверяйте имя в Конфигураторе или пользуйтесь контекстной подсказкой 1С при вводе Справочники.ВидыКонтактнойИнформации....
Представим ситуацию: вы формируете печатную форму сразу для 100 сотрудников. Вызов функции ПредставлениеКонтактнойИнформацииОбъекта в цикле создаст 100 обращений к базе данных, что существенно замедлит работу системы. Для таких случаев в БСП предусмотрен метод для массовой выборки данных.
Выясним, как это работает. Функция КонтактнаяИнформацияОбъектов принимает массив ссылок и массив видов КИ, возвращая таблицу значений с результатами. Рассмотрим пример:
// Подготовим массивы
МассивСотрудников = СписокСотрудников.ВыгрузитьЗначения();
МассивФизЛиц = Новый Массив;
Для Каждого Сотр Из МассивСотрудников Цикл
МассивФизЛиц.Добавить(Сотр.ФизическоеЛицо);
КонецЦикла;
МассивВидов = Новый Массив;
МассивВидов.Добавить(Справочники.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица);
// Получаем данные одним запросом к БД
ТаблицаАдресов = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъектов(МассивФизЛиц, МассивВидов);
// Теперь можно быстро найти адрес для каждого сотрудника
Для Каждого СтрФизЛицо Из МассивФизЛиц Цикл
ПараметрыПоиска = Новый Структура("Объект, Вид", СтрФизЛицо, МассивВидов[0]);
НайденныеСтроки = ТаблицаАдресов.НайтиСтроки(ПараметрыПоиска);
Если НайденныеСтроки.Количество() > 0 Тогда
ТекущийАдрес = НайденныеСтроки[0].Представление;
Иначе
ТекущийАдрес = "";
КонецЕсли;
// ... дальнейшая обработка
КонецЦикла;
Иногда формат печатной формы требует вывести адрес не одной строкой, а разбить его по полям. В базе данных адрес часто хранится в виде XML или JSON (в поле ЗначенияПолей). Чтобы не парсить эти строки вручную, воспользуемся инструментами БСП.
Проанализируем процесс преобразования внутренней строки в структуру:
ЗначенияПолей из контактной информации.УправлениеКонтактнойИнформацией.АдресИзЗначенияПолей(ЗначениеПолей).Город, Улица, Дом, Индекс и так далее.
// Пример получения индекса
ЗначениеПолей = ... // получаем из запроса или функции БСП
СтруктураАдреса = УправлениеКонтактнойИнформацией.АдресИзЗначенияПолей(ЗначениеПолей);
ПочтовыйИндекс = СтруктураАдреса.Индекс;
Город = СтруктураАдреса.Город;
При выводе адреса в печатные формы стоит учитывать несколько важных моментов:
ФизическиеЛица или регистр контактной информации, вместо адреса он увидит пустое поле или получит ошибку доступа. В таких случаях код получения адреса стоит выносить в привилегированный модуль.Подводя итог, можно сказать, что наиболее современным и правильным способом является использование функций программного интерфейса БСП. Это гарантирует корректную работу кода при обновлениях конфигурации и смене способа хранения данных в платформе.