Consulting

Results 1 to 16 of 16

Thread: what exactly is a "sub"

  1. #1
    Banned VBAX Regular
    Joined
    Sep 2009
    Posts
    20
    Location

    what exactly is a "sub"

    i honestly dont know what a sub is i see what it does but how would i describe that to someone. thnks

  2. #2
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    A sub is just a runnable procedure, it can be a stand-alone macro that achieves the whole task, or it could be just one within a bunch of subs that in combiantion achieve the task.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  3. #3
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Hi xld. Distinguished Lord? Hoooweeee! When did THAT category come about?

    Mike, from other threads you have posted it sures seems like you do not bother to do anything for yourself, but look for someone to hand you things...hmmmm, like a lord perhaps. Except I know for a fact that xld works hard.

    Did you even try to look up what a Sub is? Here, let me hold your hand since you appear to need it.

    As xld stated, a Sub is a runnable procedure. I will be more explicit and clear - as I hope I have tried to impress upon you in another thread that clarity and exactness works in your favour.

    Sub: a procedure with one or more instructions; it can take arguments (parameters).

    Function: a procedure with one of more instructions; it can take arguments (parameters), and returns a single value.

    That is what makes Functions different from Subs. Functions always return a value. Whether you (as the programmer) use that value or not is up to you. Best practice states that:

    1. if you do not need/use that value, then you should use a Sub;

    2. the Data Type should be defined. If you do not define it, VBA defaults to returning a Variant.
    [vba]
    Function Yadda (arg1 As Long, arg2_whatever As String) As String
    instruction_1
    instruction_2
    Yadda = some_string
    End Function
    [/vba]
    returns a string variable.
    [vba]
    Function Yadda (arg1 As Long, whatever As String)
    instruction_1
    instruction_2
    Yadda = some_string
    End Function
    [/vba]
    no Data Type defined, returns a Variant. That variant will be set as the string...but it is still a Variant.
    [vba]
    Sub Yadda(arg1 As Long, whatever As String)
    instruction_1
    instruction_2
    instruction_3
    End Sub
    [/vba]is a set of instructions. That is it. The instructions are fired (executed, run) by calling the name of the procedure.

  4. #4
    Banned VBAX Regular
    Joined
    Sep 2009
    Posts
    20
    Location
    i just posted those so that i had enough posts to allow me to attach a picture.

  5. #5
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    Quote Originally Posted by fumei
    Hi xld. Distinguished Lord? Hoooweeee! When did THAT category come about?
    That just dropped it on me Gerry as I was the first to 10K posts.

    Quote Originally Posted by fumei
    Function: a procedure with one of more instructions; it can take arguments (parameters), and returns a single value.

    That is what makes Functions different from Subs. Functions always return a value. Whether you (as the programmer) use that value or not is up to you. Best practice states that:
    Just a small issue, but from my perspective, Subs and Functions are the same, and apart from event procedures I only use functions. My rationale is that every call should return at least one result (although I ave to admit I don't follow that religiously), to indicate succes or faiilure. Other return values can be acheived by ByRef arguments, either individually, in arrays, or in Types. I know that you know all that, but I just opened it up for discussion, not necessarily for the OP.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  6. #6
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    "I only use functions."

    " My rationale is that every call should return at least one result"

    Could you elaborate on that? Are you saying you use that result for something EVERY time you use that set of instructions?

    I agree that Subs and Functions are the same, in that they are both sets of instructions.

    I am 180 degrees opposite to you, it seems. I use Subs, and only use Functions when a function is what I want; a set of instructions that returns a single Data Type.

  7. #7
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    Quote Originally Posted by fumei
    "I only use functions."

    " My rationale is that every call should return at least one result"

    Could you elaborate on that? Are you saying you use that result for something EVERY time you use that set of instructions?.
    I am saying that I can easily argue that every time a call is made to a procedure, that procedure should at least return a success or failure value, and that the caller should test that call to see whether it was successful or not, or the degree of success. By that logic, all calls would be to functions.

    Quote Originally Posted by fumei
    I am 180 degrees opposite to you, it seems. I use Subs, and only use Functions when a function is what I want; a set of instructions that returns a single Data Type.
    So what do you do if you want to return 2 values, 3 values, ..., do you b end a sub?
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  8. #8
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Well, it depends on what you mean by "return".

    If I need 2, 3, 4...x values, then I have those values are variables, and those are set by the instructions themselves. If those values need processing (or error trapping), then those values can be routed through a set of instructions - which may in fact be a Function.
    [vba]
    Function YesItIsTrue(SomeParameter As Long) As Boolean
    If SomeParameter > 5 Then
    YesItIstrue = True
    Else
    YesItIsTrue = False
    End If
    End Function

    Sub Blah()
    Dim yadda As Long
    ' do this
    instruction_1
    ' do that
    instruction_2
    ' do something else
    instruction_3

    Yadda = whatever
    If YesItIsTrue(Yadda) Then
    ' go for a walk
    Else
    ' ride a bike
    End If
    End Sub
    [/vba]

    The instructions 1, 2, 3 of the Sub are just instructions. The only place I need a "return" - to use it! - is the instruction regarding the value of Yadda. So...it uses a Function.

    instruction_1, and _2, and _3 do NOT need a "return", so they are what they are...instructions.

    So again, if I need 3, 4, 5 values then those are variables.

    Besides, a Function can only return a single value anyway. While of course the instructions within a Function can do - like a Sub - any number of things, the Function itself can not give 2, 3, 4 returns. Functions return ONE value. IMO, that is their purpose.

  9. #9
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    Quote Originally Posted by fumei
    Besides, a Function can only return a single value anyway.
    [vba]

    Public Function TheCaller()
    Dim var1 As String
    Dim var2 As Long

    var1 = "the start value is "
    var2 = 25
    MsgBox var1 & var2

    var2 = MyFunction(var1)
    MsgBox var1 & var2

    End Function

    Private Function MyFunction(ByRef inValue As String) As Long

    Select Case inValue

    Case "the start value is "

    inValue = "and has been changed to "
    MyFunction = 101

    Case Else

    inValue = "oops, what has happened "
    MyFunction = -1
    End Select

    End Function
    [/vba]
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  10. #10
    Moderator VBAX Master Tommy's Avatar
    Joined
    May 2004
    Location
    Houston, TX
    Posts
    1,184
    Location
    Bob,
    How does a string and a number (long) concatenate?

    There is no conversion.

  11. #11
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    Sorry Tommy, I don't understand the question.
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  12. #12
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    Tommy,

    Concatenation automatically assumes strings and so if you try and concatenate a non-string, it does the conversion for you, there is no need to do it (although it could be argued that it would be good practice to do so).

    Thus ?"My age is " & 35 will end up as "My age is 35", no error, no mis-typing.

    It is casting the number to a string just because the first part is a string, try concatenating two numbers and they do not get added. SO

    ?25 & 73 is not 98, it is 2573!

    Strangely enough, at leats it is to me, you can concatenate with +, although explicit conversion is reqyired here.

    ?"my age is " + CStr(27) returns "my age is 27"

    whereas

    ?"my age is " + 27

    just errors with a type mismatch
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  13. #13
    Moderator VBAX Master Tommy's Avatar
    Joined
    May 2004
    Location
    Houston, TX
    Posts
    1,184
    Location
    Quote Originally Posted by xld
    Tommy,

    Concatenation automatically assumes strings and so if you try and concatenate a non-string, it does the conversion for you, there is no need to do it (although it could be argued that it would be good practice to do so).
    Old habits die hard. I, most of the time, will make sure it is a string before concatenating. In VB5 where I started coding in VB I got a lot of errors with the + so I had to use the Cstr function. Then I found out about the & and still used Cstr to change it to a string first. That is why I was asking, thanks for the explanation.

    Back on topic:
    As a Fortran developer for years, I didn't know what a function was, so I used subs. Now I only use a function when I am interested in returning a value that helps the logic of the program to make a decision, or when it is a worker bee that sets the value of a variable. To me a function that returns a null value is a sub.

  14. #14
    Distinguished Lord of VBAX VBAX Grand Master Bob Phillips's Avatar
    Joined
    Apr 2005
    Posts
    25,453
    Location
    I am not suggesting that everyone does as I do, there are no clear benefits to my approach that I can see. I was just pointing out the alternatives, and it just seems cleaner to me and suits my style. I do use subs in my postings though
    ____________________________________________
    Nihil simul inventum est et perfectum

    Abusus non tollit usum

    Last night I dreamed of a small consolation enjoyed only by the blind: Nobody knows the trouble I've not seen!
    James Thurber

  15. #15
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    I am with Tommy:

    "Now I only use a function when I am interested in returning a value that helps the logic of the program to make a decision, or when it is a worker bee that sets the value of a variable. To me a function that returns a null value is a sub."

    My bolding.

    As for the two functions posted...you STILL have to use a...ahem....Sub to use TheCaller, yes?

    And, in fact, no matter what, as TheCaller function value (and as the Data Type is NOT defined, it will be a Variant) is never actually explicitly set....the function itself will always return the same value (vbEmpty). So what is the point exactly?
    [vba]
    Option Explicit
    Public WhatIsTheCallerValue As Variant


    Public Function TheCaller()
    Dim var1 As String
    Dim var2 As Long

    var1 = "the start value is "
    var2 = 25
    MsgBox var1 & var2

    var2 = MyFunction(var1)
    MsgBox var1 & var2
    WhatIsTheCallerValue = TheCaller
    End Function

    Private Function MyFunction(ByRef inValue As String) As Long

    Select Case inValue
    Case "the start value is "
    inValue = "and has been changed to "
    MyFunction = 101
    Case Else
    inValue = "oops, what has happened "
    MyFunction = -1
    End Select
    End Function

    ' you have to use a Sub to...well, use the functions.
    Sub TryIt()
    Call TheCaller
    If WhatIsTheCallerValue = vbEmpty Then
    MsgBox "Empty"
    Else
    MsgBox "Huh?"
    End If
    End Sub
    [/vba]It will always come back as Empty. So again...what is the point?

    Further, in the Function MyFunction, you have:[vba]

    Case Else
    inValue = "oops, what has happened "
    MyFunction = -1
    [/vba]Considering the inValue variable is never changed by the first Function, the Case Else can never execute...so, again...what is the point of this? I do not get it. I would do it as:
    [vba]
    Option Explicit

    Public Sub TheCaller()
    Dim var1 As String
    Dim var2 As Long

    var1 = "the start value is "
    var2 = 25
    MsgBox var1 & var2

    var2 = MyFunction(var1)
    MsgBox var1 & var2
    End Sub

    Private Function MyFunction(ByRef inValue As String) _
    As Long

    Select Case inValue
    Case "the start value is "
    inValue = "and has been changed to "
    MyFunction = 101
    Case Else
    inValue = "oops, what has happened "
    MyFunction = -1
    End Select
    End Function
    [/vba]You STILL get the two messages:

    "the start value is 25"

    and

    "and has been changed to 101"

    So, if the purpose is to display those messages, this has been achieved. But, you do not need an additional Sub to call the two functions, as there is only ONE function...whose purpose is to - as Functions do - return a single value (in this case the 101).

    The use of ByRef on the string to change "the start value is " to "and has been changed to " is a good thing, but technically totally irrelevant to the function (because, as it is written, it can NOT do anything else).

    True, using the Case Else to set a value of -1 to MyFunction would be a good idea (even though it can never happen here)...if you ever use it. But if you never use it...again, what is the point?

    In fact, there could be an argument made for no functions at all (at least in the example that is being posted).
    [vba]
    Public Sub TheCaller()
    Dim var1 As String
    Dim var2 As Long
    var1 = "the start value is "
    var2 = 25
    MsgBox var1 & var2

    Call ChangeStuff(var1, var2)
    MsgBox var1 & var2

    End Sub
    Sub ChangeStuff(ByRef strIn As String, _
    ByRef lngIn As Long)
    strIn = "and has been changed to "
    Select Case lngIn
    Case 25
    lngIn = 101
    Case Else
    lngIn = 2345
    End Select
    End Sub
    [/vba]Result?


    "the start value is 25"

    and

    "and has been changed to 101"

    Exactly the same result. So, if the purpose is to display X, do a set of instructions, and display Y, then...a set of instructions is what is needed, which is exactly what a Sub is. A set of instructions.

    If there is a requirements for error-trapping, then by all means do error-trapping within the Sub. But you do not need a return value, then...you do not need a return value. And Functions can only return ONE value. Sure the - ahem - set of instructions within a function can do, well, anything you want, but that is...a set of instructions.

    A Sub.

  16. #16
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    Here is another alternative.
    [vba]
    Public Sub TheCaller()
    Dim var1 As String
    Dim var2 As Long
    var1 = "the start value is "
    var2 = InputBox("A number please.")
    MsgBox var1 & var2
    var2 = MyFunction(var1, var2)
    If var2 <> -1 Then
    ' function does NOT return -1
    MsgBox var1 & var2
    Else
    MsgBox var1
    ' the Case Else in the function
    End If
    End Sub

    Private Function MyFunction(ByRef inValue As String, _
    lngIn As Long) As Long

    Select Case lngIn
    Case 25
    inValue = "and has been changed to "
    MyFunction = 101
    Case Else
    inValue = "oops, what has happened? It is " & _
    "suppose to be 25."
    MyFunction = -1
    End Select
    End Function
    [/vba]Now if you enter 25 into the Inputbox you get:

    "the start value is 25"

    and

    "and has been changed to 101"

    But if you enter anything else, you get:

    "the start value is X" (the value entered into the Inputbox)

    and

    "oops, what has happened? It is suppose to be 25."

    In other words, it actually uses the returned value of the Function. It does what Tommy mentioned: "a value that helps the logic of the program to make a decision".

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •