我怎样才能把这个UDF转换成一个macros

我有一个问题,我在Excel中有这个用户自定义公式

Function RANDNUMNOREP(Bottom As Integer, Top As Integer, Amount As Integer) As String 'This UDF will generate a non-repeating set of random numbers in excel and display those in the same cell as the function Dim iArr As Variant Dim i As Integer Dim r As Integer Dim temp As Integer Application.Volatile ReDim iArr(Bottom To Top) For i = Bottom To Top iArr(i) = i Next i For i = Top To Bottom + 1 Step -1 r = Int(Rnd() * (i - Bottom + 1)) + Bottom temp = iArr(r) iArr(r) = iArr(i) iArr(i) = temp Next i For i = Bottom To Bottom + Amount - 1 RANDNUMNOREP = RANDNUMNOREP & " " & iArr(i) Next i RANDNUMNOREP = Trim(RANDNUMNOREP) End Function 

基本上是这样做的是基于一个标准,它是第一个数字(的范围)最后一个数字(的范围),我想这个数字不会重复,因此,例如我会写在一个cell = RANDNUMNOREP(25,50,10)这将导致25到50之间的10个随机数字,这些数字将不会重复。

问题是,既然是一个公式,所有生成的数字都留在同一个单元格中,我的理解是没有办法在公式生成数字或文本或其他单元格中的任何值,但公式写入上。

所以我的问题是如何将其转换成一个macros,将显示或生成单独的单元格中的随机数字?

你可以让你的函数返回一个数组 ,从而填充一组单元格,而不是创build一个值的string:

 Function RANDNUMNOREP(Bottom As Long, Top As Long, Amount As Long) 'This UDF will generate a non-repeating set of random numbers in excel and display them in a row of cells Dim iArr As Variant Dim i As Long Dim r As Long Dim temp As Long Application.Volatile ReDim iArr(Bottom To Top) For i = Bottom To Top iArr(i) = i Next i For i = Top To Bottom + 1 Step -1 r = Int(Rnd() * (i - Bottom + 1)) + Bottom temp = iArr(r) iArr(r) = iArr(i) iArr(i) = temp Next i RANDNUMNOREP = iArr End Function 

例如,高亮度单元格A1E1和公式栏中input数组公式:

 =RANDNUMNOREP(10,50,5) 

数组公式必须使用Ctrl + Shift + Enterinput,而不仅仅是Enter键。

这就是它的样子:

演示

微不足道的解决办法是

  1. 在macros中运行函数,
  2. 将输出转换为Variant数组
  3. Set RngVariable = Range("A1:A10")或类似的东西
  4. RngVariable = OutputVariantArrayVariableName

更好的解决scheme,如果你需要维护这些作为单独的函数从不同的单元格拖动下面所示(如果感兴趣)

解决scheme并不像看起来那么明显,可以通过两种方式来处理。

  1. 用静态variables创build一个函数。 所以你的function…

    • 调用你的子程序
    • 将结果存储在静态variables数组中
    • 根据电子表格中的位置提供正确的值。

    这可能会起作用,但仍然会导致问题,因为您必须非常积极地pipe理variables,在不需要时覆盖它们等。

    这可以做,但不可取。

    您可以使用与全局variables相同的方法,但没有更大的增益

  2. 现在为一个简单而优雅的解决scheme:

    • 在程序中使用由种子激活的伪随机数发生器,而不是使用标准的随机数发生器。
    • 你的调用函数应该带有要生成的序列号,即3 =生成子将要生成的第3个号码。

    它需要一个种子,你可以在电子表格中随机生成一个种子。

这样你的电子表格上的function将是

 = CALLNONREPEATINGNUMBER(RandomSeed, SerialNumber, Optional Min, Optional Max) 

为每个系列保留相同的种子,并使用种子内部计算原始系列中第10个数字中的第3个数字是什么。

有许多简单的统一的随机数生成algorithm可用,其将使用种子确定性地生成数字,使得这些数字在统计上不可能与真正的统一随机数区分开。

PS无论如何,这就是即使Rnd函数内部工作