Показват се публикациите с етикет Mid. Показване на всички публикации
Показват се публикациите с етикет Mid. Показване на всички публикации

вторник, 19 май 2015 г.

#60 Интервали и интервал без разделяне

Една бърза тема за тези, които използват Copy/Paste от уеб страници. Попаднаха ми данни имащи следния вид:


Данни      




На пръв поглед фасулска работа. Самия Excel показва, че данните в първата клетка са числа, но оформени като текст (зеленото триъгълниче в ляво на клетката). Това позволява тези данни да се преобразуват в числа без проблем.

Преобразуване на данни   
 
 В долната клетка нещата изглеждат подозрително. Използвах функции и "трикове" за преобразуване на текст в число. Неуспешно за клетката A3!:( Вижда се, че Excel позволява използването на стойността в математически израз (колонка F), въпреки че не е число (проверката в колонка B)!

Преобразуване на текст в число
За това се заех по-обстойно с втората клетка. Реших да проверя кой е третия символ в клетката. Стори ми се подозрителен:) Това извърших чрез функцията:
 =CODE(MID(A3;3;1)), която върна отговор 160! "Нормалния" интервал има код 32.
Къде е проблема?! Кодът 160 е на символа "non-breakable space". Това е интервал, който се разглежда като символ и се разглежда като част от думата (например 100 км/ч.). В HTML това е символа &nbsp,  а в MS Word се въвежда чрез Ctrl+Shift+Space. Явно в текста който е копиран в Excel е използван този символ. Оказва се, че в много от сайтовете използват този символ за подредба на данните.

Решения:

1. Чрез търсене и замяна

Търсене и замяна
Забележка: Задържа се клавиша Alt и се набира от ЦИФРОВАТА клавиатура (не от основния блок) 0160.

2. Чрез функция

=VALUE(SUBSTITUTE(A3;CHAR(160);""))

Забележка: Между кавичките няма нищо!

Ми това е:)
Успех и умната с интервалите (и с Copy/Paste):):)

петък, 23 март 2012 г.

#049 "Умна" страница календар

Скоро помагах по правенето на едни отчетни таблици. В тези таблици има аналогични листи за всеки месец. Замислих се, че до сега съм правил висш пилотаж с бутони за размножаване на страниците и донастройка на таблицата с код. Реших да не ползвам код и направя "умен" работен  лист който сам да се настройва!  Ето резултата: Споделени таблици (таблицата се казва Calendar-Sheet.xls). Старал съм се да е работоспособен и за старите версии на Excel преди Excel 2007!


Лист с календар


Листа показва името на месеца,  датите, названието на дните и номера на седмицата. Наричам този лист "умен", защото ако го копирате с име "2" ще се получи календар за месец Февруари, ако е с  име "3" календар за месец Март и т,.н. Т.е. спокойно вие може да добавите вашите данните, формули и после само да копирате този лист за останалите месеци!
NB! - Най-лесно можете да копирате  работен лист като влачите неговото име със задържан клавиш CTRL. Не забравяйте след като го копирате да смените неговото име с новия месец!

Имена на листите
 Цялата магия се състои в използване името на листа! Ето малка дисекция на формулите намиращи се в този лист.

Формула в клетка АI1 (внимавайте да не я изтриете по погрешка!). Може да я скриете. Там се взема името на листа и се преобразува в число. 
=VALUE(MID(CELL("filename";AH1);FIND("]";CELL("filename";AH1))+1;255))

  • CELL("filename";AH1) - Функцията Cell е много екзотична. В случая се използва нейния параметър "filename". Като втори параметър се посочва произволна клетка от таблицата (важно е да не съдържа съобщение за грешка!). Тук "далаверата" че освен името на файла ( заедно с пътя до него!) функцията връща и име на работния лист! (например: "F:\Documenti\[calendar-sheet.xls]1")
  • FIND("]";CELL()) - Намираме знака "]" който означава край на името
  • MID(CELL();FIND))+1;255)) - Извличаме от намерената позиция +1 (т.е. от следващия знак) всичко останало. Избрал съм мързеливия подход написвайки голямо число за брой знаци:) Може и по прецизно да се вземе точния брой знаци, но при положение, че не дава грешка защо да не се възползваме от тази възможност:) Така получаваме името на листа. Този трик може да използвате ако в други случаи ви трябва името на листа!
  • =Value(Mid()) - Преобразуваме текста в числова стойност! Разбира се ако вашите таблици имат имена съдържащи нецифрови символи тази стъпка не се прави!

 Формула в клетка C4: "Конструираме" първата дата в месеца.

=DATE(YEAR(NOW());$AI$1;1)

Формула в клетка D4 (и всички останали дати): Тъй като месеците имат различен брой дни се прави проверка дали получената нова дата (+1 на предходния ден) е все още в същия месец!
=IF(ISNUMBER(C4);IF(MONTH(C4+1)=$AI$1;C4+1;"");"") 

Формула в клетка C5: Име на деня от седмицата. Винаги го връща на български независимо от регионалните настройки! За повече информация вижте темата #013 в блога!=TEXT(C4;"[$-402]dddd") 

Формула в клетка C1: Показва името на месеца и годината.=UPPER(TEXT(C4;"[$-402]MMMM")) & " " & YEAR(C4)


Копирайте листа колкото пъти ви трябва, променете неговото име и ползвайте със здраве:)

Успех
















четвъртък, 16 септември 2010 г.

#033 R1C1 адреси и преобразуване на имена на колони в номера и обратно...

За по-лесното боравене с адреси по подразбиране Excel борави с така наречената A1 нотация... Т.е. "име на колоната и номер на реда". Съществува и втори вид наречен R1C1... При не го се посочва номер на реда(първо е ред!) и НОМЕР на колоната. Преди числата се постановя R и C. Например R1C1 е клетката $A$1 (първа колона първи ред). R3C2 е $B$3 (ВТОРА колона и ТРЕТИ ред!). Обърнете внимание и на още една особеност. Не случайно дадох отговорите като абсолютни адреси ($A$1 и $B$3)!  Задаването на относителни адреси е по-особено. Например ако адресът е R[-1]C означава "клетката с адрес един ред нагоре спрямо текущата клетка и същата колона"! Например ако сме в клетка G5 става въпрос за клетката G4! Адресът R[+1]C[-1] ако сме B3 е еквивалентен на A4 (ред надолу и колона на ляво)... И т.н... За повече информация  прочетете тук:
http://office.microsoft.com/bg-bg/excel-help/HP005198323.aspx където има информация и как да си включите/изключите този режим на показване на работните листи (не че има някакъв смисъл де):) Използването на R1C1 адреси е доста често използван в макросите за това и "подгрявам" публиката с тази тема:)

Вчера ми се наложи да правя преобразуване на номер на колона в име и преобразуване на име на колона в номер... Покрай тези примери ще разгледам и  две "екзотични" функции:)

Пример 1. Да се преобразува име на колона в число... Името се намира клетка A1 (например XZ).
=COLUMN(INDIRECT(A1&":"&A1)) Тук няма никаква магия. Създава се валиден адрес и се взема неговата колона. Адресът се получава като се долепят името на колоната сама до себе си (получава се  "XZ:XZ"), чрез Indirect се преобразува в зона и чрез Column се преобразува в число. Със същия успех може да се "сглоби" адрес като се долепи към името на колонката някакво число за номер на ред. Например A1&1 което е и по-кратко!
=COLUMN(INDIRECT(A1&1))

Пример 2. Да се преобразува номер на колона в нейно име... Номера се намира в клетка А1 (например 156).
=MID(ADDRESS(1,A1),2,FIND("$",ADDRESS(1,A1),2)-2)
Тук "магията" е във функцията ADDRESS. Пълното описание на български може да намерите тук: http://office.microsoft.com/bg-bg/excel-help/HP010062407.aspx

ADDRESS(1,A1) За разлика от Indirect, която преобразува текст в зона, функцията Addrеss преобразува числа (ред и колона) в адрес. В нашия случай получавам адресът на клетка с ред едно (използваното число няма значение) и НОМЕРА на колоната посочен в клетка A1. Например за числото 156 функцията ще върне $EZ$1
(по подразбиране връща абсолютен адрес) след което извличаме с Mid знаците от втория (първия е $!) до следващия (обърнете внимание на Find) намерен знак $ (ако имате проблеми с Mid/Find комбинирането пишете да за да спретна някоя темичка):)

Пример 3. Да се намери адресът на средната клетка в листа. Да не се влияе от версията на Excel (2003 и 2007 имат различен брой редове и колони!)

=ADDRESS(SUMPRODUCT(MAX(ROW(A:A))) /2, SUMPRODUCT(MAX(COLUMN(1:1))) / 2) или CSE {=ADDRESS(MAX(ROW(A:A)) / 2, MAX(COLUMN(1:1)) / 2)}
"Пакетират" се функциите Max със Sumproduct за да се намери най-големия ред (колона) на дадена зона... Ако премахнем Sumproduct трябва да въведем формулата като CSE! Номерата и колоните се делят на две (търсим средата) и се дават като параметри на Address....

----
Забележка под линия:):) Има различни варианти за правенето на нещо... Често и аз бъркам и не винаги ви давам най-добрия вариант забравяйки някоя функция на Excel:):) Когато за първи път правих примерът със средата бях изключил за Address... И го направих по много екзотичен начин:)
=CELL("address",INDIRECT("R" & SUMPRODUCT(MAX(ROW(A:A))) / 2 & "C" & SUMPRODUCT(MAX(COLUMN(1:1))) / 2,FALSE))
Използвах два "трика". Първия трик е възможността Indirect да работи с R1C1 зони (обърнете  внимание на параметърът False. (просто "слепвам" числа и буквите R и C!). Зоната получена от Indirect я давам като параметър на функцията Cell за да превърне зона в адрес. Функцията Cell е много екзотична и много рядко се използва:) http://office.microsoft.com/bg-bg/excel-help/HP010062392.aspx . Както споменах посоченото решение е много тромаво и объркано и ме е леееко срам от него, но нали в крайна сметка работи:):):)
Но както казват хората ... Many (not All) Roads Lead to Rome  :):)

Бързата кучка слепи ги ражда:) Вместо да се правя на умен вместо MAX(ROW(A:A) просто може да се напише Rows(A:A) и съответно Columns(1:1)...


четвъртък, 19 август 2010 г.

#017 Търсене и броене със Substitute

Функцията Substitute има за цел да подменя един текст с друг... Синтаксисът  и е =Substitute( текст в който се подменя, стария текст, новия текст, [коя появя на текстът да се подмени, ако се пропусне се подменят всички намерени текстове] )

Ето два примера:
  • =SUBSTITUTE("0000001","0","*")  резултат: ******1
  • =SUBSTITUTE("003592300838","00","+",1) Резултат: +3592300838 (замества със знака "+" само първите намерени две нули! (този пример е само за илюстрация и ако работите с мобилни номера ще се наложи по-сложни трикове!)
Функцията обаче се използва и в по-сложни формули по малко по-специален (и често труден за разбиране) начин.

Да се преброи колко пъти даден текст (или знак) го има в друг текст. Ето израза:
=Len(текстът в който търсим)-Len(Substitute(текстът в които търсим, текстът (знакът) който искаме да преброим, "") )
Трикът е, че се премахва търсения текст (подменя се с "") и се намира разликата между дължините на оригиналния и променения текст.

Пример 1: Да се преброят тиретата в даден текст.
Отговор: =LEN("123-345-678-987")-LEN(SUBSTITUTE("123-345-678-987","-",""))

Пример 2: Да се преброят интервалите в дадена клетка
Отговор: =LEN(A7)-LEN(SUBSTITUTE(A7," ","")) (Между първите кавички има интервал, а между вторите няма!)

Второ приложение е да се намери позицията на N-тото появяване на даден текст/знак.
=Find(char(7),Substitute(текст в който търсим, текст който търсим, Char(7), появяването което търсим)

Тук се прилага следния трик. Подменя се този текст/символ с нещо което знаем че го няма в текстът. Например  с Char(7) (камбанка):) Припомням за последния параметър на Substitute който позволява избирателна промяна. След което се намира позицията на този символ със Find.


Ето примери:
Пример 3: Да се намери позицията на ВТОРОТО тире в текст:
Отговор: =FIND(CHAR(7),SUBSTITUTE("123-345-678-987","-",CHAR(7),2))

Пример 4: Да се намери позицията на ТРЕТИЯ интервал в дадена клетка
Отговор: =FIND(CHAR(7),SUBSTITUTE(A7," ",CHAR(7),3))


И като десерт два сложни примера за тези които искат да си размърдат мозъците:)))

Пример 5: Да се намери броят на цифрите в дадена клетка. Не се броят точки и други символи. Само цифрите от нула до девет!
Отговор: =SUMPRODUCT(LEN(A8)-LEN(SUBSTITUTE(A8,ROW(INDIRECT("1:10"))-1,"")))
Тук се прави вътрешен цикъл за да се използва трикът с броенето. Единия вариант е в да се сложи масив {0,1,2,3...9} . Другия вариант е с Row (беше дискутиран вече в по-стари теми). Поради фактът че нулев ред няма (т.е. Row(0) ще даде грешка!) се брои от едно до десет и се вади единица и по този начин се получава броене от нула до девет! Задал съм в червено този "цикъл".


Пример 6. Да се извлече ПОСЛЕДНАТА дума от клетка. Думите са разделени с интервал. Не знаем колко думи има! Думите са повече от една (ако не сме сигурни, трябва да се направи проверка, която в отговора съм спестил!).

Отговор:
=MID(A11,FIND(CHAR(7),SUBSTITUTE(A11," ",CHAR(7), LEN(A11)-LEN(SUBSTITUTE(A11," ",""))))+1,32767)

Тук се използва функцията MID за извличане. За намирането на началната позиция се използва комбинация от двата метода за търсене и броене. Чрез броене се намира броя (т.е. колко интервала има) и след това се намира позицията на последния (=броя) интервал. Вместо да се прави сложна гимнастика за определяне броя на символите за извличане просто се посочва 32767 (текстът в една клетка не може да бъде повече от 32767!) и функцията Mid взема всичко до края. (За лимитите ето ви справка http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP010342495.aspx )

Това е:)