Страницы: 1
RSS
Перебор символов ячейки с конца (нахождение подряд идущих цифр), пользовательская функция
 
Прошу простить меня уважаемое сообщество, коль безполезной окажется сия тема, Но рискну изложить свои мысли.
По ходу работы возникла необходимость сопоставить внутренние коды номенклатуры с кодами номенклатуры поставщика.
В названии внутренней номенклатуры в конце зачастую указывается код номенклатуры поставщика.
Потому необходимо было извлечь сию цифирь на свет божий в чистом виде по следующему условию: берутся из содержимого ячейки с конца только подряд идущие цифры до первого встречного символа НЕ цифры.
Сгоряча имелось желание исторгнуть глас вопиющего о помощи, но устыдившись своей слабости в сим вопросе решил упорно до посинения пытаться сделать самостоятельно. Вот, что вышло:
Скрытый текст
Функция выполняет поставленную задачу, но сдаётся мне, что она не оптимальна в своей реализации. Возможно она кому пригодится, а возможно, кто добрым советом поможет сделать её оптимальнее, благодаря чему не только Ваш покорный слуга улучшит свои познания в ВБА.  :)  
Спасибо.
Изменено: JayBhagavan - 26.02.2014 15:58:10 (опечатка)

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Код
Function ЦифрыПодрядСКонцаСтроки(Адрес_Ячейки As Range)
    Dim i As Integer
        For i = Len(Адрес_Ячейки) To 1 Step -1
            If IsNumeric(Mid(Адрес_Ячейки, i, 1)) Then
            Else
                Exit For
            End If
    ЦифрыПодрядСКонцаСтроки = Mid(Адрес_Ячейки, i, 1) & ЦифрыПодрядСКонцаСтроки
        Next
End Function

 
 
Код
Function ЦифрыПодрядСКонцаСтроки(Строка As String)
Dim i As Long
For i = Len(Строка) To 1 Step -1
  If Not IsNumeric(Mid$(Строка, i, 1)) Then
    ЦифрыПодрядСКонцаСтроки = Mid(Строка, i + 1)
    Exit Function
  End If
Next
ЦифрыПодрядСКонцаСтроки = Строка
End Function
 
 
Kuzmich, спасибо. Изящно. Осмелюсь чуток подправить.
Код
Function ЦифрыПодрядСКонцаСтроки(Адрес_Ячейки As Range)
    Dim i As Integer
     For i = Len(Адрес_Ячейки) To 1 Step -1
      If IsNumeric(Mid(Адрес_Ячейки, i, 1)) Then 
          ЦифрыПодрядСКонцаСтроки = Mid(Адрес_Ячейки, i, 1) & ЦифрыПодрядСКонцаСтроки 
      Else
          Exit For
      End If
     Next
End Function  
Надеюсь, я верно поступил?
Kuzmich, скажите, пожалуйста, а верно ли то, что лучше записывать результаты вычислений в переменные, чем рассчитывать их каждый раз в программе заново? (на примере данного кода, каждый раз вычисляется длина содержимого ячейки и возвращается символ из ячейки) Извиняюсь за мою наглость спрашивать у Вас такое, но у меня в голове сформировался данный вопрос по причине того, что некогда я что-то читал про оптимизацию кода. (это было давно и больше ради интереса)
Ещё раз, Kuzmich, выражаю Вам свою искреннюю благодарность за участие в этой теме. _/\_

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Я бы еще добавил одну строчку перед End Function
If ЦифрыПодрядСКонцаСтроки = "" Then ЦифрыПодрядСКонцаСтроки = "Нет цифр в конце"

Цитата
лучше записывать результаты вычислений в переменные,
но тогда надо определять дополнительно эти переменные, не знаю, что лучше
 
Kuzmich, спасибо. Оставлю так, как Вы оптимизировали.
В моём случае лучше пусто, если не найдено искомое.
Если я правильно понимаю, то тут или избыток вычислений (без промежуточных переменных), или больше памяти занимается (коль с доп. переменными). Действительно, двойственная ситуация.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Скорректировал последний вариант кода:
Код
Function ЦифрыПодрядСКонцаСтроки(Адрес_Ячейки As Range)
'функция возвращает подряд идущие цифры с конца текста указанной ячейки
    Dim i As Integer
    ЦифрыПодрядСКонцаСтроки = ""
    For i = Len(Адрес_Ячейки) To 1 Step -1
        If IsNumeric(Mid(Адрес_Ячейки, i, 1)) Then
            ЦифрыПодрядСКонцаСтроки = Mid(Адрес_Ячейки, i, 1) & ЦифрыПодрядСКонцаСтроки
        Else
            Exit For
        End If
    Next
End Function
Добавил строку:
Код
ЦифрыПодрядСКонцаСтроки = "" 
т.к. без неё не находя искомое возвращает 0, что мне не подходит.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Вариант (наверно ничем не лучше других):
Код
Function nums(txt As String) As String
    Dim i As Long
    For i = Len(txt) To 1 Step -1
        If Not IsNumeric(Mid$(txt, i, 1)) Then Exit For
    Next i
    nums = Mid$(txt, i + 1)
End Function
 
MCH, спасибо. Вариант короче и оптимальней стал. _/\_

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Код
Function lastnums(s$)
    lastnums = StrReverse(Val(StrReverse(s)))
End Function
 
Точек ведь не будет? :)
 
Цитата
Hugo пишет:
Точек ведь не будет?
Не будет. Код сплошь состоит из цифр.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Цитата
Hugo пишет:
Точек ведь не будет?
Игорь, а если цифр больше 15 штук, или заканчиваются нулями, или вообще отсутствуют?
 
Цитата
MCH пишет:
а если цифр больше 15 штук, или заканчиваются нулями, или вообще отсутствуют?
Как правило цифр от 5 до 7. В конце встречаются нули. Но это уточнение никак не влияет на вставшую передо мной задачу, я так думаю. :)
Признаюсь, что код Hugo я пока не осознавал. Надеюсь с завтрашнего приступлю к осознанию. :)

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Проходили уже много раз, со StrReverse
https://www.google.ru/search?q=StrReverse+Val+StrReverse+site%3Aplanetaexcel.ru
Например
http://www.planetaexcel.ru/forum/?PAGE_NAME=read&FID=8&TID=30422
 
Да, про нули я не подумал. И забыл  :)  
Третий вариант с единицей:

Код
Function lastnums(s$)
    lastnums = (StrReverse(Val(1 & StrReverse(s))) - 1) / 10
End Function
 
И вот из такого
1313dgdg12000001000000
делает такое:
12000001000000
Можно вероятно ещё одну цифру добавить - заменить последнюю/первую на 1, затем вернуть её назад.
Изменено: Hugo - 26.02.2014 21:04:17
 
Казанский, спасибо. Делал запросы по иному. Про StrReverse не имел ни малейшего представления.
Hugo, спасибо. Уразумел Ваш код.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
До кучи
Код
Function TrailingFigures(s As String)
With CreateObject("vbscript.regexp")
  .Pattern = "\d*$"
  TrailingFigures = .Execute(s)(0)
End With
End Function
 
 
Казанский, спасибо. Есть с чем разобраться и над чем поразмыслить. :)

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
 
Hugo, проверил Ваш код. Работает замечательно, вот, только если цифр в конце строки нет, то возвращает "0", а не "". Правда, это не смертельно. Спасибо.
Казанский, пытаюсь разобраться с Вашим кодом. Что я понял (если не верно, то поправьте меня, пожалуйста):
Код
.Pattern = "\d*$" 
шаблон для поиска равен любой цифре повторяющейся ноль и более раз до конца строки. Далее.
Код
TrailingFigures = .Execute(s)(0) 
функция возвращает результат выполнения команды Execute (а тут я процитирую её описание из сего источника):
Цитата
поиск соответствующих шаблону вхождений в строке-оригинале. Возвращает коллекцию найденных подстрок в виде агрегатного объекта.
Попробую по своему сказать: Execute ищет в строке s все вхождения Pattern и из них формирует массив, а параметр (0) указывает, что из сформированного массива нужно вернуть первый найденный результат (нумерация элементов массива начинается с нуля).
Проверил работу сего кода. Работает хорошо - без сбоев. _/\_
Только у меня вопрос, если Execute не находит Pattern, то что она возвращает? (по результатам отработки формулы на примере без цифр в конце строки, я так понял, что "").
Спасибо.

Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori
Страницы: 1
Наверх