+ Reply to Thread
Results 1 to 10 of 10

Use a Variable to Retun an Element from a Type Array

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    01-25-2011
    Location
    Virginia
    MS-Off Ver
    Excel 2016
    Posts
    166

    Use a Variable to Retun an Element from a Type Array

    I have several type structures that have many element names in common. Currently to deal with that I have a bunch of select cases to determine which type to use and then get the proper element. To avoid all the case statements it occurred to me I could use the replace function - but I can't get this to work. Here is a way dumbed down section of code to illustrate my requirement:

    Type TEST
      lTest As Long
      iTest As Integer
      sTest As String
      'many more elements
    End Type
    Sub UseVaribleforType()
    Dim T As TEST
    Dim lRet As Long
    
    T.lTest = 1
    'this is where i would like to evaluate T.lTest with a variable
    lRet = Evaluate(Replace("T.X", "X", "lTest"))
    
    End Sub
    What I would like to do is replace the "X" in "T.X" to get the T.lTest element. The above code gets a vartype error as my evaluate is returning a string. I tried to replace the quotes with another replace using chr(34) but that didn't work either.

    SNB, I think this ones for you?

    Thanks,
    Tom

    If my answer resolves your issue, please mark your Thread as SOLVED.

    If you're satisfied by any members response to your issue please use the star icon at the lower left of their post
    .

  2. #2
    Forum Expert mikerickson's Avatar
    Join Date
    03-30-2007
    Location
    Davis CA
    MS-Off Ver
    Excel 2011
    Posts
    6,229

    Re: Use a Variable to Retun an Element from a Type Array

    Thick fingered double post of the following.
    Last edited by mikerickson; 05-20-2014 at 07:39 PM.
    _
    ...How to Cross-post politely...
    ..Wrap code by selecting the code and clicking the # or read this. Thank you.

  3. #3
    Forum Expert mikerickson's Avatar
    Join Date
    03-30-2007
    Location
    Davis CA
    MS-Off Ver
    Excel 2011
    Posts
    6,229

    Re: Use a Variable to Retun an Element from a Type Array

    I see a User Defined Type called Test, that has 3 elements (lTest, iTest, and sTest).

    It looks like the question you want answered is "given a variable V of type Test, and a value x, which element of V has a value of X"?

    Your Select Case construct is probably the best way to approach this.

  4. #4
    Forum Contributor
    Join Date
    01-25-2011
    Location
    Virginia
    MS-Off Ver
    Excel 2016
    Posts
    166

    Re: Use a Variable to Retun an Element from a Type Array

    Mike,
    Thanks for the quick response. I have 5 different types and they have at least 20 elements in common. This forces me to do the 5 case select case construct 20 times! It works but it is ugly, if I could find a way to get to the type via a variable I would only have to do the case once. I suspect I don't have a choice but I had to ask. I have seen SNB do some really wild stuff with replace so hopefully he will take a gander at this post.

    Regards,
    Last edited by tom.hogan; 05-21-2014 at 02:08 PM.

  5. #5
    Forum Guru Norie's Avatar
    Join Date
    02-02-2005
    Location
    Stirling, Scotland
    MS-Off Ver
    Microsoft Office 365
    Posts
    19,643

    Re: Use a Variable to Retun an Element from a Type Array

    You could use a class instead of a user defined type, then you could use CallByName.

    Class Module : TEST
    Option Explicit
    
    
    Dim plTest As Long
    Dim piTest As Integer
    Dim psTest As String
    
    Property Get iTest() As Integer
        iTest = piTest
    End Property
    
    Property Let iTest(Value As Integer)
        piTest = Value
    End Property
    
    Property Get lTest() As Long
        lTest = plTest
    End Property
    
    Property Let lTest(Value As Long)
        plTest = Value
    End Property
    
    Property Get sTest() As String
        sTest = psTest
    End Property
    
    Property Let sTest(Value As String)
        psTest = Value
    End Property
    Standard Module
    Sub UseVaribleforType()
    Dim T As TEST
    Dim lRet As Long
    
        Set T = New TEST
    
        T.lTest = 1
        'this is where i would like to evaluate T.lTest with a variable
        lRet = CallByName(T, "lTest", VbGet)
        MsgBox lRet
    
    End Sub
    If posting code please use code tags, see here.

  6. #6
    Forum Contributor
    Join Date
    01-25-2011
    Location
    Virginia
    MS-Off Ver
    Excel 2016
    Posts
    166

    Re: Use a Variable to Retun an Element from a Type Array

    Norie,
    That's a great solution. However, the actual UDTs are from WINAPI and it won't accept classes in lieu of UDTs.

    Thanks,
    Last edited by tom.hogan; 05-21-2014 at 02:07 PM.

  7. #7
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,297

    Re: Use a Variable to Retun an Element from a Type Array

    There is no equivalent for UDTs that I know of - Evaluate will not work here.

    Can you give a specific example of why you need this, and how you are coding it now? Would it help to put the common fields into a new UDT and have that as a member of each relevant UDT?
    Remember what the dormouse said
    Feed your head

  8. #8
    Forum Contributor
    Join Date
    01-25-2011
    Location
    Virginia
    MS-Off Ver
    Excel 2016
    Posts
    166

    Re: Use a Variable to Retun an Element from a Type Array

    Rory,
    It's really a long story (and several hundred lines of code) but I am trying to set a dozen or so extended printer settings (like NUP) which requires manipulating DEVMODE types. In my code there are 5 different DEVMODES based on Universal vs. PostScript and also Windows versions. Snippet of the code (reduced DEVMODES to 3 and features to 3 for ease of viewing) looks like this:
    Option Base 1
    Option Explicit
    
    Private Type DEVMODE_A
      'many more elements
      dmOrientation As Integer
      dmPaperSize As Integer
      'many more elements
      dmFormName As String * 32
      'many more elements
    End Type
    Private Type DEVMODE_B
      'many more elements
      dmOrientation As Integer
      dmPaperSize As Integer
      'many more elements
      dmFormName As String * 32
      'many more elements
    End Type
    Private Type DEVMODE_C
      'many more elements
      dmOrientation As Integer
      dmPaperSize As Integer
      'many more elements
      dmFormName As String * 32
      'many more elements
    End Type
    Type TT
      lTest As Long
    End Type
    Sub SetDevModebyType(Feature As Long, Setting As Variant)
    Dim DMType As Long
    Dim DEVMODE_A As DEVMODE_A
    Dim DEVMODE_B As DEVMODE_B
    Dim DEVMODE_C As DEVMODE_C
    Dim lRet As Long
    
    DMType = GetDevmodeType 'Returns 1,2 or 3
    
    'Fill the correct DEVMODE based on DMType
    Select Case DMType
      Case 1
        DEVMODE_A = GetDevModeA
      Case 2
        DEVMODE_B = GetDevModeB
      Case 3
        DEVMODE_C = GetDevModeC
     End Select
    
    'Apply the setting for the Feature in the right DEVMODE
    
    Select Case Feature
    Case DM_ORIENTATION
      Select Case DMType
        Case 1
          DEVMODE_A.dmOrientation = Setting
        Case 2
          DEVMODE_B.dmOrientation = Setting
        Case 3
          DEVMODE_C.dmOrientation = Setting
      End Select
    Case DM_PAPERSIZE
      Select Case DMType
        Case 1
          DEVMODE_A.dmPaperSize = Setting
        Case 2
          DEVMODE_B.dmPaperSize = Setting
        Case 3
          DEVMODE_C.dmPaperSize = Setting
      End Select
    Case DM_FORMNAME
      Select Case DMType
        Case 1
          DEVMODE_A.dmFormName = Setting
        Case 2
          DEVMODE_B.dmFormName = Setting
        Case 3
          DEVMODE_C.dmFormName = Setting
      End Select
    End Select
    
    Select Case DMType
      Case 1
        Call CopyMemory(yDevModeArr(1), DEVMODE_A, Len(DEVMODE_A))
      Case 2
        Call CopyMemory(yDevModeArr(1), DEVMODE_B, Len(DEVMODE_B))
      Case 3
        Call CopyMemory(yDevModeArr(1), DEVMODE_C, Len(DEVMODE_C))
    End Select
    
    End Sub
    While this method works, what I am trying to avoid are the interior cases which have to be repeated for each feature. I was hoping there was a way (such as evaluate and replace) to replace each of these cases with a single line that would set the feature to the correct DEVMODE.

    I had previously tried your type within a type method but that doesn't help with this particular issue.

    Note: I played around with conditional compiling but that won't work as I don't know the printer driver type (and thus DEVMODE type) until well into program execution.

    Thanks,
    Last edited by tom.hogan; 05-21-2014 at 02:07 PM.

  9. #9
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,297

    Re: Use a Variable to Retun an Element from a Type Array

    The best I can think of at the moment is to use classes as Norie suggested, which at least removes a lot of the Select Case coding. For example:

    Class DM_A:
    Option Explicit
    
    Private dma As DEVMODE_A
    
    Public Property Let dmOrientation(ByVal value As Integer)
        dma.dmOrientation = value
    End Property
    Public Property Let dmPaperSize(ByVal value As Integer)
      dma.dmPaperSize = value
    End Property
    'many more elements
    Public Property Let dmFormName(ByVal value As String)
      dma.dmFormName = value
    End Property
    
    Public Property Get DEVMODE() As DEVMODE_A
        DEVMODE = dma
    End Property
    Public Property Let DEVMODE(value As DEVMODE_A)
        dma = value
    End Property
    The other DEVMODEs would need similar classes.

    Then your routine becomes something like:
    Sub SetDevModebyType(Feature As String, Setting As Variant)
        Dim DMType As Long
        Dim DEVMODE_A As DEVMODE_A
        Dim DEVMODE_B As DEVMODE_B
        Dim DEVMODE_C As DEVMODE_C
        Dim oDevModeA As DM_A
        Dim oDevModeB As DM_B
        Dim oDevModeC As DM_C
        Dim lRet As Long
        
        DMType = getDevModeType 'Returns 1,2 or 3
        
        'Fill the correct DEVMODE based on DMType
        Select Case DMType
          Case 1
            Set oDevModeA = New DM_A
            DEVMODE_A = GetDevModeA
           oDevModeA.DEVMODE = DEVMODE_A
            'Apply the setting for the Feature in the right DEVMODE
            CallByName oDevModeA, Feature, VbLet, Setting
                Call CopyMemory(yDevModeArr(1), oDevModeA.DEVMODE, Len(oDevModeA.DEVMODE))
          Case 2
            Set oDevModeB = New DM_B
            DEVMODE_B = GetDevModeB
           oDevModeB.DEVMODE = DEVMODE_B
            CallByName oDevModeB, Feature, VbLet, Setting
                Call CopyMemory(yDevModeArr(1), oDevModeB.DEVMODE, Len(oDevModeB.DEVMODE))
          Case 3
            Set oDevModeC = New DM_C
            DEVMODE_C = GetDevModeC
           oDevModeC.DEVMODE = DEVMODE_C
            CallByName oDevModeC, Feature, VbLet, Setting
                Call CopyMemory(yDevModeArr(1), oDevModeC.DEVMODE, Len(oDevModeC.DEVMODE))
         End Select
            
    End Sub
    Where you now pass the feature as a string:
    Sub foo()
        SetDevModebyType "dmOrientation", 5
    End Sub
    Would that help at all?

  10. #10
    Forum Expert romperstomper's Avatar
    Join Date
    08-13-2008
    Location
    East Sussex, UK
    MS-Off Ver
    365, varying versions/builds
    Posts
    21,297

    Re: Use a Variable to Retun an Element from a Type Array

    Note: you could probably also just have one class with all the possible properties and 5 separate properties for accessing each of the relevant DEVMODE types within the class.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Taking an element in array (variant type) in Excel VBA
    By blackarrow in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 11-16-2013, 01:45 PM
  2. Error passing element of string array get ByRef argument type mismatch
    By welchs101 in forum Excel Programming / VBA / Macros
    Replies: 6
    Last Post: 10-17-2011, 02:59 PM
  3. we type data on one page and retun to sevral pages
    By Music master in forum Excel Formulas & Functions
    Replies: 3
    Last Post: 01-17-2009, 08:01 AM
  4. Array problem: Key words-Variant Array, single-element, type mismatch error
    By davidm in forum Excel Programming / VBA / Macros
    Replies: 6
    Last Post: 11-09-2005, 01:54 AM
  5. Array problem: Key words-Variant Array, single-element, type mismatch error
    By davidm in forum Excel Programming / VBA / Macros
    Replies: 1
    Last Post: 11-08-2005, 12:30 AM

Bookmarks

Posting Permissions

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

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1