【问题标题】:How can I randomly select a number of cells and display the contents in a message box?如何随机选择多个单元格并在消息框中显示内容?
【发布时间】:2015-11-08 11:15:04
【问题描述】:

我在单元格 A1-A37 中有一个 ID 号 1101-1137 的列表。我想单击一个按钮以随机选择其中的 20 个,不重复,并将它们显示在消息框中。

我现在所拥有的似乎是从数字 1-37 中随机选择的,而不是单元格的实际内容,我不知道如何修复它。例如,如果我从单元格 A37 中删除数字 1137,数字 37 仍会出现在消息框中;如果我将单元格 A5 中的数字 1105 替换为字母 E,则 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

我确定这是一个愚蠢的错误,但我迷路了。非常感谢您的帮助。

【问题讨论】:

    标签: excel vba


    【解决方案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
    

    【讨论】:

      【解决方案2】:

      我在您的代码中添加了一小行...现在是:

      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
      

      因此,它不是返回数字,而是使用返回的数字来查看与其相关的行上的值。

      【讨论】:

      • 你真是太可爱了,当然现在它工作得很好。谢谢!!
      【解决方案3】:

      只需随机播放指数

      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
      

      【讨论】:

        【解决方案4】:

        另一种方法:

        Sub test()
            Dim Dic As Object, i%
            Set Dic = CreateObject("Scripting.Dictionary")
            Dic.comparemode = vbTextCompare
            While Dic.Count <> 20
                i = WorksheetFunction.RandBetween(1, 37)
                If Not Dic.exists(i) Then Dic.Add i, Cells(i, "A")
            Wend
            MsgBox Join(Dic.Items, Chr(13))
        End Sub
        

        测试:


        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-26
          • 2021-11-16
          • 1970-01-01
          相关资源
          最近更新 更多