I'm new at this. I want to create an array of 16 elements. Let's say that my array is ReDim arr(15) as Integer and in that array I want to put the numbers from 1 to 16 but scrambled, for example arr(0) = 3, arr(5) = 8 and so on.
Asked
Active
Viewed 8,690 times
1
-
`arr(15)` only gives you 15 elements. – findwindow Nov 04 '15 at 23:53
-
1So...have you tried anything – Scott Craner Nov 04 '15 at 23:55
-
3`arr(15)` (aka `arr(0 to 15)`) gives 16 elements. – Nov 04 '15 at 23:56
-
I thought the number gives you number of elements so arr(15) would be 0-14? But Jeeped is always right ^_^; Edit: ah, the number is upperbound not elements. But if you have option base of 1, then it's elements =P Edit2: so I have been doing it all wrong XD – findwindow Nov 04 '15 at 23:57
-
Yeah, if just a single value is in the brackets, it treats it as the upper bound, with 0 as the lower bound. – Andy Wynn Nov 05 '15 at 00:01
-
Possible [duplicate](http://stackoverflow.com/questions/18543169/unique-random-numbers-using-vba)? – findwindow Nov 05 '15 at 00:03
2 Answers
2
Give this a try:
Sub MAIN()
Dim ary(1 To 16) As Variant
Dim i As Long, msg As String
For i = 1 To 16
ary(i) = i
Next i
Call Shuffle(ary)
msg = ""
For i = 1 To 16
msg = msg & vbCrLf & ary(i)
Next i
MsgBox msg
End Sub
Sub Shuffle(InOut() As Variant)
Dim HowMany As Long, i As Long, J As Long
Dim tempF As Double, temp As Variant
Hi = UBound(InOut)
Low = LBound(InOut)
ReDim Helper(Low To Hi) As Double
Randomize
For i = Low To Hi
Helper(i) = Rnd
Next i
J = (Hi - Low + 1) \ 2
Do While J > 0
For i = Low To Hi - J
If Helper(i) > Helper(i + J) Then
tempF = Helper(i)
Helper(i) = Helper(i + J)
Helper(i + J) = tempF
temp = InOut(i)
InOut(i) = InOut(i + J)
InOut(i + J) = temp
End If
Next i
For i = Hi - J To Low Step -1
If Helper(i) > Helper(i + J) Then
tempF = Helper(i)
Helper(i) = Helper(i + J)
Helper(i + J) = tempF
temp = InOut(i)
InOut(i) = InOut(i + J)
InOut(i + J) = temp
End If
Next i
J = J \ 2
Loop
End Sub

Gary's Student
- 95,722
- 10
- 59
- 99
1
Here is some very lazy code:
Dim arr(15) As Integer
Dim i As Integer, j As Integer
i = 1
Do
j = Int(16 * Rnd)
If arr(j) = 0 Then
arr(j) = i
i = i + 1
End If
Loop Until i = 17
Rnd generates a single
from 0 to 1, multiply that by 16 and strip the decimal portion with Int
and it will give you a random number from 0 to 15.
It isn't efficient, I wouldn't use this in production, but it'll do the job.
Hope this helps!

Andy Wynn
- 1,171
- 7
- 11
-
No it wont, I thought of that in this code. If the rnd function returns a value that has already been used, it will just restart the loop. – Andy Wynn Dec 02 '15 at 13:54
-
You are correct, I apologize and will delete my comment. I missed the if statement. This works great for the requested small subset. I would be interested in knowing the average number loops to get them all filled. By the odds there is a chance of an infinite loop if the subset got to large. That is not what was asked, and this small of a subset would not run that risk. – Scott Craner Dec 02 '15 at 14:17
-
1Yeah, as I said it isn't great code but it'll do the job here of you are only going to use it for small sets. I ran it 500 times and it took an average of 35 loops to complete, but all 500 took less than a second, so I'm not too worried. If this was code for a serious production I would write it properly. – Andy Wynn Dec 03 '15 at 15:12