Solved

Passing Variable ByRef

Posted on 2000-05-03
14
381 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
 
LVL 28

Expert Comment

by:AzraSound
Comment Utility
how bout passing it like this:


Private Function Cnv(Variable As Any)
0
 

Author Comment

by:garymather
Comment Utility
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
Comment Utility
why not declare it as a variant then?
0
 
LVL 18

Expert Comment

by:deighton
Comment Utility
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:garymather
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
how about using the VarPtr() function then to pass a pointer instead of the actual value instead
0
 

Author Comment

by:garymather
Comment Utility
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
Comment Utility
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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

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…
The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

763 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now