Получение контактной информации, такой как адрес регистрации (прописки) сотрудника, является классической задачей при разработке печатных форм трудовых договоров или кадровых отчетов. Несмотря на кажущуюся простоту, новички часто сталкиваются с трудностями при использовании конструктора запросов или при попытке "достучаться" до адреса напрямую через справочник сотрудников. В этой статье мы разберем, как правильно извлекать эти данные, проанализируем типичные ошибки и рассмотрим наиболее эффективные методы, предлагаемые платформой 1С и библиотекой стандартных подсистем (БСП). Для быстрого решения подобных задач без необходимости ручной разработки кода можно использовать готовую внешнюю печатную форму трудового договора для 1С.
Рассмотрим ситуацию, с которой часто начинают начинающие разработчики. При попытке добавить адрес в конструкторе запроса многие выбирают таблицу Справочник.ФизическиеЛица.КонтактнаяИнформация и соединяют её со справочником физических лиц. Однако, если сделать это без жесткого фильтра по Виду контактной информации, возникнет серьезная проблема — "картезианское произведение" или дублирование строк.
Проанализируем, почему это происходит. У одного физического лица в базе может быть заполнено множество записей контактной информации: мобильный телефон, домашний телефон, адрес проживания, адрес регистрации, личный email и рабочий email. Если в запросе мы просто соединяем ФизическиеЛица с их КонтактнойИнформацией, система выдаст столько строк для одного сотрудника, сколько видов контактов у него заведено. Если у сотрудника 5 видов контактов, в результате запроса он повторится 5 раз. Именно на это указывали участники обсуждения, критикуя некорректно составленный запрос.
Для того чтобы получить конкретно адрес регистрации через запрос, необходимо выполнить левое соединение с таблицей контактной информации и обязательно наложить условие на вид этой информации. Выясним, как это реализовать по шагам:
Документ.ПриемНаРаботу или Справочник.Сотрудники).ФизическиеЛица, так как адрес регистрации привязан именно к человеку (физлицу), а не к его позиции как сотрудника.РегистрСведений.КонтактнаяИнформация (в современных конфигурациях данные хранятся в регистре, а не в табличной части справочника).ФизическиеЛица.Ссылка и КонтактнаяИнформация.Объект.Вид. Оно должно быть равно конкретному значению из справочника ВидыКонтактнойИнформации.Пример правильно сконструированного текста запроса будет выглядеть следующим образом:
ВЫБРАТЬ
ПриемНаРаботу.Ссылка КАК Ссылка,
ПриемНаРаботу.ФизическоеЛицо КАК ФизическоеЛицо,
КИ_Адрес.Представление КАК АдресРегистрации
ИЗ
Документ.ПриемНаРаботу КАК ПриемНаРаботу
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КонтактнаяИнформация КАК КИ_Адрес
ПО ПриемНаРаботу.ФизическоеЛицо = КИ_Адрес.Объект
И КИ_Адрес.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица)
ГДЕ
ПриемНаРаботу.Ссылка = &Ссылка
Использование оператора ЗНАЧЕНИЕ позволяет жестко ограничить выборку только одним типом записи, что исключает появление дублей и гарантирует получение именно адреса по прописке.
Если задача стоит в получении адреса для одного конкретного объекта (например, при формировании печатной формы в Word или табличного документа), использование чистого запроса может быть избыточным. В типовых конфигурациях (ЗУП 3.1, БП 3.0, ERP) реализован мощный программный интерфейс для работы с контактной информацией. В качестве готового примера выгрузки кадровых сведений в текстовые шаблоны подойдёт обработка для формирования дополнительных соглашений в Word из кадровых переводов.
Рассмотрим функцию КонтактнаяИнформацияОбъекта из общего модуля УправлениеКонтактнойИнформацией. Этот метод позволяет получить представление адреса в одну строку кода, не заботясь о структуре регистров.
Посмотрим на пример кода, который возвращает строковое представление адреса регистрации:
// Определяем физлицо, для которого нужен адрес
ФизическоеЛицо = СсылкаНаОбъект.ФизическоеЛицо;
// Получаем вид контактной информации (лучше использовать предопределенные значения)
ВидКИ = Справочники.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица;
// Вызываем функцию БСП
АдресРегистрации = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(ФизическоеЛицо, ВидКИ);
// Теперь переменную АдресРегистрации можно передать в параметр печатной формы
// Например, в Word через закладки:
// Word.Bookmarks("RegistrationAddress").Range.Text = АдресРегистрации;
Важно отметить, что данный метод по умолчанию возвращает Представление (готовую строку). Если вам нужно разобрать адрес по полям (город, улица, дом), необходимо работать со структурой или JSON-строкой, которая также может быть получена этим методом.
Проанализируем ситуацию, когда нам нужно вывести адреса регистрации для целого списка сотрудников (например, в реестре). Вызывать функцию КонтактнаяИнформацияОбъекта в цикле — плохая практика, так как это приведет к огромному количеству мелких запросов к базе данных и существенно замедлит работу системы.
Для таких случаев в БСП предусмотрен метод СформироватьЗапросПоКонтактнойИнформации. Он позволяет подготовить текст запроса с правильными соединениями автоматически. Разберем, как это работает:
// Создаем массив объектов, для которых нужны адреса
МассивФизлиц = Новый Массив;
МассивФизлиц.Добавить(Физлицо1);
МассивФизлиц.Добавить(Физлицо2);
// Описываем виды контактной информации
МассивВидов = Новый Массив;
МассивВидов.Добавить(Справочники.ВидыКонтактнойИнформации.АдресПоПропискеФизическиеЛица);
// Получаем таблицу данных за один запрос
ТаблицаАдресов = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъектов(МассивФизлиц, МассивВидов, ТекущаяДата());
// Теперь мы можем быстро найти адрес для конкретного лица в полученной таблице
Этот подход является наиболее производительным и рекомендуется для использования в сложных отчетах и пакетных обработках данных.
При работе с адресами следует учитывать несколько технических особенностей платформы:
Физических лиц. Если вы попытаетесь соединить регистр со справочником Сотрудники, вы, скорее всего, получите пустой результат, так как записи в регистре привязаны к ссылке физлица.Представление хранится адрес в том виде, в котором его ввел пользователь. В поле Значение (или в полях XML/JSON) хранятся структурированные данные. Для печатных форм обычно достаточно Представления.// ПРЕДСТАВЛЕНИЯ_КИ, знайте, что система сама подставит нужные соединения при выполнении запроса.Подводя итог, можно сказать: наиболее гибким и "правильным" способом для программиста является использование встроенных функций БСП (модуль УправлениеКонтактнойИнформацией). Это избавляет от необходимости вручную прописывать сложные соединения в конструкторе и защищает от ошибок, связанных с изменением структуры метаданных в будущих обновлениях платформы.