Если Вы не читали первую статью, то Вам сюда:
Работа с контактной информацией. Часть 1
Составим план статьи:
1. Как прочитать адрес, записанный в формате JSON?
2. Рассмотрим процесс преобразования адреса из формата КЛАДР в формат муниципального адреса.
3. Какие ошибки в тиражном решении усложняют этот процесс?
4. Сложности при решении задач, связанных с контактной информацией.
Как прочитать адрес, записанный в формате JSON
Для этого воспользуемся программным интерфейсом:
Адрес = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(Значение, Перечисления.ТипыКонтактнойИнформации.Адрес);
В результате получим структуру, которая инициализируется следующим программным интерфейсом:
Результат = РаботаСАдресамиКлиентСервер.ОписаниеНовойКонтактнойИнформации(ТипКонтактнойИнформации);
//Поля структуры:
Результат.Вставить("value", "");
Результат.Вставить("comment", "");
Результат.Вставить("type", ТипКонтактнойИнформацииВСтроку(ТипКонтактнойИнформации));
Результат.Вставить("country", "");
Результат.Вставить("addressType", АдресВСвободнойФорме());
Результат.Вставить("countryCode", "");
Результат.Вставить("ZIPcode", "");
Результат.Вставить("area", "");
Результат.Вставить("areaType", "");
Результат.Вставить("city", "");
Результат.Вставить("cityType", "");
Результат.Вставить("street", "");
Результат.Вставить("streetType", "");
Результат.Вставить("id", "");
Результат.Вставить("areaCode", "");
Результат.Вставить("areaId", "");
Результат.Вставить("district", "");
Результат.Вставить("districtType", "");
Результат.Вставить("districtId", "");
Результат.Вставить("munDistrict", "");
Результат.Вставить("munDistrictType", "");
Результат.Вставить("munDistrictId", "");
Результат.Вставить("cityId", "");
Результат.Вставить("settlement", "");
Результат.Вставить("settlementType", "");
Результат.Вставить("settlementId", "");
Результат.Вставить("cityDistrict", "");
Результат.Вставить("cityDistrictType", "");
Результат.Вставить("cityDistrictId", "");
Результат.Вставить("territory", "");
Результат.Вставить("territoryType", "");
Результат.Вставить("territoryId", "");
Результат.Вставить("locality", "");
Результат.Вставить("localityType", "");
Результат.Вставить("localityId", "");
Результат.Вставить("streetId", "");
Результат.Вставить("houseType", "");
Результат.Вставить("houseNumber", "");
Результат.Вставить("houseId", "");
Результат.Вставить("buildings", Новый Массив);
Результат.Вставить("apartments", Новый Массив);
Результат.Вставить("codeKLADR", "");
Результат.Вставить("oktmo", "");
Результат.Вставить("okato", "");
Результат.Вставить("asInDocument", "");
Результат.Вставить("ifnsFLCode", "");
Результат.Вставить("ifnsULCode", "");
Результат.Вставить("ifnsFLAreaCode", "");
Результат.Вставить("ifnsULAreaCode", "");
Результат.Вставить("stead", "");
Результат.Вставить("steadId", "");
По этому коду должно стать понятно, что здания и квартиры - это массивы! Тип адреса по умолчанию - "ВСвободнойФорме".
Если адрес записан в свободной форме, то реквизит "Значение" выглядит так:
{
"value": "142700, Московская обл, Ленинский р-н, Видное г, Зеленые аллеи б-р, дом 10, кв.200",
"type": "Адрес",
"country": "Россия",
"addressType": "ВСвободнойФорме",
"ZIPcode": "142700",
"street": "142700, Московская обл, Ленинский р-н, Видное г, Зеленые аллеи б-р, дом 10, кв.200"
}
Теперь стоит посмотреть на заполненную версию этой структуры:
Сначала для адреса в произвольной форме:
| Свойство | Значение |
| Адрес | Структура |
| ZIPcode | "142700" |
| addressType | "ВСвободнойФорме" |
| apartments | Массив |
| area | "" |
| areaCode | "" |
| areaId | "" |
| areaType | "" |
| asInDocument | "" |
| buildings | Массив |
| city | "" |
| cityDistrict | "" |
| cityDistrictId | "" |
| cityDistrictType | "" |
| cityId | "" |
| cityType | "" |
| codeKLADR | "" |
| comment | "" |
| country | "Россия" |
| countryCode | "" |
| district | "" |
| districtId | "" |
| districtType | "" |
| houseId | "" |
| houseNumber | "" |
| houseType | "" |
| id | "" |
| ifnsFLAreaCode | "" |
| ifnsFLCode | "" |
| ifnsULAreaCode | "" |
| ifnsULCode | "" |
| locality | "" |
| localityId | "" |
| localityType | "" |
| munDistrict | "" |
| munDistrictId | "" |
| munDistrictType | "" |
| okato | "" |
| oktmo | "" |
| settlement | "" |
| settlementId | "" |
| settlementType | "" |
| stead | "" |
| steadId | "" |
| street | "142700, Московская обл, Ленинский р-н, Видное г, Зеленые аллеи б-р, дом 10, кв.200" |
| streetId | "" |
| streetType | "" |
| territory | "" |
| territoryId | "" |
| territoryType | "" |
| type | "Адрес" |
| value | "142700, Московская обл, Ленинский р-н, Видное г, Зеленые аллеи б-р, дом 10, кв.200" |
Для адреса в муниципальном формате заполненная структура будет показана ниже на шаге №3 преобразования адреса.
Процесс преобразования адреса в муниципальный формат
Поясню идею, которая мне помогла провести преобразование адреса...
Если в форме ввода адреса установить переключатель в положение "Муниципальное деление"

И начать что-то вводить в поле город, то система предлагает несколько вариантов, среди которых есть правильный!
Аналогичный подбор есть и при вводе улицы. Н надо понимать, что вариантов очень много и надо сначала правильно определить населённый пункт.

Мне стало интересно, что происходит, как принято говорить, "под капотом"...
В статье не буду описывать процесс изучения кода и перебор возможных вариантов... Опишу найденный путь, который помог.
Шаг №1. Формируем строку подбора. Сначала пробуем Регион + Район + Город.
Текст ниже взят из обработчика события формы на предыдущем скрине.
//Подберем Регион/Район/Населенный пункт
ТекстПодбора = Выборка.Регион + ", " + Выборка.Район + ", " + Выборка.Город;
ДополнительныеПараметры = УправлениеКонтактнойИнформациейСлужебный.ПараметрыАвтоподбораАдреса();
ДополнительныеПараметры.Уровни = "1,3,31,4,41,5,6,65";
Результат = Обработки.РасширенныйВводКонтактнойИнформации.СписокАвтоподбораНаселенногоПункта(ТекстПодбора, ДополнительныеПараметры);
УправлениеКонтактнойИнформациейСлужебный.ФорматированиеРезультатовАвтоподбора(Результат.Данные, ТекстПодбора, ПустаяСтрока(Выборка.Тип));
На этом этапе результат может быть пустой.
Шаг №2. Проверяем полученный результат, если он пустой, то повторяем поиск. В этот раз используем только Регин + Город.
//Попробуем подобрать адрес без района
Если Результат.Данные.Количество() = 0 Тогда
ТекстПодбора = Выборка.Регион + ", " + Выборка.Город;
ДополнительныеПараметры = УправлениеКонтактнойИнформациейСлужебный.ПараметрыАвтоподбораАдреса();
ДополнительныеПараметры.Уровни = "1,3,31,4,41,5,6,65";
Результат = Обработки.РасширенныйВводКонтактнойИнформации.СписокАвтоподбораНаселенногоПункта(ТекстПодбора, ДополнительныеПараметры);
УправлениеКонтактнойИнформациейСлужебный.ФорматированиеРезультатовАвтоподбора(Результат.Данные, ТекстПодбора, ПустаяСтрока(Выборка.Тип));
Если Результат.Данные.Количество() = 0 Тогда
Возврат ЗначенияПолей;
КонецЕсли;
КонецЕсли;
Смотрим результат (Результат.Данные):

Получился список значений, в котором есть город в муниципальном формате.
Как видно из результатов, проблема преобразования в том, что в административно-территориальном формате не используется почему-то район!?
Для меня осталось загадкой, почему же не используется!? На мой взгляд - это ОШИБКА!
Откроем отдельно нужный нам адрес. Это структура:

Поле "Адрес" содержит адрес города правильно записанный в JSON формат.
Поле "Идентификатор" - это уникальный идентификатор конкретного населенного пункта. Он нам понадобится дальше для поиска улицы.
Поле "Адрес" содержит такую информацию:
{
"value": "Московская обл, г.о. Ленинский, г Видное",
"comment": "",
"type": "Адрес",
"country": "Россия",
"addressType": "Муниципальный",
"countryCode": "",
"ZIPcode": "",
"area": "Московская",
"areaType": "обл",
"city": "Видное",
"cityType": "г",
"street": "",
"streetType": "",
"id": "9a72b510-9413-41d8-b076-576fbfd78404",
"areaCode": "5000000000000",
"areaId": "29251dcf-00a1-4e34-98d4-5c47484a36d4",
"district": "",
"districtType": "",
"districtId": "",
"munDistrict": "Ленинский",
"munDistrictType": "г.о.",
"munDistrictId": "c2c325fc-435f-4ab7-88fc-d632f6b33c87",
"cityId": "9a72b510-9413-41d8-b076-576fbfd78404",
"settlement": "",
"settlementType": "",
"settlementId": "",
"cityDistrict": "",
"cityDistrictType": "",
"cityDistrictId": "",
"territory": "",
"territoryType": "",
"territoryId": "",
"locality": "",
"localityType": "",
"localityId": "",
"streetId": "",
"houseType": "",
"houseNumber": "",
"houseId": "",
"stead": "",
"steadId": "",
"buildings": [],
"apartments": [],
"codeKLADR": "5000002500000",
"oktmo": "46707000001",
"okato": "46407000000",
"asInDocument": "",
"ifnsFLCode": "5003",
"ifnsULCode": "5003",
"ifnsFLAreaCode": "",
"ifnsULAreaCode": ""
}
Шаг №3. Преобразуем формат JSON в привычную нам структуру. Предварительно из полученных результатов выберем нужный.
Если вдруг не получилось найти такой город, то дальнейшие шаги выполнять нет смысла!
Преобразование в структуру идёт через программный интерфейс. Поля структуры приведены в разделе "Как прочитать адрес..."
ДанныеНаселенногоПункта = Неопределено;
//Если есть муниципальный вариант, выберем его. Иначе берем последний
Для Каждого ТекНаселенныйПункт Из Результат.Данные Цикл
ДанныеНаселенногоПункта = ТекНаселенныйПункт;
Если ТекНаселенныйПункт.Значение.Муниципальный Тогда
Прервать;
КонецЕсли;
КонецЦикла;
//Получим в структуру данные населенного пункта
ДанныеНаселенногоПунктаСтруктура = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(ДанныеНаселенногоПункта.Значение.Адрес, Выборка.Тип);
Полученная структура:
| Ключ | Значение |
| "value" | "Московская обл, г.о. Ленинский, г Видное" |
| "comment" | "" |
| "type" | "Адрес" |
| "country" | "Россия" |
| "addressType" | "Муниципальный" |
| "countryCode" | "" |
| "ZIPcode" | "" |
| "area" | "Московская" |
| "areaType" | "обл" |
| "city" | "Видное" |
| "cityType" | "г" |
| "street" | "" |
| "streetType" | "" |
| "id" | 9a72b510-9413-41d8-b076-576fbfd78404 |
| "areaCode" | "5000000000000" |
| "areaId" | 29251dcf-00a1-4e34-98d4-5c47484a36d4 |
| "district" | "" |
| "districtType" | "" |
| "districtId" | "" |
| "munDistrict" | "Ленинский" |
| "munDistrictType" | "г.о." |
| "munDistrictId" | c2c325fc-435f-4ab7-88fc-d632f6b33c87 |
| "cityId" | 9a72b510-9413-41d8-b076-576fbfd78404 |
| "settlement" | "" |
| "settlementType" | "" |
| "settlementId" | "" |
| "cityDistrict" | "" |
| "cityDistrictType" | "" |
| "cityDistrictId" | "" |
| "territory" | "" |
| "territoryType" | "" |
| "territoryId" | "" |
| "locality" | "" |
| "localityType" | "" |
| "localityId" | "" |
| "streetId" | "" |
| "houseType" | "" |
| "houseNumber" | "" |
| "houseId" | "" |
| "buildings" | Массив |
| "apartments" | Массив |
| "codeKLADR" | "5000002500000" |
| "oktmo" | "46707000001" |
| "okato" | "46407000000" |
| "asInDocument" | "" |
| "ifnsFLCode" | "5003" |
| "ifnsULCode" | "5003" |
| "ifnsFLAreaCode" | "" |
| "ifnsULAreaCode" | "" |
| "stead" | "" |
| "steadId" | "" |
Дальнейшие шаги иначе как танцы с бубном не назовёшь))) Но было очень интересно всё таки решить задачу преобразования!
Шаг №4. Получим представление адреса с учетом полученного населенного пункта, правильно разложенного по полям.
Для этого выполним уже описанные в первой статье шаги и заменим в структуре полученные поля:
//Перепишем данные в структуру и получим представление типовым программным интерфейсом
СтруктураКонтактнойИнформации = РаботаСАдресамиКлиентСервер.СтруктураКонтактнойИнформацииПоТипу(Выборка.Тип);
ЗаполнитьЗначенияСвойств(СтруктураКонтактнойИнформации, Выборка, ,"Представление");
//Заполним полученный населённый пункт
СтруктураКонтактнойИнформации.Город = ДанныеНаселенногоПунктаСтруктура.city;
СтруктураКонтактнойИнформации.ГородСокращение = ДанныеНаселенногоПунктаСтруктура.cityType;
СтруктураКонтактнойИнформации.Район = ДанныеНаселенногоПунктаСтруктура.munDistrict;
СтруктураКонтактнойИнформации.РайонСокращение = ДанныеНаселенногоПунктаСтруктура.munDistrictType;
СтруктураКонтактнойИнформации.Регион = ДанныеНаселенногоПунктаСтруктура.area;
СтруктураКонтактнойИнформации.РегионСокращение = ДанныеНаселенногоПунктаСтруктура.areaType;
СтруктураКонтактнойИнформации.Вставить("ТипАдреса", "Муниципальный");
//Получим новое представление, которое преобразуем далее в JSON
//Чтоб из представления не убирался район/городской округ необходимо:
//В функции ИменаУровнейАдреса из модуля РаботаСАдресамиКлиентСервер для муниципального адреса добавить
// Уровни.Добавить("District");
Представление = УправлениеКонтактнойИнформацией.ПредставлениеКонтактнойИнформации(СтруктураКонтактнойИнформации);
Как видно из комментария, типовой код содержит ошибки! Почему-то в указанной процедуре отсутствует поле Район, полученный таким трудом.
Такое ощущение, что поле район хотели убрать для другого вида адресов, а убрали для муниципального!
Вот как функция выглядит после исправления:
Функция ИменаУровнейАдреса(ТипАдреса, ВключатьУровеньУлицы, ВключатьУровеньДома = Ложь, ИсключитьУровеньГорода = Ложь) Экспорт
Уровни = Новый Массив;
Если ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес() Тогда
Уровни.Добавить("Area");
Иначе
Уровни.Добавить("Area");
Если ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС() Тогда
Уровни.Добавить("District");
Если Не ИсключитьУровеньГорода Тогда
Уровни.Добавить("City");
КонецЕсли;
Уровни.Добавить("Locality");
Иначе
Если ТипАдреса = "Все" Тогда
Уровни.Добавить("District");
Уровни.Добавить("MunDistrict");
Уровни.Добавить("Settlement");
Уровни.Добавить("City");
Иначе
Если ЭтоМуниципальныйАдрес(ТипАдреса) Тогда
Уровни.Добавить("MunDistrict");
Уровни.Добавить("Settlement");
//Филатов +
Уровни.Добавить("District");
//Филатов -
Если Не ИсключитьУровеньГорода Тогда
Уровни.Добавить("City");
КонецЕсли;
Иначе
Уровни.Добавить("District");
Уровни.Добавить("City");
КонецЕсли;
КонецЕсли;
Уровни.Добавить("CityDistrict");
Уровни.Добавить("Locality");
Уровни.Добавить("Territory");
КонецЕсли;
КонецЕсли;
Если ВключатьУровеньУлицы Тогда
Уровни.Добавить("Street");
КонецЕсли;
Если ВключатьУровеньДома Тогда
Уровни.Добавить("house");
КонецЕсли;
Возврат Уровни;
КонецФункции
Еще одна ошибка заключается в том, что программный интерфейс РаботаСАдресамиКлиентСервер.СтруктураКонтактнойИнформацииПоТипу
не добавляет в структуру поле "ТипАдреса". Т.е. нет возможности указать, что это муниципальный адрес! Поэтому поле в структуру добавляем самостоятельно.
Из-за этого полученное представление ошибочно преобразовывается в административно-территориальный адрес.
В итоге поле "Представление" = "142700, Московская обл, г.о. Ленинский, г Видное, Зеленые аллеи б-р, д. 10, кв. 200"
Как говорится - то, что доктор прописал!
Шаг №5. Подготовка представления к тому, чтоб его распознать.
На этом шаге необходимо использовать функцию "ЧастиАдресаТаблицей" общего модуля "АдресныйКлассификаторСлужебный".
На мой взгляд здесь заложена ещё одна ошибка: эта функция почему-то не экспортная!!!
Я её скопировал к себе в модуль обработки. Вот эта функция:
Функция ЧастиАдресаТаблицей(Знач Текст)
Результат = УправлениеКонтактнойИнформациейСлужебный.ЧастиАдреса();
Номер = 1;
Для Каждого Часть Из СловаТекстаТаблицей(Текст, "," + Символы.ПС) Цикл
Значение = СокрЛП(Часть.Значение);
Если ПустаяСтрока(Значение) Тогда
Продолжить;
КонецЕсли;
Строка = Результат.Добавить();
Строка.Уровень = 0;
Строка.Позиция = Номер;
Номер = Номер + 1;
Строка.Начало = Часть.Начало;
Строка.Длина = Часть.Длина;
Позиция = СтрДлина(Значение);
Пока Позиция > 0 Цикл
Символ = Сред(Значение, Позиция, 1);
Если ПустаяСтрока(Символ) Тогда
Строка.Наименование = СокрЛП(Лев(Значение, Позиция-1));
Прервать;
КонецЕсли;
Строка.Сокращение = Символ + Строка.Сокращение;
Позиция = Позиция - 1;
КонецЦикла;
Если ПустаяСтрока(Строка.Наименование) Тогда
Строка.Наименование = СокрЛП(Строка.Сокращение);
Строка.Сокращение = "";
КонецЕсли;
Если СтрЗаканчиваетсяНа(Строка.Наименование, "тер.") Тогда
Строка.Наименование = СокрЛП(СтрЗаменить(Строка.Наименование, "тер.", ""));
Строка.Сокращение = "тер. " + Строка.Сокращение;
КонецЕсли;
Строка.Значение = СокрЛП(Строка.Наименование + " " + Строка.Сокращение);
КонецЦикла;
Возврат Результат;
КонецФункции
Возвращает она таблицу:
| Уровень | Позиция | Значение | Наименование | Сокращение | Начало | Длина | Идентификатор |
| 0 | 1 | "142700" | "142700" | "" | 1 | 6 | "" |
| 0 | 2 | "Московская обл" | "Московская" | "обл" | 8 | 15 | "" |
| 0 | 3 | "г.о. Ленинский" | "г.о." | "Ленинский" | 24 | 15 | "" |
| 0 | 4 | "г Видное" | "г" | "Видное" | 40 | 9 | "" |
| 0 | 5 | "Зеленые аллеи б-р" | "Зеленые аллеи" | "б-р" | 50 | 18 | "" |
| 0 | 6 | "д. 10" | "д." | "10" | 69 | 5 | "" |
| 0 | 7 | "кв. 200" | "кв." | "200" | 75 | 8 | "" |
Самое плохое в этом то, что функция не способна корректно определить, где наименование, а где всё-таки сокращение!
И это очередная ошибка! Получается, что мы программным интерфейсом получили правильное представление для муниципального адреса, т.к. получали его из структуры,
а эта функция не понимает, что сокращение может быть в начале фразы. Это также добавляет проблем в момент распознавания адреса!
Чтоб функция сработала, вместе с ней необходимо скопировать ещё 2 не экспортные функции:
Функция СловаТекстаТаблицей(Знач Текст, Знач Разделители = Неопределено)
// Удаление из текста спец. символов "точек", "номеров".
Текст = СтрЗаменить(Текст, "№", "");
НачалоСлова = 0;
Состояние = 0;
Результат = ТаблицаФрагментов();
Для Позиция = 1 По СтрДлина(Текст) Цикл
ТекущийСимвол = Сред(Текст, Позиция, 1);
ЭтоРазделитель = ?(Разделители = Неопределено, ПустаяСтрока(ТекущийСимвол), СтрНайти(Разделители, ТекущийСимвол) > 0);
Если Состояние = 0 И (Не ЭтоРазделитель) Тогда
НачалоСлова = Позиция;
Состояние = 1;
ИначеЕсли Состояние = 1 И ЭтоРазделитель Тогда
Строка = Результат.Добавить();
Строка.Начало = НачалоСлова;
Строка.Длина = Позиция-НачалоСлова;
Строка.Значение = Сред(Текст, Строка.Начало, Строка.Длина);
Состояние = 0;
КонецЕсли;
КонецЦикла;
Если Состояние = 1 Тогда
Строка = Результат.Добавить();
Строка.Начало = НачалоСлова;
Строка.Длина = Позиция-НачалоСлова;
Строка.Значение = Сред(Текст, Строка.Начало, Строка.Длина)
КонецЕсли;
Возврат Результат;
КонецФункции
// Функция-конструктор таблицы фрагментов
//
// Возвращаемое значение:
// ТаблицаЗначений:
// * Значение - Строка
// * Начало - Число
// * Длина - Число
//
Функция ТаблицаФрагментов()
ТипСтрока = Новый ОписаниеТипов("Строка");
ТипЧисло = Новый ОписаниеТипов("Число");
Результат = Новый ТаблицаЗначений;
Колонки = Результат.Колонки;
Колонки.Добавить("Значение", ТипСтрока);
Колонки.Добавить("Начало", ТипЧисло);
Колонки.Добавить("Длина", ТипЧисло);
Возврат Результат;
КонецФункции
Шаг №6. Изменение функции для распознавания адреса
Распознавание происходит с помощью функции "РаспознатьАдрес" общего модуля "АдресныйКлассификаторСлужебный"
В ней 2 варианта работы:
-- Через загруженный классификатор
-- Через веб-сервис.
Из-за ошибок на шаге №5, распознавание через загруженный классификатор не происходит!
Проблема в том, что в запрос к регистру сведений города и городского округа передаются сокращения. Естественно, запрос выдаёт пустой результат!
Для того, чтобы решить эту проблему, необходимо в функции "РаспознатьАдрес" поменять местами условия. Получится вот так:
Функция РаспознатьАдрес(ЧастиАдреса, Представление, ВСтруктуру = Ложь) Экспорт
ЗагруженныеАдресныеСведения = АдресныйКлассификаторПовтИсп.СведенияОЗагрузкеСубъектовРФ();
КодРегиона = ОпределитьКодРегионаПоЧастямАдреса(ЧастиАдреса);
//Филатов +
Если ЗагруженныеАдресныеСведения.Получить("КлассификаторДоступен") = Истина Тогда
Адрес = РаспознатьАдресВебСервис(ЧастиАдреса, Представление, ВСтруктуру);
Возврат Адрес;
ИначеЕсли ЗагруженныеАдресныеСведения.Получить("ИспользоватьЗагруженные") = Истина
И ТипЗнч(ЗагруженныеАдресныеСведения.Получить(КодРегиона)) = Тип("Структура")
И ЗагруженныеАдресныеСведения.Получить(КодРегиона).ИспользоватьЗагруженные Тогда
Адрес = РаспознатьАдресЗагруженныеДанные(ЧастиАдреса);
Если СтрСравнить(Адрес.addressType, АдресВСвободнойФорме()) <> 0 Тогда
Возврат Адрес;
КонецЕсли;
КонецЕсли;
//Филатов -
Возврат Неопределено;
КонецФункции
На мой взгляд, эта функция также содержит ошибку! Вопрос не в том, в какой последовательности пытаться распознать адрес.
Вопрос в том, почему нельзя воспользоваться обоими способами для достижения наилучшего результата???
Т.е. посмотрели сначала через загруженный классификатор, проверили переменную "Адрес" на Неопределено. И если не получилось - смотрим через веб-сервис!
ВАЖНО: Для работы веб-сервиса необходимо авторизоваться в базе под логином к сайту ИТС. Ну и подписка ИТС должна быть действующей, иначе не сработает.
Ещё важней то, что это не реклама подписки ИТС)))
Шаг №7. Распознавание адреса
Вызываем измененный программный интерфейс:
//Распознаем с помощью веб-сервиса адрес и поместим в структуру
//Для того, чтоб веб-сервис включился необходимо поменять местами условия в вызываемой функции!
ПравильныйАдресСтруктура = АдресныйКлассификаторСлужебный.РаспознатьАдрес(ТаблицаЧастейАдреса, Представление, Истина);
Если ПравильныйАдресСтруктура = Неопределено Тогда
Возврат "";
КонецЕсли;
Полученная структура выглядит так:
| Свойство | Значение |
| ПравильныйАдресСтруктура | Структура |
| ZIPcode | "142703" |
| addressType | "Муниципальный" |
| apartments | Массив |
| area | "Московская" |
| areaCode | "5000000000000" |
| areaId | 29251dcf-00a1-4e34-98d4-5c47484a36d4 |
| areaType | "обл" |
| asInDocument | "" |
| buildings | Массив |
| city | "Видное" |
| cityDistrict | "" |
| cityDistrictId | "" |
| cityDistrictType | "" |
| cityId | 9a72b510-9413-41d8-b076-576fbfd78404 |
| cityType | "г" |
| codeKLADR | "" |
| comment | "" |
| country | "Россия" |
| countryCode | "" |
| district | "" |
| districtId | "" |
| districtType | "" |
| houseId | 4a08fd6b-0563-4439-9525-92b8ec03927f |
| houseNumber | "10" |
| houseType | "Дом" |
| id | 4a08fd6b-0563-4439-9525-92b8ec03927f |
| ifnsFLAreaCode | "" |
| ifnsFLCode | "5003" |
| ifnsULAreaCode | "" |
| ifnsULCode | "5003" |
| locality | "" |
| localityId | "" |
| localityType | "" |
| munDistrict | "Ленинский" |
| munDistrictId | c2c325fc-435f-4ab7-88fc-d632f6b33c87 |
| munDistrictType | "г.о." |
| okato | "46407000000" |
| oktmo | "46707000001" |
| settlement | "" |
| settlementId | "" |
| settlementType | "" |
| stead | "" |
| steadId | "" |
| street | "Зеленые аллеи" |
| streetId | f6b2a8ba-9b06-4646-b88e-4f25c8100cec |
| streetType | "б-р" |
| territory | "" |
| territoryId | "" |
| territoryType | "" |
| type | "Адрес" |
| value | "142703, Московская обл, г Видное, б-р Зеленые аллеи, Дом 10, кв. 200" |
Как Вы, наверно, помните, квартира записывается в массив, каждый элемент массива - это ещё одна структура:
| type | number |
| "Кв." | "200" |
Шаг №7. Преобразование структуры в строку JSON.
Здесь всё просто! Вызываем программный интерфейс:
Значение = УправлениеКонтактнойИнформациейСлужебный.СтруктураВСтрокуJSON(ПравильныйАдресСтруктура);
Наконец-то мы получаем желанный адрес разбитый как надо и в формате JSON! Можем его записывать в табличную часть.
Как записать я писал в первой статье (ссылка вверху).
Долгожданный результат выглядит так:
{
"value": "142703, Московская обл, г Видное, б-р Зеленые аллеи, Дом 10, кв. 200",
"type": "Адрес",
"country": "Россия",
"addressType": "Муниципальный",
"ZIPcode": "142703",
"area": "Московская",
"areaType": "обл",
"city": "Видное",
"cityType": "г",
"street": "Зеленые аллеи",
"streetType": "б-р",
"id": "4a08fd6b-0563-4439-9525-92b8ec03927f",
"areaCode": "5000000000000",
"areaId": "29251dcf-00a1-4e34-98d4-5c47484a36d4",
"munDistrict": "Ленинский",
"munDistrictType": "г.о.",
"munDistrictId": "c2c325fc-435f-4ab7-88fc-d632f6b33c87",
"cityId": "9a72b510-9413-41d8-b076-576fbfd78404",
"streetId": "f6b2a8ba-9b06-4646-b88e-4f25c8100cec",
"houseType": "Дом",
"houseNumber": "10",
"houseId": "4a08fd6b-0563-4439-9525-92b8ec03927f",
"apartments": [
{
"type": "Кв.",
"number": "200"
}
],
"oktmo": "46707000001",
"okato": "46407000000",
"ifnsFLCode": "5003",
"ifnsULCode": "5003"
}
ВАЖНО: Имейте в виду, что если адрес в табличной части уже есть, то программный интерфейс всё равно добавит новую строку!
Поэтому, если Вы исправляете существующие адреса, то не забывайте их удалять.
Процесс чтения адреса и преобразования в новый формат полностью рассмотрели. Надеюсь, коллеги разработчики БСП исправят ошибки в тиражных решениях.
Кстати, всё, что описано в этой статье, делалось на релизе ЗУП КОРП 3.1.23.63. Версия подсистемы БСП 3.1.7.110.
Другие технические публикации:
Отладка временных таблиц и типа ТаблицаЗначений
Особенности работы с COM-соединением
Пример работы с файлами odt в клиент-серверной модели работы
Практикую менторство по ЗУП. Связь через телегу: @PabloFilatelly
Статьи про ЗУП:
Ни в ЗУП ногой!? А мне нравится! Главные сложности решения, что отталкивает
Вступайте в нашу телеграмм-группу Инфостарт