函数参数VBA

Nil*_*ne- 2 excel vba arguments function

我具有以下三个功能:

当我运行前两个函数时,没有问题,但是当我运行最后一个函数(LMTD)时,它说“被零除”,但是当我调试某些参数时,它们却没有值。我知道我必须做的事,但是我想知道为什么要这样做,因为这对我来说毫无意义。

Tinn-function没有Tut的参数,因此我必须将它们添加到Tinn-function的参数中。Tut也是如此,因为它不了解Tinn的所有论点,而LMTD必须同时包含Tinn和Tut的论点。如果我这样做,一切都会顺利进行。为什么我必须这样做?

Public Function Tinn(Tw, Qw, Qp, Q, deltaT)

Tinn = (((Tw * Qw) + (Tut(Q, fd, mix) * Q)) / Qp) + deltaT

End Function
Run Code Online (Sandbox Code Playgroud)
Public Function Tut(Q, fd, mix)

Tut = Tinn(Tw, Qw, Qp, Q, deltaT) _
    - (avgittEffektAiUiLMTD() / ((Q * fd * mix) / 3600))

End Function
Run Code Online (Sandbox Code Playgroud)
Public Function LMTD(Tsjo)

LMTD = ((Tinn(Tw, Qw, Qp, Q, deltaT) - Tsjo) - (Tut(Q, fd, mix) - Tsjo)) _
    / (WorksheetFunction.Ln((Tinn(Tw, Qw, Qp, Q, deltaT) - Tsjo) _
       / (Tut(Q, fd, mix) - Tsjo)))

End Function
Run Code Online (Sandbox Code Playgroud)

Tra*_*ace 5

我将尝试给出有关如何传递参数的有用且完整的解释:

据我所知,LMTD是调用另一个函数的主要函数。每次调用一个新函数时,它都会被放置在他们所谓的“堆栈”之上。
堆栈的原理涉及在内存的一端(堆栈的顶部)分配和释放内存:将内存分配给在堆栈顶部的函数中声明和使用的那些局部变量(称为函数的作用域)并且在函数超出范围时(返回值时)立即释放这些局部变量。通常称为“后进先出”(LIFO)的内容。
因此,如果您考虑将LMTD作为基础(可能不是最终基础,因为必须由另一个子例程或函数调用它),则每当调用这些函数时,Tinn和Tut就会放在堆栈的顶部。

但是(这里是要点),
不是在函数中本地声明并作为参数传递的变量是标准通过Reference传递的,它们是指针变量,包含在函数的较低层上由函数(或子函数)发送的参数的内存地址。堆。当函数通过引用获取参数时(默认),它可以更改传递的内存地址中包含的值,因此,当返回被调用函数时,可以更改原始变量值。

这个例子说明了这一点:

Sub Base_Sub()

Dim i as single
Dim c as single
Dim d as single

c = 5
d = 6

i = Function_1(c, d)

End Sub

Function Function_1(c, d)

c = 7 'Notice that the variables c and d are also changed in the Base_sub
d = 5 

Function_1 = c + d

End Function
Run Code Online (Sandbox Code Playgroud)

相反,如果按值发送变量(byVal关键字),则意味着将生成原始变量的副本(作为参数传递),并且在函数中操作该副本时,原始变量将保持不变。换句话说,此副本将成为堆栈顶部的局部变量,并在函数超出范围时立即释放。

因此,无需深入研究代码,当您在一个例程中调用许多函数时,它可能有助于您牢记不同层的一般概念。为了关注局部变量,请在VBA中使用“ locals”窗口进行跟踪,或在直接窗口中使用debug.print进行跟踪。通过执行检查,可以帮助您提高有关错误的更多透明度。例如Tinn函数:

If QP = 0 then 
    'Notify problem at QP. 
end if
Run Code Online (Sandbox Code Playgroud)

很抱歉,如果我的解释超出了您的预期,但我试图对此做得尽可能完整。