VBScript function returning multiple values

R

Roland Hall

Is there a way to return multiple values from a function without using an
array? Would a dictionary object work better?

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
M

McKirahan

Roland Hall said:
Is there a way to return multiple values from a function without using an
array? Would a dictionary object work better?

s = Func()
Response.Write(s)

Function Func()
Const A = "a"
Const B = "b"
Const C = "c"
Func = A & "," & B & "," & C
End Function

Or do you consider a CSV string an array?

Whether a Dcitionary would be "better" depends on what are you trying to
do...
 
J

Jan Peter Stotz

Roland said:
Is there a way to return multiple values from a function without using an
array? Would a dictionary object work better?

There is a third alternative: Make your own "datatype" by defining a class
that has all values you need:

Class MyClass
Public Value1
Public Value2
Public Value3
End Class

Function ReturnMyClass
Dim c
set ReturnMyClass = new MyClass
ReturnMyClass.Vlalue1 = "1"
ReturnMyClass.Vlalue2 = "2"
End Function

Jan
 
R

Roland Hall

in message : : > Is there a way to return multiple values from a function without using
an
: > array? Would a dictionary object work better?
: >
: > --
: > Roland Hall
:
: s = Func()
: Response.Write(s)
:
: Function Func()
: Const A = "a"
: Const B = "b"
: Const C = "c"
: Func = A & "," & B & "," & C
: End Function
:
: Or do you consider a CSV string an array?
:
: Whether a Dcitionary would be "better" depends on what are you trying to
: do...

Thank you for your suggestion.

If I returned my values as a string, then I'd have to parse it after my
call.
My question was kind of vague. I was trying to pass two return values
without having to do it with an array and I didn't want to make 2 calls to
the function or call 2 functions. I actually wanted named pairs. this=
some value, that= some value

I normally use functions as: result = myFunc(param1, param2, ...)
So, I can pass multiple parameters to the function but I was only receiving
one result. I have a need for two and possibly more in the future.

My function calls 4 other functions that do return arrays and at points I
have quite a few arrays in memory.

I first looked using a dictionary object but I can't make it work. It
appears either it is not possible or it's me. I saw in VB 6 I could return
the whole dictionary object but in vbscript, it appears I can only return
keys or items but not both. In VB 6, 'set' is used on the return. ASP
(vbscript) bit the dust when I tried that.

Ex.

function myFunc(param1, param2)
' create dictionary object
dim d
set d = CreateObject(...)
d.Add "string", value
...
set myFunc = d
end function

Now, myFunc = d.Keys or myFunc = d.Items works fine but I need the key and
item values or I have to index them.
So, I started reading about classes and that appears to be the right
approach. I'm just going to have more reading to do.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
R

Roland Hall

in message
: Roland Hall schrieb:
:
: > Is there a way to return multiple values from a function without using
an
: > array? Would a dictionary object work better?
:
: There is a third alternative: Make your own "datatype" by defining a class
: that has all values you need:
:
: Class MyClass
: Public Value1
: Public Value2
: Public Value3
: End Class
:
: Function ReturnMyClass
: Dim c
: set ReturnMyClass = new MyClass
: ReturnMyClass.Vlalue1 = "1"
: ReturnMyClass.Vlalue2 = "2"
: End Function

Jan...

Thank you for your response. I started reading about classes today and it
appears this is the right approach for this application. It's just new to
me and will require some research to implement it. This helps.


--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
M

McKirahan

Roland Hall said:
in message : : > Is there a way to return multiple values from a function without using
an
: > array? Would a dictionary object work better?
: >
: > --
: > Roland Hall
:
: s = Func()
: Response.Write(s)
:
: Function Func()
: Const A = "a"
: Const B = "b"
: Const C = "c"
: Func = A & "," & B & "," & C
: End Function
:
: Or do you consider a CSV string an array?
:
: Whether a Dcitionary would be "better" depends on what are you trying to
: do...

Thank you for your suggestion.

If I returned my values as a string, then I'd have to parse it after my
call.
My question was kind of vague. I was trying to pass two return values
without having to do it with an array and I didn't want to make 2 calls to
the function or call 2 functions. I actually wanted named pairs. this=
some value, that= some value

I normally use functions as: result = myFunc(param1, param2, ...)
So, I can pass multiple parameters to the function but I was only receiving
one result. I have a need for two and possibly more in the future.

My function calls 4 other functions that do return arrays and at points I
have quite a few arrays in memory.

I first looked using a dictionary object but I can't make it work. It
appears either it is not possible or it's me. I saw in VB 6 I could return
the whole dictionary object but in vbscript, it appears I can only return
keys or items but not both. In VB 6, 'set' is used on the return. ASP
(vbscript) bit the dust when I tried that.

Ex.

function myFunc(param1, param2)
' create dictionary object
dim d
set d = CreateObject(...)
d.Add "string", value
...
set myFunc = d
end function

Now, myFunc = d.Keys or myFunc = d.Items works fine but I need the key and
item values or I have to index them.
So, I started reading about classes and that appears to be the right
approach. I'm just going to have more reading to do.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp


To extend your thoughts...

Declare the dictionary outside of all functions (globally) then add to the
Dictionary by assigning the name=value pair to the Item and make the Key
something that you'll reference later; (such as "a", "b", etc.)

' create dictionary object
Dim d
Set d = CreateObject("Scripting.Dictionary")
Call myFunc(param1, param2)
Set d = Nothing

function myFunc(param1, param2)
d.Add "a","string1=" & value1
d.Add "b","string2=" & value2
...
set myFunc = d
end function
 
R

Roland Hall

in message
: Declare the dictionary outside of all functions (globally) then add to the
: Dictionary by assigning the name=value pair to the Item and make the Key
: something that you'll reference later; (such as "a", "b", etc.)
:
: ' create dictionary object
: Dim d
: Set d = CreateObject("Scripting.Dictionary")
: Call myFunc(param1, param2)
: Set d = Nothing
:
: function myFunc(param1, param2)
: d.Add "a","string1=" & value1
: d.Add "b","string2=" & value2
: ...
: set myFunc = d
: end function

I think this is the problem I had with the Dictionary object:

"set" myFunc = d

Usually it's just myFunc = d
Also, once you set d = nothing, the dictionary object is gone.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
M

McKirahan

Roland Hall said:
in message
: Declare the dictionary outside of all functions (globally) then add to the
: Dictionary by assigning the name=value pair to the Item and make the Key
: something that you'll reference later; (such as "a", "b", etc.)
:
: ' create dictionary object
: Dim d
: Set d = CreateObject("Scripting.Dictionary")
: Call myFunc(param1, param2)
: Set d = Nothing
:
: function myFunc(param1, param2)
: d.Add "a","string1=" & value1
: d.Add "b","string2=" & value2
: ...
: set myFunc = d
: end function

I think this is the problem I had with the Dictionary object:

"set" myFunc = d

I should have removed that line from ny code.
Usually it's just myFunc = d
Also, once you set d = nothing, the dictionary object is gone.

Yes, but I was setting to Nothing after it was no longer referenced (or so I
thought -- I don't know all your code).
 
R

Roland Hall

in message : : > "McKirahan" wrote in message : >
: > : Declare the dictionary outside of all functions (globally) then add to
: the
: > : Dictionary by assigning the name=value pair to the Item and make the
Key
: > : something that you'll reference later; (such as "a", "b", etc.)
: > :
: > : ' create dictionary object
: > : Dim d
: > : Set d = CreateObject("Scripting.Dictionary")
: > : Call myFunc(param1, param2)
: > : Set d = Nothing
: > :
: > : function myFunc(param1, param2)
: > : d.Add "a","string1=" & value1
: > : d.Add "b","string2=" & value2
: > : ...
: > : set myFunc = d
: > : end function
: >
: > I think this is the problem I had with the Dictionary object:
: >
: > "set" myFunc = d
:
: I should have removed that line from ny code.
:
: > Usually it's just myFunc = d
: > Also, once you set d = nothing, the dictionary object is gone.
:
: Yes, but I was setting to Nothing after it was no longer referenced (or so
I
: thought -- I don't know all your code).

Ok, I see what you're getting at. I can access the keys and values outside
the function if it's public instead of private.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
R

Roland Hall

in message
: Roland Hall schrieb:
:
: > Is there a way to return multiple values from a function without using
an
: > array? Would a dictionary object work better?
:
: There is a third alternative: Make your own "datatype" by defining a class
: that has all values you need:
:
: Class MyClass
: Public Value1
: Public Value2
: Public Value3
: End Class
:
: Function ReturnMyClass
: Dim c
: set ReturnMyClass = new MyClass
: ReturnMyClass.Vlalue1 = "1"
: ReturnMyClass.Vlalue2 = "2"
: End Function

Ok, it appears this is what you're referring to but I am still calling the
function twice or am I doing something wrong?

<%@ Language=VBScript %>
<%
Option Explicit
Response.Buffer = True

class shipping
public m_ups
public m_freight
end class

function getXMLShipping()
set getXMLShipping = new shipping
getXMLShipping.m_ups = "1.00"
getXMLShipping.m_freight = "2.00"
end function

dim shipUPS, shipFreight
shipUPS = getXMLShipping.m_ups
shipFreight = getXMLShipping.m_freight

Response.Write "UPS: " & shipUPS & "<br />" & vbCrLf & "Freight: " &
shipFreight & vbCrLf
%>


Perhaps I need to provide more information as to what I have and my intended
goal.

I have a function.
getXMLShipping(custNum)

custNum is a value of a cookie.

I call this function to get the shipping information for products being
sold. When only accepting a single carrier, it worked well. Now that I am
adding additional carriers it needs to be altered above the alterations I am
doing converting all files to XML.

The function gets information by calling 3 other functions.

1. get the shopping cart items based on custNum
2. get the UPS rate chart which returns the chart of rates per zone
3. get the zone the customer zip code falls within

I then look at each item, determine the shipping carrier for that item and
add it to the appropriate total while calculating weight * quantity of
items.

For items shipped by UPS, I then take the total weight for that zone and
calculate it against the rate/ounce of that zone and then convert oz to lb
and round up to the next lb.

For items shipped by freight I call a function that is passed the zip code
and total weight and I am returned the freight cost.

Now comes my dilemma. I need to return from the function UPS shipping and
freight shipping. Because freight shipping is so expensive, I need them
separate so I can show UPS shipping costs and freight rather than a total.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
C

Chris Hohmann

[snip]
I first looked using a dictionary object but I can't make it work. It
appears either it is not possible or it's me. I saw in VB 6 I could return
the whole dictionary object but in vbscript, it appears I can only return
keys or items but not both. In VB 6, 'set' is used on the return. ASP
(vbscript) bit the dust when I tried that.

Ex.

function myFunc(param1, param2)
' create dictionary object
dim d
set d = CreateObject(...)
d.Add "string", value
...
set myFunc = d
end function

Now, myFunc = d.Keys or myFunc = d.Items works fine but I need the key and
item values or I have to index them.
So, I started reading about classes and that appears to be the right
approach. I'm just going to have more reading to do.

Your function looks fine. I believe your problem was that you were
forgetting to use the SET statement when you assigned the return value of
the function to a variable. The following worked for me:

<%
Function myFunc(param1, param2)
' create dictionary object
Dim d
Set d = CreateObject("Scripting.Dictionary")
d.Add "A", "Apple"
d.Add "B", "Banana"
d.Add "C", "Carrot"
Set myFunc = d
End Function

Dim d
Set d = myFunc("param1","param2")
Response.Write d("A")
%>
 
R

Roland Hall

in message
: :
: [snip]
: > I first looked using a dictionary object but I can't make it work. It
: > appears either it is not possible or it's me. I saw in VB 6 I could
: return
: > the whole dictionary object but in vbscript, it appears I can only
return
: > keys or items but not both. In VB 6, 'set' is used on the return. ASP
: > (vbscript) bit the dust when I tried that.
: >
: > Ex.
: >
: > function myFunc(param1, param2)
: > ' create dictionary object
: > dim d
: > set d = CreateObject(...)
: > d.Add "string", value
: > ...
: > set myFunc = d
: > end function
: >
: > Now, myFunc = d.Keys or myFunc = d.Items works fine but I need the key
and
: > item values or I have to index them.
: > So, I started reading about classes and that appears to be the right
: > approach. I'm just going to have more reading to do.
:
: Your function looks fine. I believe your problem was that you were
: forgetting to use the SET statement when you assigned the return value of
: the function to a variable. The following worked for me:
:
: <%
: Function myFunc(param1, param2)
: ' create dictionary object
: Dim d
: Set d = CreateObject("Scripting.Dictionary")
: d.Add "A", "Apple"
: d.Add "B", "Banana"
: d.Add "C", "Carrot"
: Set myFunc = d
: End Function
:
: Dim d
: Set d = myFunc("param1","param2")
: Response.Write d("A")
: %>

Oh, set outside the function. I didn't think of that. Makes sense, since
it is an object. Doh!
Thanks Chris. I'll try that.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
M

Michael D. Kersey

Roland said:
Is there a way to return multiple values from a function without using an
array? Would a dictionary object work better?
You can return multiple arguments in a function's parameter list, since
function arguments are call-by-reference by default . So, for example,

' the call...
Dim strA, strB, strC, s
IF ( Func(strA, strB, strC) = 0 )then
Response.Write(s, strA, strB, strC)
....

' The called function...
Function Func(A, B, C)
A = "a"
B = "b"
C = "c"
Func = 0
End Function
 
R

Roland Hall

in message
: Roland Hall wrote:
: > Is there a way to return multiple values from a function without using
an
: > array? Would a dictionary object work better?
: >
: You can return multiple arguments in a function's parameter list, since
: function arguments are call-by-reference by default . So, for example,
:
: ' the call...
: Dim strA, strB, strC, s
: IF ( Func(strA, strB, strC) = 0 )then
: Response.Write(s, strA, strB, strC)
: ...
:
: ' The called function...
: Function Func(A, B, C)
: A = "a"
: B = "b"
: C = "c"
: Func = 0
: End Function

I have the dictionary solution working but what if I'm passing different
variables than I'm returning?

Your timing was almost perfect. It answered another question of something I
worked around but didn't understand why it was happening.

I'll see if I can give an example...

dim gVar, result
gVar = "abcde"

function test(pVar)
pVar = left(pVar,3)
Response.Write gVar ' returns abc
test = pVar
end function

result = test(gVar)

It appears that since it is passed byRef, the original is changed when I
change what I thought was a private variable. If I change it to this:

function test(byVal pVar)
pVar = left(pVar,3)
Response.Write gVar ' returns abc
test = pVar
end function

gVar is no longer modified when I change pVar. It makes sense but I've
never experienced this issue before and should have on this very function,
although now what I used as an example here.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
J

Jan Peter Stotz

Roland said:
Ok, it appears this is what you're referring to but I am still calling the
function twice or am I doing something wrong?

Yes, you are calling the function twice. Call it once and save the object
for future use:

dim ship
set ship = getXMLShipping

Response.Write "UPS: " & ship.m_ups & "<br />" & vbCrLf & "Freight: " & _
ship.m_freight & vbCrLf

Jan
 
R

Roland Hall

: Roland Hall schrieb:
:
: > Ok, it appears this is what you're referring to but I am still calling
the
: > function twice or am I doing something wrong?
:
: Yes, you are calling the function twice. Call it once and save the object
: for future use:
:
: dim ship
: set ship = getXMLShipping
:
: Response.Write "UPS: " & ship.m_ups & "<br />" & vbCrLf & "Freight: " & _
: ship.m_freight & vbCrLf

Thanks Jan.

--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 
M

Michael D. Kersey

Roland said:
in message
: Roland Hall wrote:
: > Is there a way to return multiple values from a function without using
an
: > array? Would a dictionary object work better?
: >
: You can return multiple arguments in a function's parameter list, since
: function arguments are call-by-reference by default . So, for example,
:
: ' the call...
: Dim strA, strB, strC, s
: IF ( Func(strA, strB, strC) = 0 )then
: Response.Write(s, strA, strB, strC)
: ...
:
: ' The called function...
: Function Func(A, B, C)
: A = "a"
: B = "b"
: C = "c"
: Func = 0
: End Function

I have the dictionary solution working but what if I'm passing different
variables than I'm returning?

All variables in the parameter list are passed. When using the default
of call-by-refererence (ByRef), whether an argument is an input to the
function, an output of the function or both input/output depends on how
you code the function.

Suppose a values is _defined_ (not necessarily initialized) in the
calling program and passed as a ByRef argument to the
function/subroutine. The function/subroutine can return anything in that
argument. Above strA, strB, and StrC are not explicitly initialized by
the calling program; the called function sets them.
Your timing was almost perfect. It answered another question of something I
worked around but didn't understand why it was happening.

I'll see if I can give an example...

dim gVar, result
gVar = "abcde"

function test(pVar)
pVar = left(pVar,3)
Response.Write gVar ' returns abc
test = pVar
end function

result = test(gVar)

It appears that since it is passed byRef, the original is changed when I
change what I thought was a private variable. If I change it to this:

function test(byVal pVar)
pVar = left(pVar,3)
Response.Write gVar ' returns abc
Should be pVar-----^^^^, gvar is still "abcde"
test = pVar
end function

gVar is no longer modified when I change pVar. It makes sense but I've
never experienced this issue before and should have on this very function,
although now what I used as an example here.

As you note, when an argument is passed ByRef, changes made in the
called function/subroutine affect the passed variable in the calling code.

I usually think of calling ByRef as pushing a pointer to the variable
onto the stack and think of calling ByVal as pushing the contents of the
variable on the stack.

Defining function/subroutine arguments as ByVal can ensure that passed
variables are not modified inadvertently. But calling ByVal can be
significantly more costly: contrast passing ByVal a large structure
(e.g. an array, recordset, or dictionary object) where the entire
structure must be pushed onto the stack versus passing it ByRef, where
only a pointer to the array is pushed onto the stack.
 
R

Roland Hall

in message
: Roland Hall wrote:
: > Your timing was almost perfect. It answered another question of
something I
: > worked around but didn't understand why it was happening.
: >
: > I'll see if I can give an example...
: >
: > dim gVar, result
: > gVar = "abcde"
: >
: > function test(pVar)
: > pVar = left(pVar,3)
: > Response.Write gVar ' returns abc
: > test = pVar
: > end function
: >
: > result = test(gVar)
: >
: > It appears that since it is passed byRef, the original is changed when I
: > change what I thought was a private variable. If I change it to this:
: >
: > function test(byVal pVar)
: > pVar = left(pVar,3)
: > Response.Write gVar ' returns abc
: Should be pVar-----^^^^, gvar is still "abcde"

No, I mean gVar. When it was passed with byRef, by default, modifying the
length of pVar changed the length of gVar. I guess I never noticed it
before because I probably never modified the passed variable but rather
reassigned it to something else as:
gVar = "abcde"
function test(pVar)
dim npVar
npVar = left(pVar,3)
...
end function


--
Roland Hall
/* This information is distributed in the hope that it will be useful, but
without any warranty; without even the implied warranty of merchantability
or fitness for a particular purpose. */
Technet Script Center - http://www.microsoft.com/technet/scriptcenter/
WSH 5.6 Documentation - http://msdn.microsoft.com/downloads/list/webdev.asp
MSDN Library - http://msdn.microsoft.com/library/default.asp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

ASP design question 4
the perfect function 4
Compressed Zipped Folder 6
sub or function 26
Application question 2
screen scraping 4
replace text 2
Objects and collections 4

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top