Function arguments VBA

2019-07-19 17:49发布

I have these three functions:

When I run the first 2 functions, There's no problem, but when I run the last function (LMTD), It says 'Division by zero' yet when I debug some of the arguments have values, some don't. I know what I have to do, but I want to know why I have to do it, because it makes no sense to me.

Tinn-function doesn't have Tut's arguments, so I have to add them to Tinn-function's arguments. Same goes for Tut, that doesn't know all of Tinn's arguments, and LMTD has to have both of Tinn and Tut's arguments. If I do that, it all runs smoothly. Why do I have to do this?

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

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

End Function

Public Function Tut(Q, fd, mix)

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

End Function

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

1条回答
\"骚年 ilove
2楼-- · 2019-07-19 18:23

I will try to give a useful and complete explanation on how arguments are being passed:

As far as I can tell, LMTD is the main function calling the other function. Each time a new function is called, it is placed on top of what they call the "stack";
The principle of Stack involves that memory is allocated and deallocated at one end of the memory (top of the stack): memory is allocated to those local variables declared and used in the function on top of the stack (function that is called gets in scope and forms a new layer on top of the stack) while these local variables are being released as soon as the function goes out of scope (when the value is returned). Something generally referred to as "Last In First Out" (LIFO).
So if you consider LMTD the base (which is probably not the ultimate base, since it is must be called by another sub routine or function), Tinn and Tut are placed on top of the stack whenever these functions are being called.

However (and here is the point),
Variables not locally declared in functions and passed as argument are standard passed by Reference, they are pointer variables containing the memory address of the arguments sent by the function (or sub) on the lower layer of the stack. When a function takes parameters by reference (default), it can change the values contained by the memory addresses that are passed and thus the original variable value can be changed when the called function is returned.

This example illustrates it:

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

On the contrary, if you would send variable by value (byVal keyword), this would mean that a copy of the original variable (that is passed as argument) is made and the original variable remains untouched while the copy is being manipulated in the function. In other words, this copy would become a local variable on top of the stack and released as soon as the function goes out of scope.

So without looking into dept into your code to deep, when you call many functions in one routine, it may help you to keep this general concept of the different layers in mind. In order to keep an eye on your local variables, use the "locals" window in VBA for follow-up or use debug.print to follow up in the immediate window. What could help you gain more transparency regarding the error is by performing a check. For example for Tinn function:

If QP = 0 then 
    'Notify problem at QP. 
end if

I'm sorry if my explanation was more than you expected, but I tried to be as complete as possible on this one.

查看更多
登录 后发表回答