VBA - Как я могу получить рандомизировать строковый массив для работы? - PullRequest
0 голосов
/ 18 октября 2018

Обзор: я вставляю много слов в отдельных строках в текстовое поле: 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

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Это работает для меня:

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
0 голосов
/ 18 октября 2018

На основании некоторого быстрого тестирования функция ShuffleArray в размещенной ссылке фактически не возвращает рандомизированный массив.Поскольку вы храните свой массив в переменной strRandoms, вы можете использовать функцию «на месте» в любом случае (функция «на месте» также будет более эффективной, поскольку ей не нужно создавать и заполнять совершенно новый массив, когдаnamed).

При вызове функции и передаче массива в качестве аргумента не включайте скобки после массива.Так что сделайте это:

ShuffleArrayInPlace a
' Or this:
Call ShuffleArrayInPlace(a)

Однако, чтобы сделать это успешно, вы должны слегка изменить сигнатуру метода ShuffleArrayInPlace из этого (как сейчас):

Sub ShuffleArrayInPlace(InArray() As Variant)

к этому:

Sub ShuffleArrayInPlace(InArray As Variant)

Обратите внимание, что скобки после InArray пропали.Зачем это делать?

Первоначально, в скобках, функция ожидает массив значений Variant.Однако функция split возвращает массив значений string .Изменяя сигнатуру метода для удаления скобок, вы в основном говорите, что можете передать в функцию все что угодно (массив строк, массив вариантов или даже что-то, что вообще не является массивом).По этой причине вы можете обновить ShuffleArrayInPlace, чтобы выдавать ошибку, если аргумент не является массивом (используя функцию IsArray ).

Говоря о рефакторинге: в то время как алгоритм ShuffleArrayInPlace использование для перемешивания массива понятно, это не обязательно лучший.Я бы пересмотрел случайное перемешивание Фишера-Йейтса и попытался реализовать его самостоятельно в VBA в качестве упражнения.


Итак, в заключение ...

  • При вызове функции, которая принимает массив в качестве аргумента, не ставьте скобки после массива: `Call ShuffleArrayInPlace (strRandoms)
  • Использование ShuffleArrayInPlace, а не ShuffleArray.
  • Измените функцию ShuffleArrayInPlace, чтобы InArray было Variant, а не Variant().
...