Results 1 to 25 of 25

Thread: [RESOLVED] Function Return More Than One Value

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2005
    Posts
    400

    Resolved [RESOLVED] Function Return More Than One Value

    I know this is a stupid question but I've never needed to do this until now. How can I make a function return more than one value? For example, if I want a function to return the time, day, month, and year all in different variables, how would I do this? Thanks

  2. #2
    Frenzied Member zynder's Avatar
    Join Date
    Nov 2006
    Location
    localhost
    Posts
    1,434

    Re: Function Return More Than One Value

    You can make Sub rather than a function.

    Private Sub ReturnTime

    Private Sub ReturnDay

    Private Sub ReturnMonth

    Private Sub ReturnYear

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Jul 2005
    Posts
    400

    Re: Function Return More Than One Value

    How do I even use subs? I never used subs because they didn't return values so I used functions.

  4. #4
    Frenzied Member
    Join Date
    Jun 2006
    Posts
    1,098

    Re: Function Return More Than One Value

    Code:
    Option Explicit
    
    Private Sub Command1_Click()
      Dim lngA As Long
      Dim lngB As Long
      
      Call Example(20, lngA, lngB)
      Debug.Print lngA
      Debug.Print lngB
    End Sub
    
    Private Sub Example(lngIn As Long, lngOutA As Long, lngOutB As Long)
      lngOutA = lngIn * 2
      lngOutB = lngIn \ 2
    End Sub

  5. #5
    Former Admin/Moderator MartinLiss's Avatar
    Join Date
    Sep 1999
    Location
    San Jose, CA
    Posts
    33,431

    Re: Function Return More Than One Value

    abazabam, just so you don't get the wrong idea from what has been posted so far, it's not the fact that Subs are being used but rather as in Logophobic's example that the values that are being passed to the sub are being passed (by default) ByRef, so it could be rewritten as follows.

    Private Sub Example(ByRef lngIn As Long, ByRef lngOutA As Long, ByRef lngOutB As Long)

    When you pass something ByVal only a copy of the value is passed so any changes to the value remain in the called sub, but if you pass ByRef you are actually passing a pointer to the variable in memory so changes made in the called sub affect the variable in the calling routine.

  6. #6
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Function Return More Than One Value

    This might need a bit more explanation: by default variables are passed to subs and functions ByRef. This means that a reference to a variable is used in the procedure, so changing the contents of the variable change the variable that was passed to the procedure.

    When variables are passed ByVal, then you can change the contents of the variable just as much you like within the procedure and it has no effects to the variable that was given as a parameter to the procedure.


    For some random knowledge, speedwise ByRef is faster for Strings and Variants, ByVal is faster for numeric datatypes. This because ByVal makes a copy of the variable contents, and copying a String includes memory management. However, it is faster to use local (ByVal) variables than external (ByRef) variables, so datatypes such as Long that only have four bytes get copied instantly and are also faster to access when passed as ByVal.


    Edit!
    Slow, that I am, with all this useless extra information

  7. #7
    New Member
    Join Date
    Apr 2007
    Posts
    5

    Re: Function Return More Than One Value

    The best way to do it - is returning Array of Variant from function:

    vb Code:
    1. Function ABC(n As Integer) As Variant()
    2.  
    3. Dim x(2) As Variant
    4.  
    5.         x(0) = 12
    6.         x(1) = "HHH"
    7.  
    8.         ABC = x
    9.  
    10. End Function
    11.  
    12. Private Sub Command1_Click()
    13.  
    14.         Debug.Print ABC(1)(0)
    15.  
    16. End Sub

    Create new project, add a form and put a command button to it. Then insert the code written above. Start project and press a button. Then change line in click event :
    vb Code:
    1. Debug.Print ABC(1)(1)
    . Start project and press button. OK?

  8. #8
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Function Return More Than One Value

    Variant is never a good solution. You should always use a specific datatype. Reasoning this goes off the scope of the topic of the thread so no more on that.

    Returning an array is also bit of a waste if you only need the certain variables out of the procedure. I just fixed a PHP project that returned tons of array variables from functions and it was almost a nightmare to track down how it all worked (of course there were other things that weren't done all that well increasing the difficulty). The point however: if you use good variable names, you self document the code well. Although writing comments is not a bad idea.

  9. #9
    New Member
    Join Date
    Apr 2007
    Posts
    5

    Re: Function Return More Than One Value

    If Variant "is NEVER a good solution" why this data type in VB exist? My solution will also work if type of array is not Variant (Integer, Long, String and so on)! Abazabam wish return from function different data types (Date, Time, integer...). Variant array is one of the simplest solutions. Another way - returning UDT-variable.
    Last edited by CatsTail; Apr 8th, 2007 at 04:47 AM.

  10. #10
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Function Return More Than One Value

    A UDT is a good idea, tho it doesn't necessarily provide an advantage over separate parameters (except ease of reading, as you can use it as the return value for a Function).
    Quote Originally Posted by CatsTail
    If Variant "is NEVER a good solution" why this data type in VB exist?
    To make things easier for people who are new to programming.. it means that they can ignore one subject (Data types) for a while as they are learning.

    Variants have many bad points, such as: memory wastage, they are slow, and they are prone to coercion errors.

  11. #11
    New Member
    Join Date
    Apr 2007
    Posts
    5

    Re: Function Return More Than One Value

    Do You like "Variant" as well as "GoTo"?
    Last edited by CatsTail; Apr 8th, 2007 at 10:04 AM.

  12. #12
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Function Return More Than One Value

    Two of the three worst things to ever happen to VB.... Variant (#3) and GoTo (#2). The #1 worst thing to ever happen to VB... On Error Resume Next.

    But that's just this gnomes opinion.

    The array gives you no advantage to individual return parameters (byRef). It gives no context as to what's in it. Element 1... what is it? I don't know. No one knows, it's a variant. Could be anything. IS it the time? Or is it the date? There's no data typing so when it's returned, before I can do anything with it, it has to be validated, checked and in the end remains suspicious. It can't be trusted. But a parameter typed specific to a Date and called BirthDay, well, heck I know what that is.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  13. #13
    Addicted Member TBeck's Avatar
    Join Date
    Apr 2006
    Location
    Ontario, Canada
    Posts
    254

    Re: Function Return More Than One Value

    you could create a custom type that contains your two variables and return that type

  14. #14
    New Member
    Join Date
    Apr 2007
    Posts
    5

    Re: Function Return More Than One Value

    Element 1 of Variant type... What is it? No problem! Do you know such functions as isNumeric(), isDate(), and so on.

  15. #15
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Function Return More Than One Value

    Of course - but that's lots of extra work (that is prone to errors), which is not required if the sub/function is set up properly.

    Using a custom type as you and TBeck suggested is a suitable alternative to parameters.. but typically (tho not always) involves slightly more work than the parameter method.

  16. #16
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Function Return More Than One Value

    Quote Originally Posted by CatsTail
    Element 1 of Variant type... What is it? No problem! Do you know such functions as isNumeric(), isDate(), and so on.
    This is exactly what makes Variant array return value a pain to debug: if it doesn't always return the same datatype that is expected, then it really is horrible to know all the return values that it gives by the end user of the function, if it is someone else than who has written the function.

    With regular functions that return a certain datatype you immediately know what is the range of values that can be returned. You can also know the error situatation.


    What is important with functions is that they can handle errors. First thing for a function is to handle it's input values so that it validates them to be in the format the function can handle. Easiest way for this is to set specific datatypes, which narrows down the possible values. If you need further validation, then that needs some code.

    The next thing is to handle return values: if an error occurs, the function should return some value that is out of the normal scope of possible return values. For functions returning a string the easiest way is to return a null string (codewise this either means giving vbNullString or not returning anything at all). But to go for actual topic, how to tell such a thing when returning multiple values?

    Code:
    Public Function GetDataByID(ByVal ID As Long, ByRef Title As String, ByRef Description As String) As Boolean
        ' the ID can't be negative or zero: database starts from ID 1
        If ID < 1 Then Exit Function
        ' get data from database... just some pseudocode
        ' the ID might be unexistant in which case the database call fails!
        ' we can't trust input values to be always correct
        If DatabaseCallSucceeded Then
            ' set return values
            Title = TitleValueFromDB
            Description = TitleValueFromDB
            ' return true in success
            GetDataByID = True
        End If
    End Function
    Now the advantages: the function itself returns True in success, so in the main code that calls the function you know if you can continue a certain processing:
    Code:
        Dim strTitle As String, strDescription As String, lngID As Long
        ' get written ID from textbox:
        ' we don't need to validate it here because we know the function does that for us!
        lngID = CLng(Val(Text1.Text))
        ' now call the function
        If GetDataByID(lngID, strTitle, strDescription) Then
            ' show the data in a message box
            MsgBox strDescription, vbInformation, strTitle
        Else
            ' show error message in failure
            MsgBox "The ID value you gave is invalid. Please make sure the ID is a positive number and exists in the database.", vbExclamation, "Error"
        End If
    Far far easier than doing complicated checks for Variant return values!

  17. #17
    New Member
    Join Date
    Apr 2007
    Posts
    5

    Re: Function Return More Than One Value

    I see. You are right. And original question is "return more than one value". Return, but no changing with using ByRef modificator...

  18. #18
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    Re: Function Return More Than One Value

    Which is kind of irrelevant. If you always help strictly by the question, you end up giving bad help. Sometimes it is even impossible to know what exactly is wanted. I find it more important also to teach good techniques. The person who asks the question doesn't know of the better way to do things, so that is why it is important to let them know. Of course at times there is no one right way to do things -> there is space for different answers and opinions.

    But all this is already pretty thick offtopic, so...

  19. #19
    Frenzied Member zynder's Avatar
    Join Date
    Nov 2006
    Location
    localhost
    Posts
    1,434

    Re: Function Return More Than One Value

    Quote Originally Posted by techgnome
    Two of the three worst things to ever happen to VB.... Variant (#3) and GoTo (#2). The #1 worst thing to ever happen to VB... On Error Resume Next.

    But that's just this gnomes opinion.

    The array gives you no advantage to individual return parameters (byRef). It gives no context as to what's in it. Element 1... what is it? I don't know. No one knows, it's a variant. Could be anything. IS it the time? Or is it the date? There's no data typing so when it's returned, before I can do anything with it, it has to be validated, checked and in the end remains suspicious. It can't be trusted. But a parameter typed specific to a Date and called BirthDay, well, heck I know what that is.

    -tg
    #2 GoTo is not actually worst thing to happen in VB. In fact it's useful on error handlers and the On Error Resume Next, yes it's to be avoided as much as possible but there are some circumstances that it is needed.

    However, the Variant usage is a waste of memory.

  20. #20
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Function Return More Than One Value

    On Error GoTo and GoTo are not the same thing.... the GoTo stands alone. On Error GoTo is a complete statement.

    I've never, ever, ran in to a case where OERN was needed. I'll admit, I used to use it pretty judiciously, until I learned better. Granted error handling on VB6- isn't all that, but there really is no need for OERN.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  21. #21
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Function Return More Than One Value

    I know where you are coming from, almost every time I see O.E.R.N. on the forums it is completely inappropriate - it is just being used to mask errors, at which point we are asked "why doesn't this code do what it should?"

    There are times when (if used properly) it is the most appropriate method tho.. typically I will use it 2 or 3 times in a program (out of about 500 subs/functions). Most often is when working with groups of controls (which may or may not be part of a control array).

    Apart from "On Error", I have yet to find a valid use for GoTo.

  22. #22
    Fanatic Member bgmacaw's Avatar
    Join Date
    Mar 2007
    Location
    Atlanta, GA USA
    Posts
    524

    Re: Function Return More Than One Value

    Quote Originally Posted by si_the_geek
    I have yet to find a valid use for GoTo.
    The only potential semi-legit use I've seen for it was for it in VB6 to act as a stand-in Continue For or Continue Loop statement. I inherited some code where the original programmer had done something like this:

    VB6 Code

    vb Code:
    1. Private Sub BigHugeProcess()
    2.     Dim nLoop As Long
    3.     For nLoop = 1 To NumberOfLinesInFile
    4.         '
    5.         ' Check for a condition at the start of the loop
    6.         '
    7.         If SkipThisLine(LineText) Then
    8.             GoTo EndOfLoop
    9.         End If
    10.         '
    11.         ' about 3 pages of processing follows
    12.         '
    13. EndOfLoop:
    14.     Next
    15. End Sub

    What it would look like in VB.Net code

    vb Code:
    1. Private Sub BigHugeProcess()
    2.         For nLoop As Integer = 1 To NumberOfLinesInFile
    3.             '
    4.             ' Check for a condition at the start of the loop
    5.             '
    6.             If SkipThisLine(LineText) Then
    7.                 Continue For
    8.             End If
    9.             '
    10.             ' about 3 pages of processing follows
    11.             '
    12.         Next
    13.     End Sub

    Of course, it's usually a lot better idea to break up BigHugeProcess into several smaller routines since it's also a bad coding practice to have large monolithic routines.

    As for variants in VB6, I have used them in a few cases to implement kind of a "poor man's overloading" and as variant arrays in return values where they acted somewhat like Serialization or other object packaging methods in .NET. I agree these are risky to use and great care must be exercised to avoid conversion problems and that the performance impact has to be weighed against the flexibility advantages. Flexibility won out in the apps where I used these methods since quickly implementing new clients and processes was the most important requirement.

  23. #23
    PowerPoster
    Join Date
    Feb 2006
    Location
    East of NYC, USA
    Posts
    5,691

    Re: Function Return More Than One Value

    Quote Originally Posted by techgnome
    I've never, ever, ran in to a case where OERN was needed.
    Needed, no. Used properly, yes.
    Code:
    On Error GoTo XYZ
    ...
    'code
    
    On Error Resume Next
    Kill sFileNameToBeKilled
    On Error GoTo XYZ
    You could trap the file not found error and figure out if it's the file we're trying to delete, but it's simpler to resume around that one line. That particular error in that particular place - once the program has been fully debugged - is to be expected at times.
    The most difficult part of developing a program is understanding the problem.
    The second most difficult part is deciding how you're going to solve the problem.
    Actually writing the program (translating your solution into some computer language) is the easiest part.

    Please indent your code and use [HIGHLIGHT="VB"] [/HIGHLIGHT] tags around it to make it easier to read.

    Please Help Us To Save Ana

  24. #24
    PowerPoster
    Join Date
    Feb 2006
    Location
    East of NYC, USA
    Posts
    5,691

    Re: Function Return More Than One Value

    Quote Originally Posted by bgmacaw
    The only potential semi-legit use I've seen for it was for it in VB6 to act as a stand-in Continue For or Continue Loop statement.
    You can just invert the logic to avoid most uses of this type
    Code:
    Private Sub BigHugeProcess()
        Dim nLoop As Long
        For nLoop = 1 To NumberOfLinesInFile
            '
            ' Check for a condition at the start of the loop
            '
            If Not SkipThisLine(LineText) Then
            ' about 3 pages of processing follows
            End If
            '
        Next
    End Sub
    There's no real difference, but it's more "PC", if that matters.
    The most difficult part of developing a program is understanding the problem.
    The second most difficult part is deciding how you're going to solve the problem.
    Actually writing the program (translating your solution into some computer language) is the easiest part.

    Please indent your code and use [HIGHLIGHT="VB"] [/HIGHLIGHT] tags around it to make it easier to read.

    Please Help Us To Save Ana

  25. #25
    Fanatic Member bgmacaw's Avatar
    Join Date
    Mar 2007
    Location
    Atlanta, GA USA
    Posts
    524

    Re: Function Return More Than One Value

    Quote Originally Posted by Al42
    You can just invert the logic to avoid most uses of this type
    True, although in a large routine where there is a lot of If...Then...Else or Select...Case filtering the indent levels also create a readibility problem. That's why it's best to break these huge routines up into more manageable and readable chunks.

Posting Permissions

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



Click Here to Expand Forum to Full Width