Random generated value inside grid.

Afro_Cookie

Board Regular
Joined
Mar 17, 2020
Messages
103
Office Version
  1. 365
Platform
  1. Windows
I have a 10x10 grid from A1:J10 and want to generate a 'x' in the cells in a random order, based off the below criteria, almost like a reverse COUNTA() function.
- Each row and each column has 4 'x' in it.
- The placement of those 'x' are random.

Something similar to the below grid, but with the placements randomized?

12345678910Total
1xxxx4
2xxxx4
3xxxx4
4xxxx4
5xxxx4
6xxxx4
7xxxx4
8xxxx4
9xxxx4
10xxxx4
Total4444444444
 

Excel Facts

Which Excel functions can ignore hidden rows?
The SUBTOTAL and AGGREGATE functions ignore hidden rows. AGGREGATE can also exclude error cells and more.
This question caused me a few more grey hairs, but I think the following code will do what you asked for:

VBA Code:
Sub RandomlyPlaceXs()
'
    Dim i                       As Long, j                      As Long, temp   As Long
    Dim RowCount                As Long
    Dim ColumnNumbersArray()    As Variant
    Dim Column_X_CountArray()   As Long, Row_X_CountArray()     As Long
'
    With Range("A1:J10")
        .ClearContents
'
        ReDim ColumnNumbersArray(1 To .Columns.Count)
        For i = 1 To .Columns.Count
            ColumnNumbersArray(i) = i
        Next
'
        ReDim Column_X_CountArray(1 To .Columns.Count)
        ReDim Row_X_CountArray(1 To .Rows.Count)
'
' Randomly place four 'X' values in each row while ensuring each column has exactly four 'X' values
        For RowCount = 1 To .Rows.Count
' Shuffle the ColumnNumbersArray using Fisher-Yates algorithm
            For i = LBound(ColumnNumbersArray) To UBound(ColumnNumbersArray) - 1
                j = WorksheetFunction.RandBetween(i, UBound(ColumnNumbersArray))
                temp = ColumnNumbersArray(j)
                ColumnNumbersArray(j) = ColumnNumbersArray(i)
                ColumnNumbersArray(i) = temp
            Next
'
' Fill each row with exactly 4 X's
            For i = 1 To UBound(ColumnNumbersArray)
                If Row_X_CountArray(RowCount) > 3 Then Exit For
'
                If .Cells(RowCount, ColumnNumbersArray(i)).Value2 = "" And _
                        Column_X_CountArray(ColumnNumbersArray(i)) < 4 Then
                    .Cells(RowCount, ColumnNumbersArray(i)).Value2 = "X"
                    Column_X_CountArray(ColumnNumbersArray(i)) = Column_X_CountArray(ColumnNumbersArray(i)) + 1
                    Row_X_CountArray(RowCount) = Row_X_CountArray(RowCount) + 1
                End If
            Next
        Next
    End With
'
' Check if the last row of Row_X_CountArray has exactly 4 'X's and recursively call the subroutine if not
    If Row_X_CountArray(RowCount - 1) <> 4 Then Call RandomlyPlaceXs
End Sub
 
Upvote 1
Solution
This question caused me a few more grey hairs, but I think the following code will do what you asked for:

VBA Code:
Sub RandomlyPlaceXs()
'
    Dim i                       As Long, j                      As Long, temp   As Long
    Dim RowCount                As Long
    Dim ColumnNumbersArray()    As Variant
    Dim Column_X_CountArray()   As Long, Row_X_CountArray()     As Long
'
    With Range("A1:J10")
        .ClearContents
'
        ReDim ColumnNumbersArray(1 To .Columns.Count)
        For i = 1 To .Columns.Count
            ColumnNumbersArray(i) = i
        Next
'
        ReDim Column_X_CountArray(1 To .Columns.Count)
        ReDim Row_X_CountArray(1 To .Rows.Count)
'
' Randomly place four 'X' values in each row while ensuring each column has exactly four 'X' values
        For RowCount = 1 To .Rows.Count
' Shuffle the ColumnNumbersArray using Fisher-Yates algorithm
            For i = LBound(ColumnNumbersArray) To UBound(ColumnNumbersArray) - 1
                j = WorksheetFunction.RandBetween(i, UBound(ColumnNumbersArray))
                temp = ColumnNumbersArray(j)
                ColumnNumbersArray(j) = ColumnNumbersArray(i)
                ColumnNumbersArray(i) = temp
            Next
'
' Fill each row with exactly 4 X's
            For i = 1 To UBound(ColumnNumbersArray)
                If Row_X_CountArray(RowCount) > 3 Then Exit For
'
                If .Cells(RowCount, ColumnNumbersArray(i)).Value2 = "" And _
                        Column_X_CountArray(ColumnNumbersArray(i)) < 4 Then
                    .Cells(RowCount, ColumnNumbersArray(i)).Value2 = "X"
                    Column_X_CountArray(ColumnNumbersArray(i)) = Column_X_CountArray(ColumnNumbersArray(i)) + 1
                    Row_X_CountArray(RowCount) = Row_X_CountArray(RowCount) + 1
                End If
            Next
        Next
    End With
'
' Check if the last row of Row_X_CountArray has exactly 4 'X's and recursively call the subroutine if not
    If Row_X_CountArray(RowCount - 1) <> 4 Then Call RandomlyPlaceXs
End Sub
The hairs were well worth it. This works perfectly.
 
Upvote 0

Forum statistics

Threads
1,224,814
Messages
6,181,121
Members
453,021
Latest member
Justyna P

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