What about making a custom type for your grid items:
Public Type GridItem
itemValue as String
numOccurences as Integer
End Type
GridItems (5) as GridItem 'will hold 6 grid items, indexed 0 to 5
if you have your values in column A, rows 1 to 6 and your frequency numbers
in column B, rows 1 to 6, you could populate your array of items with
For rowNum = 1 to 6
GridItems(rowNum - 1).ItemValue = Cells(rowNum, 1).value
GridItems(rowNum -1).numOccurences = Cells(rowNum,2).value
Next rowNum
If your grid will not be densely populated you can just ignore collisions
and generate random row and column numbers:
if targetCell.value <> "" then
'skip cell
Start with the first item in your GridItems array and decrement the
numOccurences "property" each time you successfully place an item.. When it
hits zero, increment your GridItems() index and place the next item in the
grid.
If the grid is densely populated it could potentially take a long time to
fill the grid if you ignore collisions completely. To reduce/avoid
collision, you could periodically poll all cells in the grid range. Add the
address of any empty cells to an array of grid targets and generate a random
index. Periodically update your array of empty cells to reduce collisions
(or use a more complext array type that will let you easily remove items from
the list ). For example, you can track the number of consecutive collisions.
If you get 3 or 4 collisions in a row, call your FindTargets function to
update (and return) a new list. Use UBound(gridTargets) as the upper bound
of your random number generator.