В современных конфигурациях 1С, таких как Управление торговлей 11.4, ERP 2.5 или Комплексная автоматизация 2.4, работа с адресами контрагентов часто вызывает вопросы у разработчиков. Основная сложность заключается в том, что адрес — это не просто строка, а сложная структура. Рассмотрим подробнее, как правильно составить запрос, чтобы получить адресные данные, и как избежать типичных ошибок, таких как «размножение» строк в отчете.
Прежде чем приступать к написанию кода, проанализируем, где именно хранятся адреса. В 1С для этого используется табличная часть КонтактнаяИнформация, которая есть у справочников Контрагенты, Партнеры, ФизическиеЛица и многих других.
Важно понимать, что в этой таблице для одного контрагента может быть несколько записей: юридический адрес, фактический адрес, почтовый адрес, телефон, электронная почта и так далее. Каждая запись идентифицируется полем Вид (ссылка на справочник ВидыКонтактнойИнформации).
В таблице есть два ключевых поля для адреса:
Начнем с базового примера. Допустим, нам нужно получить список всех контрагентов и их юридические адреса. Для этого мы используем ЛЕВОЕ СОЕДИНЕНИЕ со справочником контактной информации.
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
ЕСТЬNULL(КонтрагентыКонтактнаяИнформация.Представление, "") КАК Адрес
ИЗ
Справочник.Контрагенты КАК Контрагенты
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты.КонтактнаяИнформация КАК КонтрагентыКонтактнаяИнформация
ПО Контрагенты.Ссылка = КонтрагентыКонтактнаяИнформация.Ссылка
И КонтрагентыКонтактнаяИнформация.Вид = &ВидАдреса
Обратите внимание на крайне важный момент: условие КонтрагентыКонтактнаяИнформация.Вид = &ВидАдреса должно находиться именно в условии связи ПО, а не в разделе ГДЕ. Если вы вынесете его в ГДЕ, то контрагенты без заполненного адреса просто не попадут в выборку, так как ЛЕВОЕ СОЕДИНЕНИЕ фактически превратится во ВНУТРЕННЕЕ. Разобраться в тонкостях работы условий связи поможет руководство по соединениям в запросах.
Разберем ситуацию, с которой часто сталкиваются начинающие разработчики: почему в запросе получается слишком много строк? Рассмотрим пример, когда мы хотим получить контрагента, его контактное лицо и его адрес одновременно. Если просто соединить таблицы Партнеры, КонтактныеЛица и КонтактнаяИнформация, количество строк может увеличиться в геометрической прогрессии.
Это происходит потому, что у одного партнера может быть 3 контактных лица, а у контрагента — 3 вида контактной информации (телефон, почта, адрес). В итоге 1 контрагент превращается в 9 строк (3 лица * 3 вида КИ). Чтобы этого избежать, выясним причину: нам нужно жестко ограничивать типы данных при соединении.
Проанализируем более профессиональный подход. Вместо одного огромного соединения, разделим получение данных на этапы. Это сделает код понятным и позволит избежать дублей. Для изучения подобной логики подойдёт пример фильтрации данных через временные таблицы в запросе.
Шаг 1. Подготовка основных данных. Сначала выберем контрагентов и их основных менеджеров (которые часто хранятся в связанном справочнике Партнеры).
ВЫБРАТЬ
Спр.Ссылка КАК Контрагент,
Спр.Партнер.ОсновнойМенеджер КАК Менеджер
ПОМЕСТИТЬ втКонтрагентМенеджер
ИЗ
Справочник.Контрагенты КАК Спр;
Шаг 2. Извлечение контактной информации. Теперь выберем всю контактную информацию для этих контрагентов во временную таблицу. Это позволит нам в дальнейшем обращаться к этой таблице несколько раз под разными алиасами.
ВЫБРАТЬ
КИ.Ссылка КАК Ссылка,
КИ.Вид КАК ВидКИ,
КИ.Представление КАК Представление
ПОМЕСТИТЬ втКонтактнаяИнформация
ИЗ
Справочник.Контрагенты.КонтактнаяИнформация КАК КИ
ГДЕ
КИ.Ссылка В (ВЫБРАТЬ втКонтрагентМенеджер.Контрагент ИЗ втКонтрагентМенеджер);
Шаг 3. Итоговое соединение. Теперь соединяем основную таблицу с контактной информацией столько раз, сколько типов данных нам нужно (адрес, телефон, почта).
ВЫБРАТЬ
втКМ.Контрагент КАК Контрагент,
втКМ.Менеджер КАК Менеджер,
втАдрес.Представление КАК Адрес,
втТелефон.Представление КАК Телефон,
втEmail.Представление КАК ЭлектроннаяПочта
ИЗ
втКонтрагентМенеджер КАК втКМ
ЛЕВОЕ СОЕДИНЕНИЕ втКонтактнаяИнформация КАК втАдрес
ПО втКМ.Контрагент = втАдрес.Ссылка
И втАдрес.ВидКИ = &ВидАдрес
ЛЕВОЕ СОЕДИНЕНИЕ втКонтактнаяИнформация КАК втТелефон
ПО втКМ.Контрагент = втТелефон.Ссылка
И втТелефон.ВидКИ = &ВидТелефон
ЛЕВОЕ СОЕДИНЕНИЕ втКонтактнаяИнформация КАК втEmail
ПО втКМ.Контрагент = втEmail.Ссылка
И втEmail.ВидКИ = &ВидEmail
Теперь перейдем к самой сложной части: фильтрации. Рассмотрим два способа реализации.
Самый простой, но «грязный» метод — поиск подстроки в поле Представление.
ГДЕ
КонтрагентыКонтактнаяИнформация.Представление ПОДОБНО "%Ленина%"
И КонтрагентыКонтактнаяИнформация.Представление ПОДОБНО "%Ростов-на-Дону%"
Минусы: Это работает медленно на больших базах и крайне неточно. Например, если в названии компании есть слово «Ленина» или если в городе есть «переулок Ленина» и «улица Ленина», такой фильтр выдаст обе записи.
Если адрес в базе заполнялся корректно через классификатор (ФИАС/ГАР), то внутри поля ЗначенияПолей хранится подробная структура. Напрямую в запросе 1С не может «распарсить» JSON, но мы можем использовать хитрость в Системе компоновки данных (СКД).
В СКД можно создать вычисляемое поле или использовать функции общих модулей БСП. Рассмотрим алгоритм:
УправлениеКонтактнойИнформацией.ПолучитьСтруктуруАдресаИзСтроки() для поля ЗначенияПолей.Город, Улица, Дом.Если же стоит задача сделать это именно запросом для массовой обработки, то технически правильнее всего будет сначала найти уникальный идентификатор (GUID) улицы в адресном классификаторе, а затем искать вхождение этого GUID в строке ЗначенияПолей с помощью того же оператора ПОДОБНО. Поскольку GUID уникален, это даст 100% точность, в отличие от поиска по названию.
Для создания качественного отчета по географии клиентов в УТ 11.4, рекомендуем использовать механизм СКД. Вы можете вытащить в запрос поле Представление для вывода пользователю и поле ЗначенияПолей для программной обработки.
Не забывайте проверять настройки справочника Виды контактной информации. Если в настройках вида адреса стоит флаг "Запретить ввод не по классификатору", вы можете быть уверены, что структура внутри ЗначенияПолей будет однородной, и ваши отборы по конкретным полям адреса будут работать корректно.
Таким образом, мы рассмотрели, как правильно соединять таблицы контактной информации, выяснили причину появления дублей и определили наиболее надежные методы фильтрации данных по адресным признакам.