VBA - 如何使随机化字符串数组工作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VBA - 如何使随机化字符串数组工作?相关的知识,希望对你有一定的参考价值。

概述:我在单独的行中将许多单词粘贴到文本框中:txtWordRandomizer。然后,将每一行移动到字符串数组中。我需要随机播放/随机化数组,但似乎无法让它工作。

我得到了底部Sub,ShuffleArray(),这里:http://www.cpearson.com/excel/ShuffleArray.aspx ......而且似乎是每个人在谈论改组/随机化数组时所引用的。

我得到错误:类型不匹配:在调用ShuffleArrayInPlace()时期望的数组或用户定义类型,但认为这是随机化字符串数组。我是否需要将字符串数组转换为变量数组?

或者,关于如何让它工作的任何其他建议?

    Private Sub btnRandomize_Click()

        Dim strRandoms() As String
        strRandoms() = Split(Me.txtWordRandomizer.Value, vbCrLf)
        strRandoms() = ShuffleArray(strRandoms())

    End Sub    


Function ShuffleArray(InArray() As Variant) As Variant()

' This function returns the values of InArray in random order. The original
' InArray is not modified.

    Dim N As Long
    Dim Temp As Variant
    Dim J As Long
    Dim Arr() As Variant


    Randomize
    L = UBound(InArray) - LBound(InArray) + 1
    ReDim Arr(LBound(InArray) To UBound(InArray))
    For N = LBound(InArray) To UBound(InArray)
        Arr(N) = InArray(N)
    Next N
    For N = LBound(InArray) To UBound(InArray)
        J = CLng(((UBound(InArray) - N) * Rnd) + N)
        Temp = InArray(N)
        InArray(N) = InArray(J)
        InArray(J) = Temp
    Next N
    ShuffleArray = Arr
End Function
答案

基于一些快速测试,发布链接中的ShuffleArray函数实际上并不返回随机数组。由于您将数组保存在strRandoms变量中,因此无论如何都可以使用就地函数(就地函数也会更高效,因为它在调用时不必创建和填充全新的数组) 。

调用函数并将数组作为参数传递时,请不要在数组后包括括号。这样做:

ShuffleArrayInPlace a
' Or this:
Call ShuffleArrayInPlace(a)

但是,为了成功完成此操作,您必须稍微更改ShuffleArrayInPlace的方法签名(就像现在一样):

Sub ShuffleArrayInPlace(InArray() As Variant)

对此:

Sub ShuffleArrayInPlace(InArray As Variant)

请注意,InArray之后的括号已经消失。为什么这样?

最初,使用括号,函数期望一组Variant值。但是,split函数返回一个字符串值数组。通过更改方法签名以删除括号,您基本上是说可以将任何内容传递给函数(字符串数组,变体数组,甚至根本不是数组的东西)。因此,如果参数不是数组(使用ShuffleArrayInPlace函数),则可以更新IsArray以引发错误。

说到重构:虽然ShuffleArrayInPlace用来对阵列进行洗牌的算法很清楚,但它不一定是最好的算法。我会回顾一下Fisher-Yates shuffle,并尝试在VBA中自己实施它作为练习。


So, in summary...

  • 当调用一个以数组作为参数的函数时,不要在数组后加括号:`Call ShuffleArrayInPlace(strRandoms)
  • 使用ShuffleArrayInPlace,而不是ShuffleArray
  • 改变ShuffleArrayInPlace函数,使InArrayVariant,而不是Variant()
另一答案

这对我有用:

Private Sub btnRandomize_Click()

    Dim strRandoms() As String
    strRandoms = Split("A|B|C|D|E", "|")
    strRandoms = ShuffleArray(strRandoms)

    Debug.Print Join(strRandoms, ", ")

End Sub


Function ShuffleArray(InArray() As String) As String()
    Dim N As Long, Temp As Variant
    Dim J As Long, Arr() As String

    Randomize

    'make a copy of the array
    ReDim Arr(LBound(InArray) To UBound(InArray))
    For N = LBound(InArray) To UBound(InArray)
        Arr(N) = InArray(N)
    Next N
    'shuffle the copy
    For N = LBound(Arr) To UBound(Arr)
        J = CLng(((UBound(Arr) - N) * Rnd) + N)
        Temp = Arr(N)
        Arr(N) = Arr(J)
        Arr(J) = Temp
    Next N
    ShuffleArray = Arr 'return the shuffled copy
End Function

以上是关于VBA - 如何使随机化字符串数组工作?的主要内容,如果未能解决你的问题,请参考以下文章

我的数组随机化函数打印相同的数组 [重复]

VBA:如何使变体为空?

EXCEL VBA里我想上定义一个字符型变量,比如aaa 如何使aaa=“””,英文版的引号

如何随机化数组中的单元格内容

如何在 C# 中以相同的方式随机化/洗牌两个数组

如何使列表视图出现在片段中?