我一直在努力解决这个问题,但无法找到有帮助的资源。
默认情况下,rand()
和randbetween()
功能会在电子表格中的任何值发生更改时更改。
我想要做的是编写一个函数,当单个单元格中的值发生变化时,它只会改变值(使用randbetween)。
因此该函数类似于=Myrand(sourcecell, maxvalue, minvalue)
,只会在sourcecell
更改值时更改值。
非常感谢任何帮助。
答案 0 :(得分:3)
VBA用户定义函数(UDF)会在其中一个参数发生更改时重新计算。因此sourcecell
作为Range
应该是此用户定义函数中的参数。然后,此函数始终在sourcecell
更改时重新计算。
问题是WorksheetFunction.RandBetween
使这个UDF变得不稳定。为避免这种情况,我们需要在调用Application.Volatile False
后设置WorksheetFunction.RandBetween
。
Public Function Myrand(sourcecell As Range, minvalue As Double, maxvalue As Double) As Double
Myrand = Application.WorksheetFunction.RandBetween(minvalue, maxvalue)
Application.Volatile False
End Function
答案 1 :(得分:1)
只需将以下用户定义的函数放在标准模块中,它应该可以正常工作:
Option Explicit
Public Function MyRand(SourceCell As Range, maxval As Long, minval As Long) As Long
Randomize
MyRand = CLng(Rnd * (maxval - minval + 1)) + minval
End Function
答案 2 :(得分:1)
此UDF使用静态变量数组来存储最后一个sourceCell值和它返回的最后一个随机值。如果独立的sourceCell值未更改,则UDF返回先前计算的随机值。如果已更改,则存储新值并返回新的随机值。
这可以在整个工作簿中多次使用,但如果多次使用,则必须将其使用的渐进索引计数添加到参数中;即每次使用时, ndx 参数必须上升一个。
Function myRand(sourceCell As Range, valMin As Long, valMax As Long, _
Optional ndx As Long = 1)
Static lastSrc As Variant, lastVal As Variant
ndx = ndx - 1 '<~~ zero-based array; one-based count
If Not IsArray(lastSrc) Then
ReDim lastSrc(0 To ndx)
ReDim lastVal(0 To ndx)
ElseIf ndx > UBound(lastSrc) Then
ReDim Preserve lastSrc(0 To ndx)
ReDim Preserve lastVal(0 To ndx)
End If
If lastSrc(ndx) <> sourceCell.Value2 _
Or IsEmpty(lastSrc(ndx)) Or IsEmpty(lastVal(ndx)) Then
lastSrc(ndx) = sourceCell.Value2
lastVal(ndx) = Application.RandBetween(valMin, valMax)
End If
myRand = lastVal(ndx)
End Function
当然,关闭并重新打开工作簿后,无法保留随机值的存储。