0

我正在尝试在 excel 范围之间随机选择并获得不重复的结果。

当我键入时,我得到一个单元格值Msgbox Range("C2")

但是,当我使用 时MsgBox Range("F" & WorksheetFunction.RandBetween(1, UBound(ElementHeader))),它会告诉我'type-mismatch'.

知道为什么吗?以及如何将其实际存储到 VBA 中的字符串数组中?

我的代码如下所示:

Sub Testy()
    Dim ElementHeader
    ElementHeader = Range("F1:F" & Range("F" & Rows.Count).End(xlUp).Row)
    MsgBox Range("F" & WorksheetFunction.RandBetween(1, UBound(ElementHeader)))
End Sub

这只是代码的一部分,但我希望将它存储到一个数组中,这样我就可以检查它们中的每一个,看看是否有任何重复。

Sub GenerateDescription()
    Dim Element
    Dim AddOn
    Dim MainRange
    ' Declare Sentences
    ' Addon Range is in Column F
    AddOn = Range("G1:G" & Range("G" & Rows.Count).End(xlUp).Row)
    ' Main Range is in Column D
    Set MainRange = Range("E1:E" & Range("E" & Rows.Count).End(xlUp).Row)
        For Each Element In MainRange
            Element.Offset(, 4).Value = Element & " " & Range("G" & WorksheetFunction.RandBetween(1, UBound(AddOn))) & " " & Range("G" & WorksheetFunction.RandBetween(1, UBound(AddOn))) & " " & Range("G" & WorksheetFunction.RandBetween(1, UBound(AddOn))) & " " & Range("G" & WorksheetFunction.RandBetween(1, UBound(AddOn))) & " " & Range("G" & WorksheetFunction.RandBetween(1, UBound(AddOn)))
        Next Element
End Sub

如您所见,这个重复G的 Range 是我要解决的部分。

For Each我希望 G 列句子在每种方法中只出现一次。意思是,我希望每个元素包含来自 G 列的 5 个唯一句子。

假设我有 10 个句子,对于每个循环,我想得到 5 个唯一的句子,例如:G1、G4、G2、G9、G10。永远不应该重复同一个单元格,这意味着如果函数生成 G1、G2、G5、G3、G1,我想用 G 列中的另一个随机单元格编号替换重复的 G1。

4

1 回答 1

1

使用 Chip Pearson 的函数获取唯一的随机数并将您的代码调整为如下所示:

For Each Element In MainRange
    vRandom = UniqueRandomLongs(1, UBound(AddOn), 5)
    Element.Offset(, 4).Value = Element & " " & _
    Range("G" & vRandom(1)) & " " & _
    Range("G" & vRandom(2)) & " " & _
    Range("G" & vRandom(3)) & " " & _
    Range("G" & vRandom(4)) & " " & _
    Range("G" & vRandom(5))
Next Element

http://www.cpearson.com/excel/RandomNumbers.aspx

Public Function UniqueRandomLongs(Minimum As Long, Maximum As Long, _
            Number As Long, Optional ArrayBase As Long = 1, _
            Optional Dummy As Variant) As Variant
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' UniqueRandomLongs
' This returns an array containing elements whose values are between the Minimum and
' Maximum parameters. The number of elements in the result array is specified by the
' Number parameter. For example, you can request an array of 20 Longs between 500 and
' 1000 (inclusive).
' There will be no duplicate values in the result array.
'
' The ArrayBase parameter is used to specify the LBound of the ResultArray. If this
' is omitted, ResultArray is 1-based.
'
' The Dummy argument is to be used only when the function is called from a worksheet.
' Its purpose is to allow you to use the NOW() function as the Dummy parameter to force
' Excel to calculate this function any time a calculation is performed. E.g.,
'       =UniqueRandomLongs(100,199,10,NOW())
' If you don't want to recalulate this function on every calculation, omit the Dummy
' parameter. The Dummy argument serves no other purpose and is not used anywhere
' in the code.
'
' The function returns an array of Longs if successful or NULL if an error occurred
' (invalid input parameter).
'
' Note: The procedure creates its own array of size (Maximum-Minium+1), so very large
' differences between Minimum and Maximum may cause performace issues.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Dim SourceArr() As Long
Dim ResultArr() As Long
Dim SourceNdx As Long
Dim ResultNdx As Long
Dim TopNdx As Long
Dim Temp As Long

''''''''''''''''''''''''''''''''''''''
' Test the input parameters to ensure
' they are valid.
''''''''''''''''''''''''''''''''''''''
If Minimum > Maximum Then
    UniqueRandomLongs = Null
    Exit Function
End If
If Number > (Maximum - Minimum + 1) Then
    UniqueRandomLongs = Null
    Exit Function
End If
If Number <= 0 Then
    UniqueRandomLongs = Null
    Exit Function
End If

Randomize
''''''''''''''''''''''''''''''''''''''''''''''
' Redim the arrays.
' SourceArr will be sized with an LBound of
' Minimum and a UBound of Maximum, and will
' contain the integers between Minimum and
' Maximum (inclusive). ResultArray gets
' a LBound of ArrayBase and a UBound of
' (ArrayBase+Number-1)
''''''''''''''''''''''''''''''''''''''''''''''
ReDim SourceArr(Minimum To Maximum)
ReDim ResultArr(ArrayBase To (ArrayBase + Number - 1))
''''''''''''''''''''''''''''''''''''''''''''
' Load SourceArr with the integers between
' Minimum and Maximum (inclusive).
''''''''''''''''''''''''''''''''''''''''''''
For SourceNdx = Minimum To Maximum
    SourceArr(SourceNdx) = SourceNdx
Next SourceNdx

''''''''''''''''''''''''''''''''''''''''''''''
' TopNdx is the upper limit of the SourceArr
' from which the Longs will be selected. It
' is initialized to UBound(SourceArr), and
' decremented in each iteration of the loop.
' Selections from SourceArr are always in the
' region including and to the left of TopNdx.
' The region above (to the right of) TopNdx
' is where the used numbers are stored and
' no selection is made from that region of
' the array.
''''''''''''''''''''''''''''''''''''''''''''''
TopNdx = UBound(SourceArr)
For ResultNdx = LBound(ResultArr) To UBound(ResultArr)
    ''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Set SourceNdx to a random number between 1 and
    ' TopNdx. ResultArr(ResultNdx) will get its value from
    ' SourceArr(SourceNdx). Only elements of SourceArr
    ' in the region of the array below (to the left of)
    ' TopNdx (inclusive) will be selected for inclusion
    ' in ResultArr. This ensures that the elements in
    ' ResultArr are not duplicated.
    ''''''''''''''''''''''''''''''''''''''''''''''''''
    SourceNdx = Int((TopNdx - Minimum + 1) * Rnd + Minimum)
    ResultArr(ResultNdx) = SourceArr(SourceNdx)
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Now, swap elements SourceNdx and TopNdx of SourceArr,
    ' moving the value in SourceArr(SourceNdx) to the region
    ' of SourceArr that is above TopNdx.  Since only elements
    ' of SourceArr in the region below TopNdx (inclusive) are
    ' possible candidates for inclusion in ResultArr, used
    ' values are placed at TopNdx to ensure no duplicates.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Temp = SourceArr(SourceNdx)
    SourceArr(SourceNdx) = SourceArr(TopNdx)
    SourceArr(TopNdx) = Temp
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    ' Decrment TopNdx. This moves the effective UBound of SourceArr
    ' downwards (to the left), thus removing used numbers from the
    ' possibility of inclusion in ResultArr. This ensures we have
    ' no duplicates in the ResultArr.
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    TopNdx = TopNdx - 1
Next ResultNdx

''''''''''''''''''''''''''''''
' Return the result array.
''''''''''''''''''''''''''''''
UniqueRandomLongs = ResultArr

End Function
于 2013-07-27T08:23:48.157 回答