Прошу простить меня уважаемое сообщество, коль безполезной окажется сия тема, Но рискну изложить свои мысли. По ходу работы возникла необходимость сопоставить внутренние коды номенклатуры с кодами номенклатуры поставщика. В названии внутренней номенклатуры в конце зачастую указывается код номенклатуры поставщика. Потому необходимо было извлечь сию цифирь на свет божий в чистом виде по следующему условию: берутся из содержимого ячейки с конца только подряд идущие цифры до первого встречного символа НЕ цифры. Сгоряча имелось желание исторгнуть глас вопиющего о помощи, но устыдившись своей слабости в сим вопросе решил упорно до посинения пытаться сделать самостоятельно. Вот, что вышло:
Скрытый текст
Код
Function ЦифрыПодрядСКонцаСтроки(Адрес_Ячейки As Range)
'функция возвращает подряд идущие цифры с конца текста указанной ячейки
Dim theS As Variant, theR As Variant, theCh As Variant, thePosCh As Variant, i As Variant
Const theDigits = "0123456789" ' целевые символы
theS = Адрес_Ячейки.Value ' переменная с значением переданной ячейки
theR = "" ' переменная, в которой накапливается целевой результат
theCh = "" ' переменная, которая содержит в себе текущий итый символ
thePosCh = 0 ' переменная, в которую пишется положение текущего итого символа среди целевых
i = Len(theS) ' счётчик (в данном случае с конца сроки)
Do ' начало цикла
If i = 0 Then Exit Do ' если счётчик достиг нуля, то выход
theCh = Mid(theS, i, 1) ' итый символ
thePosCh = InStr(theDigits, theCh) ' позиция итого символа в целевых
If thePosCh = 0 Then Exit Do ' если достигли НЕ целевого символа, то выход
theR = theCh + theR ' накапливаем целевые символы из указанной ячейки
i = i - 1 ' уменьшаем счётчик на единицу
Loop ' конец цикла
ЦифрыПодрядСКонцаСтроки = theR ' возвращаем результат
End Function
Функция выполняет поставленную задачу, но сдаётся мне, что она не оптимальна в своей реализации. Возможно она кому пригодится, а возможно, кто добрым советом поможет сделать её оптимальнее, благодаря чему не только Ваш покорный слуга улучшит свои познания в ВБА. Спасибо.
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
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
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 пишет: а если цифр больше 15 штук, или заканчиваются нулями, или вообще отсутствуют?
Как правило цифр от 5 до 7. В конце встречаются нули. Но это уточнение никак не влияет на вставшую передо мной задачу, я так думаю. Признаюсь, что код Hugo я пока не осознавал. Надеюсь с завтрашнего приступлю к осознанию.
Формула массива (ФМ) вводится Ctrl+Shift+Enter Memento mori
Да, про нули я не подумал. И забыл Третий вариант с единицей:
Код
Function lastnums(s$)
lastnums = (StrReverse(Val(1 & StrReverse(s))) - 1) / 10
End Function
И вот из такого 1313dgdg12000001000000 делает такое: 12000001000000 Можно вероятно ещё одну цифру добавить - заменить последнюю/первую на 1, затем вернуть её назад.
Hugo, проверил Ваш код. Работает замечательно, вот, только если цифр в конце строки нет, то возвращает "0", а не "". Правда, это не смертельно. Спасибо. Казанский, пытаюсь разобраться с Вашим кодом. Что я понял (если не верно, то поправьте меня, пожалуйста):
Код
.Pattern = "\d*$"
шаблон для поиска равен любой цифре повторяющейся ноль и более раз до конца строки. Далее.
Код
TrailingFigures = .Execute(s)(0)
функция возвращает результат выполнения команды Execute (а тут я процитирую её описание из сего источника):
Цитата
поиск соответствующих шаблону вхождений в строке-оригинале. Возвращает коллекцию найденных подстрок в виде агрегатного объекта.
Попробую по своему сказать: Execute ищет в строке s все вхождения Pattern и из них формирует массив, а параметр (0) указывает, что из сформированного массива нужно вернуть первый найденный результат (нумерация элементов массива начинается с нуля). Проверил работу сего кода. Работает хорошо - без сбоев. _/\_ Только у меня вопрос, если Execute не находит Pattern, то что она возвращает? (по результатам отработки формулы на примере без цифр в конце строки, я так понял, что ""). Спасибо.
Формула массива (ФМ) вводится Ctrl+Shift+Enter Memento mori