如何在 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
我一直在尝试打乱一个 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