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

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

Разработка - Математика и алгоритмы

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

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

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

Ранее пользовались Яндексом, однако с недавних пор они бесплатный порог убрали.
6. ivangrant 10 03.09.21 11:19 Сейчас в теме
Всё не так однозначно. Улицы состоят порой из 2-4 слов. Ещё есть в названии улиц числа. Например, Улица 1905-го года. А есть где в городе и улица и переулок имеют одинаковые названия.
Насчет описания достаточно точной геопозиции - не всегда работает эта схема.
Например с магазинами, где на одном адресе их может быть несколько.
Геокодирование удобно, когда 2-3 точки на 1 кв.км. Если больше, можно сколько угодно подбирать точки, погрешности при сопоставлении будут возрастать.
7. AnatolPopov 123 03.09.21 16:39 Сейчас в теме
(6)
Улицы состоят порой из 2-4 слов. Ещё есть в названии улиц числа. Например, Улица 1905-го года. А есть где в городе и улица и переулок имеют одинаковые названия.

Поэтому требуется большая подготовительная работа по устранению всяких вольностей в адресах, приведению названий к одному виду. Довольно муторно. А "-го" в конце "1905-го" убирается при создании формализованного адреса.
Оставьте свое сообщение

См. также

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Универсальные обработки Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    11950    89    sapervodichka    92    

114

Система контроля ведения учета [БСП]

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

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    5542    quazare    8    

101

Хитрости СКД. Часть 3

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

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

28.05.2022    6700    milkers    11    

87

Модули общего назначения - готовые полезные функции и процедуры конфигураций на БСП

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

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

25.04.2022    10265    quazare    11    

130

Несколько простых приемов для удобной работы в конфигураторе

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

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

12.11.2021    13691    acces969    95    

142

Самый простой парсинг и обработка веб-страниц в 1С

WEB-интеграция Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Рассмотрим самый простой парсинг веб-страниц средствами платформы 1С и еще некоторые полезные приемы работы с веб-страницами.

07.08.2020    25091    Infostart    30    

146

Полезные встроенные функции для работы с печатными формами и не только на УТ 11.4 и БП 3.0 (сравнение)

Универсальные функции Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 Россия Бесплатно (free)

В данном обзоре приведу примеры встроенных используемых функций для работы с печатными формами на примерах конфигураций Управление торговлей 11.4 и Бухгалтерия 3.0.

10.07.2020    15253    quazare    7    

94

Форма выбора (подбор) в управляемых формах

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

Разбор небольших примеров того, как правильно открывать форму выбора (подбора) в управляемых формах, не прибегая к модальным окнам.

08.05.2020    180441    user5300    40    

291

Сходство Джаро - Винклера. Нечеткое сравнение строк

Универсальные функции Платформа 1С v8.3 Россия Бесплатно (free)

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

25.12.2019    11342    brooho    21    

170

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

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

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

02.12.2019    40790    Infostart    63    

161

Полезные процедуры и функции для программиста

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

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

07.10.2019    48046    HostHost    41    

284

"Хочу универсально!" [Часть 1]

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

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

02.09.2019    11650    SeiOkami    35    

76

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

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

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

2 стартмани

24.08.2019    24753    BenGunn    29    

132

Иерархия без "В ИЕРАРХИИ"

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Говорится о том, как эффективно представлять иерархию в СУБД, как получать и использовать эти представления при решении задач в запросной технике. Уточняются и дополняются запросы из статьи "Уровни, глубина, прародители, циклы и аналоги запросом" [https://infostart.ru/public/160707/].

22.08.2019    19520    ildarovich    24    

181

Алгоритмы поиска пути в графе. Часть 2

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Новые возможности, ранее реализованных алгоритмов поиска пути в графе на платформе 1С 8.3.

1 стартмани

13.08.2019    13960    11    RonX01    10    

92

Обработчики событий при записи объектов. Зачем и что за чем?

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Программисту, имеющему немного опыта на платформе 1С 8.3, бывает сложно разобраться: ПередЗаписью, ПриЗаписи, ПослеЗаписи, на сервере, на клиенте, в модуле формы, в модуле объекта.... Эта шпаргалка была создана в процессе обучения и реального опыта с целью разложить всё по полочкам, чтобы было четкое понимание в каком случае какой обработчик нужно использовать и в какой последовательности они запускаются при записи и проведении документов. Данная статья будет полезна в большей степени начинающим разработчикам. Но и опытным позволит освежить информацию, упорядочить её.

25.07.2019    201418    AlbinaAAA    51    

757

Что делает "В ИЕРАРХИИ" в запросе?

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Описание действий платформы 1С при использовании конструкции "В ИЕРАРХИИ" в запросах.

16.07.2019    74997    Infostart    34    

131

Алгоритмы поиска пути в графе

Математика и алгоритмы Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Реализуем алгоритмы поиска пути в графе на платформе 1С 8.3, такие как алгоритм А*, поиск в ширину, жадный поиск, алгоритм Дейкстры и вконце волновой.

1 стартмани

09.07.2019    29759    14    RonX01    11    

116

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

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

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

25.06.2019    103720    ids79    33    

336

Реализуем Стек, Очередь и Приоритетную очередь в 1С

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

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

24.06.2019    19678    RonX01    70    

88

Вычисление 200 тысяч знаков числа pi

Математика и алгоритмы Платформа 1С v8.3 Россия Бесплатно (free)

В статье рассматриваются возможности платформы выполнять сверхточные вычисления без использования сложных алгоритмов и внешних компонент на примере вычисления числа pi.

28.05.2019    11237    Oleg_nsk    97    

79

Добавление отчетов в типовые конфигурации 1С

Универсальные функции БСП (Библиотека стандартных подсистем) Управляемые формы Система компоновки данных Конфигурации 1cv8 Бесплатно (free)

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

07.03.2019    104897    ids79    51    

325

Как писать код? Технологии древних цивилизаций, или все новое - это хорошо забытое старое

Математика и алгоритмы Бесплатно (free)

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

23.01.2019    13002    starik-2005    43    

78

Ректальное программирование: основы для практикующих 1С-программистов

Математика и алгоритмы Бесплатно (free)

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

19.12.2018    54845    for_sale    355    

343

Подмена заголовка 1С

Универсальные функции Работа с интерфейсом Россия Бесплатно (free)

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

08.12.2018    12451    moolex    26    

26

Универсальные функции ЗУП 3.1 / ЗКГУ 3.1, которые помогут в разработке

Универсальные функции Зарплата Кадровый учет Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Бухгалтерский учет Бесплатно (free)

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

14.11.2018    231549    GeterX    175    

1007

Кадровые данные сотрудников в ЗУП 3.1 в отчетах

Универсальные функции Кадровый учет Платформа 1С v8.3 Сложные периодические расчеты 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Параметры используемые для получения данных сотрудников в ЗУП 3.1. Пригодится для разработки отчетов как напоминалка.

07.11.2018    80355    fromlion    38    

125

Отправка электронной почты с помощью локального почтового клиента из 1С, развернутой под удаленным рабочим столом

Печатные формы Универсальные функции Email рассылки Платформа 1С v8.3 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием Абонемент ($m)

Решение для интерактивной (нажал-отредактировал) отправки электронных писем и печатных форм через почтовый клиент (Thunderbird, Outlook) находящийся на локальном компьютере, из конфигурации 1С, развернутой под удаленным рабочим столом (RDP, remote-app). Подходит также для локального развертывания 1С. Представлен пример быстрой интеграции с конфигурациями "Управление торговлей 10.3", "Управление производственным предприятием 1.3", "Комплексная автоматизация 1.1", "Бухгалтерия предприятия 2.0".

1 стартмани

21.09.2018    40359    24    stvorl    1    

20

Работаем с дополнительными реквизитами на форме

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

Пара полезных процедур для работы с дополнительными реквизитами на форме. Далее в статье: 1. Как называются дополнительные реквизиты на форме и в какой момент они появляются на форме? 2. Как проверить до записи корректность заполнения пользователем дополнительного реквизита? 3. Как заполнить значение дополнительного реквизита по другому событию и обновить данные на форме? 4. Как расположить дополнительный реквизит в указанном месте на форме?

15.07.2018    77885    papche    81    

266

Повышение качества разработки. Статья 3. Ошибки программы

Математика и алгоритмы Рефакторинг и качество кода Бесплатно (free)

Учебный курс по теории и практике программирования. Бесплатно. В виде структурированного текста. Статья 3. Эта статья посвящена ошибкам программ, их классификации и способам исправления.

10.07.2018    24791    Артано    92    

106

Строковые функции для совместимости с платформой 8.3.5 и ниже

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

СтрНайти(), СтрНачинаетсяС(), СтрЗаканчиваетсяНа(), СтрРазделить(), СтрСоединить(), СтрШаблон() для платформы ниже 8.3.6

03.06.2018    38226    json    49    

103

Нанесение штампа на PDF файл при регистрации (входящий номер и дата)

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

Данный код реализует возможность автоматического нанесения штампа на PDF файл при регистрации (входящий номер и дата).

14.05.2018    23307    aabogachev    47    

94

Повышение качества разработки. Статья 1. Определение терминологии и проблематики

Математика и алгоритмы Бесплатно (free)

Учебный курс по теории и практике программирования. Бесплатно. В виде структурированного текста. Часть 1

10.05.2018    19588    Артано    52    

128

Нечеткое сравнение строк. Метод Джаро-Винклера на 1С

Математика и алгоритмы Управляемые формы Конфигурации 1cv8 Абонемент ($m)

Схожесть строк. Метод Джаро-Винклера. В обработке реализован алгоритм нечеткого сравнения строк.

3 стартмани

20.04.2018    31187    120    Serg1701    20    

141

"Взлом" теста "1С:Профессионал" методом машинного обучения

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

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

12.03.2018    23338    ildarovich    44    

95

Правила программирования и автоматизации

Математика и алгоритмы Бесплатно (free)

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

21.02.2018    20076    Dzenn    127    

78

Минимализмы 3

Математика и алгоритмы Платформа 1С v8.3 Бесплатно (free)

Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.

19.02.2018    54202    ildarovich    47    

423