Страницы: 1
RSS
Оставить только цифры (не функция)
 
Ребята помогите плз, нужно во всех ячейках столбца B, кроме шапки, оставить только цифры (диапазон с B2 и вниз, может быть больше 100к строчек).  
Видел уже много функций по преобразованию текста, но реализовать нужно строго в виде макроса, а не пользовательской функции.  
 
По возможности подскажите, плохо разбираюсь просто. Реально ли добавлять функцию, потом использовать ее внутри макроса?! Макрос должен быть в личной книге макросов, вариант если каждый раз придется в действующий лист вставлять функцию не катит.
 
Знаю, уже читал и пробовал эту функцию.  
 
Повторяюсь мне не нужно использовать пользовательскую функцию, а нужно иметь макрос, чтобы запустить данное действие (изменение данных в ячейках столбца), нажав на кнопку.  
 
P.S. Это часть макроса, которую я просто в ставлю в другой более объемный. Он должен выполнять еще и иные функции =)
 
Сорри, уже натыкался и на вашу юзерформу. Все ок, но мне не нужно указания куда нужно выводить значения (нужно прямо в ячейках все менять в которых и были) + это нужно делать в строго заданном  столбце сразу, а не указывать диапазон каждый раз для 100тысяч строчек, я хочу просто код вставить в более здоровый макрос который еще много чего делает с исходным файлом.  
Нужно без юзерформы для ввода данных, просто - нажал на запуск макроса, значения в диапазоне от B2 до последней непустой ячейки в столбце поменялись (убрать все спец. символы, запятые, пробелы, тирэ и тп)
 
Надо получить:  
из  
23234аывавыа34; rs3  
fsdf34 5  
fs11df  
 
23234343  
345  
11  
 
The_Prist, я понимаю как работает функция, как конкретно вызывается юзерформа - плохо понимаю. Мне нужно, чтобы макрос использовал уже написанную функцию. В общих словах, наверное что-то типа  
For Each Cell in Range (B:B)  
cell = Extract_Number_From_Text(cell)  
Но у меня проблемы с синтаксисом, т.к. нет опыта и знаний определенных, пока получается только несложно менять рабочие коды, с нуля не могу сам прописать (ошибки в компиляции происходят). Поэтому и попросил готовый пример, чтобы посмотреть как это пишется (я так понимаю, что для знающего человека в этом нет ничего сложного, т.к. функция уже прописана и в различных вариациях)
 
UPD:  
 
The_Prist, я как раз упростил вашу функцию для своей задачи:  
Function Extract_Number_from_Text(sWord As String, Optional Metod As Integer)  
 
   Dim sSymbol As String, sInsertWord As String  
   Dim i As Integer  
 
   If sWord = "" Then Extract_Number_from_Text = "": Exit Function  
   sInsertWord = ""  
   sSymbol = ""  
   For i = 1 To Len(sWord)  
       sSymbol = Mid(sWord, i, 1)  
           If Not sSymbol Like "*[0-9]*" Then
                   sSymbol = ""  
                   sInsertWord = sInsertWord & sSymbol  
               Else  
                   sInsertWord = sInsertWord & sSymbol  
           End If  
   Next i  
   Extract_Number_from_Text = sInsertWord  
End Function  
 
Вот мне нужно как-то прописать, чтобы для всех ячеек из нужного диапазона (с B2 до последней непустой в столбце)  
cell = Extract_Number_from_Text (cell)  
просто не пойму с синтаксисом...
 
Пропишите в отдельной процедуре:  
For Each cl In Range([b2], Cells(Rows.Count, 2).End(xlUp))
cl=Extract_Number_from_Text(cl)  
Next
 
м.б. как-то так  
 
Sub ert()  
Dim x, i&  
x = Range("B2", Cells(Rows.Count, 2).End(xlUp)).Value  
With CreateObject("vbscript.regexp")  
   .Global = True: .Pattern = "[^0-9]"
   For i = 1 To UBound(x)  
       x(i, 1) = .Replace(x(i, 1), "")  
   Next  
End With  
Range("B2", Cells(Rows.Count, 2).End(xlUp)).Value = x  
End Sub
 
Function onlyNum$(rng As Range)  
   With CreateObject("VBScript.RegExp")  
       .Global = True: .IgnoreCase = True: .MultiLine = True: .Pattern = "\D+"  
       onlyNum = .Replace(rng.Value, "")  
   End With  
End Function
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
Может, это подойдёт:  
Function ИЗВЛЕЧЬ_ЦЕЛЫЕ(ParamArray Диапазон())  
'---------------------------------------------------------------------------------------  
' Author       : Alex_ST, v__step, nerv  
' URL          : http://www.excelworld.ru/forum/3-1012-12791-16-1324630051  
' Topic        : Функция (UDF) "ИЗВЛЕЧЬЦЕЛЫЕ"  
' Purpose      : Создать массив из целых чисел, извлечённых из текста произвольно расположенных диапазонов ячеек  
' Notes        : К полученному массиву можно применять любые стандартные формулы листа  
'---------------------------------------------------------------------------------------  
  Dim rArea, rCell, sStr$, oMatches, i&, Arr()  
  On Error GoTo xlErrEXIT  
  For Each rArea In Диапазон  
     For Each rCell In IIf(rArea.Count = 1, Array(rArea.Value), rArea.Value)  
        sStr = sStr & " " & rCell  
     Next rCell  
  Next rArea  
  With CreateObject("VBScript.RegExp"): .Global = True: .Pattern = "\d+": Set oMatches = .Execute(sStr): End With  
  If oMatches.Count = 0 Then ИЗВЛЕЧЬ_ЦЕЛЫЕ = CVErr(xlErrNA): Exit Function      ' вернуть ошибку #Н/Д если чисел нет  
  '   If oMatches Is Nothing Then ИЗВЛЕЧЬ_ЦЕЛЫЕ = CVErr(xlErrNA): Exit Function   ' вернуть ошибку #Н/Д если чисел нет  
  ReDim Arr(1 To oMatches.Count)  
  For i = 0 To oMatches.Count - 1: Arr(i + 1) = CLng(oMatches(i).Value): Next i  
  ИЗВЛЕЧЬ_ЦЕЛЫЕ = Arr  
xlErrEXIT:    If Err Then ИЗВЛЕЧЬ_ЦЕЛЫЕ = CVErr(xlErrValue)   ' вернуть ошибку #ЗНАЧ! если была ошибка  
End Function
С уважением, Алексей (ИМХО: Excel-2003 - THE BEST!!!)
 
из любопытства потестировал (экс у меня 2003, поэтому на 50000 значений)  
 
Sub x()  
 Const lim& = 50000  
 Dim a$(1 To lim, 1 To 1), b(), c(), s$, s2$, i&, j%, t&, re As Object  
 t = GetTickCount  
 For i = 1 To lim  
   s = ""  
   For j = 1 To Rnd() * 12 + 3  
     s = s & Chr(Rnd() * 30 + 40)  
   Next  
   a(i, 1) = s  
 Next  
 Sheets(1).[a1].Resize(lim) = a
 Debug.Print GetTickCount - t  
   
 Erase a  
 b = Sheets(1).[a1].Resize(lim).Value
   
 t = GetTickCount  
 ReDim c(1 To lim, 1 To 1)  
 For i = 1 To lim  
   s = b(i, 1): s2 = ""  
   For j = 1 To Len(s)  
     If Mid(s, j, 1) Like "#" Then s2 = s2 & Mid(s, j, 1)  
   Next  
   c(i, 1) = s2  
 Next  
 Sheets(1).[b1].Resize(lim) = c
 Debug.Print GetTickCount - t  
   
 Set re = CreateObject("vbscript.regexp")  
 With re  
   .Global = True  
   .Pattern = "\D+"  
 End With  
   
 t = GetTickCount  
 ReDim c(1 To lim, 1 To 1)  
 For i = 1 To lim  
   c(i, 1) = re.Replace(b(i, 1), "")  
 Next  
 Sheets(1).[c1].Resize(lim) = c
 Debug.Print GetTickCount - t  
End Sub  
 
у меня время одинаковое, с точностью до тика :)
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Private Declare Function GetTickCount Lib "kernel32" () As Long  
 
конечно же )
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Какой-то длинный код получился
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
1) заполнить диапазон тестовыми значениями - для чистоты эксперимента случайными  
2) обработать без помощи регулярок  
3) обработать с помощью регулярок  
 
и чего в нем лишнее? :)
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Да всё Ок, код супер :)  
Просто RegExp сам по себе на больших объёмах долго обрабатывает данные, так что скорость тут сравнивать незачем, это ведь не словарь :)
Киса, я хочу Вас спросить, как художник — художника: Вы рисовать умеете?
 
так в том-то и фокус :)  
regexp в данном случае работает ровно столько же времени, что и встроенный вба-шный like (который, правда, тоже быстрым назвать нельзя:)  
 
вероятно, регулярка слишком простая.
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
У меня тики разные:  
 
1516    
1219    
1156    
 
1766    
1187    
1172    
 
1531    
1203    
1125    
 
1672    
1218    
1141    
 
Регулярка чуть быстрее.
 
>> Какой-то длинный код получился  
Богдан, Саша - предлагаю просмотреть тему:  
http://www.programmersforum.ru/showthread.php?p=1122950#post1122950  
Это как комментарий к вопросу длины и простоты кода. Блестящий пример от Алексея(Казанский). Его длинный и усложненный код, против моего короткого и простого. На десятке строк разницы не увидишь, а на серьезном объеме он меня в асфальт закатает:-) Так что иной раз простота хуже воровства...
Я сам - дурнее всякого примера! ...
 
посмотрел. :)  
в общем-то, это давным-давно известно, что короткий и красивый код совсем необязательно будет быстрым (даже, скорее, наоборот).  
 
но, кажется, я ничего не понял :(  
в той теме основное, от чего избавлялся Алексей - многократное создание и определение объекта.    
у меня это тоже вынесено из цикла.  
 
а на том, чтобы не проверять ссылку на Nothing (каждый раз), а пытаться обратиться к "пустому" объекту (один раз), перехватить обработчик ошибок и т.д. - вряд ли много сэкономишь. даже на большом объеме. хотя...  
можно и потестировать.  
но, чувствую я, разница будет в пределах статистического шума :)
фрилансер Excel, VBA - контакты в профиле
"Совершенствоваться не обязательно. Выживание — дело добровольное." Э.Деминг
 
Всем спасибо за советы!  
Удалил все ненужное сам =) Код вполне рабочий вышел.
Страницы: 1
Читают тему
Наверх
Loading...