Работа с контактной информацией. Часть 2

05.06.23

Разработка - Механизмы типовых конфигураций

Во второй части статьи рассмотрим вопрос преобразования адреса из старого формата в новый. Рассмотрим реальные задачи, связанные с контактной информацией.

Если Вы не читали первую статью, то Вам сюда:

Работа с контактной информацией. Часть 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 в клиент-серверной модели работы

 

Статьи про ЗУП:

Ни в ЗУП ногой!? А мне нравится! Главные сложности решения, что отталкивает

Я - ЗУПер! Компетенции сотрудников.

Заполнение графиков при вахтовом методе работы

См. также

Расширяем возможности дополнительных обработок и настраиваем их отладку

БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Уже не одна веб-страница исписана знаниями о дополнительных обработках, как создать, как подключить. Есть масса вариантов, как их можно отладить. Я разобрался в кишках работы библиотеки и покажу, как можно расширить возможности дополнительных отчетов, а также покажу удобный способ отладки.

07.02.2024    2355    YA_418728146    11    

40

Регистры накопления в 1С:КА2 и 1С:ERP для расчета НДФЛ, страховых взносов и взаиморасчетов с сотрудниками на январь 2024 года. Краткое описание

Зарплата Механизмы типовых конфигураций Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет НДФЛ Абонемент ($m)

Для расчета зарплаты и соответствующих налогов в конфигурациях 1С:КА2 и 1С:ERP используется 22 регистра накопления, 7 регистров сведений, 1 регистр расчета и бухгалтерские проводки. В таблице приведены названия этих регистров, указаны основные регистраторы и виды движений приход/расход. В описании приводится краткое функциональное назначение регистров в основных зарплатных процессах. Описание регистров родилось из черновиков при написании различных отчетов и обработок при эксплуатации 1С-овских конфигураций и исправлении ошибок по НДФЛ, взаиморасчетов с сотрудниками и прочих. Информация не претендует на полноценное описание работы регистров, скорее это дискуссионный материал. Но, возможно, кому-то пригодится и сократит время при подготовке отчетности за непростой (в плане учета зарплаты) 2023 год. А возможно, кто-то поделится своим опытом.

1 стартмани

10.01.2024    1025    6    2ncom    3    

8

Шаблоны новых объектов 1С для 1С:Бухгалтерии предприятия

Инструментарий разработчика БСП (Библиотека стандартных подсистем) Механизмы типовых конфигураций Платформа 1С v8.3 1С:Бухгалтерия 3.0 Бесплатно (free)

Используются для создания новых объектов в конфигурации, чтобы не забыть, что нужно сделать. Сделано на примере 1С:Бухгалтерия предприятия, в других конфигурациях могут быть другие, а могут быть и похожие объекты.

28.12.2023    4836    mrXoxot    11    

99

Ключи аналитик учета в ЕРП, КА, УТ

Механизмы типовых конфигураций Платформа 1С v8.3 1С:ERP Управление предприятием 2 Россия Управленческий учет Бесплатно (free)

Разбираемся, зачем в системе ЕРП созданы справочники: ключи аналитик учета, зачем созданы аналогичные по набору измерений регистры сведений. Какие проблемы они решают, какие создают новые и что с этим делать.

08.11.2023    7072    ids79    25    

74

Распределение по базе среднего в ЗИКГУ 3.1

Зарплата Механизмы типовых конфигураций Платформа 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 Россия Бюджетный учет Абонемент ($m)

Результат расчета начислений (отпуск, БЛ и т.д.) может распределятся по базе среднего заработка. У таких начислений на вкладке "Налоги, взносы, бухучет" стоит галка "По базе среднего заработка". Но бывают случаи, что данное распределение необходимо скорректировать.

1 стартмани

14.09.2023    445    2    Vlx    0    

1

Расширение типового механизма настройки заполнения бухгалтерской отчетности (на примере конфигурации 1С:ERP. Управление холдингом 3.1.8.15)

Механизмы типовых конфигураций Платформа 1С v8.3 1С:Управление холдингом 1С:Франчайзи, автоматизация бизнеса Россия Бесплатно (free)

В статье приведен алгоритм доработок типового механизма настройки заполнения бухгалтерской отчетности на примере конфигурации 1С:ERP. Управление холдингом (3.1.8.15). Цель доработок - сделать процесс настроек более гибким и удобным для пользователей

11.09.2023    1931    ICL-Soft    3    

12

Разбор механизма "Настройки полей формы" в 1С:ERP. Управление холдингом

Механизмы типовых конфигураций Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

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

18.07.2023    2160    it_box    1    

7

Особенности настройки хранения файлов в томах в конфигурации 1С:Документооборот 3.0

Механизмы типовых конфигураций Платформа 1С v8.3 1С:Документооборот Бесплатно (free)

В данной статье мы рассмотрим, как настроить хранение файлов в томах, тома хранения файлов в 1С, правила размещения файлов в томах и проверку целостности данных тома в 1С:ДО.

30.05.2023    8919    Koder_Line    1    

5
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. fatman78 17 06.06.23 21:41 Сейчас в теме
Проделана серьезная изыскательная работа. Достойна уважения.

Помню проблемы, когда 1С: Документооборот перевели с версии БСП 2.х на 3.x. Добавилось тогда незапланированной работы.
Good_Smile; RealSurfer; NiGMa; biimmap; +4 Ответить
2. biimmap 1835 06.06.23 21:44 Сейчас в теме
3. пользователь 07.06.23 06:33
Сообщение было скрыто модератором.
...
4. NiGMa 07.06.23 11:09 Сейчас в теме
Спа-си-бо!!!
Снимаю шляпу!
5. japopov 68 28.09.23 07:56 Сейчас в теме
Спасибо, отличная работа! Использовал её, сильно переработав в конце (сделал подбор улицы и дома аналогично подбору населённого пункта).
Замечание по п.4: не обязательно дорабатывать типовой метод. Достаточно при вызове указать ТипАдреса - "Все". То есть, строку
СтруктураКонтактнойИнформации.Вставить("ТипАдреса", "Муниципальный");

заменить на
СтруктураКонтактнойИнформации.Вставить("ТипАдреса", "Все");

и все поля появляются - магия! :-)
Оставьте свое сообщение