Сравнение адресов: случай из практики

Публикация № 1176209

Разработка - Практика программирования

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

Прочитал статью infostart.ru/public/1175238/, а потом еще и комментарии к ней, и вспомнил, как я решал задачу примерно из той же серии. Правда, мне не требовалось раскладывать адрес на компоненты, хотя это могло бы быть одним из путей решения. Задача состояла в том, чтобы сравнить два адреса, представленных в виде строк, и решить, означают ли они одно и то же с некоторыми оговорками.

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

Проблема

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

Здесь важно отметить, что речь идет о местных жителях. С одной стороны, это провоцирует сотрудников учреждения на всякие вольности, сокращения и упрощения, ибо «и так понятно», а с другой – позволяет нам делать некие предположения вероятностного характера для упрощения задачи.

Надо заметить, что в данном случае наши предположения – ни что иное, как ответ на «и так понятно», то есть попытка поставить себя на место сотрудника учреждения и представить, какую информацию он счел само собой разумеющейся и поэтому поленился внести в базу.

Так вот, однажды в учреждении возникла идея не только модернизировать базы данных, но и объединить их в одну. Причем данные, относящиеся к одному и тому же заявителю, следовало аккуратно свести в одну карточку.

Тут-то и возникла проблема, как определить, что сведения о заявителе из разных карточек, введенные абы как, означают одного и того же гражданина. То есть берем из разных баз две карточки с одними и теми же ФИО заявителя и с большой вероятностью обнаруживаем, что:

  • любые поля, кроме ФИО, могут оказаться незаполненными;
  • в любых заполненных полях могут быть допущены любые ошибки;
  • в полях адреса могут быть любые сокращения, понятные только местным жителям, а заодно еще и всякие примечания, показавшиеся кому-то крайне необходимыми в этом месте;
  • кроме того, гражданин мог обращаться в учреждение в разное время, а в период между обращениями сменить паспорт, адрес, телефон, обзавестись новыми родственниками, расстаться с прежними и т.д. и т.п.

Глядя на весь этот бардак, пришлось уточнить формулировку задачи:

  • необходимо разработать простой быстрый алгоритм, позволяющий свести к минимуму количество пар карточек с одинаковыми ФИО заявителя, по которым решение не может быть принято по формальным признакам;
  • следует иметь в виду, что объединение баз данных будет проведено лишь несколько раз, включая предварительное тестирование, после чего инструментальное ПО в основном станет ненужным вместе с исходными базами;
  • необходимо создать утилиту (внешнюю обработку), позволяющую человеку просматривать в объединенной базе оставшиеся пары карточек и при необходимости применять к ним процедуру объединения.

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

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

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

Кстати, анализировать ошибки и сокращения проще всего оказалось в Экселе. Выгружаете справочник, сортируете по какому-нибудь столбцу или по нескольким, пробегаете по ним взглядом – и все видно, как на ладони. В глаза всегда бросается то, что выпадает из общего ряда, как, впрочем, и сам ряд.

Осталось найти формальные признаки, по которым алгоритм, не обладающий пристальным взглядом, определит, идет ли речь об одном и том же гражданине. Были выбраны три варианта:

1. Совпадают ФИО и данные паспорта (серия, номер, дата выдачи)

Это единственный надежный признак, не требующий оговорок.

2. Совпадают ФИО, дата рождения и адрес

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

3. Совпадают ФИО и адрес

Полные тезки редко проживают по одному адресу, при этом еще реже обращаются в некое муниципальное учреждение и еще реже их там регистрируют без даты рождения. То есть практически никогда. Обратите внимание, что этот признак применяется только при условии, что хотя бы в одной из карточек не заполнена дата рождения, а иначе смотрим предыдущий пункт.

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

Задача

Ну вот, собственно, мы и дошли до сравнения адресов, записанных с разной степенью небрежности. И здесь самое время вспомнить, что речь идет о местных жителях. Это дает нам право предполагать, что если не указаны населенный пункт, район и область, то скорее всего, это наш город и, разумеется, наш регион. Именно потому, что кому-то до нас это было «и так понятно».

То есть можно смело считать, что адреса

г. Наш город, ул. А, дом Б, …
ул. А, дом Б, …

означают одно и то же.

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

Сложнее, когда в адресе указан поселок, входящий в состав города. То есть адреса

г. Наш город, пос. Поселок, ул. А, дом Б, …
пос. Поселок, ул. А, дом Б, …
ул. А, дом Б, …
г. Наш город, ул. А, дом Б, …

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

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

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

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

Кроме сложностей с содержанием адреса, есть еще и синтаксические неудобства. Хорошо бы упростить разбор слов и сокращений, указывающих вид объекта ("г.", "пос.", "ул." и т.д.), во всем их разнообразии, справиться с наличием и отсутствием запятых и прочих знаков препинания и т.д. и т.п. Автор упомянутой статьи смело берется за эту задачу, а я просто избавился от нее.

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

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

Решение

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

Из адреса выбрасываются все обозначения вида объекта. Специально для этого подготовлен длинный список бесполезных слов. Заодно выкидываются окончания, приписанные к числам. Подряд идущие пробелы и знаки препинания заменяются одной запятой. Ну, а что осталось в результате, преобразуется в верхний регистр.

Так получается формализованный адрес. Боюсь, на почте откажутся его понимать. Да нам и не надо.

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

Например, всем известный адрес

Москва, 3-я улица Строителей, д. 25, кв. 12

превращается в

МОСКВА,3,СТРОИТЕЛЕЙ,25,12

Кстати, названия вроде Усть-Кулом и Камень-на-Оби при таком преобразовании превращаются в УСТЬ,КУЛОМ и КАМЕНЬ,ОБИ.

Если во второй карточке будет тот же адрес в Ленинграде, сравнение даст отрицательный результат. А если просто

3-я улица Строителей, д. 25, кв. 12

то строка

3,СТРОИТЕЛЕЙ,25,12

будет найдена в первой строке, и процедура сочтет адреса совпадающими.

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

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

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

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

Несомненно, предложенное решение спорное и состоит из одних недостатков. Можете даже не перечислять их в комментариях. Я сам подскажу, если кто еще не заметил.

Прежде чем применять это решение в общем случае, нужно крепко задуматься. В следующем разделе сказано, над чем.

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

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

И главное, я очень внимательно читал протоколы предварительного тестирования.

В результате все получилось.

Доказательство

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

При дальнейших рассуждениях необходимо иметь в виду, что выборка данных резко ограничена тем, что адреса берутся из карточек, имеющих одинаковые ФИО заявителя. То есть мы исследуем остальные предположения и пользуемся словами вроде «обязательно», «никогда», «может быть, но вряд ли» внутри этого резко ограниченного подмножества.

1. Мы все привыкли писать адреса от большего к меньшему и считаем это само собой разумеющимся.

Это значит, что при записи адресов мы привыкли соблюдать иерархическую структуру адреса, причем перечислять уровни (объекты) в порядке вложенности от большего к меньшему. Можно считать это базовым принципом, закрепленным в нашей культуре на протяжении нескольких поколений. Нам представляется совершенно естественным описывать местонахождение в населенном пункте, последовательно «открывая матрешку».

2. То, что важно для понимания, редко отбрасывается за ненадобностью.

Отсюда следует вывод, что промежуточные уровни, без которых можно, но неудобно обходиться, с большой вероятностью будут присутствовать в адресе. Как правило, это относится к городским районам, как-либо обособленным на территории города. Использование этого уровня упрощает восприятие адреса людьми.
Ненадежность сделанного вывода связана с тем, что если названия улиц уникальны в пределах всего города, то для правильной адресации уровень городского района не требуется. И тогда он с легкостью может быть пропущен, если, конечно, речь не идет о личном восприятии территории или, к примеру, об ограничении зон ответственности.

Следствие 1

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

Следовательно, оставив только названия и номера объектов, мы получим совершенно одинаковые записи адресов. В предложенном решении такая запись называется формализованным адресом.

А из предположения 2 следует, что с небольшой вероятностью состав объектов может отличаться в зависимости от того, присутствуют ли в адресе необязательные уровни и насколько они важны лично для того, кто пишет адрес. Это замечание требует внести в следствие поправку: с большой вероятностью получим одинаковые записи.

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

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

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

Ответ простой – для этого надо быть уверенным, что адрес начинается именно с улицы или городского района (поселка). То есть мало того, что нужен список названий всех улиц и районов, так еще и требуется хороший алгоритм разбора произвольно записанного адреса, способный преодолеть все интуитивно понятные вольности. Достаточно было представить объем работы, чтобы предпочесть решение, которое вообще не требует анализа адреса и явного добавления отсутствующих данных.

4. В обсуждаемых базах адрес достаточно подробно указывает местонахождение заявителя.

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

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

Следствие 2

Из предположений 1, 3 и 4 следует, что если более короткий вариант формализованного адреса полностью содержится в более длинном, то они оба однозначно указывают одно и то же местонахождение заявителя.

Или, попросту говоря, адрес может не иметь начала, но всегда имеет конец, и у одинаковых адресов он совпадает.

Программный код

Как неинтересна книжка без картинок, так и рассуждения о программном коде неинтересны без самого кода. Он был написан для режима совместимости с 8.2.

Функция ФормализоватьАдрес(СтрокаАдрес, МассивСокращений)

	// Приводит запись адреса одной строкой в общепринятой произвольной форме к 
	// формату, позволяющему сравнить адреса
	
	// Возвращает строку с формализованной записью адреса
	
	СтрАдрес = ВРег(СтрокаАдрес);
	
	СтрАдрес = СтрЗаменить(СтрАдрес, ",", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, ".", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "-", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "/", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "(", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, ")", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, ";", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, ":", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "!", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "?", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "\", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "№", " ");
	СтрАдрес = СтрЗаменить(СтрАдрес, """", " ");
	
	МассивАдрес = РазложитьСтрокуВМассивПодстрок(СтрАдрес, " ");
	
	РазмерМассива = МассивАдрес.Количество();
	
	Для Счетчик = 1 По РазмерМассива Цикл
		
		// Для удаления элементов массива обходим его с конца
		
		Индекс = РазмерМассива - Счетчик;
		
		Если МассивСокращений.Найти(МассивАдрес[Индекс]) <> Неопределено Тогда
		
			МассивАдрес.Удалить(Индекс);
		
		КонецЕсли;
		
	КонецЦикла; // Счетчик
	
	// Разделитель по умолчанию - ","
	
	Возврат ПолучитьСтрокуИзМассиваПодстрок(МассивАдрес);

КонецФункции // ФормализоватьАдрес()

Упомянутый здесь МассивСокращений – это тот самый список бесполезных слов, которые следует выкинуть из формализованного адреса. Массив предварительно заполняется отдельной процедурой, показанной ниже.

Функция РазложитьСтрокуВМассивПодстрок() позаимствована из общего модуля ОбщегоНазначенияЗК типовой конфигурации ЗиКБУ 1.0

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

Функция ПолучитьСтрокуИзМассиваПодстрок() позаимствована из общего модуля СтроковыеФункцииКлиентСервер типовой конфигурации БГУ 1.0. По умолчанию она вставляет в качестве разделителя запятую.

К функции ФормализоватьАдрес() есть дополнение, предназначенное для адресов учреждений, выдающих документы. Они ведь тоже переписаны абы как, а сравнивать приходится.

Функция ФормализоватьУчреждДок(Наименование, МассивСокращений)

	// Приводит наименование учреждения, выдавшего документ, записанное в 
	// общепринятой форме с общепринятыми сокращениями, к формату, позволяющему 
	// сравнить наименования
	
	// Возвращает строку с формализованной записью
	
	// Замена "ОУФМС" на "УФМС" выполняется в расчете на то, что варианты слова 
	// "Отдел" исключаются в формализованном адресе
	
	СтрАдрес = ВРег(Наименование);
	
	СтрАдрес = СтрЗаменить(СтрАдрес, "  ", " "); // Замена двух пробелов на один
	
	СтрАдрес = СтрЗаменить(СтрАдрес, "УПРАВЛЕНИЕМ ВНУТРЕННИХ ДЕЛ", "УВД");
	СтрАдрес = СтрЗаменить(СтрАдрес, "УПРАВЛЕНИЕ ВНУТРЕННИХ ДЕЛ", "УВД");
	СтрАдрес = СтрЗаменить(СтрАдрес, "ОТДЕЛОМ ВНУТРЕННИХ ДЕЛ", "ОВД");
	СтрАдрес = СтрЗаменить(СтрАдрес, "ОТДЕЛ ВНУТРЕННИХ ДЕЛ", "ОВД");
	СтрАдрес = СтрЗаменить(СтрАдрес, "ПОСЕЛКОВЫМ ОТДЕЛОМ МИЛИЦИИ", "ПОМ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "ПОСЕЛКОВЫЙ ОТДЕЛ МИЛИЦИИ", "ПОМ");
	СтрАдрес = СтрЗаменить(СтрАдрес, "ОУФМС", "УФМС");
	
	Возврат ФормализоватьАдрес(СтрАдрес, МассивСокращений);

КонецФункции // ФормализоватьУчреждДок()

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

МассивСокращений = Новый Массив;
ЗаполнитьМассивСокращенийАдресов(МассивСокращений);

...

Процедура ЗаполнитьМассивСокращенийАдресов(МассивСокращений)

// Заполняет массив сокращений, используемых в почтовых адресах

// МассивСокращений - пустой одномерный массив

// Цифры в комментариях – приоритет строк в списке

МассивСокращений.Добавить(""); // 0
МассивСокращений.Добавить("Б"); // 1
МассивСокращений.Добавить("В"); // 1
МассивСокращений.Добавить("Г"); // 1
МассивСокращений.Добавить("Д"); // 1
МассивСокращений.Добавить("Е"); // 1
МассивСокращений.Добавить("И"); // 1
МассивСокращений.Добавить("Й"); // 1
МассивСокращений.Добавить("К"); // 1
МассивСокращений.Добавить("М"); // 1
МассивСокращений.Добавить("Н"); // 1
МассивСокращений.Добавить("П"); // 1
МассивСокращений.Добавить("Р"); // 1
МассивСокращений.Добавить("С"); // 1
МассивСокращений.Добавить("Т"); // 1
МассивСокращений.Добавить("Ш"); // 1
МассивСокращений.Добавить("Я"); // 1
МассивСокращений.Добавить("АЯ"); // 2
МассивСокращений.Добавить("БУЛ"); // 2
МассивСокращений.Добавить("ВО"); // 2
МассивСокращений.Добавить("ГОР"); // 2
МассивСокращений.Добавить("ДЕР"); // 2
МассивСокращений.Добавить("ИЙ"); // 2
МассивСокращений.Добавить("КВ"); // 2
МассивСокращений.Добавить("КОМ"); // 2
МассивСокращений.Добавить("КОМН"); // 2
МассивСокращений.Добавить("КОР"); // 2
МассивСокращений.Добавить("КОРП"); // 2
МассивСокращений.Добавить("КР"); // 2
МассивСокращений.Добавить("КТ"); // 2
МассивСокращений.Добавить("МЕСТ"); // 2
МассивСокращений.Добавить("МК"); // 2
МассивСокращений.Добавить("МКР"); // 2
МассивСокращений.Добавить("МКРН"); // 2
МассивСокращений.Добавить("НА"); // 2
МассивСокращений.Добавить("НАБ"); // 2
МассивСокращений.Добавить("НЕ"); // 2
МассивСокращений.Добавить("ОБ"); // 2
МассивСокращений.Добавить("ОБЛ"); // 2
МассивСокращений.Добавить("ОБЩ"); // 2
МассивСокращений.Добавить("ОЙ"); // 2
МассивСокращений.Добавить("ОТ"); // 2
МассивСокращений.Добавить("ПЕР"); // 2
МассивСокращений.Добавить("ПО"); // 2
МассивСокращений.Добавить("ПОС"); // 2
МассивСокращений.Добавить("ПР"); // 2
МассивСокращений.Добавить("РН"); // 2
МассивСокращений.Добавить("СТ"); // 2
МассивСокращений.Добавить("СТР"); // 2
МассивСокращений.Добавить("ТОВ"); // 2
МассивСокращений.Добавить("УЛ"); // 2
МассивСокращений.Добавить("УЧ"); // 2
МассивСокращений.Добавить("БУЛЬВАР"); // 3
МассивСокращений.Добавить("КОРПУС"); // 3
МассивСокращений.Добавить("ОБЩЕСТВО"); // 3
МассивСокращений.Добавить("ПЕРЕУЛОК"); // 3
МассивСокращений.Добавить("ПОСЕЛОК"); // 3
МассивСокращений.Добавить("ПРОЕЗД"); // 3
МассивСокращений.Добавить("ПРОСПЕКТ"); // 3
МассивСокращений.Добавить("СЕКЦИЯ"); // 3
МассивСокращений.Добавить("СТРОЕНИЕ"); // 3
МассивСокращений.Добавить("УЛИЦА"); // 3
МассивСокращений.Добавить("УЧАСТОК"); // 3
МассивСокращений.Добавить("ШОССЕ"); // 3
МассивСокращений.Добавить("АО"); // 4
МассивСокращений.Добавить("ПГТ"); // 4
МассивСокращений.Добавить("РК"); // 4
МассивСокращений.Добавить("ТП"); // 4
МассивСокращений.Добавить("ГОРОД"); // 5
МассивСокращений.Добавить("ГОРОДА"); // 5
МассивСокращений.Добавить("ГОРОДЕ"); // 5
МассивСокращений.Добавить("ГОРОДУ"); // 5
МассивСокращений.Добавить("КРАЕ"); // 5
МассивСокращений.Добавить("КРАЙ"); // 5
МассивСокращений.Добавить("КРАЮ"); // 5
МассивСокращений.Добавить("КРАЯ"); // 5
МассивСокращений.Добавить("ОБЛАСТИ"); // 5
МассивСокращений.Добавить("ОБЛАСТЬ"); // 5
МассивСокращений.Добавить("ОТДЕЛ"); // 5
МассивСокращений.Добавить("ОТДЕЛА"); // 5
МассивСокращений.Добавить("ОТДЕЛЕНИЕ"); // 5
МассивСокращений.Добавить("ОТДЕЛЕНИЕМ"); // 5
МассивСокращений.Добавить("ОТДЕЛОМ"); // 5
МассивСокращений.Добавить("РАЙОН"); // 5
МассивСокращений.Добавить("РАЙОНА"); // 5
МассивСокращений.Добавить("РАЙОНЕ"); // 5
МассивСокращений.Добавить("РАЙОНУ"); // 5

КонецПроцедуры // ЗаполнитьМассивСокращенийАдресов()

И напоследок небольшой лайфхак для написания таких кусков кода. Основная часть процедуры была создана в виде таблицы в Ворде, а затем таблица преобразована в текст. Цифры в комментариях ведь не просто так стоят. Они нужны для сортировки таблицы по приоритету слов.

 

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. Идальго 129 04.01.20 21:34 Сейчас в теме
А не проще верифицировать "не нормализованную" адресную строку на тойже DaData, которая в структурированном виде вернёт адрес, ну или там информацию об ошибке и т.п.? Там вроде ещё и коды ФИАС и Кладр будут, что удобно, ну и сами же наименования улиц также могут меняться и прочее.
2. AnatolPopov 63 05.01.20 00:26 Сейчас в теме
(1) Я в то время не знал про DaData. Хотя, скорее всего, не стал бы использовать. В любом случае воспринял бы задачу как свою личную головную боль ;)
К тому же, обращение к каким-то там сервисам потребовало бы прописывания доступа, бодания с отделом ИБ, в общем, эта идея была бы отброшена сразу.
3. EliasShy 49 14.01.20 07:05 Сейчас в теме
Решал подобную задачу по адресам - через Google Geocoding Api получаю координаты адреса, саму строку адреса хэширую, и хэш с координатами сохраняю.
Новый адрес ищу по координатам - если совпадает - то адреса одинаковые
4. AnatolPopov 63 15.01.20 20:24 Сейчас в теме
(3) Сурово ;) Как я понимаю, такие сведения необходимо получать при внесении адреса в базу? И как быть с погрешностью измерений, с последующими поправками картографии? Предусмотрен какой-то допуск?

В моем случае надо было работать с тем, что дают, и не добавлять отсебятины, даже если очень хочется. Мое решение хорошо тем, что это тупая молотилка, которая просто сравнивает, что дали, ничего не придумывает, а мы можем быть уверены, что вероятность ложных отказов будет просто мала, а вероятность ложных срабатываний - ничтожно мала. Причем второе условие гораздо важнее первого. Это как раз тот случай, когда лучше недоделать, чем потом исправлять.
5. EliasShy 49 16.01.20 08:18 Сейчас в теме
(4) погрешность решается количеством знаков в широте и долготе.
Сервисы геокодирования достаточно точно описывают точку и хорошо работают по пользовательскому представлению адреса.

Сведения о геоданных получаются не для всех адресов, а для участвующих в процессе (в моем случае доставка грузополучателю).
В месяц порядка 200 запросов идет - они проходят по бесплатному порогу Google.

Ранее пользовались Яндексом, однако с недавних пор они бесплатный порог убрали.
Оставьте свое сообщение

См. также

Программная работа с настройками СКД

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Нюансы программной работы с настройками системы компоновки данных в отчетах и динамических списках. Обзор всех видов настроек компоновки. Что в каких случаях правильно применять. В качестве примера рассмотрена работа с отборами и группировками.

27.01.2020    4830    ids79    25       

INFOSTART MEETUP Kazan. 13 марта 2020 г. Промо

Инфостарт продолжает путешествие по России. Следующая остановка - Казань. Тема мероприятия - управление и технологии автоматизации учета на платформе "1С: Предприятие". Ждем всех: докладчиков и участников! Стоимость участия - 5 500 рублей. Цена действительна до 30.01.2020

5 500

[СКД] Программное создание схемы компоновки данных

Статья Программист Стажер Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Сделаем отчет на СКД полностью программно, без использования макета "схема компоновки данных".

15.01.2020    6850    John_d    20       

Универсальные функции: разложение произвольной строки адреса в структуру

Статья Программист Внешняя обработка (ert,epf) v8 1cv8.cf Абонемент ($m) Практика программирования Универсальные функции

Процедуры и функции раскладывают произвольную строку адрес в структуру по ключевым словам.

1 стартмани

30.12.2019    1448    4    vik070777    10       

Голосование за доклады на INFOSTART MEETUP Kazan - до 25 февраля. Промо

Выбирайте и голосуйте за самые интересные доклады! Лучшие из лучших попадут в окончательную программу казанского митапа. Оставить свой голос можно до 25 февраля 2020 года.

30 задач. Странных и не очень

Статья Программист Стажер Нет файла v8 Бесплатно (free) Практика программирования

30 задач на знание языка программирования 1С и некоторого поведения платформы. Маленьких. Странных и не очень.

02.12.2019    9089    YPermitin    72       

​​​​​​​CorelDRAW Graphics Suite 2019 Промо

CorelDRAW – пакет профессиональных инструментов для редактирования фотографий, разработки дизайна, создания макетов страниц и векторных иллюстраций

Агрегатные функции СКД, о которых мало кто знает

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    23429    ids79    45       

Базовый курс по управлению ИТ-проектами. Курс проходит с 26 февраля по 22 апреля 2020 года. Промо

Отличительная черта курса - органичное сочетание трех вещей: 1.Теория проектного управления (PMI®+Agile Alliance+Российские ГОСТ+Методологии от 1С); 2. Опыт внедрения продуктов 1С (опыт франчайзи и успешных компаний + тренды Infostart Event и Agile Days); 3. Разбор реальных проблем и рекомендации экспертов по проектам слушателей. Мы будем фиксироваться на тех инструментах, которые реально оказываются полезными в практике руководителей проектов внедрения. Ведущая курса - Мария Темчина.

от 11000 рублей

Три костыля. Сказ про фокусы в коде

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования

Три интересных (или странных) костыля в коде, которые могут помочь в повседневных и не очень задачах.

03.09.2019    13867    YPermitin    70       

Готовые переносы данных из различных конфигураций 1C Промо

Рекомендуем готовые решения для переноса данных из различных конфигураций 1C. C техподдержкой от разработчиков и гарантией от Инфостарт.

Отслеживание выполнения фонового задания

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Универсальные функции Разработка

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

17.08.2019    17858    ids79    16       

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    31919    ids79    36       

Открыто голосование за доклады на INFOSTART MEETUP Krasnodar Промо

Выбирайте и голосуйте за самые интересные доклады, лучшие из них попадут в окончательную программу митапа. Голосование продлится до 30 января 2020 года.

Фоновое выполнение кода в 1С - это просто

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования

Как легко запускать выполнение в фоне, не прибегая к долгому описанию фоновых процедур.

02.08.2019    17942    avalakh    21       

Онлайн-курс "Подготовка к экзамену 1С:Эксперт и 1С:Профессионал по технологическим вопросам" с 7 по 24 апреля 2020 г. Промо

На курсе вы получите практические навыки решения задач производительности 1С, в том числе характерных для высоконагруженных информационных систем (более 1000 пользователей). Подготовка к экзамену – только одна из составляющих курса. 70% слушателей приходят за знаниями, которые позволят расти и зарабатывать, делать сложные задачи на крупных проектах.

16450 рублей

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты

Статья Программист Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    26242    ids79    9       

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Инструментарий разработчика Практика программирования

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    19074    ids79    27       

1C:Предприятие для программистов: Расчетные задачи (зарплата). Онлайн-интенсив с 01 по 17 июня 2020 г. Промо

Данный онлайн-курс предусматривает изучение механизмов платформы “1С:Предприятие”, которые предназначены для автоматизации периодических расчетов, а именно - для расчета зарплаты. Курс предназначен для тех, кто уже имеет определенные навыки конфигурирования и программирования в системе “1С:Предприятие”, а также для опытных пользователей прикладного решения “1С:Зарплата и управление персоналом” и прочих прикладных решений, в которых реализован функционал расчета зарплаты.

4900 рублей

Регистры сведений. За кулисами

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Небольшие заметки по внутреннему устройству регистров сведений.

09.07.2019    14548    YPermitin    12       

"Меньше копипаста!", или как Вася универсальную процедуру писал

Статья Программист Стажер Нет файла v8 v8::СКД 1cv8.cf Бесплатно (free) Практика программирования Разработка

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    11962    SeiOkami    49       

Базовый курс по обмену данными в системе 1С:Предприятие. Онлайн-интенсив с 12 по 28 мая 2020 г. Промо

Данный онлайн-курс предусматривает изучение механизмов платформы “1С:Предприятие”, обеспечивающих обмен данными между различными прикладными 1С-решениями и взаимодействие с другими информационными системами. Курс предназначен для тех, кто уже имеет определенные навыки конфигурирования и программирования в системе “1С:Предприятие”.

5500 рублей

Создание отчетов с помощью СКД - основные понятия и элементы

Статья Программист Нет файла v8 v8::СКД Бесплатно (free) Практика программирования Математика и алгоритмы

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    31197    ids79    17       

Многопоточное ускорение однопользовательских нагрузок в 1С + Microsoft SQL Server 2017

Статья Программист Нет файла v8 v8::Запросы Бесплатно (free) Практика программирования Разработка

Взаимодействие с Microsoft SQL Server нередко вызывает трудности у 1С-ников, а потому интересны любые моменты, связанные с его использованием. О своем опыте работы с новым SQL Server 2017 участникам конференции Infostart-2018 рассказал директор ООО «Аналитика софт» Дмитрий Дудин.

11.06.2019    16715    dmurk    144       

1C:Предприятие для программистов: Запросы и отчеты. Второй поток. Онлайн-интенсив с 17 марта по 16 апреля 2020 г. Промо

Данный онлайн-курс предусматривает углубленное изучение языка запросов и возможностей системы компоновки данных, которые понадобятся при разработке отчетов, работающих на платформе “1С:Предприятие” в рамках различных прикладных решений. Курс предназначен для тех, кто уже имеет определенные навыки конфигурирования и программирования в системе “1С:Предприятие”, а также для опытных пользователей различных прикладных решений, которые используют в своей работе отчеты разного назначения.

6500 рублей

Регистры накопления. Структура хранения в базе данных

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

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

16.05.2019    26750    YPermitin    27       

Выполнение внешней обработки в фоновом задании

Статья Программист Нет файла v8 1cv8.cf Бесплатно (free) Практика программирования Разработка

Подробное описание подхода к созданию длительной операции на основе внешней обработки. Реализация протестирована на 1С 8.3.12.1714 (x64).

11.05.2019    16964    Eret1k    23       

Программы для исполнения 488-ФЗ: Маркировка товаров Промо

1 января 2019 года вступил в силу ФЗ от 25.12.2018 № 488-ФЗ о единой информационной системе маркировки товаров с использованием контрольных (идентификационных) знаков, который позволяет проследить движение товара от производителя до конечного потребителя. Инфостарт предлагает подборку программ, связанных с применением 488-ФЗ и маркировкой товаров.

Выгрузка документа по условию

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Разработка

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    9186    m-rv    2       

Как прикрутить ГУИД к регистру сведений

Статья Программист Нет файла v8 Бесплатно (free) Практика программирования Перенос данных из 1C8 в 1C8 Разработка

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

16.04.2019    12291    m-rv    16       

Подборка программ для взаимодействия с ЕГАИС Промо

ЕГАИС (Единая государственная автоматизированная информационная система) - автоматизированная система, предназначенная для государственного контроля за объёмом производства и оборота этилового спирта, алкогольной и спиртосодержащей продукции. Инфостарт рекомендует подборку проверенных решений для взаимодействия с системой.

О расширениях замолвите слово...

Статья Программист Стажер Нет файла v8 Бесплатно (free) Практика программирования Разработка

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    23071    ellavs    125       

Git-репозитории для 1С-кода (опыт использования при небольших проектах)

Статья Программист Стажер Нет файла v8 Windows Бесплатно (free) Практика программирования Разработка

Инструкции по взаимодействию с Git-репозиторием, которые писались для тех наших программистов, которые вообще никогда не работали с Git (руководства в духе "Как получить код из git-репозитория?", "Как отправить код в git-репозиторий")...

28.03.2019    18306    ellavs    83