'How to find the parent userform of a control in VBA

This code is part of a class module.

Private pImg As Image 'For example, pImg = U_Cursor.Img

Public Property Let ItemID(ID As Byte)
    pImg.Picture = LoadPicture(ThisWorkbook.Path & "\Images\Img" & ID & ".gif")

    *ParentUserform*.Repaint 'ParentUserform is the userform I'm looking for
End Property

I have to force Excel to repaint the userform, otherwise the image sometimes doesn't update on screen.

Is there a way to know which userform "pImg" is in?

If there is no efficient way to do it, I can add another variable to the class module containing the userform name, but I'd prefer not to.



Solution 1:[1]

pImg.Parent will work if pImg is the direct child of the user form. If it is within another container (like a multi or a frame) you'll need to climb the .Parent tree.

With your code in break mode take a look in the Locals window and look at the properties of pImg

Solution 2:[2]

I know this is an old thread, but I wanted to add to the collective wisdom on this "Finding the Parent Userform" topic.

My Excel VBA project includes object/controls located directly on the Userform as well as obj/ctrls within several Frames. I use the frames to easily adjust the layout of groups of related obj/ctrls instead of coding each of their .Left/.Top individually (ie. code for 1 frame instead of 20 obj/ctrls).

The specific task that I was trying to accomplish was to code a popup menu for the right/click event on several different ListBoxes in order to edit that ListItem's data. The problem that I ran into, was running the Do/Loop up the .Parent tree to find the main Userform, so that I could calc the XY coords to position the menu just below the cursor.

After a couple of days ... and a reduction of hair (along with their follicles) ... I finally figured out that Excel considers the Frame control to be a Userform. An excerpt from my final loop is as follows ...

'the callingCtrl obj is declared as Public in a module
'then Set in the MouseUp event for the Listbox

'then in frm_Popup_Menu's Initialize sub ...
Private Sub UserForm_Initialize()
  '==============================
  ' un-related stuff happens here
  '==============================

    'zero the coordinates - (0,0)
      zeroX = 0
      zeroY = 0

    'adjust zero for the cursor position
      zeroX = zeroX + curX
      zeroY = zeroY + curY

    'adjust zero for the calling control position
      zeroX = zeroX + callingCtrl.Left
      zeroY = zeroY + callingCtrl.Top

    'adjust zero for any intermediate control/object positions
      Dim myParent As Object
        Set myParent = callingCtrl.Parent

        Do Until TypeOf myParent Is MSForms.UserForm And Not LCase(TypeName(myParent)) = "frame"
            zeroX = zeroX + myParent.Left
            zeroY = zeroY + myParent.Top

          'reset to previous parent in the tree
            Set myParent = myParent.Parent
        Loop

    'adjust zero for the form's position
      zeroX = zeroX + myParent.Left
      zeroY = zeroY + myParent.Top

    'adjust zero for borders & margins
      zeroX = zeroX + 7
      zeroY = zeroY + 25

    'set the final coordinates for the cursor position
      frm_Popup_Menu.Left = zeroX
      frm_Popup_Menu.Top = zeroY

  '==============================
  ' end of related code
  '==============================

Hope you find this helpful. Enjoy.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 SmileyFtW
Solution 2 DarkMain94