Solved

Passing Variable ByRef

Posted on 2000-05-03
14
391 Views
Last Modified: 2010-08-05
I have written a generic application to test MTS objects. The application has no pre-knowledge of the object's interface and as such does not know what the parameter types will be.
I have a variant array which holds all the values to be passed as parameters.
The problem is that the MTS object may be expecting a parameter as a String, Integer, Long, etc, so I can CStr, CInt, CLng the variant array's element to pass it to the function. But what if the function expects the parameter to be passed ByRef so it can modify the contents of the parameter. Eg, a function returns the records from an SQL call and has an "Error As String" parameter to indicate whether there was an error or not.

Any ideas on how to do this?
Thanks.
0
Comment
Question by:garymather
  • 6
  • 5
  • 3
14 Comments
 
LVL 18

Expert Comment

by:deighton
ID: 2774004
How about passing it by ref as a variant, then using the VarType command to determine its type in the function.

Changing a variant of any type to a string eg

varMy = "Error"

is then no problem, and the value drops back to your calling routine.
0
 
LVL 18

Expert Comment

by:deighton
ID: 2774008
Returns a value indicating the subtype of a variable.

Syntax

VarType(varname)

The varname argument can be any variable except a variable of a user-defined type.

Return Values

Constant      Value      Variable type description

vbEmpty      0      Empty (uninitialized).
vbNull      1      Null (no valid data).
vbInteger      2      Integer.
vbLong      3      Long integer.
vbSingle      4      Single-precision floating-point number.
vbDouble      5      Double-precision floating-point number.
vbCurrency      6      Currency.
vbDate      7      Date.
vbString      8      String.
vbObject      9      OLE Automation object.
vbError      10      Error.
vbBoolean      11      Boolean.
vbVariant      12      Variant (used only with arrays of Variants).
vbDataObject      13      Non-OLE Automation object.

vbByte      17      Byte
vbArray      8192      Array.

Note   These constants are specified by Visual Basic for applications.  As a result, the names can be used anywhere in your code in place of the actual values.

Remarks

The VarType function never returns the value for vbArray by itself.  It is always added to some other value to indicate an array of a particular type.  The constant vbVariant is only returned in conjunction with vbArray to indicate that the argument to the VarType function is an array of type Variant.  For example, the value returned for an array of integers is calculated as vbInteger + vbArray, or 8194.  If an object has a default property, VarType (object) returns the type of its default property.
0
 

Author Comment

by:garymather
ID: 2774058
This does not help as I cannot control how the function is declared. Also, if the function is expecting a String, passing a variant causes a type mismatch.

Here's the code I'm using to make the call:

varReturn = CallByName(objMTS, lstMembers.Text, VbMethod, Cnv(0), Cnv(1))


Private Function Cnv(ByRef Variable As Long)

    Select Case lstParameters.ItemData(Variable)
        Case 2  ' VT_I2
            Cnv = CInt(varParameters(Variable))
        Case 3  ' VT_I4
            Cnv = CLng(varParameters(Variable))
        Case 8  ' VT_BSTR
            Cnv = CStr(varParameters(Variable))
        Case 11 ' VT_BOOL
            Cnv = CBool(varParameters(Variable))
        Case Else
            Cnv = varParameters(Variable)
    End Select

End Function

This works fine as long as the called function does not try to manipulate any of the parameters.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
LVL 28

Expert Comment

by:AzraSound
ID: 2774079
how bout passing it like this:


Private Function Cnv(Variable As Any)
0
 

Author Comment

by:garymather
ID: 2774100
VB does not allow you to declare a function as "Any". This is only used for API declarations. Anyway, the only reason the Cnv function is there, is to convert the Variant to the correct type. But this still only returns the Value and not a Reference.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2774114
why not declare it as a variant then?
0
 
LVL 18

Expert Comment

by:deighton
ID: 2774124
You can't change the declaration of the function, but it is called by ref and wants a string?

Surely its easy, you load the variant into a string variable (or whatever type it is), then call the function over the string variable and be able to look at its changed value.

Then put the string back into the variant.  Might not be totally elegant but it solves the problem.



0
 

Author Comment

by:garymather
ID: 2774137
Uh, I think we're going off on a tangent now. The CNV function has nothing to do with the problem. I would like a way to modify the CallByName call so that the variable is passed ByRef not ByVal.

If you're suggesting changing the function declaration within the MTS object, then the answer would be that this is a generic tester app and I cannot dictate to other developers how to define their objects.
0
 

Author Comment

by:garymather
ID: 2774156
sorry, deighton, i missed your comment.

The problem is that I don't want to have to write thousands of lines of code for each possible combination of variable types in the CallByName call. It's bad enough that I have to have 10 lines to cater for the possibility of 10 parameters. It's enough that I restrict the app to allow a maximum of 10 parameters.

Currently I have for :
1 parm:
CallByName(......, Cnv(0))
2 parms:
CallByName(......, Cnv(0), Cnv(1))
.....etc.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2774161
what harm comes from declaring the call as byref initially?  declaring it to expect a variable of variant data type should provide all the functionality it needs.
0
 

Author Comment

by:garymather
ID: 2774176
Once again. I cannot dictate to other developers how to implement their interfaces. This is to be a generic app that should be able to work with any MTS object, regardless of who or how it was written.
0
 
LVL 28

Accepted Solution

by:
AzraSound earned 100 total points
ID: 2774183
how about using the VarPtr() function then to pass a pointer instead of the actual value instead
0
 

Author Comment

by:garymather
ID: 2774227
This looks like it will do the trick. Just FYI, what i did was this to test the idea.

Declare a module level variable:
Public s1 As String
I will have to declare s0 thru s9 for strings, i0 thru i9 for integers etc.

Then, before the callbyname, declare another variable to hold the name of the module level variable:

Dim strVarName As String

strVarName = "s1"
' Now change the CallByName call to this:
Call CallByName(objMts, lstMembers.Text, VbMethod, Cnv(0), VarPtr(CallByName(Me, strVarName, VbGet)))

Worked like a charm. I knew coming to this forum would pay off!!
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2774240
i had just woken up and my head was a bit foggy...should have suggested this from the beginning...glad its working for you now
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question