Goto should be avoided. Use loops instead.
This code first calculates the number of stars for each row, then uses nested loops to enter them, so there are never more stars in a row. By stepping to the next row, but retaining the column position, and then starting in the same row in the first column, you can ensure that there are no more than the defined number of stars in a column, either. The blank cells will travel diagonally from top left to right. You can see this when you apply conditional formatting.
With this pattern, you don't need to use trial and error and the code runs super fast.
Sub test()
Dim gridRows As Long, gridColumns As Long, Stars As Long
Dim myRow As Long, myColumn As Long
Dim i As Long, j As Long
Dim rowCounter As Long, columnCounter As Long, rowOffset As Long
Dim ws As Worksheet
Set ws = Me
'You can get the grid rows and columns and the number of stars from
' user input or from worksheet cells in you want. Just make sure
' they end up in the variables below.
gridRows = 20
gridColumns = 10
Stars = 60
mycolumns = Stars / gridRows
myRows = Stars / gridColumns
j = 1
rowCounter = 1
columnCounter = 1
ws.Range("A1:zz9990").ClearContents
For j = 1 To gridRows
rowOffset = 0
For i = 1 To gridColumns
ws.Cells(j, i) = 1
columnCounter = columnCounter + 1
If columnCounter > mycolumns Then
j = j + 1
columnCounter = 1
rowOffset = 1
End If
Next i
j = j - rowOffset
Next j
' randomize the results
Dim SortRange As Range
' randomize the columns
Set SortRange = ws.Range(ws.Cells(gridRows + 1, 1), ws.Cells(gridRows + 1, gridColumns))
' enter random numbers
For Each cel In SortRange
Debug.Print cel.Address
cel.Value = Rnd
Next cel
' sort left to right
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add2 Key:=SortRange _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ws.Sort
.SetRange Range("A1", Cells(gridRows + 1, gridColumns))
.Header = xlGuess
.Orientation = xlLeftToRight
.SortMethod = xlPinYin
.Apply
End With
' clear the random numbers
SortRange.ClearContents
Set SortRange = ws.Range(ws.Cells(1, gridColumns + 1), ws.Cells(gridRows, gridColumns + 1))
' randomize the rows
' enter random numbers
For Each cel In SortRange
Debug.Print cel.Address
cel.Value = Rnd
Next cel
'Sort Rows
ws.Sort.SortFields.Clear
ws.Sort.SortFields.Add2 Key:=SortRange _
, SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
With ws.Sort
.SetRange Range("A1", Cells(gridRows, gridColumns + 1))
.Header = xlGuess
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' clear the random numbers
SortRange.ClearContents
End Sub
Edit after comment: Added code to randomize the results. Add a row with random numbers to the end of the table, sort by those random numbers left to right, and remove them again. Do the same with a column of random numbers and sort top to bottom, then remove the helper numbers.
The screenshot shows a grid with 20 rows, 10 columns and 60 stars using conditional formatting to show the distribution better.
A grid with 60 rows, 30 columns and 1200 stars takes less than a second to build (without using conditional formatting).
