четвъртък, 2 ноември 2023 г.

#68 (1/2) Как се цепи текст ... с функции (или как съм икономисвал шоколад)

    Пишейки #67 се замислих за по-полезни приложения на Let. И се сетих за задачката, за чието решение съм обещавал шоколад на студентите. Казвам "обещавал", защото май никога някой е давал решение. В крайна сметка шоколада го получаваше някоя симпатична студентка, но вече отиваме в много неполиткоректна тематика:)

    Условие: Да се извлече само презимето от три имена на човек. За целта да се използват само функции и да не се използват междинни клетки!

    Както разбирате от условието съм бил голяма скръндза и ми се е свидил шоколад:) Но в крайна сметка идеята е студентите да си мръднат мозъците. Разбира се, задачата не е изключително сложна и когато се покаже решението всеки казва "Ахаа. Елементарно е!". 

    1. Класическо решение. Това е универсално решение, което работи на всички версии на Excel. Това и е "шоколаденото" решение, което съм искал. След малко ще видим, че има и други решения, базирани на по-новите функции в новите версии на Excel.

Ето самото решение:

=MID(B2;FIND(" "; B2)+1;FIND(" "; B2; FIND(" "; B2)+1)-FIND(" "; B2)-1)

    Ето първо на картинка за какво иде реч:

Извличане на презиме

     За извличане на презимето ни трябват неговите "ограничители". Позициите на двата интервала.

- позицията на първия интервал се намира лесно с функцията Find (или Search) - > FIND(" "; B2)

- позицията на втория интервал изисква да се знае позицията на първия интервал и търси СЛЕД него -> FIND(" "; B2; FIND(" "; B2)+1)

За извличане на презимето ще използваме функцията Mid. Трябва ни начална позиция и дължина на текста.

- началната позиция е позицията на първия интервал + 1 (следващия след интервала символ)
- дължината е позицията на втория минус позицията на първия - 1 (разгледайте добре фигурата защо е така!).

    2. Класическо решение с Let. Решението в точка 1 изисква много внимание, защото е дълго, с много скоби, и това го прави трудно за сглобяване и анализ. Всъщност, това решение го използвам за илюстрация за необходимостта от помощни клетки (колонки), които наричам "помощни колелца за учене на каране на велосипед". Или в сегашния случай от необходимостта от Let! Новият вариант на формулата изглежда така:

=LET(f; FIND(" "; B2); s; FIND(" "; B2; f+1); MID(B2; f+1; s-f-1))

    Дефинирани са две променливи (f и s (ако искате формулата да стане по-разбираема, може да кръстите променливите с по-описателни имена, например first и second), съдържащи позициите на двата интервала. Обърнете внимание, че за дефиницията на s е използвана стойността на f, което намалява възможните грешки! В описанието на една променлива може да участват стойностите на вече дефинирани променливи!

    Както се вижда, това решение е много по структурирано и разбираемо. Не трябва да се забравя факта, че Let се появи чак в Office 2021!! Следващите решения са още по-лесни, но и изискват Office 365!


3. Решение с TextBefore и TextAfter. В Office 365 се появиха множество нови функции за работа с текст. Функциите TextBefore и TextAfter позволяват да се върне част от текста спрямо определен разделител. Извличането на презимето с помощта на тези функции става по следния начин:

 =TEXTBEFORE(TEXTAFTER(B2;" ");" ")

    Чрез функцията TextAfter се извличат презимето и фамилията (текстът след първия интервал), а чрез TextBefore извличаме презимето (текстът преди интервала в презимето и фамилията)!

    Забележка: Ако имаме за задача да извлечем фамилията, това може да стане само чрез еднократно извикване TextAfter:

=TEXTAFTER(B2;" ";2) или =TEXTAFTER(B2;" "; -1)  

Извличаме текста след втория интервал. С отрицателен знак се броят отдясно наляво! Т.е. -1 е последния интервал!

4. Решение с TextSplit. Функцията TextSplit (също нова в Office365!) служи за разделяне на даден текст спрямо разделител или списък от разделители. Резултатът от функцията са ВСИЧКИ елементи на текста. Това, означава, че функцията "протича" извън клетката (ще имаме отделна тема за "протичането"). Ако искаме само част от резултатите (в нашия случай  само презимето) функцията се "пакетира" с Index, ChooseCols, ChooseRows за филтриране на необходимите резултати. 

За извличане на презимето се използва:

=INDEX(TEXTSPLIT(B2;" "); 2)

=CHOOSECOLS(TEXTSPLIT(B2;" ");2)

Забележка: Както се вижда от примерите, функциите Index и ChooseCols/Rows използват "нормално" броене от единица! В нашия случай ни трябва втория елемент на резултата! 

Еми това е! 

П.П. Сега ще трябва да измислям друга задача за да (не) давам шоколад! :)