В процессе эксплуатации информационных систем на базе 1С часто возникает проблема появления дублей в справочниках Сотрудники, ФизическиеЛица или Контрагенты. Одной из самых сложных ситуаций является та, при которой одни и те же данные внесены в разном порядке. Например, один оператор ввел «Петров Иван Николаевич», а другой — «Иван Николаевич Петров». Для стандартной группировки в запросе это разные записи. В этой статье мы подробно разберем, как реализовать эффективный механизм поиска таких дублей, используя как простые методы нормализации, так и продвинутые алгоритмы нечеткого поиска.
Самый доступный и логичный способ, предложенный в обсуждении, — привести все записи к единому стандарту (индексу) перед сравнением. Если мы отсортируем слова в строке по алфавиту, то порядок их первоначального ввода перестанет иметь значение. Для обеих записей («Петров Иван» и «Иван Петров») мы получим одинаковый ключ для сравнения: «Иван Петров».
Рассмотрим по шагам, как это реализовать программно. Проанализируем пример кода, который можно использовать в обработке по поиску дублей:
Функция ПолучитьИндексФИО(ИсходноеФИО)
// Очищаем строку от лишних пробелов и приводим к регистру
ЧистаяСтрока = СокрЛП(НРег(ИсходноеФИО));
// Разбиваем строку на массив слов по разделителю "пробел"
МассивСлов = СтрРазделить(ЧистаяСтрока, " ", Ложь);
// Используем СписокЗначений для быстрой сортировки
СписокДляСортировки = Новый СписокЗначений;
СписокДляСортировки.ЗагрузитьЗначения(МассивСлов);
СписокДляСортировки.СортироватьПоЗначению();
// Собираем слова обратно в строку через пробел
МассивСортированныхСлов = СписокДляСортировки.ВыгрузитьЗначения();
Возврат СтрСоединить(МассивСортированныхСлов, " ");
КонецФункции
Проанализируем ситуацию: создав временную таблицу или добавив колонку в ТаблицаЗначений с результатом этой функции, мы сможем легко сгруппировать данные. Все записи, имеющие одинаковый результат функции ПолучитьИндексФИО, с высокой долей вероятности являются дублями.
Если вы работаете в современной конфигурации (например, 1С:ERP, ЗУП 3.1 или УТ 11), в ней уже интегрирована подсистема «Поиск и удаление дублей». Необязательно изобретать велосипед — достаточно вызвать программные методы БСП. Рассмотрим подробнее преимущества этого подхода:
Для поиска рекомендуется использовать обработку ПоискИУдалениеДублей, которая находится в разделе «Администрирование» — «Обслуживание».
Сортировка слов помогает при разном порядке, но бессильна против опечаток (например, «Иванов» и «Ивановв»). Выясним причину, почему это критично: человеческий фактор при вводе данных неизбежен. Для решения этой задачи профессионалы используют алгоритм Левенштейна.
Этот алгоритм вычисляет «стоимость» превращения одной строки в другую (количество правок). Посмотрим на пример реализации функции вычисления сходства на языке 1С:
Функция РасстояниеЛевенштейна(Стр1, Стр2)
н = СтрДлина(Стр1);
м = СтрДлина(Стр2);
Если н = 0 Тогда Возврат м; КонецЕсли;
Если м = 0 Тогда Возврат н; КонецЕсли;
// Инициализация матрицы
Матрица = Новый Массив(н + 1, м + 1);
Для и = 0 По н Цикл Матрица[и][0] = и; КонецЦикла;
Для й = 0 По м Цикл Матрица[0][й] = й; КонецЦикла;
// Вычисление расстояния
Для и = 1 По н Цикл
Для й = 1 По м Цикл
ЦенаЗамены = ?(Сред(Стр1, и, 1) = Сред(Стр2, й, 1), 0, 1);
Матрица[и][й] = Минимум(Матрица[и-1][й] + 1,
Минимум(Матрица[и][й-1] + 1,
Матрица[и-1][й-1] + ЦенаЗамены));
КонецЦикла;
КонецЦикла;
Возврат Матрица[н][м];
КонецФункции
Используя этот метод, мы можем вывести пользователю список записей, где коэффициент сходства выше 85%. Это позволит найти дубли даже при наличии ошибок в фамилиях.
Важным аспектом является работа со спецификой русского языка. Разберем по шагам дополнительные меры по улучшению качества поиска:
Семёнов и Семенов — абсолютно разные строки. Всегда выполняйте СтрЗаменить(Текст, "ё", "е") перед сравнением.Как справедливо отмечено в обсуждении, полные тезки — это реальность. Чтобы не объединить двух разных людей с одинаковым ФИО, необходимо использовать систему весов. Рассмотрим пример логики принятия решения:
Если итоговая сумма баллов превышает порог (например, 80), система должна предложить объединение. Если баллов мало (например, только ФИО), запись помечается как «подозрительная», требующая ручной проверки бухгалтером или кадровиком.
Проанализируем ситуацию, когда в справочнике более 100 000 записей. Прямой перебор всех элементов и сравнение «каждый с каждым» по алгоритму Левенштейна займет часы. Чтобы ускорить процесс, выполним следующие шаги:
1. Предварительная индексация: Создайте в справочнике дополнительный реквизит ХешФИО (индексируемый). Заполняйте его при записи элемента результатом функции нормализации (Метод 1).
2. Запросный поиск: Сначала найдите группы с одинаковым ХешФИО через запрос с предложением СГРУППИРОВАТЬ ПО. Это мгновенно отсеет 90% явных дублей.
3. Уточняющий поиск: Только для оставшихся записей применяйте тяжелые алгоритмы нечеткого сравнения.
Таким образом, комбинируя методы программной нормализации строк и встроенные инструменты 1С, мы получаем надежный инструмент для поддержания чистоты данных в информационной базе.