Страницы: 1
RSS
Извлечь ИНН из текста
 
Задача такая: имею столбец с совершенно криворукими названиями клиентов, которые записаны черти как, абсолютно не системно и не однотипно, но в какой то части их названия присутствует ИНН, который собственно нужно извлечь.
Задача упрощается тем, что слава богу кто-то все-таки догадался перед числовым номером ИНН писать сами буквы "ИНН", поэтому начальную позицию забора текста вычислить не сложно. Но после самого номера ИНН-на еще может продолжаться текст, и ИНН после своего окончания отделен от этого текста либо запятой, либо пробелом, либо открывающей или закрывающей скобкой.
И вот конечную позицию ИНН-на собственно нужно определить позицией первой встречающейся запятой, пробела или открывающей/закрывающей скобки в строке, в которой все до начала самого номера ИНН-на уже откинуто. Как то никогда не доводилось использовать комбинацию =ПОИСК(ИЛИ(искомый текст1; искомый текст2)...     Сейчас к своему удивлению выяснил, что такая комбинация не работает.
Можно конечно это решить через ЕСЛИОШИБКА(ПОИСК(",";текст где ищем);ЕСЛИОШИБКА(ПОИСК(" ";текст где ищем);ЕСЛИОШИБКА(ПОИСК("(";текст где ищем);ЕСЛИОШИБКА(ПОИСК(")";текст где ищем)...     Но это в данном случае у меня всего 4 варианта окончания номера ИНН. А если их будет 100? Не вариант 100 раз писать ЕСЛИОШИБКА (да и длины ячейки не хватит).

Код
ПОДСТАВИТЬ(текст;ИЛИ(",";" ";"(";")");"*")
тоже не работает.

Как можно емко определить номер позиции одного из четырех искомых символов, который первым встретится в тексте ячейки?
 
А что, ИНН по количеству символов разные?
Предврительня подготовка: инструмент НАЙТИ-ЗАМЕНИТЬ, меняекм на 5-6 пробелов (с запасом, для гарантии) скобку, запятую, чтотамеще. После этого применяем формулу:
=СЖПРОБЕЛЫ(ПСТР(Таблица1[@Клиент];НАЙТИ("ИНН";Таблица1[@Клиент])+3;13))
13 - На 1 больше максимальной длины ИНН. Но если между словом "ИНН" и ИНН встречается больше одого символа, то число нужно ставить больше.

Цитата
ИЛИ(",";" ";"(";")")... тоже не работает.
И правильно не работает. Синтаксис неправильный.
 
Разные, в 12 строке например.
Здесь естественно только маленький кусочек базы приведен, в оригинале там десятки тысяч строк.
Изменено: VasiliY_Seryugin - 18.06.2020 00:01:31
 
Цитата
инструмент НАЙТИ-ЗАМЕНИТЬ
не хотелось бы им, хотелось бы чисто формулой, чтоб было универсальное решение на случай, если вариантов окончания будет значительно больше четырех.

Цитата
И правильно не работает. Синтаксис неправильный.
Вероятно. Если поясните почему именно не правильный буду очень благодарен!
 
Не надо пояснять, я сам понял почему:) Потому что там должны быть логические значения, а не просто варианты искомого текста.
 
UDF
Код
Function INN(cell$)
 With CreateObject("VBScript.RegExp")
     .Global = True
     .Pattern = "ИНН\s?(\d{10,12})"
     INN = .Execute(cell)(0).SubMatches(0)
 End With
End Function
 
Цитата
VasiliY_Seryugin написал: если вариантов окончания будет значительно больше четырех...
...то никакая формула не угадает, какие там варианты могут быть еще... Появится какая-нибудь закорючка, которая в формуле не предусмотрена... А если будет в тексте: "ИНН этого объекта-субъекта ИНН 111111" или какое-нибудь "ДЛИННОШЕЕЕ"- пиши пропало.
Универсальным может быть макрос, который будет проверять наличие слова или фрагмента "ИНН", определять. что после него находится, вычленять из текста только числовое значение.

Формулу такую тоже можно соорудить, но
Цитата
в оригинале там десятки тысяч строк
и на таких данных книга повесится и будет уговаривать пользователя последовать за ней :)
 
Kuzmich,  работает, спасибо!
У меня к сожалению не достаточно знаний VBA чтобы понять, как именно и почему именно оно работает, но я попробую это понять :)
 
Если нужен ИНН с хвостиком, то
Код
Function INN_(cell$)
 With CreateObject("VBScript.RegExp")
     .Global = True
     .Pattern = "\d{10,12}(.+)?$"
     INN_ = .Execute(cell)(0)
 End With
End Function
 
vikttur, ок, спасибо!
Приобретение понимания того, что формулой это сделать невозможно, это тоже ценное для меня знание. Доверюсь и не буду тратить тучу времени на то, чтоб сам к этому пониманию прийти.
 
Вот тут же на форуме нашел вариант формулы с извлечением из строки всей последовательности цифр, идущих одна за другой.
Может кому пригодится потом, кто через поиск темы сюда придет.

Массивная функция:
Код
=ПСТР(A2;ПОИСКПОЗ(ИСТИНА;ЕЧИСЛО(ПСТР(A2;СТРОКА(ДВССЫЛ("1:"&ДЛСТР(A2)));1)*1);0);СУММ(ЕЧИСЛО(ПСТР(A2;СТРОКА(ДВССЫЛ("1:"&ДЛСТР(A2)));1)*1)*1))


Пример во вложении.
 
Такая точно подвесит Ваши десятки тысяч строк. И работает при условии, что в тексте леее ИНН гарантированно нет цифр
 
Найдено решение, через ИИ


Sub ExtractINN_Simple()
   Dim rng As Range, cell As Range
   Dim s As String, inn As String
   Dim i As Long, j As Long
   Dim result As String, outCell As Range
   
   If TypeName(Selection) = "Range" Then
       Set rng = Selection
   Else
       Set rng = ActiveSheet.UsedRange
   End If
   
   Application.ScreenUpdating = False
   
   For Each cell In rng
       If cell.Value <> "" Then
           s = cell.Value
           result = ""
           i = 1
           Do While i <= Len(s)
               ' Проверяем, является ли символ цифрой
               If Mid(s, i, 1) Like "#" Then
                   ' Ищем 10 или 12 цифр подряд
                   For j = 10 To 12 Step 2
                       If i + j - 1 <= Len(s) Then
                           inn = Mid(s, i, j)
                           ' Проверяем, что это только цифры
                           If inn Like String(j, "#") Then
                               ' Проверяем, что перед ИНН не цифра (или начало строки)
                               Dim beforeOK As Boolean, afterOK As Boolean
                               beforeOK = (i = 1) Or (Not Mid(s, i - 1, 1) Like "#")
                               afterOK = (i + j > Len(s)) Or (Not Mid(s, i + j, 1) Like "#")
                               
                               If beforeOK And afterOK Then
                                   If result <> "" Then result = result & vbLf
                                   result = result & inn
                                   i = i + j - 1
                                   Exit For
                               End If
                           End If
                       End If
                   Next j
               End If
               i = i + 1
           Loop
           
           If result <> "" Then
               Set outCell = cell.Offset(0, 1)
               outCell.Value = result
               outCell.WrapText = True
           End If
       End If
   Next cell
   
   Application.ScreenUpdating = True
   MsgBox "Готово! ИНН извлечены."
End Sub
 
все варианты формулой вряд ли получится решить
еще вариант - формула в С2
=СЖПРОБЕЛЫ(ПСТР(A2;ПОИСК("ИНН*??????????";A2;1)+3;12))
возможно попадание символа в конце найденного номера, но это легко решаемо 2-м шагом

УПС...похожий вариант уже выложил vikttur выше, ну будем считать повторением :)
Изменено: ВовавВова - 29.05.2026 21:32:11
познакомился с Excel
 
Ещё вариант
Код
=ФИЛЬТР.XML("<t><s>"&ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(A2;"ИНН";" ");",";"");")";"");" ";"</s><s>")&"</s></t>";"//s[.*0=0][string-length()=10 or string-length()=12]")

ещё можно икать после слова ИНН
Код
=ФИЛЬТР.XML("<t><s>"&ПОДСТАВИТЬ(СЖПРОБЕЛЫ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(A2;"ИНН";" ИНН ");",";"");")";""));" ";"</s><s>")&"</s></t>";"//s[preceding::*[1]='ИНН']")
Изменено: Msi2102 - 29.05.2026 17:42:00
 
ИНН это 12 цифр для физических лиц и из 10 цифр — для юридических лиц. Третьего не дано, вроде.
Такого монстра под конец работы сочинил . Но, если в тексте будет ...инн....
=ПСТР(СЖПРОБЕЛЫ(Таблица1[@Клиент]);ПОИСК("ИНН";Таблица1[@Клиент])+4-ЕОШИБКА(ПОИСК("ИНН ";Таблица1[@Клиент]));10+2*ЕЧИСЛО(--ПСТР(Таблица1[@Клиент];ПОИСК("ИНН";Таблица1[@Клиент])+15-2*ЕОШИБКА(ПОИСК("ИНН ";Таблица1[@Клиент]));1)))
 
Здравствуйте.
Ещё вариант:
Код
=ПСТР([@Клиент];СУММПРОИЗВ(МИН(ЕСЛИОШИБКА(ПОИСК({"0";"1";"2";"3";"4";"5";"6";"7";"8";"9"};A2);9^9)));СУММ(ДЛСТР(A2)-ДЛСТР(ПОДСТАВИТЬ(A2;{"0";"1";"2";"3";"4";"5";"6";"7";"8";"9"};""))))
Но если в тексте будут ещё числа, кроме ИНН, то результат будет не верный. В файле есть ещё вариант, для исключения этой ошибки, но он длиннее и точно не знаю, от всех ли ошибок защитит.
Изменено: gling - 29.05.2026 22:47:00
 
В ИНН или 10 цифр, или 12. Попробуйте такую формулу:
ЕСЛИОШИБКА(ЛЕВСИМВ(СЖПРОБЕЛЫ(ПСТР(A2;ПОИСК("ИНН";A2)+3;1000));12)*1;ЛЕВСИМВ(СЖПРОБЕЛЫ(ПСТР(A2;ПОИСК("ИНН";A2)+3;1000));10)*1)
 
Msi2102, belsergey, теряются ведущие нули
для примера можно и так:
=СЖПРОБЕЛЫ(ЛЕВБ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(СЖПРОБЕЛЫ(ПСТР(A2;НАЙТИ("ИНН";A2)+3;13));")";" ");",";" ");" ";"  ");12))
или
=ПСТР(A2;НАЙТИ("ИНН";A2)-ЕОШ(НАЙТИ("ИНН ";A2))+4;12-2*ЕОШ(-ПСТР(A2;НАЙТИ("ИНН";A2)-ЕОШ(НАЙТИ("ИНН ";A2))+14;1)))
ну и Мгновенное заполнение справилось после коррекции двух значений. Только скопировать надо вместе буквами (ИНН 0000000000). Далее можно Текст по столбцам...
 
Цитата
ПавелW написал:
Msi2102 ,  belsergey , теряются ведущие нули
Тогда так  :)
Код
= ПОДСТАВИТЬ(ФИЛЬТР.XML("<t><s>"&ПОДСТАВИТЬ(СЖПРОБЕЛЫ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПОДСТАВИТЬ(A2;"0";"|");"ИНН";" ИНН ");",";"");")";""));" ";"</s><s>")&"</s></t>";"//s[preceding::*[1]='ИНН']");"|";"0")
Изменено: Msi2102 - 02.06.2026 09:27:49
Страницы: 1
Читают тему
Наверх