您可以采取很多方法,但@CMArg 说数组或字典是确保您没有重复项的好方法是正确的。
您要避免的是每个单元格填充时间逐渐延长的情况。对于非常小的正方形(例如 10x10)来说这不是问题,但是非常大的正方形会变得丑陋。(如果您的范围是 1-100,并且除了 31 之外的所有数字都已经在表中,那么平均需要很长时间 - 100 次猜测,对吧? - 拉出一个未使用的数字。如果范围是 1 -40000 (200x200),需要 40000 次猜测才能填充最后一个单元格。)
因此,与其保留已使用的数字列表,不如考虑如何有效地检查并“划掉”已使用的数字,以便每个新单元格准确地填充 1 个“猜测”。
这是您可以实现它的一种方法:
类:SingleRandoms
Option Explicit
Private mUnusedValues As Scripting.Dictionary
Private mUsedValues As Scripting.Dictionary
Private Sub Class_Initialize()
Set mUnusedValues = New Scripting.Dictionary
Set mUsedValues = New Scripting.Dictionary
End Sub
Public Sub GenerateRange(minimumNumber As Long, maximumNumber As Long)
Dim i As Long
With mUnusedValues
.RemoveAll
For i = minimumNumber To maximumNumber
.Add i, i
Next
End With
End Sub
Public Function GetRandom() As Long
Dim i As Long, keyID As Long
Randomize timer
With mUnusedValues
i = .Count
keyID = Int(Rnd * i)
GetRandom = .Keys(keyID)
.Remove GetRandom
End With
mUsedValues.Add GetRandom, GetRandom
End Function
Public Property Get AvailableValues() As Scripting.Dictionary
Set AvailableValues = mUnusedValues
End Property
Public Property Get UsedValues() As Scripting.Dictionary
Set UsedValues = mUsedValues
End Property
实际使用的类示例:
Public Sub getRandoms()
Dim r As SingleRandoms
Set r = New SingleRandoms
With r
.GenerateRange 1, 100
Do Until .AvailableValues.Count = 0
Debug.Print .GetRandom()
Loop
End With
End Sub
使用集合实际上比使用字典更节省内存和更快,但是字典更容易验证它正在做它应该做的事情(因为你可以使用.Exists
等)。