Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Excel / Programming / October 2008

Tip: Looking for answers? Try searching our database.

Function to return two values

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jac Tremblay - 09 Oct 2008 21:13 GMT
Hi,
Is it possible to create a function that will return two values, a boolean
and a string?
I need to exit the main procedure if the data checked by the function is not
valid and also display a message according to the particular validation.
For example:
If Not DataIsValid Then
 Msgbox strErrorMsg  ' Returned from the function
 Exit Sub
end IF
Thanks
Signature

Jac Tremblay

Jim Cone - 09 Oct 2008 21:50 GMT
Maybe...
'--
Function IcelandBanking(ByRef strMsg As String) As Boolean
Dim WontPay As Long
Dim NoReserves As Boolean

'Code here to calculate WontPay and NoReserves
WontPay = 0
NoReserves = True

If WontPay > 0 Then
  strMsg = "Small Withdrawals Only"
Else
  strMsg = "You are out of luck"
End If
IcelandBanking = NoReserves
End Function
'--
Sub FinancialStatus()
Dim strText As String
MsgBox IcelandBanking(strText) & vbCr & strText
End Sub
Signature

Jim Cone
Portland, Oregon  USA

"Jac Tremblay"
<jac.tremblay@donotspam.com>
wrote in message
Hi,
Is it possible to create a function that will return two values, a boolean
and a string?
I need to exit the main procedure if the data checked by the function is not
valid and also display a message according to the particular validation.
For example:
If Not DataIsValid Then
 Msgbox strErrorMsg  ' Returned from the function
 Exit Sub
end IF
Thanks
--
Jac Tremblay

Peter T - 09 Oct 2008 22:07 GMT
ouch, LOL!

Peter T

> Maybe...
> '--
[quoted text clipped - 18 lines]
> MsgBox IcelandBanking(strText) & vbCr & strText
> End Sub
Jac Tremblay - 10 Oct 2008 07:10 GMT
Hi Jim,
When I first read your answer, I thought that wouldn't work. But I tried it
out and found it is interesting. I changed it a bit so I could get the two
values in two separated variables. Here is what I came up with:
Function IcelandBanking(ByRef strMsg As String) As Boolean
  Dim WontPay As Long
  Dim NoReserves As Boolean
 
  'Code here to calculate WontPay and NoReserves
   WontPay = 1
   NoReserves = False
 
  If WontPay > 0 Then
     strMsg = "Small Withdrawals Only"
  Else
     strMsg = "You are out of luck"
  End If
  IcelandBanking = NoReserves
End Function
'--
Sub FinancialStatus()
  Dim strText As String
  Dim strTrueOrFalse As String
  Dim strMsg As String
  Dim strResult As String
  Dim intPosVbCr As Integer
'   MsgBox IcelandBanking(strText) & vbCr & strText
  strResult = IcelandBanking(strText) & vbCr & strText
  intPosVbCr = InStr(1, strResult, vbCr)
  strTrueOrFalse = Mid(strResult, 1, intPosVbCr - 1)
  strMsg = Mid(strResult, intPosVbCr + 1, Len(strResult) - intPosVbCr)
  MsgBox "strTrueOrFalse = " & strTrueOrFalse & vbCrLf & _
        "strMsg = " & strMsg
End Sub
It works OK, but I am not sure I will use it.
My problem is that I have to check 4 different information from a
transaction. I want to group the 4 validations in a separate procedure or
function. If an error occurs, I want to display a pertinent message and exit
the main proc. Here is another way I figured out to solve my problem:
Option Explicit
Public strMessage As String
' ---
Function fbooDataIsValid(ByVal pstrParam1 As String, _
     ByVal pintParam2 As Integer) As Boolean
  If pstrParam1 = "Hi Jim" Then
     strMessage = "Error, my friend. You should have said Hello!."
     fbooDataIsValid = False
     Exit Function
  End If
  If pintParam2 < 100 Then
     strMessage = "Error, your number is < 100."
     fbooDataIsValid = False
     Exit Function
  End If
  fbooDataIsValid = True
End Function
' ---
Sub TestDeJac()
  Dim strText As String
  strText = "Hi Jim"
  If Not fbooDataIsValid(strText, 36) Then
     MsgBox strMessage, vbCritical, "Sofica"
     Exit Sub
  End If
  MsgBox "It's OK...", vbInformation, "Sofica"
End Sub
Thank you for your original comment and good night.
Signature

Jac Tremblay

> Maybe...
> '--
[quoted text clipped - 18 lines]
> MsgBox IcelandBanking(strText) & vbCr & strText
> End Sub
keiji kounoike - 11 Oct 2008 08:09 GMT
You seem to have already solved your problem. so, you maybe don't need
this one. but just for a reference. I would use a user defined variable
instead of using global variable. Using this way, your sample code looks
like this.

Type fboo
    msg As String
    state As Boolean
End Type

Function fbooDataIsValid(ByVal pstrParam1 As String, _
      ByVal pintParam2 As Integer) As fboo

Dim tmp As fboo

If pstrParam1 = "Hi Jim" Then
    tmp.msg = "Error, my friend. You should have said Hello!."
    tmp.state = False
    fbooDataIsValid = tmp
    Exit Function
End If

If pintParam2 < 100 Then
    tmp.msg = "Error, your number is < 100."
    tmp.state = False
    fbooDataIsValid = tmp
    Exit Function
End If

tmp.msg = "Suceed"
tmp.state = True

fbooDataIsValid = tmp

End Function

' ---
Sub TestDeJac()
    Dim strText As String
    Dim result As fboo

    strText = "Hi Jim"
    result = fbooDataIsValid(strText, 136)
    If Not result.state Then
        MsgBox result.msg, vbCritical, "Sofica"
    Else
        MsgBox "It's OK...", vbInformation, "Sofica"
    End If
End Sub

keiji

> Hi Jim,
> When I first read your answer, I thought that wouldn't work. But I tried it
[quoted text clipped - 63 lines]
> End Sub
> Thank you for your original comment and good night.
Peter T - 09 Oct 2008 22:04 GMT
A function can return an array of values so the direct answer to your
question is yes. However, unless your function is a UDF (for use in cell
formulas), it would probably be better to pass an additional argument
'ByRef', eg

Sub Test
dim v as variant
Dim bResult as boolean
sMsg as string

v = 123
bResult  = foo(v, sMsg)
if not bResult then
   msgbox sMsg
Else
   msgbox bResult
End if

End Sub

Function foo(ByVal data as Variant, ByRef strErrorMsg  as String) as Boolean
' code to check data
If Not DataIsValid then
strErrorMsg  = "this data not right right for this reason"
Else
foo = True
End If
End function

Regards,
Peter T

> Hi,
> Is it possible to create a function that will return two values, a boolean
[quoted text clipped - 8 lines]
> end IF
> Thanks
Jac Tremblay - 10 Oct 2008 07:26 GMT
Hi Peter,
I tried your code but it does not return two values at the same time. It
returns one or the other. See my answer to Jim's comment.
Thank you for your time.
Signature

Jac Tremblay

> A function can return an array of values so the direct answer to your
> question is yes. However, unless your function is a UDF (for use in cell
[quoted text clipped - 40 lines]
> > end IF
> > Thanks
Peter T - 10 Oct 2008 15:29 GMT
Jac,

I can only repeat what I tried to explain previously, perhaps in different
words.  A function can only return one 'thing'. This 'thing' can be a value,
an object or an array of values or objects. IOW, a function can return
multiple values in an array, indeed virtually unlimited subject resources.

When multiple values are required back from a function the alternative to an
array is to pass arguments ByRef. Such arguments can be assigned or changed
in the function and are returned to the calling procedure. Obviously, as I
mentioned previously, this approach is of no use if your function is
intended as a UDF (although a UDF can return a 1 or 2D array of values for
use in an array entered function).

Both Jim's and my examples demonstrated the ByRef approach to give you your
second value, the first being returned by the function itself. Jim's example
was rather more prescient, mine included a typo -

>> sMsg as string
should of course have read
Dim sMsg as string

I do not agree with Bernd's recommendation not to change ByRef variables,
it's exactly what ByRef is intended for in this context (and assuming not a
UDF).

Regards,
Peter T

Jim -
Q. What's the capital of Iceland
A. About 25 dollars, a bit less by the time you read this

> Hi Peter,
> I tried your code but it does not return two values at the same time. It
[quoted text clipped - 49 lines]
>> > end IF
>> > Thanks
Jim Cone - 10 Oct 2008 16:10 GMT
Hi Peter,
re:  "Q. What's the capital of Iceland
       A. About 25 dollars, a bit less by the time you read this"

That's a good one, I can't top that.
Regards,
Jim Cone
Bernd P - 10 Oct 2008 19:11 GMT
Hello Peter,

[Not OT - w.r.t ByRef]
Then let's agree to disagree.

My basis is:
http://ei.cs.vt.edu/~cs2604/Standards/Standards.html

[Search for the first two occurances of "reference".]

Regards,
Bernd
Peter T - 10 Oct 2008 20:47 GMT
Hi Bernd,

I take it you are referring to this comment -

"
Limit the number of parameters passed by reference (var parameters in
Pascal, pointers passed in C). There are only two ways that a subroutine can
screw up a variable in another subroutine: global variables and variables
passed such that they can be changed. The problem in both cases is that you
increase the chance that something will be changed in a way that you didn't
expect.
"

The paper is all about style, by definition that's subjective albeit based
on hard learnt experience. As a general comment I do not entirely disagree,
however ByRef has a valid and useful purpose. Indeed in our example the only
reason for the existence of the argument is to be able to pass it ByRef, for
the sole purpose of returning it with a new value.

For other purposes, where there is no deliberate intention to change the
ByRef argument, it can still be worth sending ByRef where performance is an
issue. It depends slightly on the data type but in general it's faster to
send a pointer to the variable (ByRef) rather than make and send a copy of
the variable (ByVal).

> Then let's agree to disagree.

No problem :-)

Regards,
Peter T

PS in VB/A ByRef is the default

> Hello Peter,
>
[quoted text clipped - 8 lines]
> Regards,
> Bernd
Jac Tremblay - 11 Oct 2008 00:49 GMT
Hi Peter,
Thanks again for your time and your quick answer.
I did understand what you explained and am now more aware of the utility of
ByRef. Thanks to Bernd and Jim who posted comments as well.
But, as I wrote in the previous answer (to Jim), I found a simple way to
solve my problem and posted the code that goes with it. It works fine and I
decided to use that solution because it is simple and sweet.
Your post was very helpful and informative.
Thanks again and have a good night.
Signature

Jac Tremblay

> Jac,
>
[quoted text clipped - 82 lines]
> >> > end IF
> >> > Thanks
Bernd P - 10 Oct 2008 12:40 GMT
Hello,

I would suggest an explicite variant which contains two values.

Take my UDF NRN as an example:
http://www.sulprobil.com/html/nearest_rational_number.html

Changing Byref variables I would NOT recommend.

Regards,
Bernd
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.