Excel vba从另一个工作簿执行用户定义的功能,即使没有被调用

时间:2018-10-24 19:35:43

标签: excel vba

我有一个子例程,该例程会在一定范围内生成6个唯一的随机数,然后将它们按升序放置在工作表中的各个单元中(是的,这是彩票生成器)。该代码工作得很好,除了打开其他包含一些用户定义函数的工作簿时。每当我的代码到达将值放置到单元格中的地步时,它就会进入我的UDF ToColletter()并执行几次(除了使程序陷入瘫痪之外,它什么都不做)。我不明白为什么它要执行我的UDF,因为我不是从子例程中调用它,也根本没有从工作簿中调用它。我尝试将带有UDF的模块设置为Option Private Module,但它仍会调用并执行几次。即使使函数本身成为私有函数也无济于事。谁能向我解释为什么会这样,以及如何阻止不必要地执行UDF?我正在使用Excel2016。这是我的随机数生成器代码:

Sub LotteryNumbers()
Dim Num1 As Integer
Dim Num2 As Integer
Dim Num3 As Integer
Dim Num4 As Integer
Dim Num5 As Integer
Dim PwrNum As Integer
Dim NumbersArr(5) As Integer
Application.ScreenUpdating = False

Range("A6").Activate

'Each loop generates one ticket containing 6 random numbers
'The '+1' is the winning numbers
For y = 1 To Range("NumTickets").Value + 1
    'Generate random numbers
    Num1 = WorksheetFunction.RandBetween(1, 70)
    Num2 = Num1
    Num3 = Num2
    Num4 = Num3
    Num5 = Num4
    PwrNum = WorksheetFunction.RandBetween(1, 25)
    'These loops prevent any of the numbers from equalling each other
    Do While ((Num2 = Num1) Or (Num2 = Num3) Or (Num2 = Num4) Or (Num2 = Num5))
        Num2 = WorksheetFunction.RandBetween(1, 70)
    Loop
    Do While ((Num3 = Num1) Or (Num3 = Num2) Or (Num3 = Num4) Or (Num3 = Num5))
        Num3 = WorksheetFunction.RandBetween(1, 70)
    Loop
    Do While ((Num4 = Num1) Or (Num4 = Num2) Or (Num4 = Num3) Or (Num4 = Num5))
        Num4 = WorksheetFunction.RandBetween(1, 70)
    Loop
    Do While (Num5 = Num4) Or (Num5 = Num3) Or (Num5 = Num2) Or (Num5 = Num1)
        Num5 = WorksheetFunction.RandBetween(1, 70)
    Loop

    'Place the numbers in an array so they can be easily sorted
    NumbersArr(1) = Num1
    NumbersArr(2) = Num2
    NumbersArr(3) = Num3
    NumbersArr(4) = Num4
    NumbersArr(5) = Num5

    'Sort the numbers in ascending order and place them in 6 individual cells
    For x = 1 To 5
        'This is the line that calls the ToCollet() function
        ActiveCell.Value = WorksheetFunction.Small(NumbersArr(), x + 1)
        ActiveCell.Offset(0, 1).Activate
    Next x
    ActiveCell.Value = PwrNum
    'Finish the loop at the beginning of the next row
    ActiveCell.Offset(1, -5).Activate
Next y

Application.ScreenUpdating = True

End Sub

这是我的UDF ToCollet()代码,该代码位于单独的工作簿和私有模块中:

Function ToColletter(Collet)
   ToColletter = Split(Cells(1, Collet).Address, "$")(1)
End Function

1 个答案:

答案 0 :(得分:0)

您的ToColletter函数称为易失函数。这意味着每次重新计算工作簿时,无论输入值是否更改,都将重新计算它。之所以调用它,是因为您的第一个函数正在更新工作簿中的值,从而导致Excel重新计算。

这是因为您没有直接给出函数值;取而代之的是,该函数需要从工作表中查找一个值,因此该函数直到它实际查找该值时才知道是否需要重新计算。

您可以采取的解决措施是摆脱函数中的单元格引用,并使输出仅取决于输入。另外,您可以在运行主子程序之前设置Application.Calculation = xlCalculationManual,并在完成后将其设置回Application.Calculation = xlCalculationAutomatic。这样可以防止Excel在子程序运行时自动重新计算。