创build一个仅与1个单元格中的变化有关的函数的randrand

我一直在努力与此一段时间,不能find一个在线帮助资源。

每当电子表格中的任何值发生更改时, rand()randbetween()函数默认都会更改。

我想要做的是编写一个函数,当单个单元格中的值发生更改时,它只会更改值(使用randbetween)。

所以函数会像=Myrand(sourcecell, maxvalue, minvalue)并且只会在sourcecell更改值时更改值。

任何帮助将非常感激。

VBA用户定义函数(UDF)会在其中一个参数发生更改时重新计算。 所以sourcecell作为Range应该是这个用户自定义函数中的一个参数。 然后这个函数总是重新计算sourcecell更改。

问题是WorksheetFunction.RandBetween使这个UDF易变。 为了避免这种情况,我们需要在调用WorksheetFunction.RandBetween之后设置Application.Volatile False

 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 

只需将以下用户定义的函数放在标准模块中,它应该按照需要工作:

 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 

这个UDF使用静态variables数组来存储最后一个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 

当然,closures和重新打开工作簿后,不能保留随机值的存储。