Extract all numbers in an expression

ChewCS

New Member
Joined
Jun 17, 2022
Messages
15
Office Version
  1. 2016
Platform
  1. Windows
Hi, I would like to seek assistance from this forum in a certain task.

I have a cell with an expression that includes ranges of numbers. Something like "1-3,13,15-17". I would like to have a VBA function that extracts all the numbers within this single expression and store them in an array. Something like

array(1,1) is 1, array(1,2) is 2, array(1,3) is 3, array(1,4) is 13, array(1,5) is 15, array(1,6) is 16, array(1,7) is 17.

Is it possible?

Thanks in advance!
 
Add this line
VBA Code:
ReDim Preserve ary(1 To 1, 1 To X)
'enter array values in the range
after
Next T

Thanks, it works :) I suppose ary now holds the array of numbers.

If I have an existing array that is holding the strings, will S be defined like this? Assuming "1-3,13,15-18" is at inArray(5 , 1),

S = inArray(5 , 1)
 
Upvote 0

Excel Facts

What does custom number format of ;;; mean?
Three semi-colons will hide the value in the cell. Although most people use white font instead.
Hi guys, thank you so much for your advice :) I too am resting. Will provide the code as soon as I can. Basically, I am reading a file with rows of data, and one such column consists of the strings that I mention. And I wish to convert this unusable string into an array of integers. The size of this array is definite, because the integers from the string can only go up to 18.

"array(1,1) is 1, array(1,2) is 2, array(1,3) is 3, array(1,4) is 13, array(1,5) is 15, array(1,6) is 16, array(1,7) is 17."
 
Upvote 0
Perhaps you could use the XL2BB add-in to give us an example of what your data looks like and what the result you want looks like?


Example:
Book1
ABCDEFGHI
1File DataResult 1Result 2->
21-3,13,15-171,2,3,13,15,16,1712313151617
Sheet1


VBA Code:
Sub MakeArray()
    
    Dim WS As Worksheet
    Dim I As Long, J As Long
    Dim NS As String
    Dim SA, SB, MyArray
    
    NS = Range("A2").Value
    
    SA = Split(NS, ",")
    NS = ""
    For I = 0 To UBound(SA)
        If InStr(SA(I), "-") > 0 Then
            SB = Split(SA(I), "-")
            For J = SB(0) To SB(1)
                NS = NS & J & ","
            Next J
        Else
            NS = NS & SA(I) & ","
        End If
        Erase SB
    Next I
    Erase SA
    
    NS = Left(NS, Len(NS) - 1)
    MyArray = Split(NS, ",")
    
    'Result 1
    Range("B2").Value = NS
    
    'Result 2
    For I = 0 To UBound(MyArray)
        Range("C2").Offset(0, I).Value = MyArray(I)
    Next I
End Sub
 
Upvote 0
Will provide the code as soon as I can. Basically, I am reading a file with rows of data, and one such column consists of the strings that I mention. And I wish to convert this unusable string into an array of integers. The size of this array is definite, because the integers from the string can only go up to 18.

"array(1,1) is 1, array(1,2) is 2, array(1,3) is 3, array(1,4) is 13, array(1,5) is 15, array(1,6) is 16, array(1,7) is 17."
You now have 3 options for step 1 but we look forward to getting more information for you for step 2 eg existing code, examples of input and output

Based on you already having an array using a line counter of k and that you are processing lines 1 at a time you could as you suggested but the whole code inside a loop that increments using "k".Replacing where we are referring to a call with you array element value. In my case that includes having the Redim command inside your k loop since it needs to be evaluated on each row.
You say the "The size of the array is definite" aren't you actually saying that it is limited to 18 eg one value 1-18 being the max and as you split it out into separate groups with gaps it reduces.
On a line by line basis this is fine if it is in the last column but what do you want it to do if it is not the last column and it has to push columns out as the number of values changes.

eg Col1 1 2 3 13 15 16 17 Col9
Col1 4 6 9 18 Col6
Col1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Col20
 
Upvote 0
VBA Code:
Dim inArray() As Variant

ref = "A1:B10"     'defined size
path = Application.ThisWorkbook.path & "\"
file = "test.xlsx"
sheet = "Sheet1"
arg = "'" & path & "[" & file & "]" & sheet & "'!" & ref

With Range(ref)
    .FormulaArray = "=" & arg
    .Value = .Value
End With

inArray = Range(ref)

This is how I would read in an input file, which looks like this:
DayTimeDurationModuleWeeks
Mon8:301:30ME14011-6,11,13,15,17
Tue9:302:00ME21012,4,6,12,14,16,18

It is basically a timetable data file meant for identifying clashes of time slots. And I wish to eventually assign all the data under a 2D array which I can run my search with. However, I cannot search with the Weeks column in such a string format. Therefore I would like to convert to something like this:

DayTimeDurationModuleWeek 1Week 2....Week 11Week 12Week 13Week 14...
Mon8:301:30ME1401111010
Tue9:302:00ME2101010101

My original question was for the conversion part so that I can eventually end up with this 2D array.
 
Upvote 0
Day​
Time​
Duration​
Module​
Weeks​
123456789101112131415161718192021
Mon​
08:30​
01:30​
ME1401​
1-6,11,13,15,17​
111111000010101010000
Tue​
09:30​
02:00​
ME2101​
2,4,6,12,14,16,18​
010101000001010101000
Note the change in Row1. Only week numbers are entered.
UDF in F2 then copied to full range

=MarkWeekNum($E2,F$1)

code for UDF 'MarkWeekNum'
VBA Code:
Function MarkWeekNum(S As String, k As Integer) As Long
Dim M, N, P
Dim T As Long, Ta As Long
P = Split(Replace(S, "-", ","), ",")

If Val(P(0)) > k Then GoTo Line1

M = Split(S, ",")
For T = 0 To UBound(M)
If InStr(1, M(T), "-") > 0 Then
N = Split(M(T), "-")
    For Ta = Val(N(0)) To Val(N(UBound(N)))
    If k < Ta Then
    GoTo Line1
    ElseIf k = Ta Then
    MarkWeekNum = 1: GoTo Line1
    End If
    Next Ta
Else
If k < Val(M(T)) Then
GoTo Line1
ElseIf k = Val(M(T)) Then
MarkWeekNum = 1: GoTo Line1
End If
End If
Next T
Line1:
End Function
How to Use UDF code:
In the developer tab click--> Visual Basic
VB window opens
Insert--> Module
Paste the code.
Close the VB window.
Now UDF is available in Function List
Save file as .xlsm
 
Upvote 0
Day​
Time​
Duration​
Module​
Weeks​
123456789101112131415161718192021
Mon​
08:30​
01:30​
ME1401​
1-6,11,13,15,17​
111111000010101010000
Tue​
09:30​
02:00​
ME2101​
2,4,6,12,14,16,18​
010101000001010101000
Note the change in Row1. Only week numbers are entered.
UDF in F2 then copied to full range

=MarkWeekNum($E2,F$1)

code for UDF 'MarkWeekNum'
VBA Code:
Function MarkWeekNum(S As String, k As Integer) As Long
Dim M, N, P
Dim T As Long, Ta As Long
P = Split(Replace(S, "-", ","), ",")

If Val(P(0)) > k Then GoTo Line1

M = Split(S, ",")
For T = 0 To UBound(M)
If InStr(1, M(T), "-") > 0 Then
N = Split(M(T), "-")
    For Ta = Val(N(0)) To Val(N(UBound(N)))
    If k < Ta Then
    GoTo Line1
    ElseIf k = Ta Then
    MarkWeekNum = 1: GoTo Line1
    End If
    Next Ta
Else
If k < Val(M(T)) Then
GoTo Line1
ElseIf k = Val(M(T)) Then
MarkWeekNum = 1: GoTo Line1
End If
End If
Next T
Line1:
End Function
How to Use UDF code:
In the developer tab click--> Visual Basic
VB window opens
Insert--> Module
Paste the code.
Close the VB window.
Now UDF is available in Function List
Save file as .xlsm
Thanks for this udf, it works :)
However, I am thinking of the entire process and the additional steps required to implement this udf.

As of now, my original code lies in a Command Button. Upon clicking, the code reads the input file, does the conversion and everything will be in a 2D array, which I will write the rest of my decision scripts to report time slot clash or no clash, etc.

With this udf, I will have to take the input file, copy the data onto this .xlsm, run the udf, and then invoke the Command Button to run the decision scripts. This will eventually be run by a user who will not be familiar with the vba scripts, and I'm trying to reduce the effort required.
 
Upvote 0
Are the headings already in your input file ? Can we assume there will be 18 weeks and set up the headings for 18 weeks in the code ?
 
Upvote 0
Are the headings already in your input file ? Can we assume there will be 18 weeks and set up the headings for 18 weeks in the code ?
The headings are not in the input file, but it's no big issue. What I really want is the 2D array with rows of data such as day, time, duration, etc. I can read those from the input file, but I will convert the "Weeks" string into 18 columns (yes 18 is fixed) of 1 or 0 and append them to the end of the 2D array.
 
Upvote 0

Forum statistics

Threads
1,223,264
Messages
6,171,081
Members
452,377
Latest member
bradfordsam

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top