Dim objConnection As Object Dim objRecordset As Object Dim arr As Variant Dim strConnection As String Dim strSQL As String Dim strText As String Dim strTextRang As String Dim WhatLen As Integer Dim i As Integer
WhatLen = Len(What) If WhatLen < 3 Then Return End If Set objConnection = CreateObject("ADODB.Connection") Set objRecordset = CreateObject("ADODB.Recordset") strConnection = IIf(Val(Application.Version) < 12, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';", "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties='Excel 12.0;HDR=NO;IMEX=1';") objConnection.Open strConnection strText = "0" For i = 1 To WhatLen - 2 strText = strText & "+iif(instr(f1,'" & Mid(What, i, 3) & "')>0,1,0)" Next strTextRang = "iif(mid(f1," & (WhatLen + 1) & ",3)=''," & WhatLen & ", len(f1))" strSQL = "select top 20 100*(" + strText + ")/(" + strTextRang + " - 2) as rang,f1 from [" + Where.Worksheet.Name + "$" + Where.Address(False, False) + "] order by 1 desc" objRecordset.Open strSQL, objConnection, adOpenStatic, adLockOptimistic, adCmdText arr = objRecordset.getRows At_GetClosestWord = arr(1, NumItem - 1)
End Function
[/vba]
Кину сюда, попробовал сделать нечеткий поиск запросом:
[vba]
Код
Public Function At_GetClosestWord(ByRef What As Range, ByRef Where As Range, Optional ByVal NumItem As Long = 1) As Variant
Dim objConnection As Object Dim objRecordset As Object Dim arr As Variant Dim strConnection As String Dim strSQL As String Dim strText As String Dim strTextRang As String Dim WhatLen As Integer Dim i As Integer
WhatLen = Len(What) If WhatLen < 3 Then Return End If Set objConnection = CreateObject("ADODB.Connection") Set objRecordset = CreateObject("ADODB.Recordset") strConnection = IIf(Val(Application.Version) < 12, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties='Excel 8.0;HDR=NO;IMEX=1';", "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties='Excel 12.0;HDR=NO;IMEX=1';") objConnection.Open strConnection strText = "0" For i = 1 To WhatLen - 2 strText = strText & "+iif(instr(f1,'" & Mid(What, i, 3) & "')>0,1,0)" Next strTextRang = "iif(mid(f1," & (WhatLen + 1) & ",3)=''," & WhatLen & ", len(f1))" strSQL = "select top 20 100*(" + strText + ")/(" + strTextRang + " - 2) as rang,f1 from [" + Where.Worksheet.Name + "$" + Where.Address(False, False) + "] order by 1 desc" objRecordset.Open strSQL, objConnection, adOpenStatic, adLockOptimistic, adCmdText arr = objRecordset.getRows At_GetClosestWord = arr(1, NumItem - 1)
Привет! Я надеюсь, что тема ещё не умерла Хотелось бы вставить свои 5 копеек. я использовал файл simtext451.xls У меня 2 столбца со словами типа: affects effects aging ageing besides beside
и т.д.
так вот, для слов типа practice и practise схожесть 67%, а для effected и affected - 83%. Почему так происходит? как это можно исправить?
Заранее спасибо за ответы
Привет! Я надеюсь, что тема ещё не умерла Хотелось бы вставить свои 5 копеек. я использовал файл simtext451.xls У меня 2 столбца со словами типа: affects effects aging ageing besides beside
и т.д.
так вот, для слов типа practice и practise схожесть 67%, а для effected и affected - 83%. Почему так происходит? как это можно исправить?
StanDaniels, извините, проворонил ваш вопрос. Но лучше поздно, чем никогда. Отвечаю: это - специфика метода Q-грамм. Различие в первой или последней букве учитывается только в одном фрагменте, различие в предпоследней - уже в двух и т.д. пока не будет достигнута константа Q. Кому интересно - смотрите посты №3, №36
StanDaniels, извините, проворонил ваш вопрос. Но лучше поздно, чем никогда. Отвечаю: это - специфика метода Q-грамм. Различие в первой или последней букве учитывается только в одном фрагменте, различие в предпоследней - уже в двух и т.д. пока не будет достигнута константа Q. Кому интересно - смотрите посты №3, №36Формуляр
Честно пытался около 6 часов разобраться как же все таки применять ваш макрос, но так и не заработала у меня программа. В чем суть - у меня есть два списка улиц один более общий, другой более подробный с адресами. Надо сравнить частный с общим и найти соответствия. Убейте меня, но я так и не смог понять как вы применяете ваши макросы. Пытался пройти простым путем - просто вставить в ваши файлы свои списки, но они не работают. Выдает ошибку - нельзя изменить массив данных. Помогите, пожалуйста, найти решение, очень вас прошу.
Спасибо.
Формуляр, Александр, добрый день!
Честно пытался около 6 часов разобраться как же все таки применять ваш макрос, но так и не заработала у меня программа. В чем суть - у меня есть два списка улиц один более общий, другой более подробный с адресами. Надо сравнить частный с общим и найти соответствия. Убейте меня, но я так и не смог понять как вы применяете ваши макросы. Пытался пройти простым путем - просто вставить в ваши файлы свои списки, но они не работают. Выдает ошибку - нельзя изменить массив данных. Помогите, пожалуйста, найти решение, очень вас прошу.
Varyag7660, добрый вечер. Пошёл тем же простым путём. Не знаю, откуда у вас взялась ошибка. Может, где-то ввели случайно формулу массива? У меня массив только там где "Подробнее:".
У меня всё работает, но ваша задача требует некоторых специфических настроек. Поскольку вам надо искать не образец в списке, а как бы наоборот - строки списка в образце, ставим константу F значительно > 1: F=99 В этом случае метрика будет игнорировать "лишние" символы из подробного списка адресов. Размер фрагмента можем оставить пока стандартным: Q=2 Как видно из адреса в D8 количество случайных совпадений довольно велико, возможноо стоит поднять порог до 60-70%.
Должен заметить, что в базовом списке много мусорного текста, который не только тормозит обработку, но и сильно снижает качество сравнения. Слова типа "улица" в большинстве случаев не несут никакой полезной нагрузки. Если попадаются, например, улица и площадь с одним названием - оставляейте, но только сокращённым, чтоб было как в рабочем адресе.
Хочу предупредить, что в данной реализации игнорируются все символы кроме букв. Возможно, стоит расширить набор символов на цифры, но тогда сразу номера домов начнут давать случайные совпадения... В ближайшее свободное время посмотрю, как ещё оптимизировать алгоритм под вашу задачу, она довольно типична и многим пригодится.
PS: зря я сразу не увеличил Q до 3 - практически все случайные совпадения сразу отваливаются.
Varyag7660, добрый вечер. Пошёл тем же простым путём. Не знаю, откуда у вас взялась ошибка. Может, где-то ввели случайно формулу массива? У меня массив только там где "Подробнее:".
У меня всё работает, но ваша задача требует некоторых специфических настроек. Поскольку вам надо искать не образец в списке, а как бы наоборот - строки списка в образце, ставим константу F значительно > 1: F=99 В этом случае метрика будет игнорировать "лишние" символы из подробного списка адресов. Размер фрагмента можем оставить пока стандартным: Q=2 Как видно из адреса в D8 количество случайных совпадений довольно велико, возможноо стоит поднять порог до 60-70%.
Должен заметить, что в базовом списке много мусорного текста, который не только тормозит обработку, но и сильно снижает качество сравнения. Слова типа "улица" в большинстве случаев не несут никакой полезной нагрузки. Если попадаются, например, улица и площадь с одним названием - оставляейте, но только сокращённым, чтоб было как в рабочем адресе.
Хочу предупредить, что в данной реализации игнорируются все символы кроме букв. Возможно, стоит расширить набор символов на цифры, но тогда сразу номера домов начнут давать случайные совпадения... В ближайшее свободное время посмотрю, как ещё оптимизировать алгоритм под вашу задачу, она довольно типична и многим пригодится.
PS: зря я сразу не увеличил Q до 3 - практически все случайные совпадения сразу отваливаются.Формуляр
Формуляр, Александр, добрый день! Спасибо вам большое, все заработало. Для меня все равно в этом есть какой то элемент магии)). По вашему совету вычистил весь мусор и поиск стал еще более эффективным. Вы меня просто выручил! Спасибо еще раз.
Формуляр, Александр, добрый день! Спасибо вам большое, все заработало. Для меня все равно в этом есть какой то элемент магии)). По вашему совету вычистил весь мусор и поиск стал еще более эффективным. Вы меня просто выручил! Спасибо еще раз.Varyag7660
Добрый день! Ситуация такая: есть огромный файл excel в ячейках наименование запасных частей, много ячеек есть дублирующихся (путем правила выделения повторяющихся ячеек удали много), но есть есть наименования где есть пробел либо с заглавными буквами строчка тогда правило уже не работает ( Рычаг поперечный задней подвески задний правый Hyundai 5522025000(0NNURI) Verna/CAR_DEX и Рычаг поперечный задней подвески задний правый HYUNDAI 5522025000(ONNURI) Verna/CAR_DEX** ). также добавленные символы** или цифры. Есть ли такой вариант где анализируется и процентах схожесть строчек отображает что бы их можно удалить.
Добрый день! Ситуация такая: есть огромный файл excel в ячейках наименование запасных частей, много ячеек есть дублирующихся (путем правила выделения повторяющихся ячеек удали много), но есть есть наименования где есть пробел либо с заглавными буквами строчка тогда правило уже не работает ( Рычаг поперечный задней подвески задний правый Hyundai 5522025000(0NNURI) Verna/CAR_DEX и Рычаг поперечный задней подвески задний правый HYUNDAI 5522025000(ONNURI) Verna/CAR_DEX** ). также добавленные символы** или цифры. Есть ли такой вариант где анализируется и процентах схожесть строчек отображает что бы их можно удалить.MS102
Доброго всем времени суток! подскажите плиз, хочется поэксперементировать со связочкой как в примерах "= FindBestMatchTxt()" и "= TextSimilarity()" ,а ,стесняюсь спросить,где эти функции "взять"-попытка найти в теме увела еще глубже в форум((.Спасибо заранее .
Доброго всем времени суток! подскажите плиз, хочется поэксперементировать со связочкой как в примерах "= FindBestMatchTxt()" и "= TextSimilarity()" ,а ,стесняюсь спросить,где эти функции "взять"-попытка найти в теме увела еще глубже в форум((.Спасибо заранее .Urri
Как зафиксировать диапазон, в котором выполняется поиск при растягивании формулы FindBestMatchTxt?
Другими словами, массив, где происходит поиск всегда в $A1:$A1000 И для каждой строки $C мы ищем соответствии из $A:$A через FindBestMatchTxt При растягивании "вниз" диапазон тоже начинает смещаться $A2:$A1001, $A3:$A1002 и так далее. Как его зафиксировать и менять только C?
Как зафиксировать диапазон, в котором выполняется поиск при растягивании формулы FindBestMatchTxt?
Другими словами, массив, где происходит поиск всегда в $A1:$A1000 И для каждой строки $C мы ищем соответствии из $A:$A через FindBestMatchTxt При растягивании "вниз" диапазон тоже начинает смещаться $A2:$A1001, $A3:$A1002 и так далее. Как его зафиксировать и менять только C?
Pushkin1799, Ваш вопрос не имеет отношения конкретно к этой теме. возможность закрепления касается любой формулы. В Интернете, про это - полно статей - достаточно в гугл вбить "как зафиксировать диапазон в excel". Пробуйте менять $ - и смотреть на результат.
Pushkin1799, Ваш вопрос не имеет отношения конкретно к этой теме. возможность закрепления касается любой формулы. В Интернете, про это - полно статей - достаточно в гугл вбить "как зафиксировать диапазон в excel". Пробуйте менять $ - и смотреть на результат.SLAVICK
Тоже озадачился данной тематикой Сама по себе тема нечёткого поиска неисчерпаема... Пока в своих изысканиях добрался до словаря с образцами правильных строк и проверки по его ключам в цикле на взаимное вхождение введённого значения/образца, если вхождение имеет место, то строка=образец из словаря. Ну и поскольку нечёткий поиск этим явно не заканчивается, то ещё и всяческие двустороние чтения строк посимвольно, если разница образца из словаря и введённого значения не более одного символа, то считаем сколько еще таких ключей есть в словаре. И т.д.. В общем пока все в зачаточном состоянии сбора и анализа доступной информации в инете. Мысли: - доп.словарь замен в виде соседних сиволов с клавиатуры на случай опечатки, лат/рус по этому же принципу - реверс подстрок опять-таки на случай опечаток - каким-то макаром вычленить в проверяемой строке с учётом предыдущих пунктов корень слова
П.С.: Полистал различные статьи на эту тему в том числе эту. Метод Q-Gramm считается не очень эффективным.
Тоже озадачился данной тематикой Сама по себе тема нечёткого поиска неисчерпаема... Пока в своих изысканиях добрался до словаря с образцами правильных строк и проверки по его ключам в цикле на взаимное вхождение введённого значения/образца, если вхождение имеет место, то строка=образец из словаря. Ну и поскольку нечёткий поиск этим явно не заканчивается, то ещё и всяческие двустороние чтения строк посимвольно, если разница образца из словаря и введённого значения не более одного символа, то считаем сколько еще таких ключей есть в словаре. И т.д.. В общем пока все в зачаточном состоянии сбора и анализа доступной информации в инете. Мысли: - доп.словарь замен в виде соседних сиволов с клавиатуры на случай опечатки, лат/рус по этому же принципу - реверс подстрок опять-таки на случай опечаток - каким-то макаром вычленить в проверяемой строке с учётом предыдущих пунктов корень слова
П.С.: Полистал различные статьи на эту тему в том числе эту. Метод Q-Gramm считается не очень эффективным.Anchoret
Если есть живые на этой теме, нужна небольшая доработка файла, а именно : Отображение не одного значения - а всех значений , которые совпадают более, чем на 20%.
Оплата. Пишите.
Если есть живые на этой теме, нужна небольшая доработка файла, а именно : Отображение не одного значения - а всех значений , которые совпадают более, чем на 20%.
Подскажите, пожалуйста, кто-нибудь, Как нужно исправить код FuzzyVLOOKUP, чтобы функция искала не наиболее точно совпадающее значение из массива, а первое удовлетворяющее проценту совпадения? Если можно, на пальцах. (Не ленюсь, просто чайник немного )
Заранее благодарна!
Подскажите, пожалуйста, кто-нибудь, Как нужно исправить код FuzzyVLOOKUP, чтобы функция искала не наиболее точно совпадающее значение из массива, а первое удовлетворяющее проценту совпадения? Если можно, на пальцах. (Не ленюсь, просто чайник немного )
Здравствуйте, форумчане. При использовании функции FindBestMatchTxt столкнулся с таким моментом. Ищем в столбике: Изделие № 1 Изделие № 2 Изделие № 3 Изделие № 4 Изделие № 5 Искомая строка: Изделие № 2 Возвращает: Изделие № 1 Собственно, для любой цифры после номера всегда выдает первую строчку. Особенно удручает, тот факт, что даже при наличии 100% одинаковых строк. Функция при параметре до 50% выдает первую строку, а дальше - выдает 0. Сложилось мнение, что функция не понимает знак №, и может даже цифры... Так ли это, и как с бороться с такой проблемой? Заранее спасибо.
Здравствуйте, форумчане. При использовании функции FindBestMatchTxt столкнулся с таким моментом. Ищем в столбике: Изделие № 1 Изделие № 2 Изделие № 3 Изделие № 4 Изделие № 5 Искомая строка: Изделие № 2 Возвращает: Изделие № 1 Собственно, для любой цифры после номера всегда выдает первую строчку. Особенно удручает, тот факт, что даже при наличии 100% одинаковых строк. Функция при параметре до 50% выдает первую строку, а дальше - выдает 0. Сложилось мнение, что функция не понимает знак №, и может даже цифры... Так ли это, и как с бороться с такой проблемой? Заранее спасибо.ToporiK
Alex_ST, здравствуйте! Отличная работа! Как раз искал нечто такое, и скоординировали на данное обсуждение. Помогите, пожалуйста, разобраться и попробовать применить вашу разработку на деле :batman:
Alex_ST, здравствуйте! Отличная работа! Как раз искал нечто такое, и скоординировали на данное обсуждение. Помогите, пожалуйста, разобраться и попробовать применить вашу разработку на деле :batman:Tso