Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
Автор |
|
insecteaterПон, 07.03.11, 09:46 |
Регулярните изрази са доста мощно средство. След като човек свикне с тях, започва да се разглезва и гледа да бяга от вложени стрингови функции, които искат концентрация при създаване и проследяване. Ето и моят вариант - ползвам две функции - една за извличане на броя и една за извличане на цената. Може да се ползва и една с два параметъра и if в тялото, за по-кратко - въпрос на вкус и виждане. Как работи: Регулярният израз извлича съответното число, след това (пак с регулярен израз) се замества неизвестният десетичен разделил, който е бил въведен със стандартния такъв за приложението и след като конвертира резултата в число с дробна част, функцията го връща. Характерно е, че за десетичен разделител на входа може да се ползва какъв да е символ. Както си личи и от примера. Според мен кодът не е чак толкова сложен. Спорен е въпросът обаче колко е бърз. По принцип стринговите функции са по-бързи от регулярните изрази. Аз и phrozencrew в случая бихме ползвали регулярни изрази, dreven стрингови функции. За случая "правилния" и "грешния" вариант зависят от познанията и навиците на програмиста. Недостатъците и на двата метода са ясни: Регулярни изрази - мощни и по-бавни, малко плашещи на пръв поглед Стрингови функции - бързи и неудобни за сложни манипулации, простотата им лесно подвежда да се придържа човек все към тях Тежката артилерия на регулярните изрази не е чак толкова необходима за прости задачи. Но нали идеята е да си опростим работата. Единият начин за някои може да е по-прост, за други по-сложен и обратното. Моят навик е такъв, че щом се налага да се "вади" информация която варира от стринг, да си ползвам регулярни изрази. Стринговите функции само ако специално се иска бързодействие, или се цепи нещо на части, които са предварително дефинирани и няма вариации. Бих се радвал да разбера вашите навици какви са. Ето сорс: Function getBr(Br As String)
Dim RegEx As RegExp
Dim Matches As Object
Dim Buff As Variant
Set RegEx = New RegExp
RegEx.Pattern = "^(\d+(\D\d+)?)"
Set Matches = RegEx.Execute(Br)
If Matches.Count = 1 Then
Buff = Matches(0).SubMatches.Item(0)
RegEx.Pattern = "\D"
getBr = CDbl(RegEx.Replace(Buff, Application.DecimalSeparator))
End If
End Function
Function getPrice(Price As String)
Dim RegEx As RegExp
Dim Matches As Object
Dim Buff As Variant
Set RegEx = New RegExp
RegEx.Pattern = "/(\d+(\D\d+)?)"
Set Matches = RegEx.Execute(Price)
If Matches.Count > 0 Then
Buff = Matches(0).SubMatches.Item(0)
RegEx.Pattern = "\D"
getPrice = CDbl(RegEx.Replace(Buff, Application.DecimalSeparator))
End If
End Function |
Ето и резултата:
Ето и примерния файл: Extract_float.xls (Във VBA работата с регулярни изрази иска повече код, отколкото в PHP :P ) Надявам се, че не ми се сърдите за намесата в дискусията ви. Ако ви дразня, можете просто да игнорирате поста ми. П. П. Между другото този вариант му е все тая и каква е бройната единица след числата и дали въобще я има или не. | | power_mПон, 07.03.11, 10:04 | RE: Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
Здравейте и на двамата уважавани от мен, заради знанията и помощта, която оказвате на начинаещите в този форум ! Аз лично спечелих от вашия спор , защото научих, тънки похвати във VBA и VB, където съм едва прохождащ ! Не искам да взимам страна, но като лаик, кодовете на DREVEN , като чели по- ми се нравят, защото са по-лесни и разбираеми за четене ...! Бих му препоръчал да се насочи ,към преподавателска дейност, защото много лесно и разбираемо обяснява сложните неща...За това се изисква талант, който много умни и надарени хора не притежават . В училище съм се срещал с много начетени в своите области преподаватели, които се "напредварваха" лесните примери да обясняват по най-сложния начин, и накрая се оказва, че това, което преподават не се усвоява... редактиран от power_m на 07.03.11 10:05 | | phrozencrewПон, 07.03.11, 19:24 |
Inseceater, прекрасна идея! Със собствени функции наистина се получава много чисто! Древен, това изби рибата: RegEx.Pattern = "[б][р][.][/]d+[.]?d+[л][в][.]" Благодаря за шегата! Тук за мен лично няма спор, защото лесните примери се решават с махване на ръка. Те не изискват програмистки умения, а просто добро познаване на функционалността на Excel. Проблема е когато имаме наистина заплетена ситуация и трябва да вземем решение за подхода. Определено VBA въобще не е подходящ език за работа със стрингове. Това е меко казано архаичен език от гледна точка на съвременното програмиране. За предпочитане в такива случаи да се използват по-съвременни и мощни езици от сорта на ruby, python, perl, php, а защо не и JavaScript. Всъщност последната актуална версия JavaScript 1.8.5 би могла напълно да си съперничи със всеки от посочените езици по отношение на работа със стрингове. Но е малко трудно да се ползва като самостоятелно приложение. Трябва да се използва интерпретатора в WSH (cscript или wscript). Да се върнем към интересните неща. Ще дам произволен пример за сложна комбинация от стрингове: Ябълки "Златна превъзходна" 25лв./1кг.
Череши 16.56лв./10кг.
Гъби - "Печурки" 2,5лв./0,5кг. |
Какъв код бихте използвали, за да извлечете резултат: Общо лева: xx.xx | Общо килограми: xx.xx Възможно ли е да се реши подобна задачка чрез конвенцианалните методи, без RegEx и формулата да е еднаква за всички клетки, ? Според мен е възможно, но ще изисква невероятно много време и писане. Дали?! Ето и файла с питанката: Excel_pitanka.xls Не съм се пробвал да търся решение, но ей така за гъдел ще се пробвам да го реша по старовремските методи на Древен. Може и да успея. | | phrozencrewПон, 07.03.11, 20:26 | RE: RE: Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
” Защо смеси езиците за интернет програмиране с езици за приложно програмиране. Не се ли притесняваш, че някой може да те разбере неправилно. „
Недей така бе човек ! Преди да кажеш нещо преброй до 1000! Ако те чуе някое Unix гуро би могло да те пребие с камъ ци . Perl, ruby, python са езици на които са базирани милиони приложни програми. Perl дори влиза като задължителен за unix-like операционните системи. Без него никоя операционна система не може да се нарече unix-like, питай Ричард Столдман . Perl е в основа на операционната система UNIX и си е абсолютно приложен. Да не говорим за Python ! Чувал ли си за една програма за 3D анимация - Blender Е та тая програма е базирана на Python! Това не е интернет език. Древен, всички тия неща ги казвам само да спреш да се излагаш толкова! Ако нещо не ти е съвсем ясно потърси в мрежата, ще намериш достатъчно информация, щото излъчваш авторитетна некомпететност, която може да те скъса от смях ! | | phrozencrewПон, 07.03.11, 22:13 | RE: RE: RE: RE: Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
” Понеже знам, че имаш слабост към Perl и си майстор на този език, ще те помоля да да поместиш едно твое приложение писано на Perl, за да го изпробвам на моята тъпа Windows машина. Предпочитам да е нещо просто от сорта Portable, където стартирам и то тръгва. „
Ето ти едно, което е толкова мощно, че няма реална безплатна алтернатива. Не е мое, но показва мощта на Perl в достатъчна степен: ExifTool . Ако си виждал друг път безплатна програма, която да ти показва с какъв обектив си снимал, тогава ще ти дам 5 кинта да ми я кажеш. И нещо скрипта ти по-горе малко не работи:
Регионалните ми настройки са по подразбиране на български, да не кажеш нещо:
Иначе ми харесва частично решението ти! ПС: Всъщност въобще не ми харесва решението ти. Ти не си изпълнил условието: Възможно ли е да се реши подобна задачка чрез конвенцианалните методи, без RegEx и формулата да е еднаква за всички клетки Пак мъчиш да манипулираш и шмекеруваш, а мошенико ньеден?! | | phrozencrewПон, 07.03.11, 22:49 | RE: RE: RE: RE: RE: RE: Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
” Аз качих напълно работещ пример с решение, което използва VBA и стринговите му функции, без използване на RegEx. Но ти, защо след като изтегли примера форматира двете клетки в колоната "лева" като стринг. Хитро си го замислил, но Excel явно показва със зелено байраче клетките на които си променил формата. Оправи си формата на двете клетки или изтегли примера отново и всичко ще е наред. „
Абсолютно нищо не съм променял бе пич! Аз да не съм dreven, та да мамя! За мен истина е по-ценна от някакъв спор! А ти вземи си оправи програмата, да отговаря на условието и спри да манипулираш! | | kookkiПон, 07.03.11, 23:47 | RE: RE: RE: RE: RE: RE: Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
” Хитро си го замислил, но Excel явно показва със зелено байраче клетките на които си променил формата. Оправи си формата на двете клетки или изтегли примера отново и всичко ще е наред. „ и при мен не работи - със заводските настройки съм
едит: Древен, пробвай да затриеш темплейтите от временните папки, че съм забелязъл че ексела ги омешва неприятно редактиран от kookki на 07.03.11 23:53 | | kookkiВто, 08.03.11, 00:08 |
Работи, докато не натисна бутона. После ситуацията се вижда на снимката
едит: изглежда бутона вижда цифрите като целочислени стойности ? редактиран от kookki на 08.03.11 00:10 | | phrozencrewВто, 08.03.11, 07:15 |
И това е огелпено. Като разменя местата на 2 реда и гърми със страшна сила. Не съм ти гледал формулите, но мисля, че пак шмекеруваш!
Пречи ли ти нещо да спазваш правилата? | | insecteaterВто, 08.03.11, 12:29 |
One function to rule them all, One function to find them ... И с тия продукти за тревопасни къде сте тръгнали бе хора? Мръвка трябва, сила да има. Ето функцията Function getFloat(Br As String, Expression As String, Parentheses As Byte)
Set RegEx = New RegExp
RegEx.Pattern = Expression
Set Matches = RegEx.Execute(Br)
If Matches.Count > 0 Then
Buff = Matches(0).SubMatches.Item(Parentheses - 1)
RegEx.Pattern = "\D"
getFloat = CDbl(RegEx.Replace(Buff, Application.DecimalSeparator))
End If
End Function |
EdnaFunkcia.xls Суджука е добавен впоследствие - не е включен в сметката, понеже го опаковах с опаковъчна хартия и му сложих панделка. Сега чакам реакцията на колежките, които цяла година се оплакваха, че им е писнало от бонбони и цветя. Има си и прилежаща картичка с подохдящи пожелания разбира се :) | | phrozencrewВто, 08.03.11, 18:57 | RE: Извличане на число от буквено-цифров низ и след това сумиране с SUBTOTAL...
” One function to rule them all, One function to find them ... И с тия продукти за тревопасни къде сте тръгнали бе хора? Мръвка трябва, сила да има. Ето функцията Function getFloat(Br As String, Expression As String, Parentheses As Byte)
Set RegEx = New RegExp
RegEx.Pattern = Expression
Set Matches = RegEx.Execute(Br)
If Matches.Count > 0 Then
Buff = Matches(0).SubMatches.Item(Parentheses - 1)
RegEx.Pattern = "D"
getFloat = CDbl(RegEx.Replace(Buff, Application.DecimalSeparator))
End If
End Function |
EdnaFunkcia.xls Суджука е добавен впоследствие - не е включен в сметката, понеже го опаковах с опаковъчна хартия и му сложих панделка. Сега чакам реакцията на колежките, които цяла година се оплакваха, че им е писнало от бонбони и цветя. Има си и прилежаща картичка с подохдящи пожелания разбира се :) „
УУУУАААААУУУУУ!!!!!! Гениално, пичага! Просто мед ми капе на душата от тоя код! Благодаря за доставеното удоволствие! А това ще го използвам със сигурност: getFloat = CDbl(RegEx.Replace(Buff, Application.DecimalSeparator)) Толкова елегантно решение! И аз се бях насочил нататък. И се чудех как да го реша по лесен начин тоя проблем. Но използвах вградените променливи $1..$9. И стана мазало. Още нямам решение по моя начин! Респект Insecteater! | | insecteaterВто, 08.03.11, 20:32 |
Phrozen, и аз мерси за заигравката. regexp rulezzz Dreven и на теб мерси за препоръките (например тези за декларирането) и най вече за exe-то, което ще е много полезно при работата ми с .... (чудя се за точната дума) ... колежки с недостатъчна компютърна грамотност. | | Коментар |