Excel VBA - For Loop with specific values - vba

I'm trying to create a For Loop that only selects some values but can't work out the Syntax, or if it's even possible?
I want it to be like
Dim i As Integer
For i = 1,3,8,15 Then
Do something
Next i
Any Ideas?

Try
Sub Demo()
Dim indexArr As Variant
Dim i As Long
indexArr = Array(1, 3, 8, 15)
For i = LBound(indexArr) To UBound(indexArr)
Debug.Print indexArr(i)
Next i
End Sub

You can do following:
Dim i as Variant
Dim iArray as Variant
iArray=Array(1,3,8,15)
For Each i In iArray
'Do Something
Next i
Cheers

You can't.
If there is a pattern you can use Step
For i = 1 to 15 Step 2
Which will do 1,3,5,7,...
In this case since there is no pattern you will need to add an If or Select Case:
Dim i As Integer
For i = 1 to 15 Then
Select Case i
Case 1,3,8,15
'Do Something
End Select
Next i

You can use if statement:
Dim i As Integer
For i = 1 To 15 Then
If i = 1 or i = 3 or i = 8 or i = 15 Then
'Do something
End If
Next i
Hope this help.

This solution combines elements from the array solution above with the ease of use that I inferred was wanted by the OP. The array method requires looping through the array elements and then converting the array element back into a variable. This method skips 2 bits. Firstly, it skips the complex step logic of stepping through array elements. Secondly, it skips the step of converting an array element back into a usable variable.
Dim number_list as collection
set number_list = new collection
number_list.add 1
number_list.add 3
number_list.add 8
number_list.add 15
for each number in number_list
'Do something with number
Next number

This is even a simplification of the routine of Kedimir:
Original question:
Dim i As Integer
For i = 1,3,8,15 Then
' Do something
Next i
Solution:
Dim i As Variant
For Each i In Array(1, 3, 8, 15)
' Do something
Next i
For your information: the Variant is needed for the For Each loop, don't try to modify it into an integer, or the For Each loop won't be accepted.
I don't think that a more resembling solution is possible :-)

Related

VBA UBound Function

I'm trying to explore UBound applications for my code in Visual Basic for Applications (VBA). Let's say I have a 4 by 2 array...(A1:B4) and I want to count the number of rows. I would think my code would be...
Function test(list) As Double
test = UBound(list)
End Function
My input is =test(A1:B4)but so far I get "#value!" error. I thought the return would be 4.
What am I doing wrong? I know how to get the number of rows using the row command but I simply want to go through the coding exercise.
List is range object not an array. Range.Value will return an array of values from a range and Range.Formula will return an array of formulas from a range.
Function test(list As Range) As Double
test = UBound(list.Value)
End Function
It seems that you have 2-dimensional array, therefore you have to provide additional parameter for UBound like:
UBound(array, dimension)
Please remember, if you get array from Excel Range than it is 1-based array.
Complete solution can look like this one:
Function testArrray(List, Dimmension)
Dim ListConverted As Variant
ListConverted = List
testArrray = UBound(ListConverted, Dimmension)
End Function
Sample call: =testArrray(G15:H20,1) produces 6 as a result which is correct.
Since you do not Dim list explicitly, it is Variant. So if you call =TEST(A1:B4) it will be a Range and not an Array. A Range does not have a UBound but does have Rows.Count.
So:
Function test(list As Range) As Double
test = list.Rows.Count
End Function
will work.
Or if you really need an Array, you could do:
Function test(list As Variant) As Double
list = list
test = UBound(list)
End Function
The list = list does the following: If list is a Range-Object then it will be implicit converted to Array since Set is not used to set an object. If list is an Array already, then it will be also an Array after that.
This is how you get the number of rows in a function.
Option Explicit
Function l_number_of_rows(rng_range As Range) As Long
l_number_of_rows = rng_range.Rows.Count
End Function
if you want the one from the dimension, this is a possible solution.
Sub test()
Dim MyArray(1 To 2, 0 To 3) As Long
MyArray(1, 0) = 10
MyArray(1, 1) = 11
MyArray(1, 2) = 12
MyArray(1, 3) = 13
MyArray(2, 0) = 20
MyArray(2, 1) = 21
MyArray(2, 2) = 22
MyArray(2, 3) = 23
Debug.Print MyArray(UBound(MyArray), 3)
End Sub
The UBound function is to give you elements in a variant array, you're passing it a range. You could try this:
Sub mains()
Dim myRange As Range, myArray As Variant
Set myRange = Range("A1:B4")
myArray = myRange.Value
Debug.Print test(myArray)
End Sub
Function test(list) As Double
test = UBound(list)
End Function
EDIT With a two dimensional range (as mentioned by KazimierzJawor) the default ubound will be the vertical, as you wanted, if you want to specify, you can add the optional perameter UBound(list, 1), but with the data you specified this defults to 4 as you wished
Ubound is a function that works on arrays you are passing it a range
try this
dim i(3)
i(0) = 1
i(1) =2
i(2) = 3
msgbox ubound(i)

VBA iterate through variant which has 2 columns

Was searching for a while, but cannot find a proper answer. I working on a variant and I used a solution provided below:
http://www.mrexcel.com/forum/excel-questions/305870-eliminate-duplicated-visual-basic-applications-array.html
So what I have is basically a variant which then beeing redimed without duplicates. It works fine if you use just one column from sheet so the variant variable has only 1 column as well.
The data I'm working on needs to be checked for 2 columns, while in the for each loop I would like to refer only to 2nd column:
Dim mgNames As Variant
Range(Cells(1, "I"), Cells(Range("a1").End(xlDown).Row, "J")).Select
mgNames = Selection
Dim myCollection As New Collection
Dim temp As Variant
On Error Resume Next
For Each temp In mgNames
myCollection.Add Item:=temp, Key:=temp
Next temp
On Error GoTo 0
ReDim mgNames(1 To myCollection.Count)
For temp = 1 To myCollection.Count
mgNames(temp) = myCollection(temp)
Next temp
so in part For Each temp In mgNames code takes each value in variant, ex mgnames(1,1) then mgnames(1,2) and so on. I would like to iterate this only for 2nd column, so from (1,2) (2,2), (3,2)...
If anyone is able to help with this it would be great
You don't have to loop through the array with For Each, you can use a normal For, as in
Dim i As Long
...
For i = LBound(mgNames,1) To Ubound(mgNames,1)
myCollection.Add Item:=mgNames(i,2), Key:=mgNames(i,2)
Next i
...

I am looking for dim mutiple variables in the for loop

Can I do this?
For i = 1 To 127
Dim cell&i as Range
Next
Because I have a lot of cells need to dim.
No, you can't.
Try using an array instead:
Dim nCells As Long
Dim myCells() As Range 'store them in an array
nCells = 127
ReDim myCells(1 To nCells)
For i = 1 To nCells
Set myCells(i) = Range("A1").Offset(i,i) ' or whatever...
Next i
Maybe you should show us what you are trying to achieve exactly. This pattern looks a bit unusual.

Variables in VBA loops

I'm trying to run a VBA application using a loop and using variables whose names depends on where in the loop I am. Specifically something like
Dim i As Integer
i = 1
Dim varname() As String
while i < 50
varname(i) = asdasd
i = i + 1
Wend
Somehow it can't read varname(i) or whatever. It reports subscript out of range.
I have no idea what the problem is, can someone helt me perhaps?
You need to give your array a capacity first.
Sub max()
Dim i As Integer
i = 1
Dim varname() As String
ReDim varname(49) '<---- There
While i < 50
varname(i) = asdasd
i = i + 1
Wend
End Sub
This is a good resource for VBA arrays:
http://msdn.microsoft.com/en-us/library/office/aa164778(v=office.10).aspx

Visual Basic Fill Array with simple number set

I need to fill an array with numbers 1-50, and I currently have the code:
Dim numberSet(49)
For x = 1 To 50
numberSet(x - 1) = x
Next x
The challenge is to do it in the least amount of lines possible. This part is bugging me because it seems like i shouldn't be using 4 lines for something so basic.
Any thoughts from you guys? I want to avoid doing something like = {1,2,3,4,5...50} if I can. Thanks!
In one line:
Dim numberSet(49): For x = 1 To 50: numberSet(x - 1) = x: Next x
One line (but it creates a 1-based array...)
Sub TT()
Dim arr
arr = Application.Transpose([=ROW(A1:A50)])
Debug.Print UBound(arr)
Debug.Print arr(1)
Debug.Print arr(13)
End Sub
...and if you turn off Option Explicit you can skip the declaration. But don't do that ;-)