-
Apr 24th, 2019, 03:25 AM
#1
Thread Starter
Member
How to set a variant without VB6 default value?
So I'm making a funky callback class for VBA. One of the core difficulties is getting around the syntax sugar set/let. I.E.
if vartype(result) = vbObject then
set FuncReturn = result
else
FuncReturn = result
end if
In the CallCallback method currently I have the following lines which call module methods dynamically. Unfortunately we have to call the method twice, first to determine the type of the output, and a 2nd time to return the data:
vb Code:
If VarType(Application.Run(Callback("Parent") & "." & Callback("Name"), args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29))) = vbObject Then
Set CallCallback = Application.Run( _
Callback("Parent") & "." & Callback("Name"), _
args(0), args(1), _
args(2), args(3), _
args(4), args(5), _
args(6), args(7), _
args(8), args(9), _
args(10), args(11), _
args(12), args(13), _
args(14), args(15), _
args(16), args(17), _
args(18), args(19), _
args(20), args(21), _
args(22), args(23), _
args(24), args(25), _
args(26), args(27), _
args(28), args(29))
Else
CallCallback = Application.Run( _
Callback("Parent") & "." & Callback("Name"), _
args(0), args(1), _
args(2), args(3), _
args(4), args(5), _
args(6), args(7), _
args(8), args(9), _
args(10), args(11), _
args(12), args(13), _
args(14), args(15), _
args(16), args(17), _
args(18), args(19), _
args(20), args(21), _
args(22), args(23), _
args(24), args(25), _
args(26), args(27), _
args(28), args(29))
End If
One option that I thought might work is the following:
vb Code:
Private Declare Function GetMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByRef RetVal As Any) As Long
...
Dim vp As LongPtr, vRet as Variant
vp = VarPtr(Application.Run(Callback("Parent") & "." & Callback("Name"), args(0), args(1), args(2), args(3), args(4), args(5), args(6), args(7), args(8), args(9), args(10), args(11), args(12), args(13), args(14), args(15), args(16), args(17), args(18), args(19), args(20), args(21), args(22), args(23), args(24), args(25), args(26), args(27), args(28), args(29)))
Call GetMem4(vp, vRet)
But I think this doesn't work because the data in vp isn't saved and is instead garbage collected.
I know this must be possible but I have no idea how... Has anyone any idea how you can call these module functions and return the data dynamically without vb always using the default value?
-
Apr 24th, 2019, 07:22 AM
#2
Re: How to set a variant without VB6 default value?
Originally Posted by sancarn
Has anyone any idea how you can call these module functions and return the data dynamically without vb always using the default value?
See if this helps:
Code:
Option Explicit
Public Declare Sub VariantCopy Lib "oleaut32.dll" (ByRef pvargDest As Variant, ByRef pvargSrc As Variant)
Function Test(ByVal SomeParam As Long) As Variant
If SomeParam And 1 Then
Set Test = New VBA.Collection
Else
Test = SomeParam
End If
End Function
Sub Main()
Dim i As Long, v As Variant
For i = 1 To 100
VariantCopy v, Test(i)
Debug.Assert (i And 1) Imp IsObject(v)
Debug.Assert (i And 1) = 0 Imp Not IsObject(v)
Next i
End Sub
Wolfgang
-
Apr 24th, 2019, 10:25 AM
#3
Re: How to set a variant without VB6 default value?
If you have control over that Callback fucntion and you can modify it, then set the return value of the function as another parameter.
-
Apr 24th, 2019, 03:34 PM
#4
Thread Starter
Member
Re: How to set a variant without VB6 default value?
Originally Posted by Wolfgang Enzinger
See if this helps:
... VariantCopy ...
You are absolutely correct! Thanks!
@Eduardo - This is for an API. Although you are correct I have this ability I would rather not unless I have to
-
Apr 25th, 2019, 01:50 AM
#5
Re: How to set a variant without VB6 default value?
You can try this simple function if you don't want API calls
Code:
Public Sub AssignVariant(vDest As Variant, vSrc As Variant)
If IsObject(vSrc) Then
Set vDest = vSrc
Else
vDest = vSrc
End If
End Sub
Note that `VariantCopy` has troubles w/ VT_BYREF Variants (not in your case as retvals are never VT_BYREF) -- instead of assigning to the original variable that the Variant is pointing to, it just assigns the value to the Variant.
Edit: Never test vartype(result) = vbObject because if result is an object this would try to call its default method/property and when DISPID_VALUE is available vartype will return it's retval type (not vbObject). Just use IsObject function.
cheers,
</wqw>
Last edited by wqweto; Apr 25th, 2019 at 01:54 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|