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

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

При разработке отчетов, печатных форм или обработок в «1С:Предприятие 8.3» программисты часто сталкиваются с задачей получения контактной информации контрагентов или собственных организаций. На первый взгляд задача кажется тривиальной: написать запрос к источнику данных и вывести результат. Однако при работе с современными конфигурациями, построенными на базе Библиотеки стандартных подсистем (БСП), такими как «Бухгалтерия для Казахстана 3.0» или «Бухгалтерия предприятия 3.0», разработчики часто совершают типичные ошибки, из-за которых запросы возвращают пустой результат.

В этой статье мы подробно проанализируем, почему стандартные запросы к регистру сведений КонтактнаяИнформация перестают работать, разберем ключевые ошибки в логике построения запросов и рассмотрим два наиболее эффективных способа решения этой проблемы: с помощью исправленного SQL-подобного запроса 1С и через использование готового программного интерфейса БСП.

В чем кроется главная причина проблемы?

Давайте выясним, почему старые методы запросов к контактной информации не работают в новых редакциях конфигураций. В устаревших версиях систем (например, в «Бухгалтерии 2.0») контактная информация физических лиц, контрагентов и организаций действительно хранилась в независимом регистре сведений РегистрСведений.КонтактнаяИнформация.

В современных конфигурациях редакции 3.0 архитектура хранения данных кардинально изменилась:

  1. Перенос данных в табличные части: Вся контактная информация теперь хранится непосредственно в табличных частях справочников-владельцев. Для организаций это табличная часть КонтактнаяИнформация справочника Организации (то есть Справочник.Организации.КонтактнаяИнформация). Сам регистр сведений может физически присутствовать в структуре метаданных для обеспечения обратной совместимости, но он либо пуст, либо не обновляется.
  2. Сериализация полей адреса в XML/JSON: Раньше отдельные составляющие адреса (город, улица, дом, квартира) записывались в отдельные текстовые колонки (Поле1, Поле2 ... Поле9). Теперь детальные поля адреса упаковываются в одну строку в формате XML или JSON и записываются в поле ЗначенияПолей. В запросе разобрать эту строку невозможно. Строковое представление адреса целиком хранится в поле Представление.

Таким образом, пытаясь обратиться напрямую к регистру сведений РегистрСведений.КонтактнаяИнформация и выбирая поля Поле4 или Поле6, мы гарантированно получим либо пустой результат, либо некорректные данные.

---

Разбор ошибок в исходном коде автора

Проанализируем программный код, который был представлен в начале обсуждения, и укажем на критические ошибки, которые не позволяли запросу отработать правильно.

Ошибка первая: Сравнение ссылки с наименованием в параметрах.

В исходном запросе мы видим условие:

КонтактнаяИнформация.Вид.Наименование = &ЮридическийВид

При этом в коде параметр устанавливается следующим образом:

Запрос.УстановитьПараметр("ЮридическийВид", Справочники.ВидыКонтактнойИнформации.НайтиПоНаименованию("Юридический адрес организации"));

Функция НайтиПоНаименованию() возвращает Ссылка на элемент справочника ВидыКонтактнойИнформации. В результате в запросе происходило сравнение строки (наименования вида) со ссылкой на элемент справочника. Такое условие никогда не выполнится, и запрос вернет пустую выборку. Правильно сравнивать ссылки напрямую: КонтактнаяИнформация.Вид = &ЮридическийВид.

Ошибка вторая: Некорректное соединение таблиц (Декартово произведение).

Посмотрим на конструкцию связи таблиц во ИЗ:


ИЗ
    РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Организации КАК Организации
        ПО КонтактнаяИнформация.Объект = Организации.Ссылка,
    (ВЫБРАТЬ ... ) КАК Юр

Использование запятой перед вложенным запросом Юр без указания явного условия соединения (ПО) приводит к полному (декартову) произведению таблиц. Это сильно снижает производительность СУБД. Более того, жесткие фильтры в секции ГДЕ для левой и правой таблиц приводят к тому, что если у организации отсутствует хотя бы один из видов адреса (например, нет фактического), то запрос не вернет вообще ничего — пропадет даже юридический адрес.

---

Решение №1. Использование объектной модели БСП (Рекомендуемый способ)

Разработчики БСП настоятельно рекомендуют отказаться от написания прямых запросов к табличным частям для получения контактной информации. Для этого в системе предусмотрены готовые, оптимизированные функции общего модуля УправлениеКонтактнойИнформацией.

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


// Определим организацию, по которой нужно получить данные
ОрганизацияСсылка = Справочники.Организации.НайтиПоРеквизиту("БИН", "123456789012"); // Пример поиска

Если ЗначениеЗаполнено(ОрганизацияСсылка) Тогда
    
    // Получаем виды контактной информации (предопределенные элементы справочника)
    ВидФактический = Справочники.ВидыКонтактнойИнформации.ФактАдресОрганизации;
    ВидЮридический = Справочники.ВидыКонтактнойИнформации.ЮрАдресОрганизации;
    
    // Получаем фактический адрес организации в виде строки
    ФактическийАдресСтрокой = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
        ОрганизацияСсылка, 
        ВидФактический
    );
    
    // Получаем юридический адрес организации в виде строки
    ЮридическийАдресСтрокой = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
        ОрганизацияСсылка, 
        ВидЮридический
    );
    
    // Выводим результат для проверки
    Сообщить("Фактический адрес: " + ФактическийАдресСтрокой);
    Сообщить("Юридический адрес: " + ЮридическийАдресСтрокой);
    
КонецЕсли;

Этот способ крайне прост в сопровождении. Функция КонтактнаяИнформацияОбъекта самостоятельно определяет актуальное место хранения данных, корректно считывает XML/JSON структуру и возвращает готовое текстовое представление адреса.

---

Решение №2. Написание правильного запроса

Если вам все же необходимо получить адреса именно через запрос (например, для использования в схеме компоновки данных (СКД), динамическом списке или сложном отчете), мы должны переписать его структуру с нуля.

Давайте пошагово разберем логику построения правильного запроса:

  1. В качестве основного источника данных выберем справочник Организации.
  2. Для получения фактического адреса выполним первое ЛЕВОЕ СОЕДИНЕНИЕ с табличной частью Организации.КонтактнаяИнформация. Условием связи будет равенство ссылок организации и ограничение по виду КИ (фактический адрес).
  3. Для получения юридического адреса выполним второе ЛЕВОЕ СОЕДИНЕНИЕ с этой же табличной частью организации, но уже с фильтром по юридическому виду КИ.
  4. Использование ЛЕВОГО СОЕДИНЕНИЯ гарантирует нам, что даже если один из адресов не заполнен, система все равно вернет саму организацию и тот адрес, который заполнен.

Ниже представлен готовый программный код с исправленным и оптимизированным запросом:


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

// Передаем параметры в запрос. 
// Используем предопределенные элементы видов КИ, чтобы избежать поиска по наименованию.
Запрос.УстановитьПараметр("Организация", ВыбраннаяОрганизация);
Запрос.УстановитьПараметр("ВидФактический", Справочники.ВидыКонтактнойИнформации.ФактАдресОрганизации);
Запрос.УстановитьПараметр("ВидЮридический", Справочники.ВидыКонтактнойИнформации.ЮрАдресОрганизации);

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

Пока Выборка.Следующий() Цикл
    // Теперь мы гарантированно получаем строковые адреса без пустых строк
    ЮрАдрес = Выборка.ЮрАдрес;
    ФактАдрес = Выборка.ФактАдрес;
    
    // Дальнейшая обработка адресов...
КонецЦикла;

Обратите внимание на использование функции ЕСТЬNULL в запросе. Если у организации не окажется заполненного фактического или юридического адреса, СУБД вернет значение NULL. Функция ЕСТЬNULL(..., "") автоматически заменяет NULL на пустую строку, что предотвращает возникновение ошибок типов при дальнейшей работе с данными в коде.

Также важным изменением является отказ от поиска видов адресов по наименованию в коде. В типовых конфигурациях 1С виды контактной информации являются предопределенными элементами. Конструкция вида Справочники.ВидыКонтактнойИнформации.ЮрАдресОрганизации работает быстрее и надежнее, так как наименование элемента в пользовательском режиме может быть изменено бухгалтером, а предопределенное имя (идентификатор) в конфигураторе остается неизменным.

← На главную