Как в 1С разложить строку с адресом на составляющие: город, улицу, дом и квартиру

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

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

Способ 1: Использование типовых функций БСП

Если вы работаете в современной конфигурации (УТ 11, БП 3.0, ERP 2 и др.), в ней уже интегрирована Библиотека стандартных подсистем (БСП). Разработчики предусмотрели специальные служебные модули для работы с контактной информацией. Рассмотрим использование функции, которая берет на себя основной труд по разбору строки.

Наиболее часто для этих целей используется метод программного интерфейса служебных модулей. Проанализируем пример вызова такой функции:


АдресТекст = "г. Москва, ул. Тверская, д. 10, кв. 5";
СтруктураАдреса = УправлениеКонтактнойИнформациейСлужебный.РазложитьАдресВСтруктуру(АдресТекст);

// Теперь мы можем обратиться к полям структуры
Город = СтруктураАдреса.Город;
Улица = СтруктураАдреса.Улица;
Дом = СтруктураАдреса.Дом;
Квартира = СтруктураАдреса.Квартира;

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

Способ 2: Десериализация внутреннего представления адреса

Часто в базе данных 1С адрес хранится не просто строкой, а в виде XML или JSON внутри строкового поля. Это происходит, когда пользователь вводит адрес через специальную форму. В этом случае "разложить на кусочки" адрес гораздо проще, так как он уже структурирован "под капотом".

Для работы с такими данными используем механизм десериализации. Проанализируем ситуацию, когда нам нужно получить данные из XML-представления:


// Допустим, ЗначениеПолей — это скрытая строка XML из реквизита адреса
ДанныеАдреса = КонтактнаяИнформацияСлужебный.ДесериализоватьАдрес(Объект.ЗначениеПолей, Объект.Тип);

// В результате получаем объект XDTO или структуру с четким разделением по ГАР (ФИАС)
Если ДанныеАдреса.Свойства().Найти("Город") <> Неопределено Тогда
    Сообщить("Населенный пункт: " + ДанныеАдреса.Город);
КонецЕсли;

Этот путь является самым надежным, так как исключает ошибки алгоритмического разбора текста. Если есть возможность получить доступ к полю ЗначениеПолей (обычно это часть табличной части КонтактнаяИнформация), всегда следует отдавать предпочтение именно ему.

Способ 3: Использование регулярных выражений (VBScript.RegExp)

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

С помощью объекта VBScript.RegExp можно вычленять фрагменты по шаблонам. Например, почтовый индекс — это всегда 6 цифр, а номер дома часто идет после сокращений "д.", "дом" или "корп.". Рассмотрим пример логики:

  1. Создаем объект RegExp через COM-объект.
  2. Задаем паттерн для поиска (например, для индекса: \b\d{6}\b).
  3. Выполняем поиск и извлекаем результат.

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

Способ 4: Интеграция с внешними API (на примере Dadata)

Если точность разбора критически важна (например, для логистических компаний), лучшим решением будет использование специализированных сервисов нормализации. Одним из самых популярных является Dadata.

Принцип работы следующий: мы отправляем "кривую" строку через HTTP-запрос, а сервис возвращает структурированный JSON с разложенными полями (индекс, регион, район, город, улица, дом, GUID по ФИАС/ГАР). Посмотрим на примерную схему взаимодействия:


НТТРЗапрос = Новый HTTPЗапрос("/suggestions/api/4_1/rs/suggest/address");
НТТРЗапрос.Заголовки.Вставить("Authorization", "Token " + ВашТокен);
НТТРЗапрос.УстановитьТелоИзСтроки("{ ""query"": """ + СтрокаАдреса + """ }");

Соединение = Новый HTTPСоединение("suggestions.dadata.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
Ответ = Соединение.ОтправитьЗапрос(НТТРЗапрос);

Если Ответ.КодСостояния = 200 Тогда
    // Читаем JSON и заполняем структуру
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
    Результат = ПрочитатьJSON(ЧтениеJSON);
КонецЕсли;

Помимо Dadata, можно использовать Яндекс.Геокодер или сервис 1С:Контрагент, который предоставляет актуальные данные непосредственно из облачного классификатора ФНС.

Способ 5: Учет перехода на ГАР (Государственный адресный реестр)

При разборе адреса важно учитывать, что классификатор ФИАС заменен на ГАР. Главное отличие — иерархическая структура и поддержка муниципального деления. Теперь один и тот же адрес может иметь два представления: административно-территориальное и муниципальное.

Разберем, что это значит для разработчика 1С:

Практические рекомендации по ручному разбору

Если внешние сервисы недоступны, а БСП не справляется, можно реализовать простейший парсер по тегам-разделителям. Проанализируем алгоритм:

  1. Приводим строку к нижнему регистру для удобства поиска.
  2. Ищем ключевые вхождения: "г.", "обл.", "ул.", "пер.", "д.", "кв.".
  3. Используем функцию СтрРазделить, если в строке есть четкие разделители (запятые).
  4. Очищаем каждый полученный фрагмент от лишних пробелов функцией СокрЛП.

Рассмотрим небольшой пример реализации такого "ручного" подхода:


ЧастиАдреса = СтрРазделить(СтрокаАдреса, ",");
Для Каждого Фрагмент Из ЧастиАдреса Цикл
    ТекФрагмент = СокрЛП(Фрагмент);
    Если Найти(ТекФрагмент, "г.") > 0 Тогда
        Структура.Город = ТекФрагмент;
    ИначеЕсли Найти(ТекФрагмент, "ул.") > 0 Тогда
        Структура.Улица = ТекФрагмент;
    КонецЕсли;
КонецЦикла;

Резюме: Для простых задач в типовых базах используйте методы БСП. Для работы с историческими или "грязными" данными подключайте внешние API. А если вам нужно разбирать адрес для отчетности — всегда стремитесь к сопоставлению с классификатором ГАР через встроенный поиск 1С.

← На главную