For the VBA side of things (note the loops), I decided to satisfy my own curiosity about the performance of a couple different methods. All of them pull the range into an array and work on it in place. The linked article will get killed in speed by any of these, simply due to the overhead in reading and writing single cell values.
For the first method, I optimized the code from the linked article "a bit":
Private Sub MidMethod(values() As Variant)
Dim r As Long, c As Long, i As Long
Dim temp As String, output As String
For r = LBound(values, 1) To UBound(values, 1)
For c = LBound(values, 2) To UBound(values, 2)
output = vbNullString
For i = 1 To Len(values(r, c))
temp = Mid$(values(r, c), i, 1)
If temp Like "[0-9]" Then
output = output & temp
End If
Next
values(r, c) = output
Next
Next
End Sub
For the second method I used RegExp.Replace
:
Private Sub RegexMethod(values() As Variant)
Dim r As Long, c As Long, i As Long
With New RegExp
.Pattern = "[^0-9]"
.MultiLine = True
.Global = True
For r = LBound(values, 1) To UBound(values, 1)
For c = LBound(values, 2) To UBound(values, 2)
values(r, c) = .Replace(values(r, c), vbNullString)
Next
Next
End With
End Sub
Finally, for the last method I used a Byte
array:
Private Sub ByteArrayMethod(values() As Variant)
Dim r As Long, c As Long, i As Long
Dim chars() As Byte
For r = LBound(values, 1) To UBound(values, 1)
For c = LBound(values, 2) To UBound(values, 2)
chars = values(r, c)
values(r, c) = vbNullString
For i = LBound(chars) To UBound(chars) Step 2
If chars(i) > 47 And chars(i) < 58 Then
values(r, c) = values(r, c) & Chr$(chars(i))
End If
Next
Next
Next
End Sub
Then I used this code to benchmark them against 1000 cells, each containing a random mix of 25 letters and numbers:
Private Sub Benchmark()
Dim data() As Variant, start As Double, i As Long
start = Timer
For i = 1 To 5000
data = ActiveSheet.Range("A1:J100").Value
MidMethod data
Next
Debug.Print "Mid: " & Timer - start
start = Timer
For i = 1 To 5000
data = ActiveSheet.Range("A1:J100").Value
RegexMethod data
Next
Debug.Print "Regex: " & Timer - start
start = Timer
For i = 1 To 5000
data = ActiveSheet.Range("A1:J100").Value
ByteArrayMethod data
Next
Debug.Print "Byte(): " & Timer - start
End Sub
The results weren't horribly surprising - the Regex method is by far the fastest (but none of them are what I'd call "fast"):
Mid: 24.3359375
Regex: 8.31640625
Byte(): 22.5625
Note that I have no idea how this compares to @SiddharthRout's cool formula method in that I can't run it through my testing harness. The www.extendoffice.com code would also probably still be running, so I didn't test it.