VBA random numbers generator with required sum

motilulla

Well-known Member
Joined
Feb 13, 2008
Messages
2,422
Office Version
  1. 2010
VBA random numbers generator with required sum </SPAN></SPAN>

I need a VBA that can choose 7 random numbers out of 3 numbers, which are listed in the cells A4:A6 </SPAN></SPAN>

Create for example 50 random in the cells F4:L53 without repetitions (I mean 2 rows should not be the same) as per each row sum is as assigned in the column M, is it possible? (Sum can be vary from 0 to 14)</SPAN></SPAN>

In the example below some set are shown with row sum=7 </SPAN></SPAN>


Book1
ABCDEFGHIJKLM
1
2
3Total Numbersn1n2n3n4n5n6n7SUM
4021001127
5111112107
6201121207
712002117
811201027
920112017
1002110127
1101111127
1211120117
1302111207
1411220017
1510200227
1610012127
1710121117
1821111017
1912012107
2011021117
2112120107
2201112117
2302011127
2411121107
2500112217
2610210127
2711111207
2812200117
2910112117
3001121117
3112111017
3201120127
3312021107
3411111117
3521110027
3622101017
3711102117
3801112027
3902020217
4011120027
4111110217
4220211107
4310221107
4421020117
4511210207
4622100117
4711210117
4810211027
4911211107
5021201017
5122100027
5212110207
5311101217
Sheet1


Thank you all</SPAN></SPAN>

Excel 2000</SPAN></SPAN>
Regards,</SPAN></SPAN>
Moti</SPAN></SPAN>
 
Last edited:
Or try:
Code:
Public Sub MyRandom()
Dim arr(1 To 7)
Dim i As Long
Dim mySum As Long
Randomize
Do While mySum <> 7
mySum = 0
    For i = 1 To 7
        arr(i) = Int(Rnd() * 3)
        mySum = mySum + arr(i)
    Next
Loop
Range("A1:G1") = arr


End Sub
Thank you Phuoc, for your help, yes this code generate with sum 7 but only one line each time I want it generate all as per post#1</SPAN></SPAN>

Regards,</SPAN></SPAN>
Moti</SPAN></SPAN>
 
Upvote 0

Excel Facts

Select all contiguous cells
Pressing Ctrl+* (asterisk) will select the "current region" - all contiguous cells in all directions.
VBA random numbers generator with required sum

I need a VBA that can choose 7 random numbers out of 3 numbers, which are listed in the cells A4:A6

Create for example 50 random in the cells F4:L53 without repetitions (I mean 2 rows should not be the same) as per each row sum is as assigned in the column M, is it possible? (Sum can be vary from 0 to 14)

Regards,
Moti

Ok, try this:
Some part of this code is using Phuoc's code above.

Code:
Sub a1079591a()
'https://www.mrexcel.com/forum/excel-questions/1079591-vba-random-numbers-generator-required-sum.html
Dim arr(1 To 7), d As Object
Dim i As Long, j As Long, k As Long
Dim dSum As Long, txt As String
Randomize
n = 1000
Set d = CreateObject("scripting.dictionary")
ReDim va(1 To n, 1 To 7)
Do
    dSum = 0
    For i = 1 To 7
        arr(i) = Int(Rnd() * 3)
        dSum = dSum + arr(i)
    Next
    If dSum = 7 Then
    txt = ""
        For i = 1 To 7
            txt = txt & arr(i)
        Next
        
        If Not d.Exists(txt) Then
            d(txt) = ""
            j = j + 1
                For i = 1 To 7
                    va(j, i) = arr(i)
                Next
        End If
    End If
    k = k + 1
Loop Until j = n Or k > 100000
Range("A1").Resize(UBound(va, 1), 7) = va

End Sub
 
Last edited:
Upvote 0
I edited the above code.
I added this line:
txt = ""
 
Upvote 0
VBA random numbers generator with required sum

I need a VBA that can choose 7 random numbers out of 3 numbers, which are listed in the cells A4:A6 ... is it possible? (Sum can be vary from 0 to 14)

Adding a requirement that the sum of each row must be the same as all the other rows changes the nature of the exercise. You are no longer asking to randomly generate a seven number set, since a set of numbers cannot be random if you constrain the sum of those numbers. Rather it becomes an execise of determing unique combinations of 7 numbers using a 3 number set, that all have the same sum. Using any sort of random number generation will hinder that, since the only way to use randomly generated numbers to produce a desired sum is to iterate and hope for the best. The modifed code below will do that for small table sizes, but if you increase the number of rows, then the number of iterations required will quickly become large.

Code:
Sub DoSomething()
    Dim WS As Worksheet
    Dim RangeOfCells As Range, RR As Range, RC As Range
    Dim I As Long, RSum As Long
    Dim S As String
    Dim SD As Object
    Dim DoNextRow As Boolean

    Set WS = ActiveSheet
    Set SD = CreateObject("Scripting.dictionary")
    Set RangeOfCells = WS.Range("F4:L53")             'Your example range

    Application.ScreenUpdating = False
    For Each RR In Intersect(RangeOfCells.Columns(1), RangeOfCells)
        I = 0
        S = ""
        Do
            RSum = 0
            For Each RC In Intersect(RR.EntireRow, RangeOfCells)
                RC.Value = Application.WorksheetFunction.RandBetween(0, 2)
                RSum = RSum + RC.Value
                S = S & RC.Value
            Next RC

            DoNextRow = (RSum = 7) And Not SD.exists(S)
            If DoNextRow Then
                SD.Add S, 0                           'Unique row
            End If
            I = I + 1
            S = ""
        Loop Until DoNextRow Or I > 5000              'I > 5000 is to prevent a runaway loop.
    Next RR
    Set SD = Nothing
    Application.ScreenUpdating = True
End Sub
 
Upvote 0
I took the challenge to come up with something but it's far from bullet proof. I'm stuck at comparing the results so that there are no duplicates. Perhaps someone can tackle that

Prints the result to the immediate window of the visual basic editor.
Code:
Sub RandomNumbers()
Dim lngLower, lngUpper, x, r, c As Long
Dim MyArray(0 To 6) As Long

lngLower = 0
lngUpper = 2

For x = 1 To 53
    Do While WorksheetFunction.Sum(MyArray) <> 7
        For r = 0 To 6
            MyArray(r) = Evaluate("RandBetween(" & lngLower & "," & lngUpper & ")")
        Next r
    Loop
    
    For c = 0 To 6
        Debug.Print MyArray(c);
    Next c
    
    Debug.Print "= " & WorksheetFunction.Sum(MyArray)
    
    Erase MyArray
Next x
End Sub
 
Upvote 0
Ok, try this:
Some part of this code is using Phuoc's code above.

Code:
Sub a1079591a()
'https://www.mrexcel.com/forum/excel-questions/1079591-vba-random-numbers-generator-required-sum.html
Dim arr(1 To 7), d As Object
Dim i As Long, j As Long, k As Long
Dim dSum As Long, txt As String
Randomize
n = 1000
Set d = CreateObject("scripting.dictionary")
ReDim va(1 To n, 1 To 7)
Do
    dSum = 0
    For i = 1 To 7
        arr(i) = Int(Rnd() * 3)
        dSum = dSum + arr(i)
    Next
    If dSum = 7 Then
    txt = ""
        For i = 1 To 7
            txt = txt & arr(i)
        Next
        
        If Not d.Exists(txt) Then
            d(txt) = ""
            j = j + 1
                For i = 1 To 7
                    va(j, i) = arr(i)
                Next
        End If
    End If
    k = k + 1
Loop Until j = n Or k > 100000
Range("A1").Resize(UBound(va, 1), 7) = va

End Sub
Thank you Akuini, tried you code it generate with sum 7 all possible unique combinations total 393, (and changing the value in this line-->"If dSum = 7 Then " 0 to 14" also it gives me all unique possible sets with each sum that I find it is very useful.</SPAN></SPAN>

Coming to my query, which is not quite clear in the opening post#1, lets re take it...
</SPAN></SPAN>
1- I wanted that code generate only the unique set as long as specific sum value finds in the column M
</SPAN></SPAN>
2- of course if code generate with 7 values as per column M then if I will replace 6, 5, 4, 3 or any between (0 to 14) it will make all the row with the specific assigned sum
</SPAN></SPAN>
It is my fault did not explain very well I am sorry about that.
</SPAN></SPAN>

Here I will try to explain again what I wanted might this help... example below shows in the column M4:M53 there are different sum vales in order 0 to 14, I want to generate each row combination as per sum M column--> row 4 sum = 0, row 5&6 sum = 1, 7&8 sum = 3 and so on...for next row,
</SPAN></SPAN>
And generate all rows as long as sum find in the M Column
</SPAN></SPAN>


Book1
ABCDEFGHIJKLM
1
2
3Total Numbersn1n2n3n4n5n6n7SUM
4000000000
5100000101
6200100001
701010002
811000013
920010003
1000012104
1120200004
1211021005
1312020005
1421200016
1501101216
1620112006
1711111106
1810211106
1921121007
2011111027
2112201017
2200121127
2312201107
2410012217
2511101127
2612200218
2711220118
2811122018
2921121108
3022202008
3120002228
3200121228
3302212209
3412200229
3522101129
3602120229
3711221029
3810122219
39220212110
40221220110
41212102210
42111212210
43212212111
44211122211
45202222111
46221221212
47222211212
48222121212
49122221212
50122222213
51212222213
52222212213
53222222214
Sheet3


Regards,
</SPAN></SPAN>
Moti
</SPAN></SPAN>
 
Last edited:
Upvote 0
Adding a requirement that the sum of each row must be the same as all the other rows changes the nature of the exercise. You are no longer asking to randomly generate a seven number set, since a set of numbers cannot be random if you constrain the sum of those numbers. Rather it becomes an execise of determing unique combinations of 7 numbers using a 3 number set, that all have the same sum. Using any sort of random number generation will hinder that, since the only way to use randomly generated numbers to produce a desired sum is to iterate and hope for the best. The modifed code below will do that for small table sizes, but if you increase the number of rows, then the number of iterations required will quickly become large.

Code:
Sub DoSomething()
    Dim WS As Worksheet
    Dim RangeOfCells As Range, RR As Range, RC As Range
    Dim I As Long, RSum As Long
    Dim S As String
    Dim SD As Object
    Dim DoNextRow As Boolean

    Set WS = ActiveSheet
    Set SD = CreateObject("Scripting.dictionary")
    Set RangeOfCells = WS.Range("F4:L53")             'Your example range

    Application.ScreenUpdating = False
    For Each RR In Intersect(RangeOfCells.Columns(1), RangeOfCells)
        I = 0
        S = ""
        Do
            RSum = 0
            For Each RC In Intersect(RR.EntireRow, RangeOfCells)
                RC.Value = Application.WorksheetFunction.RandBetween(0, 2)
                RSum = RSum + RC.Value
                S = S & RC.Value
            Next RC

            DoNextRow = (RSum = 7) And Not SD.exists(S)
            If DoNextRow Then
                SD.Add S, 0                           'Unique row
            End If
            I = I + 1
            S = ""
        Loop Until DoNextRow Or I > 5000              'I > 5000 is to prevent a runaway loop.
    Next RR
    Set SD = Nothing
    Application.ScreenUpdating = True
End Sub
Thank you rlv01, for your help yes it is generate 50 combinations as I asked in the post#1, but now i want as per post#16 is it possible?</SPAN></SPAN>

Regards,
</SPAN></SPAN>
Moti
</SPAN></SPAN>
 
Upvote 0
I took the challenge to come up with something but it's far from bullet proof. I'm stuck at comparing the results so that there are no duplicates. Perhaps someone can tackle that

Prints the result to the immediate window of the visual basic editor.
Code:
Sub RandomNumbers()
End Sub
strooman, thank you for looking in to it. </SPAN></SPAN>

Regards,
</SPAN></SPAN>
Moti
</SPAN></SPAN>
 
Upvote 0

Here I will try to explain again what I wanted might this help... example below shows in the column M4:M53 there are different sum vales in order 0 to 14, I want to generate each row combination as per sum M column--> row 4 sum = 0, row 5&6 sum = 1, 7&8 sum = 3 and so on...for next row,

And generate all rows as long as sum find in the M Column


Regards,

Moti

I want to be clear, using your example in post #16 :
Do you mean the rows in col F:L are actually blank? then you want the macro to fill the rows with combination (0,1,2) which total sum is in col M?
 
Last edited:
Upvote 0
I want to be clear, using your example in post#16 :

Do you mean the rows in col F:L are actually blank?
Yes Akuini, you are correct all col F:L rows are blank.

then you want the macro to fill the rows with combination (0,1,2) which total sum is in col M?
Yes Akuini, you got it my viewpoint it is perfect as you describe.</SPAN></SPAN>

Regards,
</SPAN></SPAN>
Moti
</SPAN>

</SPAN>
 
Last edited:
Upvote 0

Forum statistics

Threads
1,223,911
Messages
6,175,327
Members
452,635
Latest member
laura12345

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