如何将此UDF转换为宏

时间:2014-07-10 19:35:56

标签: excel vba excel-vba

我有一个问题,我在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 

基本上它的作用是根据一个标准产生一组随机数,该标准是第一个数字(范围)最后一个数字(范围)和我希望这个数字的数量不会重复,例如我会写入一个单元格= RANDNUMNOREP(25,50,10)这将产生25到50之间的10个随机数,这些数字不会重复。

这个问题是,因为是一个公式,所有生成的数字都留在同一个单元格中,根据我的理解,excel无法在公式中生成数字或文本或其他单元格中的任何值,但是公式写在上面。

所以我的问题是如何将其转换为一个宏,它将在不同的单元格中显示或生成随机数?

2 个答案:

答案 0 :(得分:1)

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

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

例如,高光单元 A1 E1 ,在公式栏中输入数组公式:

=RANDNUMNOREP(10,50,5)
必须使用 Ctrl + Shift + 输入输入

数组公式,而不仅仅是 Enter key。

这就是它的样子:

demo

答案 1 :(得分:0)

琐碎的解决方案是

  1. 在宏中运行函数,
  2. 将输出转换为Variant数组
  3. Set RngVariable = Range("A1:A10")或类似的东西
  4. RngVariable = OutputVariantArrayVariableName
  5. 更好的解决方案,如果您需要维护这些作为从拖动的不同单元调用的单独函数,如下所示(如果感兴趣)

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

    1. 使用静态变量创建一个函数。所以你的功能......

      • 调用您的子程序
      • 将结果存储在静态变量数组
      • 根据其在电子表格中的位置调出正确的值。

      这可能会有效,但仍然会导致问题,因为您必须非常积极地管理变量,在不需要时覆盖它们等等。

      可以做到,但不可取。

      您可以对全局变量使用相同的方法,但没有更大的收益

    2. 现在提供一个简单而优雅的解决方案:

      • 使用程序中种子激活的伪随机数生成器,而不是使用标准随机数生成器。
      • 您的呼叫功能应该接收要生成的系列的序列号,即3 =生成该子产生的第3个号码等。

      AND

      它会接收种子,您可以在电子表格中随机生成。

    3. 这样,您在电子表格上的功能就是

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

      为每个系列维护相同的种子,并使用种子在内部计算原始系列中第10个第4个数字的第3个。

      有许多简单的统一随机数生成算法可以使用种子确定性地生成数字,这样这些数字在统计上与真正的均匀随机数无法区分。

      P.S。无论如何,这就是Rnd函数内部工作的方式