在Excel中计算静态随机数(计算一次)

时间:2011-11-04 14:46:10

标签: excel excel-vba excel-formula vba

我正在寻找一种在Excel中计算一次随机数的方法。所以它在第一次被调用时计算,但之后它不会改变。

所以例如,如果我在B1 RANDONCE(A1)中有这样的东西,那么我第一次在A1中放一个值就会计算一个随机值但是它不会再次改变。或者至少在我再次改变A1之前。

我想这样做,而无需手动重新复制B1,将其从公式转换为here所述的值。使用宏很好。

6 个答案:

答案 0 :(得分:4)

我想我有一个更简单的方法来做到这一点。完成电子表格,然后对该列数字应用= RANDBETWEEN函数。然后这样做:

  1. 复制该列的结果。
  2. 突出显示该列并选择“粘贴特殊”并选择“值”。
  3. 现在您拥有最近创建的值,它们是静态的。

答案 1 :(得分:3)

您可以创建UDF(用户定义函数):

Public Function Rand_once(ByVal r As Range)
    Rand_once = Rnd
End Function

在您想要结果的单元格中,您可以输入:

=Rand_once(A1)

只有在源值发生变化时(#{1}}),该值才会发生变化(实际上是重新计算)。

答案 2 :(得分:3)

您需要一个带内存的UDF,因此它知道该单元格是否已更改

当引用调用更改时,此UDF将返回新的随机值,否则返回最后一个随机值(即无更改)
如果源单元格为空白(可能是您要求的也可能不是?)

,也会返回空白

注意:它有一个问题,即当工作表关闭时Static值会丢失,因此每次打开工作表时该值都会更改。

Function randonce(r As Range)
    Static trigger As Variant
    Static v As Double
    If r <> trigger Then
        v = Rnd
        trigger = r
    End If
    If Len(r) <> 0 Then
        randonce = v
    Else
        randonce = vbNullString
    End If
End Function

答案 3 :(得分:3)

您还可以使用循环引用来制作纯粹的公式驱动&#34;切换开关,&#34;允许用户计算一组随机数,然后关闭进一步的重新计算。 Turn off circular reference warnings,然后将此公式放在单元格B3中:

=IF($B$1="YES",RAND(),B3)

如果单元格B1包含&#34; YES&#34;,B3将在每个电子表格重新计算时生成一个新的随机数;如果B1包含任何其他值,则将保留B3的当前值。

答案 4 :(得分:1)

如果您必须跟踪多个单元格,这显然不是最佳解决方案,但如果它只是 A1,您需要跟踪更改,您可以使用事件在B1中执行您的功能,然后在结束时为其分配给定的值。我发现这是最简单的解决方案,它可以按照您的要求运行。

示例:

Private Sub Worksheet_Change(ByVal Target As Range)

If Target.Address = "$A$1" Then
    With Cells(1, 2)
        .Value = "=rand()" 'or whatever
        .Value = .Value
    End With
End If

End Sub

答案 5 :(得分:0)

Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Public Function MySessionRand(Optional seedMod As Single = 0) As Single
    Dim seed As Single
    seed = (-1 * GetCurrentProcessId) - seedMod
    MySessionRand = Rnd(seed)
End Function

此解决方案使用 Excel 的当前 PID 值作为种子。 每次调用 rnd() 时乘以 -1 强制相同的数字,因此只要会话处于活动状态,PID 就不会改变。 'seedMod' 可在需要时帮助重新播种功能,并可用于例如。 ROW() 或 COLUMN()。

Public Function MySessionRand2(Optional seed As Single = 0, Optional min As Double = 0, Optional max As Long = 1) As Double
    ' if called with default values will produce either 0 or 1
    If min >= max Then max = min + 1
    MySessionRand2 = Int((max - min + 1) * MySessionRand(seed) + min)
End Function

以及随机范围的补充函数。