我已经花了将近一个小时的时间来解决这个问题,但似乎无济于事。

基本上,我想尝试一个更好的随机数生成器,并找到了我想尝试在程序中实现的代码

 Function RandNorm(Optional mean As Double = 0, _
              Optional Dev As Double = 1, _
              Optional Corr As Double = 0, _
              Optional bVolatile As Boolean = False) As Double()


Randomize
Dim z(0 To 1)   As Double
Dim U           As Double
Dim V           As Double
Dim S           As Double

If bVolatile Then Application.Volatile

Do
    U = 2 * [rand()] - 1
    V = 2 * [rand()] - 1
    S = U * U + V * V
Loop Until S < 1

S = Sqr(-2 * Log(S) / S)
z(0) = Dev * U * S + mean
z(1) = Dev * V * S + mean

If Corr <> 0 Then z(1) = Corr * z(0) + Sqr(1 - Corr ^ 2) * z(1)
RandNorm = z
End Function


如您所见,该函数返回一个数字。当像=RandNorm()这样在Excel中运行时,一切都很好。但是当以这样的简单代码运行时:

 Sub test()

    Dim x() As Double, i As Long

    ReDim x(1 To 10, 1 To 1)
    For i = 1 To 10
          x(i, 1) = RandNorm
    Next i

    Range("A1:A10") = x
End Sub


尽管它已定义为As Double,但是却出现“类型不匹配”错误。
如果我在RandNorm As Double中定义Sub,那么它的值为0。
但是,如果我将x(i, 1)替换为Cells(i, 1),它将起作用。

该功能也位于其自己的模块和Sub中。

我错过了什么?任何帮助将非常感激。提前致谢!

最佳答案

DoubleDouble()不同:RandNorm返回一个数组。当在单个单元格中用作UDF时,RandNorm返回该数组的第一个元素。例如,考虑以下功能。

Function foo() As Double()
    Dim z(0 To 1) As Double
    z(0) = 1
    z(1) = 2
    foo = z
End Function


当在单个单元格中用作UDF时,=foo()将始终返回1。您需要使用Ctrl + Shift + Enter在2个单元格中将其作为数组公式输入,以显示第二个元素2

简单的解决方法可能是将Double()更改为Double,将RandNorm = z更改为RandNorm = z(0)

Function RandNorm(Optional mean As Double = 0, _
              Optional Dev As Double = 1, _
              Optional Corr As Double = 0, _
              Optional bVolatile As Boolean = False) As Double
    ....
    If Corr <> 0 Then z(1) = Corr * z(0) + Sqr(1 - Corr ^ 2) * z(1)
    RandNorm = z(0)
End Function


尽管很难说这就是您要寻找的东西-因为您实际上忽略了z(1)

关于excel - UDF随机数生成器类型不匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53195457/

10-10 18:48