Results 1 to 5 of 5

Thread: How to set a variant without VB6 default value?

  1. #1

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    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:
    1. 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
    2.   Set CallCallback = Application.Run( _
    3.     Callback("Parent") & "." & Callback("Name"), _
    4.     args(0), args(1), _
    5.     args(2), args(3), _
    6.     args(4), args(5), _
    7.     args(6), args(7), _
    8.     args(8), args(9), _
    9.     args(10), args(11), _
    10.     args(12), args(13), _
    11.     args(14), args(15), _
    12.     args(16), args(17), _
    13.     args(18), args(19), _
    14.     args(20), args(21), _
    15.     args(22), args(23), _
    16.     args(24), args(25), _
    17.     args(26), args(27), _
    18.     args(28), args(29))
    19. Else
    20.   CallCallback = Application.Run( _
    21.     Callback("Parent") & "." & Callback("Name"), _
    22.     args(0), args(1), _
    23.     args(2), args(3), _
    24.     args(4), args(5), _
    25.     args(6), args(7), _
    26.     args(8), args(9), _
    27.     args(10), args(11), _
    28.     args(12), args(13), _
    29.     args(14), args(15), _
    30.     args(16), args(17), _
    31.     args(18), args(19), _
    32.     args(20), args(21), _
    33.     args(22), args(23), _
    34.     args(24), args(25), _
    35.     args(26), args(27), _
    36.     args(28), args(29))
    37. End If

    One option that I thought might work is the following:

    vb Code:
    1. Private Declare Function GetMem4 Lib "msvbvm60.dll" (ByVal Addr As Long, ByRef RetVal As Any) As Long
    2. ...
    3. Dim vp As LongPtr, vRet as Variant
    4. 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)))
    5. 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?

  2. #2
    Addicted Member Wolfgang Enzinger's Avatar
    Join Date
    Apr 2014
    Location
    Munich, Germany
    Posts
    160

    Re: How to set a variant without VB6 default value?

    Quote Originally Posted by sancarn View Post
    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

  3. #3
    PowerPoster
    Join Date
    Feb 2017
    Posts
    5,066

    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.

  4. #4

    Thread Starter
    Member
    Join Date
    Apr 2019
    Posts
    63

    Re: How to set a variant without VB6 default value?

    Quote Originally Posted by Wolfgang Enzinger View Post
    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

  5. #5
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,163

    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>

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width