如何在 VBA / Excel 中显示打乱数组的条目

How to show entries of a shuffled array in VBA / Excel

我一直在尝试打乱一个 11 整数数组并将打乱的数组粘贴到 excel。我发现一些代码几乎可以满足我的要求,但它没有 return 排列数组的混洗条目,而是显示混洗的行号 (Col A) 和用于排序的随机数 (Col B)。

我是 VBA 的新手,无法弄清楚 return 与 Col A 中打乱后的行号对应的数组条目,是否有意义?我只想看到打乱的条目,而不是行号或随机数。希望这是有道理的!我正在使用:

Sub Shuffle()

Dim intNumbers(1 To 11) As Integer

'the list of numbers I want to shuffle 
intNumbers(1) = 1
intNumbers(2) = 1
intNumbers(3) = 1
intNumbers(4) = 1
intNumbers(5) = 1
intNumbers(6) = 1
intNumbers(7) = 2
intNumbers(8) = 5
intNumbers(9) = 6
intNumbers(10) = 3
intNumbers(11) = 7

Dim rngNumbers As Range
Dim rngRandom As Range
Dim rngSort As Range
Dim rngTemp As Range



Set rngNumbers = ActiveSheet.Range("A1:A11")
Set rngRandom = ActiveSheet.Range("B1:B11")
Set rngSort = ActiveSheet.Range("A1:B11")



Randomize
 ' store number and random sequence
For Each rngTemp In rngRandom
    rngTemp = Rnd()
    rngTemp.Offset(0, -1) = rngTemp.Row
Next

rngSort.Sort key1:=rngSort.Columns(2)
For Each rngTemp In rngNumbers
    intNumbers(rngTemp.Value) = rngTemp

Next



End Sub

我可以看到这段代码在做什么,但无法弄清楚如何让它做我想做的事。还有很多东西要学!

下面是让您的代码正常工作的一种方法:

Sub Shuffle()

    Dim intNumbers(1 To 11) As Integer
    Dim rngSort As Range
    Dim x As Long

    'the list of numbers I want to shuffle
    intNumbers(1) = 1
    intNumbers(2) = 1
    intNumbers(3) = 1
    intNumbers(4) = 1
    intNumbers(5) = 1
    intNumbers(6) = 1
    intNumbers(7) = 2
    intNumbers(8) = 5
    intNumbers(9) = 6
    intNumbers(10) = 3
    intNumbers(11) = 7

    Set rngSort = ActiveSheet.Range("A1:B11")
    rngSort.Clear

    Randomize
     ' store number and random sequence
    For x = 1 To 11
        rngSort(x, 1) = intNumbers(x)
        rngSort(x, 2) = Rnd()
    Next x

    rngSort.Sort key1:=rngSort.Columns(2)    
    rngSort.Columns(2).Clear

End Sub

试试这个代码。它将在 A 列中保留原始行,在 B 列中保留排序的随机数 A>Z,在 C 列中:数组的索引,具体取决于行号。

Sub Shuffle()

Dim intNumbers(1 To 11) As Integer

'the list of numbers I want to shuffle
intNumbers(1) = 1
intNumbers(2) = 1
intNumbers(3) = 1
intNumbers(4) = 1
intNumbers(5) = 1
intNumbers(6) = 1
intNumbers(7) = 2
intNumbers(8) = 5
intNumbers(9) = 6
intNumbers(10) = 3
intNumbers(11) = 7

Dim rngNumbers As Range
Dim rngRandom As Range
Dim rngSort As Range
Dim rngTemp As Range



Set rngNumbers = ActiveSheet.Range("A1:A11")
Set rngRandom = ActiveSheet.Range("B1:B11")
Set rngSort = ActiveSheet.Range("A1:B11")



Randomize
 ' store number and random sequence
For Each rngTemp In rngRandom
    rngTemp = Rnd()
    rngTemp.Offset(0, -1) = rngTemp.Row
Next

rngSort.Sort key1:=rngSort.Columns(2)
For Each rngTemp In rngNumbers
    rngTemp.Offset(0, 2).Value = intNumbers(rngTemp)

Next



End Sub

这里有两种方法。第一个是我在模拟 "Candyland" 游戏时首次使用的有点幼稚且效率不高的洗牌子。 sub 获取一个传递的数组并通过随机交换元素对(默认为 1000 次)对其进行洗牌。第二个 sub 说明了使用变体在 VBA 中保存数组的一些优点,并使用标准技巧将一维值数组发布到 1 行代码中的列 rage 中。每次你 运行 它 A1:A11 都会以随机顺序给出这 11 个元素。

Sub Shuffle(Deck As Variant, Optional times As Long = 1000)
    Dim a As Long, b As Long, i As Long, j As Long, k As Long
    Dim temp As Variant
    a = LBound(Deck)
    b = UBound(Deck)
    For i = 1 To times
        j = Application.WorksheetFunction.RandBetween(a, b - 1)
        k = Application.WorksheetFunction.RandBetween(j + 1, b)
        temp = Deck(j)
        Deck(j) = Deck(k)
        Deck(k) = temp
    Next i
End Sub

Sub ShuffleAndPaste()
    Dim v As Variant
    v = Array(1, 1, 1, 1, 1, 1, 2, 5, 6, 3, 7)
    Shuffle v
    Range("A1:A11").Value = Application.WorksheetFunction.Transpose(v)
End Sub

第二种方法更有效,由函数而不是子函数给出。它具有不需要对电子表格做出任何假设的理想特性(例如,B 和 C 列可用),也可以从卡片的角度来考虑——非正式地,我将其视为“52 pickup”洗牌(https://en.wikipedia.org/wiki/52_Pickup):

Function Shuffle(deck As Variant) As Variant
    Dim cards As New Collection
    Dim shuffledDeck As Variant
    Dim i As Long, j As Long, n As Long
    Dim lb As Long, ub As Long

    Randomize
    lb = LBound(deck)
    ub = UBound(deck)

    ReDim shuffledDeck(lb To ub)
    For i = lb To ub
        cards.Add deck(i)
    Next i
    n = cards.Count

    For i = lb To ub
        j = 1 + Int(n * Rnd())
        shuffledDeck(i) = cards.Item(j)
        cards.Remove j
        n = n - 1
    Next i

    Shuffle = shuffledDeck

End Function

Sub ShuffleAndPaste()
    Dim v As Variant
    v = Array(1, 1, 1, 1, 1, 1, 2, 5, 6, 3, 7)
    v = Shuffle(v) 'since now shuffle is a function
    Range("A1:A11").Value = Application.WorksheetFunction.Transpose(v)
End Sub