我正在尝试在excel范围之间随机获得一个非重复的结果。
当我输入Msgbox Range("C2")
时,我得到一个单元格值。
但是,当我使用MsgBox Range("F" & WorksheetFunction.RandBetween(1, UBound(ElementHeader)))
时,它会告诉我'type-mismatch'
。
知道为什么吗?我如何将它实际存储在VBA中的String数组中?
我的代码如下所示:
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
范围是我试图解决的部分。
我希望每个For Each
方法只能出现一次G列句子。意思是,我希望每个元素包含G列中的5个唯一句子。
假设我有10个句子,对于每个循环,我想得到5个唯一的句子,例如:G1,G4,G2,G9,G10。应该从不重复相同的单元格,这意味着如果函数生成G1,G2,G5,G3,G1,我想用G列中的另一个随机单元格数替换重复的G1。 / p>
答案 0 :(得分: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