我在单元格A1-A37中有一个ID号1101-1137的列表。我想点击一个按钮随机选择其中的20个,不重复,并在消息框中显示它们。
我现在所拥有的似乎是从数字1-37中随机选择,而不是细胞的实际内容,我无法弄清楚如何修复它。例如,如果我从单元格A37删除数字1137,则数字37仍然可以在消息框中结束;如果我用单词E替换单元格A5中的数字1105,E将不会显示在消息框中,但是5可以。
然而,如果我改变" Const nItemsTotal As Long = 37"等于其他数字,比如31,它只会输出1-31的数字。
这就是我所拥有的:
Private Sub CommandButton1_Click()
Const nItemsToPick As Long = 20
Const nItemsTotal As Long = 37
Dim rngList As Range
Dim idx() As Long
Dim varRandomItems() As Variant
Dim i As Long
Dim j As Long
Dim booIndexIsUnique As Boolean
Set rngList = Range("A1").Resize(nItemsTotal, 1)
ReDim idx(1 To nItemsToPick)
ReDim varRandomItems(1 To nItemsToPick)
For i = 1 To nItemsToPick
Do
booIndexIsUnique = True ' Innocent until proven guilty
idx(i) = Int(nItemsTotal * Rnd + 1)
For j = 1 To i - 1
If idx(i) = idx(j) Then
' It's already there.
booIndexIsUnique = False
Exit For
End If
Next j
If booIndexIsUnique = True Then
strString = strString & vbCrLf & idx(i)
Exit Do
End If
Loop
varRandomItems(i) = rngList.Cells(idx(i), 1)
Next i
Msg = strString
MsgBox Msg
' varRandomItems now contains nItemsToPick unique random
' items from range rngList.
End Sub
我确定这是一个愚蠢的错误,但我输了。非常感谢您的帮助。
答案 0 :(得分:1)
如果构造一个包含已通过随机化找到的ID的字符串,则可以检查重复。
Dim i As Long, msg As String, id As String
msg = Chr(9)
For i = 1 To 20
id = 1100 + Int((37 - 1 + 1) * Rnd + 1)
Do Until Not CBool(InStr(1, msg, Chr(9) & id & Chr(9)))
Debug.Print id & msg
id = 1100 + Int((37 - 1 + 1) * Rnd + 1)
Loop
msg = msg & id & Chr(9)
Next i
msg = Mid(Left(msg, Len(msg) - 1), 2)
MsgBox msg
答案 1 :(得分:0)
我在您的代码中添加了一行代码......现在该行:
strString = strString & vbCrLf & Cells(idx(i), 1).Value
完整的代码是:
Private Sub CommandButton1_Click()
Const nItemsToPick As Long = 20
Const nItemsTotal As Long = 37
Dim rngList As Range
Dim idx() As Long
Dim varRandomItems() As Variant
Dim i As Long
Dim j As Long
Dim booIndexIsUnique As Boolean
Set rngList = Range("A1").Resize(nItemsTotal, 1)
ReDim idx(1 To nItemsToPick)
ReDim varRandomItems(1 To nItemsToPick)
For i = 1 To nItemsToPick
Do
booIndexIsUnique = True ' Innocent until proven guilty
idx(i) = Int(nItemsTotal * Rnd + 1)
For j = 1 To i - 1
If idx(i) = idx(j) Then
' It's already there.
booIndexIsUnique = False
Exit For
End If
Next j
If booIndexIsUnique = True Then
strString = strString & vbCrLf & Cells(idx(i), 1).Value
Exit Do
End If
Loop
varRandomItems(i) = rngList.Cells(idx(i), 1)
Next i
Msg = strString
MsgBox Msg
' varRandomItems now contains nItemsToPick unique random
' items from range rngList.
End Sub
因此,不是返回数字,而是使用返回的数字来查看与其相关的行上的值。
答案 2 :(得分:0)
只需改变指数:
Sub MAIN()
Dim ary(1 To 37) As Variant
Dim i As Long, j As Long
For i = 1 To 37
ary(i) = i
Next i
Call Shuffle(ary)
msg = ""
For i = 1 To 20
j = ary(i)
msg = msg & vbCrLf & Cells(j, 1).Value
Next i
MsgBox msg
End Sub
Public Sub Shuffle(InOut() As Variant)
Dim i As Long, j As Long
Dim tempF As Double, Temp As Variant
Hi = UBound(InOut)
Low = LBound(InOut)
ReDim Helper(Low To Hi) As Double
Randomize
For i = Low To Hi
Helper(i) = Rnd
Next i
j = (Hi - Low + 1) \ 2
Do While j > 0
For i = Low To Hi - j
If Helper(i) > Helper(i + j) Then
tempF = Helper(i)
Helper(i) = Helper(i + j)
Helper(i + j) = tempF
Temp = InOut(i)
InOut(i) = InOut(i + j)
InOut(i + j) = Temp
End If
Next i
For i = Hi - j To Low Step -1
If Helper(i) > Helper(i + j) Then
tempF = Helper(i)
Helper(i) = Helper(i + j)
Helper(i + j) = tempF
Temp = InOut(i)
InOut(i) = InOut(i + j)
InOut(i + j) = Temp
End If
Next i
j = j \ 2
Loop
End Sub
答案 3 :(得分:0)