Страницы: 1 2 След.
RSS
Удалить последнее слово фразы, или все символы после последнего пробела, Excel 2003
 
Заранее прошу прощения, если решение уже есть. Но по поиску не нашел.
Суть задачи:
Есть список названий товаров, последнее слово после пробела - это код товара. Он может быть разным и текст и цифры.
Необходимо: удалить слово после последнего пробела.
А в иделе - еще и поместить его в соседний столбец.
Excel 2003
 
Код
=ПОДСТАВИТЬ(ПОДСТАВИТЬ(ПСТР(A2;ПОИСК("/";ПОДСТАВИТЬ(A2;" ";"/";ДЛСТР(A2)-ДЛСТР(ПОДСТАВИТЬ(A2;" ";))));50);")";);"(";)
 
Может не совсем понятно сформулировал, но мне важно получить значения Названия товара без слова после последнего пробела, а выделить последнее слово в отдельный столбец это уже не главная а второстепенная задача.
Было: Портмоне мужской Armani (11082)
Стало: Портмоне мужской Armani

Поможете ?
Изменено: ateccc - 18.10.2014 00:20:54
 
Не успеешь за формулистами.  :D  .
Удаляет с первого столбца и переносит в соседний
Код
Sub Extract()
    Dim Rng As Range
    Set RegExp = CreateObject("VBScript.RegExp")
    RegExp.Pattern = "\s(\S+)$"
    For Each Rng In ActiveSheet.UsedRange.Columns(1).Cells
        If Rng.Value <> "" Then
            bRes = RegExp.test(Rng.Value)
            If bRes Then
                Set oMatches = RegExp.Execute(Rng.Value)
                Rng.Offset(0, 1) = Replace(Replace(oMatches(0).subMatches(0), "(", ""), ")", "")
                Rng.Value = RegExp.Replace(Rng.Value, "")
            End If
        End If
    Next
End Sub
 
 
Это проще. Как там у скульпторов? Отсекаете у показанной формулы лишнее - и получаете... если не шедевр, то нужную формулу  :)  
=ЛЕВСИМВ(A2;ПОИСК("/";ПОДСТАВИТЬ(A2;" ";"/";ДЛСТР(A2)-ДЛСТР(ПОДСТАВИТЬ(A2;" ";))))-1)
 
vikttur, у меня Ваша формула не работает, предлагает внести исправления по количеству скобок, можете скинуть файл с формулой уже.
Doober, спасибо. Макрос работает)
 
ateccc, тут в соседней теме говорили про избыточное цитирование - у Вас та же проблема. Зачем вообще процитировали, да ещё всё целиком?
 
Извините, я новичок.
 
Цитата
- Вы за меня и кушать будете?
Двое_из_ларца:
- Ага! :)
 
vikttur, Спасибо !
 
Цитата
Doober пишет: Не успеешь за формулистами. Удаляет с первого столбца и переносит в соседний RegExp.Pattern =   "\s(\S+)$"
Doober , это, наверно, я ещё не успеваю понимать так быстро... но весь код прочитать смогла     :oops:    кроме главного нюанса... вижу: \s пробел - ( - без пробела несколько символов - ) - окончание строки...  но ведь  "("  соответствует  последовательность "\(" синтаксисом регулярок ...  правильно ли я вижу?? или "\s\(" по логике "пробел и скобка" тоже правильно?... или  символ всегда пишется между слэшем и скобкой   (например, \n( -новая строка начинающаяся со скобки или что-нибудь ещё) ... или скобка всегда понятна и без слэша?... пользовалась подсказкой Максима, но подумала многое, а уверенности никакой  :(  ... ребята, извините, но я уже по буквам начинаю разбираться... p.s. с клавиатурой мы летом разобрались  8)   вашими стараниями...
Изменено: JeyCi - 20.10.2014 23:52:01
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
всё-таки сработало...
- не могу не поддержать ветку идеей отсюда
- вошла во вкус к Replace'у   :)

Код
Sub t()
  With CreateObject("vbscript.regexp")
    .ignorecase = True: .Global = True: .MultiLine = True: .Pattern = "(\s(\S+)$)"
    For Each c In Selection: c.Value = .Replace(c.Value, ""): Next 
  End With
End Sub
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Так?

Код
' Без последней части
Function FixCell(cell As Range)
    With CreateObject("VBScript.RegExp")
        .IgnoreCase = True: .Pattern = "^(.+)\s+\(?.+\)?$"
        FixCell = .Execute(cell.Value)(0).SubMatches(0)
    End With
End Function

' Последняя часть
Function LastPart(cell As Range)
    With CreateObject("VBScript.RegExp")
        .IgnoreCase = True: .Pattern = "^.+\s+\(?(.+?)\)?$"
        LastPart = .Execute(cell.Value)(0).SubMatches(0)
    End With
End Function 
There is no knowledge that is not power
 
тогда попробую расшифровать - чтобы понять
Цитата
Johny пишет: Pattern = "^(.+)\s+\(?.+\)?$"
? распознаём: (шаблон любое количество символов), пробел или несколько пробелов, открывающая скобка, несколько символов, закрывающая скобка, символ, конец строки... точки означают отношение к объекту ( VBScript.RegExp)... ^ значит исключаем это рег. выражение...  FixCell = .Execute(cell.Value)(0).SubMatches(0) - вобщем убираем? (SubMatches(0)) первое встретившееся такое выражение: всё что в скобках (.+), пробелы \s+, открывающую скобку \(?, закрывающая скобка после нескольких символов .+\)? за которыми конец строки $
Цитата
Johny пишет: Pattern = "^.+\s+\(?(.+?)\)?$"
вобщем убираем первое встретившееся (SubMatches(0)) такое выражение: любое количество символов .+, пробел или несколько \s+, открывающую скобку \(?, за которой шаблон (.+?), который не совсем понимаю ЗАЧЕМ вносить в исключения, после чего закрывающая скобка \)? за которыми конец строки $

Johny
признайтесь честно что написали  :) , а то лишили меня спокойного сна... если я неверно расшифровываю, то предупредите please... а то ведь не усну... особенно выделенное зелёным смущает... и скажу честно, я не ТС и на вопрос "так ли?" - ответить всё равно не смогу  :oops:  а понять интересно
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Кстати, в FixCell \(? и \)? необязательны - их можно удалить.  :)  Привожу пояснение с этой поправкой.
Код
 .Pattern = "^(.+)\s+.+$"
Всё очень просто.
^ и $ определяют всю строку.
Раз нам надо "до последнего пробела", то мы знаем, что первый пробел с конца.
Символ $ нам даёт конец текста. .+ даёт весь текст в конце, а \s+ и есть наш последний пробел.
Всё, что до него - это наша искомая строка, то есть с начала строки ^ до последнего пробела \s+.

LastPart.

Код
"^.+\s+\(?(.+?)\)?$"
 
Тут принцип такой же, что и в FixCell, но я увидел, что в некоторых словах нет скобок вокруг последнего слова. А так как автору нужен текст без скобок, то \(? и \)? помогают нам исключить их, если таковые есть. Другими словами, если их не написать, то (.+?) заберёт и скобки, но они нам не нужны. Остальное - всё как в FixCell.
Что касается SubMatches(0), то это просто наш искомый текст, заключённый в скобки. Он считается слева направо: первый - 0, второй - 1 и так далее.
Если использовать Early Binding, то можно расписать попонятней и подробней. Для этого указываем библиотеку (Tools -> References ->Microsoft VBScript Regular Expressions 5.5).

Код
 Function LastPart(cell As Range)
    
    Dim re As RegExp
    Dim mc As MatchCollection
    Dim m As Match
    Dim submc As SubMatches
    
    Set re = New RegExp
    re.Pattern = "^.+\s+\(?(.+?)\)?$"
    Set mc = re.Execute(cell.Value)
    Set m = mc.Item(0)
    Set submc = m.SubMatches
    LastPart = submc.Item(0)
    
End Function
Изменено: Johny - 10.12.2014 22:43:29
There is no knowledge that is not power
 
Можно и по попроще
разбиваем сплитом на массив, переоределям размерность массива и джоиним новый массив
 
Цитата
B.Key пишет: Можно и по попроще
Я дико извиняюсь, но какой смысл вкладывается в слово "попроще"?
There is no knowledge that is not power
 
ой, господа, мне это до следующего года занятие - уложить всё это в мозг... поэтому не ждите быстрого понимания  :)  ... но всё равно большое спасибо за ответ!.. теперь засну... потому что в общем и целом Johny, кажется мне, вы за сегодня успели дать мне и статью почитать и сами по-быстрому резюме той статьи составили... respect... успехов вам по жизни - чтобы всё было так же быстро, (очень) полномасштабно и с пользой    8)  
p.s. B.Key мы тут просто случайно за рэгэксп зацепились (не судите строго) ради интереса для общего развития - на примере этой ветки... и кстати очень простые объяснения получились у Johny... читать приятнее, чем нобелевских лауреатов или ещё кого - там вообще ничего не понять... а тут на форуме очень многих очень приятно читать :)
Изменено: JeyCi - 10.12.2014 23:13:56
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
 
Попроще это  без регэкспа :)
--------
Для меня это просто, для обычного поль зователя это вынос мозга.
 
Цитата
B.Key пишет: Попроще этобез регэкспа
Феерично!  :D  Ну хотя да - огород из джоинов и сплитов, действительно, будет попроще.  :)  Лет десять назад я бы так и сделал.  :D
There is no knowledge that is not power
 
Johny, куда уж мне до Вас с Вашим опытом и 10 летним стажем.

Скрытый текст
 
B.Key,   :D
Код
Function insTxt(txt)
insTxt = Left$(txt, InStrRev(txt, " ") - 1)
End Function
Изменено: RAN - 11.12.2014 00:49:22
 
Я согласен полностью, instr еще быстрее и проще, меня удивило другое:
Цитата
Johny пишет: Лет десять назад я бы так и сделал.
 
Цитата
B.Key пишет: меня удивило другое:
Ну вот через 10 лет и поймёте...
There is no knowledge that is not power
 
Конструктивно...
 
Я имел ввиду, что B.Key через 10 лет прокачает скилл и будет использовать регэкспы.  :D
There is no knowledge that is not power
 
 Может и будет, но показанный им пример говорит о том, что по скорости выигрыш не за Вами))
На моей машине:
0,0625 split
6,796875 regexp
===
Вот и хотелось бы понять, почему лет через 10 B.Key должен будет перейти на регулярки? :-)
 
Где наш главный защитник крепких регулярных выражений? Саша!!! Ты где?!  :)
0,0546875 split
6,773438 regexp
 
А с Early Binding? :)
There is no knowledge that is not power
 
Цитата
vikttur пишет: Саша!!! Ты где?!
Я за него.
Всего 1 строчка, и если не сравнялись, то существенно приблизились.

Скрытый текст
Страницы: 1 2 След.
Читают тему
Наверх