doc/IT/programming/Excel/search-str.md
2025-12-10 13:11:47 +03:00

168 lines
7.9 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### search String
#### 1 ПОДСТАВИТЬ
Нужна формула excel. Из ячейки берется строка и в ней ищет например, пятое вхождение символа х.
Далее ищет в строке шестой символ х и возвращает всю подстроку между ними (между пятом по счету и шестым найденным символом х).
Для решения этой задачи в Excel потребуется **комбинированная формула** с использованием нескольких функций. Ниже — пошаговое объяснение и итоговая формула.
### Логика решения
1. **Найти позицию 5го вхождения символа «x»**
Используем `ПОДСТАВИТЬ` + `НАЙТИ`, заменяя 5е вхождение на уникальный маркер (например, `@@@`), затем ищем позицию этого маркера.
2. **Найти позицию 6го вхождения символа «x»**
Аналогично, заменяем 6е вхождение на маркер и находим его позицию.
3. **Выделить подстроку между 5м и 6м «x»**
Используем `ПСТР`, задавая начальную позицию (после 5го «x») и длину (разница позиций 6го и 5го «x» минус 1).
---
### Итоговая формула
Пусть исходная строка находится в ячейке **A1**, а искомый символ — **«x»**.
```excel
=ПСТР(A1;
НАЙТИ("@@@"; ПОДСТАВИТЬ(A1; "x"; "@@@"; 5)) + 1;
НАЙТИ("###"; ПОДСТАВИТЬ(A1; "x"; "###"; 6)) - НАЙТИ("@@@"; ПОДСТАВИТЬ(A1; "x"; "@@@"; 5)) - 1
)
```
---
### Пояснение к формуле
1. **`ПОДСТАВИТЬ(A1; "x"; "@@@"; 5)`**
Заменяет **5е** вхождение «x» на `@@@`.
2. **`НАЙТИ("@@@"; ...)`**
Находит позицию `@@@` (т. е. позицию 5го «x»).
3. **`ПОДСТАВИТЬ(A1; "x"; "###"; 6)`**
Заменяет **6е** вхождение «x» на `###`.
4. **`НАЙТИ("###"; ...)`**
Находит позицию `###` (т. е. позицию 6го «x»).
5. **`ПСТР(A1; начало; длина)`**
- **начало** = позиция 5го «x» + 1 (чтобы не включать сам «x»);
- **длина** = позиция 6го «x» позиция 5го «x» 1 (чтобы не включать 6й «x»).
---
### Пример работы
**Входные данные (A1):**
`abcxdefxghixjklxmnoxpqr`
**Результат:**
`jkl`
*(подстрока между 5м и 6м «x»: `x**jkl**x`)*
---
### Важные замечания
- Если в строке **меньше 6 вхождений «x»**, формула вернёт ошибку `#ЗНАЧ!`.
Чтобы избежать этого, добавьте проверку:
```excel
=ЕСЛИ(ДЛСТР(ПОДСТАВИТЬ(A1;"x";""))=ДЛСТР(A1)-6;
ПСТР(A1; НАЙТИ("@@@"; ПОДСТАВИТЬ(A1;"x";"@@@";5))+1; НАЙТИ("###"; ПОДСТАВИТЬ(A1;"x";"###";6))-НАЙТИ("@@@"; ПОДСТАВИТЬ(A1;"x";"@@@";5))-1);
"Недостаточно x")
```
- Маркеры (`@@@`, `###`) должны быть **уникальными** (не встречаться в исходной строке). Если есть риск, замените их на другие комбинации (например, `___5___`, `___6___`).
- Формула работает для **одного символа** («x»). Для подстроки логика усложняется.
### 2 Без ПОДСТАВИТЬ
Можно обойтись **без функции `ПОДСТАВИТЬ`** — через последовательное нахождение позиций вхождений с помощью `НАЙТИ` с заданным стартовым смещением.
## Принцип работы
Идея: каждый следующий вызов `НАЙТИ` стартует **после позиции предыдущего найденного символа**.
1. Находим 1е вхождение «x».
2. Находим 2е — начиная с позиции (1е +1).
3. Повторяем до 5го и 6го вхождений.
4. Выделяем подстроку между 5м и 6м «x».
## Итоговая формула (для ячейки A1, символ «x»)
```excel
=ПСТР(
A1;
НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1) + 1) + 1) + 1) + 1) + 1;
НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1) + 1) + 1) + 1) + 1) + 1) -
НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1; НАЙТИ("x"; A1) + 1) + 1) + 1) + 1) - 1
)
```
## Пояснение
- **Нахождение 5го «x»**:
Вложенные вызовы `НАЙТИ` с нарастающим смещением:
```excel
НАЙТИ("x"; A1; [позиция_4го] + 1)
```
Где `[позиция_4го]` — результат аналогичного вложенного поиска.
- **Нахождение 6го «x»**:
Аналогично, но на один уровень глубже.
- **Извлечение подстроки**:
- **Начало**: позиция 5го «x» +1 (чтобы не включать сам «x»).
- **Длина**: позиция 6го «x» позиция 5го «x» 1 (чтобы не включать 6й «x»).
## Пример
**Входные данные (A1)**:
`abcxdefxghixjklxmnoxpqr`
**Результат**:
`jkl`
*(подстрока между 5м и 6м «x»: `x**jkl**x`)*
## Важные замечания
1. **Ограничения длины формулы**
В Excel есть лимит на глубину вложенности функций. Для поиска 56го вхождения формула работает, но для бóльших номеров может превысить лимит.
2. **Обработка ошибок**
Если в строке меньше 6 вхождений «x», формула вернёт `#ЗНАЧ!`. Добавьте проверку:
```excel
=ЕСЛИ(ДЛСТР(A1)-ДЛСТР(ПОДСТАВИТЬ(A1;"x";""))>=6;
[основная_формула];
"Недостаточно x"
)
```
*Проверка: число «x» в строке ≥6.*
3. **Читаемость**
Формула громоздкая и трудно редактируется. Для сложных случаев лучше использовать:
- **Power Query** (визуальный редактор);
- **VBA** (пользовательская функция);
- **Office Scripts** (для веб‑версии).
## Альтернатива: пользовательская функция (VBA)
Если допустима VBA, создайте функцию `GetSubstringBetweenX`:
```vba
Function GetSubstringBetweenX(text As String, n1 As Integer, n2 As Integer, delimiter As String) As String
Dim parts() As String
parts = Split(text, delimiter)
If UBound(parts) >= n2 Then
GetSubstringBetweenX = parts(n1)
Else
GetSubstringBetweenX = "Недостаточно разделителей"
End If
End Function
```
**Использование в Excel**:
```excel
=GetSubstringBetweenX(A1; 5; 6; "x")
```