创建一个仅与1个单元格中的更改相关的函数

时间:2017-11-21 06:38:41

标签: excel vba excel-vba

我一直在努力解决这个问题,但无法找到有帮助的资源。

默认情况下,rand()randbetween()功能会在电子表格中的任何值发生更改时更改。

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

因此该函数类似于=Myrand(sourcecell, maxvalue, minvalue),只会在sourcecell更改值时更改值。

非常感谢任何帮助。

3 个答案:

答案 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

当然,关闭并重新打开工作簿后,无法保留随机值的存储。