Если Вы не читали первую статью, то Вам сюда:
Работа с контактной информацией. Часть 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 в клиент-серверной модели работы
Статьи про ЗУП:
Ни в ЗУП ногой!? А мне нравится! Главные сложности решения, что отталкивает