Вопрос в следующем: как изъять из ячейки только последнее число. Решений относительно отбора всех чисел (цифр) из ячейки несколько, а алгоритма по которому будет происходить отбор числа определенного порядка (первого, второго, последнего и т.п в ячейке.) я не нашел. Т.е. макрос (или формула) должен подсчитать общее количество чисел в ячейке и отобразить последнее число. (нужен именно такой алгоритм, чтобы потом можно было отобрать, например, только первое, второе число)
Надстрочные и подстрочные числа не рассматриваются как числа
Привязываться к порядковому номеру числа сомнительная затея, на сколько я понимаю нужно вытаскивать значения неких физических величин. Я бы делал это с помощью регулярных выражений, но это выходит за рамки "формульного" решения.
вариант функции uuu в столбце G для данного файл- примера
Код
Function uuu#(t$)
With CreateObject("VBScript.RegExp"): .Pattern = "(?:менее|более) (\d+,\d+|\d+)": .Global = True
uuu = .Execute(t)(.Execute(t).Count - 1).Submatches(0)
End With
End Function
sv2013, почти, но здесь решение частное, возможно, неудачный пример. Нужно сделать то же самое, но без привязки к словам более и менее и любым другим. Текст может быть любой
Нужна привязка к порядку числа, т.е. макрос должен определить сколько всего чисел в ячейке, а уже потом выбрал последнее
С макросами у меня туго, так что, как вариант, такая методика (для ячейки A1): 1. Берём Супер-UDF у Дмитрия "The_Prist"тут и меняем в коде
Код
If LCase(sSymbol) Like "*[0-9.,;:-]*" Then
на
Код
If LCase(sSymbol) Like "*[0-9., -]*" Then
Дмитрий даёт пояснения, зачем... Теперь при применении этой UDF в доп. столбце №1 на ИСХОДНУЮ ячейку, вернуться числа с кучей пробелов между ними. 2. В доп. столбце №2 применяем функцию СЖПРОБЕЛЫ или подобные ей макросы на доп. столбец №1. Удалили лишние пробелы и теперь можем использовать " " в качестве разделителя. 3. В доп. столбце №3 применяемфункцию =ЕСЛИ(ЕПУСТО(A1);0;ДЛСТР(СЖПРОБЕЛЫ(A1))-ДЛСТР(ПОДСТАВИТЬ(A1;" ";""))+1) из приёмов на доп. столбец №2, она считает количество чисел. 4. В доп. столбце №4 применяем Substring также из приёмов на доп. столбец №2 (источник текста) и доп. столбец №3 (номер последнего слова). Написал бы Profit! но уж очень много действий)))) Надеюсь, найдётся решение через UDF - они такие крутые
P.S: sv2013, при изменении количества чисел, UDF перестаёт работать
18:30. Соорудил БОМБУ, возьмёте в избушку? Решение одной формулой для ячейки A1: =ЕСЛИОШИБКА(ПРАВСИМВ(СЖПРОБЕЛЫ(Extract_Number_Or_Text(A1));ДЛСТР(СЖПРОБЕЛЫ(Extract_Number_Or_Text(A1)))-НАЙТИ("*";ПОДСТАВИТЬ(СЖПРОБЕЛЫ(Extract_Number_Or_Text(A1));" ";"*";ДЛСТР(СЖПРОБЕЛЫ(Extract_Number_Or_Text(A1)))-ДЛСТР(ПОДСТАВИТЬ(СЖПРОБЕЛЫ(Extract_Number_Or_Text(A1));" ";"")))));СЖПРОБЕЛЫ(Extract_Number_Or_Text(A1))), где "Extract_Number_Or_Text" - название UDF от Дмитрия "The_Prist" P.P.S.: обратите внимание, что оригинальное название функции Extract_Number_from_Text. У меня она переименована, поэтому необходимо это учитывать и при необходимости сменить название во всех вхождениях внутри функции
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Function uuu2#(t$)
With CreateObject("VBScript.RegExp"): .Pattern = "(?:\d+,\d+|\d+)(?!\.)": .Global = True
uuu2 = .Execute(t)(.Execute(t).Count - 1)
End With
End Function
И мой вариант для последнего числа (макрос). Только вот с квадратными миллиметрами засада: по условию должно отобразиться 2, а в файле в примере показано 1280,5. Если так, то нужно уточнять условия. Количество не считал.
sv2013, есть ли простой способ объяснить, как вы обошли "мм2" (ОЧЕНЬ слабо знаком с VBA)? Я так думаю, что в этом случае "2" не нужно вытаскивать...(лично мне точно, хоть в противном случае можно и заранее "мм2" и всё такое заменить на пустоту). 20:50 Заметил, что пропускает только, если 2 в верхнем индексе - в этом дело? Код не числовой? ))) а также не вытягивает ПОСЛЕДНЮЮ ЦИФРУ, если после него "." То есть из "356." вытянет 35)))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Юрий М, да нет))) когда 2 это просто 2 - вытягивает, а когда в верхнем индексе (ну по-правильному как квадратная степень пишется) - не вытягивает... Ошибся, Юрий - там точка стояла окаянная )))) А вот то, что при наличии точки после числа - не вытягивает, странно. Тоже, конечно, Ctrl+H лечиться, но было бы круто прописать замену точек на запятые перед основным макросом или что-то вроде того))) P.S.: ещё одно - не определяет отрицательные числа ((( т.е. минусы (они же дефисы) вообще игнорит...
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Function GetCertainNum(txt As String, lNum As Long)
Dim oNums, lcnt As Long
With CreateObject("VBScript.RegExp")
.Pattern = "(?:\d+" & Application.DecimalSeparator & "\d+|\d+)(?!\.)"
.MultiLine = True
.Global = True
Set oNums = .Execute(txt)
lcnt = oNums.Count
If lcnt < lNum Then lNum = lcnt
If lcnt > 0 Then
GetCertainNum = oNums(lNum - 1)
Else
GetCertainNum = ""
End If
End With
End Function
как видно, добавил пару моментов: 1. Надо помимо текста указать позицию числа. Если указано число больше, чем есть чисел в строке - будет возвращено последнее. 2. Добавил Application.DecimalSeparator, чтобы функция работала и в случае, если разделитель чисел точка. Хотя момент не сильно принципиальный, но в базовой реализации если число будет записано с точкой - результат будет некорректный. 3. Если чисел в строке нет вообще - вернется пустая строка.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Jack_Famous,посмотрите текст функции uuu2, там применена негативная опережающая проверка (?!),если интересуетесь регулярными выражениями,можно ,например,посмотреть разновидности позиционных проверок на с.96 Джеффри Фридл "Регулярные выражения",2015 Вначале использовал функцию uuu1 в файл примере,затем,с учетом Вашего замечания в #5,усовершенствовал шаблон(паттерн), применив (?!)
Да дело не в точке, как таковой: тогда нужно менять условия: надстрочные (и подстрочные?) символы не рассматривать, как числа. А при имеющейся постановке вопроса в пятой строке последним числом является 2.
sv2013, это не я писал, а dyhes))) насчёт ваших пояснений - я, конечно, ничего не понял, ну ничего - всё впереди))) а насчёт "точки" и "-" - это лично моё мнение, возможно отличное от автора (хочу к себе в копилку, кстати вторая за день от sv2013). Просто, если я числа вытаскиваю, то мне важно больше оно нуля или меньше (типа, если стоит перед числом слитно "-", то отрицательное, возможно как дополнительный параметр функции - типа определять отрицательные или нет), ну и точка эта мерзкая, конечно всё портит... У модернизации от The_Prist, кстати, те же проблемы... В любом случае ваши решения много круче моей "бомбы" и всё остаётся на ваше (и, частично, автора) усмотрение ))))
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
dyhes,Вы предложили в файл-примере,в соответствии с правилами форума,что дано(как надо),-в соответствии с этим здесь на форуме составляют формулы и функции. Предложите другой расширенный файл -пример,что дано(как надо),-соответственно будут другие функции.
dyhes, или используйте модернизацию от The_Prist (пост №12), если КОНКРЕТНОЕ по счёту... А ещё (для совсем рискованных ) можно использовать доп. столбец №3 (он как раз считает количество чисел) из "поста #6 (до "бомбы")
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Jack_Famous, решение от The_Prist хорошее и действительно практически универсальное, но в моем случае это не подходит, т.к. в ячейке может быть разное количество чисел и знать порядковый номер последнего (предпоследнего) не представляется возможным..
вариант для #20,предпоследнее число, функция uuu3 в столбце E,количество чисел ,функция uuu4 в столбце I
Код
Function uuu3(t$)
With CreateObject("VBScript.RegExp"): .Pattern = "(?:\d+,\d+|\d+)(?!\.)": .Global = True
If .Execute(t).Count > 1 Then uuu3 = CDbl(.Execute(t)(.Execute(t).Count - 2)) Else uuu3 = ""
End With
End Function
Код
Function uuu4(t$)
With CreateObject("VBScript.RegExp"): .Pattern = "(?:\d+,\d+|\d+)(?!\.)": .Global = True
If .test(t) Then uuu4 = CDbl(.Execute(t).Count)
End With
End Function
Андрей VG, добрый вечер,Вы,фактически меняете файл пример(что дано),тогда еще надо указать как надо и что искать последнее или предпоследнее число,к тому же создатель темы просит не учитывать ,то,что при мм(надстрочные и подстрочные символы).Данная тема давно обсуждается,ранее, на начальном этапе, я использовал для последнего числа функцию uuu1,предложите свой вариант для Вашего файл примера.
Код
Function uuu1#(t$)
With CreateObject("VBScript.RegExp"): .Pattern = "(?:\d+,\d+|\d+)": .Global = True
If InStrRev(t, "мм") Then
uuu1 = .Execute(t)(.Execute(t).Count - 2)
Else
uuu1 = .Execute(t)(.Execute(t).Count - 1)
End If
End With
End Function
Тут ещё само название темы грешит неточностью формулировки - расходится с задачей: если именно изъять, то нужно "на месте" модифицировать строку ) Просто занудствую. Но это из похожей оперы: пишут "перенести", а по факту нужно скопировать. Игорь (Hugo) поймёт
sv2013 написал: Вы,фактически меняете файл пример(что дано),тогда еще надо указать как надо
Разве я что-то поменял? Всего лишь указал, что способ определения надстрочного символа по точке после числа несколько недостаточный (всего лишь добавил немного текста после миллиметров квадратных). А если будет Спирт C2H5OH 1л 20 бутылок То что выдаёт формула в плане количества чисел?
Андрей VG, добавил Ваши варианты в файл пример(B7,B8),видно,что Ваш последний вариант(B8) не представляет трудности для функций uuu1 и uuu4,а для варианта в B7 Вам ранее предложил выложить Ваш вариант функции для последнего числа.В файл примере создателя темы все мои варианты работают корректно.
Доброе время суток sv2013, извините если что, не в какой мере не предполагал вас чем-то обижать. Просто подтолкнуть от хорошего решения к лучшему. К своему стыду, даже и не пытался писать функции. Вот набросал насколько смог вписаться в тему, исходя из того, что если перед числом стоит буква, то интерпретируем это как число верхнего или нижнего индекса или часть сложного имени некоторого изделия, например М23Ш8.