Страницы: 1 2 След.
RSS
Извлечение слов из текста следующего(их) предыдущего(их) по заданому списку или условию, извлечение 1-2 слов относительно искомого из списка или по условию что слово содержит символ
 
Здраствуйте!
Возможно есть решение под таку задачку извлечения слов относительно искомых - 1-2 слова до или 1-2 после.

Пример - слова после искомого
А2 - "Текст Иванов Иван Иванович текст" (здесь ищем),       B2 - "Иванов" (искомое слово),     С2 - здесь нужно вывести результат - два слова, расположениые после текста что содержится в ячейке A2 всключая искомое, т.е. результатом должно быть "Иванов Иван Иванович"
А3 - "Текст Петров Петр Петрович текст" (здесь ищем),       B3 - "Петров" (искомое слово),     С3 - здесь нужно вывести результат - два слова, расположенные после текста что содержится в ячейке B3 всключая искомое, т.е. результатом должно быть "Петров Петр Петрович"

Пример - слова до искомого
А2 - "Текст Иванов Иван Иванович текст" (здесь ищем),       B2 - "Иванович" (искомое слово),     С2 - здесь нужно вывести результат - два слова, расположенные до текста что содержится в ячейке A2 всключая искомое, т.е. результатом должно быть "Иванов Иван Иванович"
А3 - "Текст Петров Петр Петрович текст" (здесь ищем) всключая искомое,       B3 - "Петрович" (искомое слово),     С3 - здесь нужно вывести результат - два слова, расположениые до текста что содержится в ячейке B3, т.е. результатом должно быть "Петров Петр Петрович"

Или извлечение 1-2 слов относительно искомого при условии что искомое слово содержит символ
Пример - слова если искомое содержит символ - два слова до А2 - "Текст #Иванов Иван Иванович текст" (здесь ищем),       B2 - "#" (искомый символ который содержит интересуещее нас слово),     С2 - здесь нужно вывести результат - два слова из А2, расположениые после слова что содержит искомый символ из ячейки B2 включая само слово с искомым символом, т.е. результатом должно быть "#Иванов Иван Иванович"

И второй вариант - пример cо словом "#Иванович" - здесь вывод 2-х предыдущих слов включая слово с искомым символом, результат - "Иванов Иван #Иванович"

Excel 2021
Изменено: APech5 - 12.05.2026 08:42:36 (исправил пример)
 
Очень много слов
Приложите лучше фай-пример (Excel). Как есть - Как надо
И версию Excel укажите
Согласие есть продукт при полном непротивлении сторон
 
Excel 2021, приложил пример
 
Для всех Ваших вариантов достаточно одной формулы
Код
=ОБЪЕДИНИТЬ(" ";1;ФИЛЬТР.XML("<l><i>"&ПОДСТАВИТЬ(A2;" ";"</i><i>")&"</i></l>";"//i[position() > 1 and position() < last()]"))
Согласие есть продукт при полном непротивлении сторон
 
1; 3
=СЖПРОБЕЛЫ(ЛЕВБ(ПОДСТАВИТЬ(ПСТР(A2;ПОИСК(B2;A2);99);" ";ПОВТОР(" ";99);3);99))
2; 4
=СЖПРОБЕЛЫ(ПРАВБ(ПОДСТАВИТЬ(ЛЕВБ(A8;ПОИСК(B8;A8)+ДЛСТР(B8)-1);" ";ПОВТОР(" ";99));297))
 
Sanja, спасибо!
К сожалению немножко не так, под "текст" в ячейке А2 подразумевается много слов, пробелы и т.д.
Поэтому результат получается не совсем тот что нужно.
 
Цитата
написал:
1; 3=СЖПРОБЕЛЫ(ЛЕВБ(ПОДСТАВИТЬ(ПСТР(A2;ПОИСК(B2;A2);99);" ";ПОВТОР(" ";99);3);99))2; 4=СЖПРОБЕЛЫ(ПРАВБ(ПОДСТАВИТЬ(ЛЕВБ(A8;ПОИСК(B8;A8)+ДЛСТР(B8)-1);" ";ПОВТОР(" ";99));297))
ПавелW, спасибо большое! Работает!

В варианте с поиском(выбором) по символу "#" что содержится в слове  - если в ячейке со значеним поиска есть только "#" - тогда результат будет "Имя Фамилия #", и только тогда результат будет "Имя Фамилия #Отчество", когда в ячейке будет "#Отчество".
Можно ли реализовать чтобы и первом варианте был результат "Имя Фамилия #Отчество"?

Извините исправил пример.
Изменено: APech5 - 11.05.2026 12:47:19 (исправил пример)
 
4:
=СЖПРОБЕЛЫ(ПРАВБ(ПОДСТАВИТЬ(ЛЕВБ(A19;ПОИСК(" ";A19&" ";ПОИСК(B19;A19))-1);" ";ПОВТОР(" ";99));297))
...вариант с одиноким символом (перед отчеством)
 
ПавелW
Цитата
написал:
...вариант с одиноким символом (перед отчеством)
Да то что нужно.
Я решил по аналогии сделать для варианта с одиноким символом "#"  перед Фамилией из ячейки поиска(выбора) для результата #Фамилия Имя Отчество и... никак не получается
Данной формулой можно такое сделать? нужен и такой рабочий вариант(для приведения данных в порядок)
Изменено: APech5 - 11.05.2026 13:59:01
 
APech5, у вас он есть )  #5  (1; 3)
в данном случае не важно ищете вы "Фамилия" или "#Фамилия" или "#", если известно что "#" перед "Фамилия" (и слитно)
 
Цитата
написал:
у вас он есть )
Да, точно, 3-вариант идентичный 1 выводит результат.

Проверил в различных вариантах - идеально работает вариант 4, другие к сожалению с заковырками текста не совсем справляются
В первых 2-х вариантах - поиск производится не по слову отдельно(с пробелами в начале и конце слова), потому результат получается не совсем тот что нужно.

3-вариант возвращает не целое слово что содержит символ "#", а выдает слово начиная с символа "#", нужно целиком.

В примере более наглядно видно.

Зделать таким образом желаемый результат для вариантов 1-3 можно?
Изменено: APech5 - 11.05.2026 15:59:27
 
ПавелW, Sanja, форумчане, приведенными выше Вашими формулами можно добится такого результата как в примере или нужен макрос?
удивительно - не нашел такой функции в популярных надстройках, наверное было бы для многих полезно для анализа, исправления ошибок, и приведения текста в порядок  
 
Цитата
В первых 2-х вариантах - поиск производится не по слову отдельно(с пробелами в начале и конце слова),
APech5, ну так заверните искомое слово в пробелы, а если это слово может быть в начале либо в конце текста - то и исходный текст
Цитата
3-вариант возвращает не целое слово что содержит символ "#", а выдает слово начиная с символа "#", нужно целиком.
можно?
можно, причем разными способами, но...
правила беспощадны  2.6. )
 

Здравствуйте. Может макрос вам подойдет, если правильно понял как надо. Выделяем 2 ячейки в левой исходный текст в правой искомый текст и запускаем макрос. Результат будет в 2 ячейках справа от выделенных.

Код
Sub enstaral2()
Dim arr1, arr2, i%, stInd%, endInd%, findInd%
Const Prob As String = " "
arr1 = Selection
arr1(1, 2) = VBA.Trim(arr1(1, 2))
arr2 = VBA.Split(arr1(1, 1), Prob)
For i = LBound(arr2) To UBound(arr2)
If StrComp(arr2(i), arr1(1, 2), vbTextCompare) = 0 Then findInd = i: Exit For
Next
ReDim arr1(1 To 2)
stInd = VBA.IIf(findInd - 2 >= LBound(arr2), findInd - 2, LBound(arr2))
endInd = VBA.IIf(findInd - 2 >= UBound(arr2), findInd - 2, UBound(arr2))
For i = stInd To findInd: arr1(1) = arr1(1) & arr2(i) & Prob: Next
arr1(1) = VBA.Trim(arr1(1))
For i = findInd To endInd: arr1(2) = arr1(2) & arr2(i) & Prob: Next
arr1(2) = VBA.Trim(arr1(2))
Selection.Offset(0, 2) = arr1
End Sub

Изменено: Евгений Смирнов - 12.05.2026 17:37:06
 
UDF
Код
Function ПОЛУЧИТЬ_ФИО(текст$, искомый_текст$, направление&)
'направление: 2(два слова вперед) или -2(два слова назад)
Dim arr
Dim iKey
Dim I&, N&, a&, b&
arr = Split(Application.Trim(текст), " ")
For Each iKey In arr
  If iKey = искомый_текст Then
    a = IIf(направление < 0, N + направление, N)
    b = IIf(направление < 0, N, N + направление)
    For I = a To b
      ПОЛУЧИТЬ_ФИО = ПОЛУЧИТЬ_ФИО & " " & arr(I)
    Next
  End If
  N = N + 1
Next
End Function
Изменено: Sanja - 12.05.2026 18:54:00
Согласие есть продукт при полном непротивлении сторон
 
Еще один вариант. Наверно вывод будет отличаться от первого варианта
Код
Sub ExtractText_InStr_Mid()
Dim txtLower As String, searchLower As String, matchPos%
Dim arr1, ArrChr, ch, I%, pos%
Dim stPos1%, endPos1%, stPos2%, endPos2%
Const Prob As String = " ", kProb As Integer = 2
arr1 = Selection
    
    ArrChr = Array(vbTab, Chr(160))
For Each ch In ArrChr: arr1(1, 1) = Replace(arr1(1, 1), ch, Prob): Next ch
arr1(1, 1) = Application.WorksheetFunction.Trim(arr1(1, 1))
    
txtLower = LCase(arr1(1, 1)): searchLower = LCase(arr1(1, 2))
matchPos = InStr(1, txtLower, searchLower, vbBinaryCompare)
If matchPos = 0 Then MsgBox "Слово не найдено.", vbInformation: Exit Sub

endPos1 = VBA.InStr(matchPos, arr1(1, 1), Prob) - 1
pos = endPos1 + 2
For I = 1 To kProb
        pos = InStr(pos + 1, arr1(1, 1), Prob)
        If pos = 0 Then Exit For
Next I
If pos = 0 Then endPos2 = Len(arr1(1, 1)) Else endPos2 = pos - 1

stPos2 = VBA.InStrRev(arr1(1, 1), Prob, matchPos) + 1
pos = stPos2 - 2
For I = 1 To kProb
        pos = VBA.InStrRev(arr1(1, 1), Prob, pos - 1)
        If pos = 0 Then Exit For
Next I
If pos = 0 Then stPos1 = 1 Else stPos1 = pos + 1
ReDim ArrChr(1)
ArrChr(0) = VBA.Mid(arr1(1, 1), stPos1, endPos1 - stPos1 + 1)
ArrChr(1) = VBA.Mid(arr1(1, 1), stPos2, endPos2 - stPos2 + 1)
Selection.Offset(0, 2) = ArrChr
End Sub
 
Цитата
написал:
Еще один вариант. Наверно вывод будет отличаться от первого варианта
Евгений Смирнов, спасибо! Отлично делает вывод результата +-2 слова если слово содержит указанный искомый символ, но работает если выделять только две соседние ячейки, при выборе диапазона - работает некорректно - возвращает первые полученные результаты для всех.
Для пары сотен или тисячи ячеек не совсем вариант. Можно сделать для диапазонов?  
Изменено: APech5 - 13.05.2026 12:26:01
 
Цитата
написал:
UDF
Sanja, очень удобно изменять количество слов для вывода относительно искомого, спасибо! Суперски подходит для поиска по слову целиком(слово в искомом тексте должно быть отделено пробелами), а с поиском по 1 символу, который содержит слово искомом тексте естественно не справляется. Можете сделать вариант для поиска по 1 символу, который содержит слово искомом тексте с таким удобным выводом результатов? Так же функция чуствительна к регистру, проверил на практике - лучше без привязки к регистру.
Изменено: APech5 - 13.05.2026 16:10:37
 
Код
Option Explicit

Sub ExtractText_InStr_Mid_Areas()
    Dim rr As Range
    Set rr = Intersect(Selection, ActiveSheet.UsedRange)
    Set rr = Intersect(rr.Columns(1).EntireColumn, rr)
    
    Dim Application_Calculation As XlCalculation: Application_Calculation = Application.Calculation: Application.Calculation = xlCalculationManual
    
    Dim cl As Range
    For Each cl In rr.Cells
        cl.Resize(1, 2).Select
        ExtractText_InStr_Mid
    Next
    rr.Select
    Application.Calculation = Application_Calculation
End Sub

Sub ExtractText_InStr_Mid()
Dim txtLower As String, searchLower As String, matchPos%
Dim arr1, ArrChr, ch, I%, pos%
Dim stPos1%, endPos1%, stPos2%, endPos2%
Const Prob As String = " ", kProb As Integer = 2
arr1 = Selection
    
    ArrChr = Array(vbTab, Chr(160))
For Each ch In ArrChr: arr1(1, 1) = Replace(arr1(1, 1), ch, Prob): Next ch
arr1(1, 1) = Application.WorksheetFunction.Trim(arr1(1, 1))
    
txtLower = LCase(arr1(1, 1)): searchLower = LCase(arr1(1, 2))
matchPos = InStr(1, txtLower, searchLower, vbBinaryCompare)
If matchPos = 0 Then MsgBox "Слово не найдено.", vbInformation: Exit Sub

endPos1 = VBA.InStr(matchPos, arr1(1, 1), Prob) - 1
pos = endPos1 + 2
For I = 1 To kProb
        pos = InStr(pos + 1, arr1(1, 1), Prob)
        If pos = 0 Then Exit For
Next I
If pos = 0 Then endPos2 = Len(arr1(1, 1)) Else endPos2 = pos - 1

stPos2 = VBA.InStrRev(arr1(1, 1), Prob, matchPos) + 1
pos = stPos2 - 2
For I = 1 To kProb
        pos = VBA.InStrRev(arr1(1, 1), Prob, pos - 1)
        If pos = 0 Then Exit For
Next I
If pos = 0 Then stPos1 = 1 Else stPos1 = pos + 1
ReDim ArrChr(1)
ArrChr(0) = VBA.Mid(arr1(1, 1), stPos1, endPos1 - stPos1 + 1)
ArrChr(1) = VBA.Mid(arr1(1, 1), stPos2, endPos2 - stPos2 + 1)
Selection.Offset(0, 2) = ArrChr
End Sub

 

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

 
Пара вариантов формулой с заданием параметров в соседних ячейках:
=СЖПРОБЕЛЫ(ПСТР(ПОДСТАВИТЬ(A2;" ";ПОВТОР(" ";999));ПОИСК(B2;ПОДСТАВИТЬ(A2;" ";ПОВТОР(" ";999)))-999*(1-C2*(C2<0));999*(ABS(C2)+2)))
скрин
количество возвращаемых слов можно изменять (положительные - вправо, отрицательные - влево)

пс: но ТС вероятно нужна кнопка и желательно на ленте ))
 
МатросНаЗебре, спасибо! Теперь и для areas)

Евгений Смирнов, МатросНаЗебре - подскажите пожалуйста где в коде менять значения для вывода к примеру 5 значений до/после.
может выделить цветом или просто код для 5 значений
Изменено: APech5 - 13.05.2026 13:00:26
 
Цитата
написал:
Пара вариантов формулой с заданием параметров в соседних ячейках
ПавелW, спс очень удобный вариант!

пс. разобрался и без кнопки)
 
Цитата
написал:
где в коде менять значения для вывода к примеру 5 значений до/после.
Это в рамках одной ячейки? Или 5 ячеек до?
Покажите пример.
 
Цитата
написал:
Покажите пример.
в рамках одной ячейки, в макросе с поддержкой масивов вывод сделан +/- 2 слова относительно искомого, я спросил где/что менять в том макросе для вывода +/- к примеру 5 слов относительно искомого(включая ис)
 
APech5 Я не пробовал но должно получиться замените константу kProb на 5 сейчас там 2. должно получиться на 5 слов  
 

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

Код
Function ПОЛУЧИТЬ_ФИО(текст$, искомый_текст$, направление&)
'направление: 2(два слова вперед) или -2(два слова назад)
Dim arr
Dim iKey
Dim I&, N&, a&, b&
arr = Split(Application.Trim(текст), " ")
For Each iKey In arr
    If VBA.InStr(1, iKey, искомый_текст) Then
    a = IIf(направление < 0, N + направление, N):  If a < 0 Then a = 0
    b = IIf(направление < 0, N, N + направление):  If b > UBound(arr) Then b = UBound(arr)
    For I = a To b
      ПОЛУЧИТЬ_ФИО = ПОЛУЧИТЬ_ФИО & " " & arr(I)
    Next
    Exit For
  End If
  N = N + 1
Next
End Function
 
Цитата
написал:
немного изменил ваш код
Евгений Смирнов, ищет и по символу, очень наглядно удобно, спасибо!
правда чуствительна к регистру, если фамилия к примеру начинается не з заглавной - возвращает 0 в рузельтат.
Изменено: APech5 - 13.05.2026 17:12:04
 
APech5 наидите строку и допишите 1 вот так и будет нечувствительна к регистру
Код
If VBA.InStr(1, iKey, искомый_текст, 1) Then
 
Цитата
написал:
допишите 1
Евгений Смирнов удивительно, всего один символ(1) в нужном месте и инструмент полностью готов!
Спасибо! работает как часы
Страницы: 1 2 След.
Читают тему
Наверх