title: Excel-VBA - list controls of all userforms for ANY given workbook
body: <p><strong>Task</strong></p>
  
  <p>My goal is to list all controls of all UserForms for ANY given workbook. My code works for all workbooks within the workbooks collection <strong>other</strong> than the calling workbook (<code>ThisWorkBook</code>).</p>
  
  <p><strong>Problem</strong></p>
  
  <p>If I try to list all the userforms' controls regarding the <strong>calling workbook</strong>, I get <em>Error 91 Object variable or With block variable not set</em> at numbered error line 200 (so called <code>ERL</code>). The code below is intently broken into  <strong>2 redundant portions</strong>, to show the error explicitly. Any help is appreciated. </p>
  
  <p><strong>Code</strong></p>
  
  <pre><code> Sub ListWBControls()
   ' Purpose: list ALL userform controls of a given workbook within workbooks collection
   '
   Dim bProblem As Boolean
   Dim vbc      As VBIDE.VBComponent          ' module, Reference to MS VBA Exte 5.3 needed !!!
   Dim ctrl     As MSForms.Control
   Dim i        As Integer, imax As Integer   ' control counters
   Dim cnr      As Long, vbcnr As Long
   Dim sLit     As String
   Dim sMsg     As String                     ' result string
   Dim owb      As Workbook                   ' workbook object
   Dim wb       As String                     ' workbook name to choose by user
   ' --------------------
   ' choose Workbook name
   ' --------------------
     wb = Me.ComboBox1.List(Me.ComboBox1.ListIndex, 0)  ' &lt;&lt; existing workbook name chosen in combobox
   ' check if wb is calling workbook or other
          For Each owb In Workbooks
            If owb.Name = wb And ThisWorkbook.Name = wb Then
               bProblem = True
               Exit For
            End If
          Next owb
   ' count workbooks
     imax = Workbooks.Count
     i = 1
   ' a) start message string showing workbook name
     sMsg = sMsg &amp; vbNewLine &amp; String(25, "=") &amp; vbNewLine &amp; _
            sLit &amp; " WorkBook: " &amp; Workbooks(i).Name &amp; vbNewLine &amp; String(25, "=")
   '------------------------------
   'Loop thru components (modules) - if of UserForm type
   '------------------------------
   For Each vbc In Workbooks(wb).VBProject.VBComponents
    ' Only if Component type is UserForm
      If vbc.Type = vbext_ct_MSForm Then
       ' increment component and ctrl counters
         sLit = Chr(i + 64) &amp; "."
         vbcnr = vbcnr + 1000
         cnr = vbcnr
  
       ' b) build message new component
         sMsg = sMsg &amp; vbNewLine &amp; String(25, "-") &amp; vbNewLine &amp; sLit &amp; cnr &amp; " '" &amp; _
                vbc.Name &amp; "'" &amp; vbNewLine &amp; String(25, "-")
       '-------------------
       ' Loop thru controls
       '-------------------
       ' ===================================================================
       ' Code is intently broken into 2 portions, to show error explicitly !
       ' ===================================================================
         On Error GoTo OOPS   ' Error handler --&gt; Error 91: Object variable or With block variable not set
  
         If Not bProblem Then    ' part 1 - other workbooks: shown explicitly, are no problem
  100         For Each ctrl In Workbooks(wb).VBProject.VBComponents(vbc.Name).Designer.Controls
               ' increment ctrl counter
                 cnr = cnr + 1
               ' c) build messages controls)
                 sMsg = sMsg &amp; vbLf &amp; "  " &amp; Format(cnr, "0 000") &amp; " " &amp; ctrlInfo(ctrl)
              Next
          Else                    ' part 2 - problem arises here (wb = calling workbook)
  200         For Each ctrl In Workbooks(wb).VBProject.VBComponents(vbc.Name).Designer.Controls    ' &lt;&lt; ERROR 91
               ' increment ctrl counter
                 cnr = cnr + 1
               ' c) build messages controls)
                 sMsg = sMsg &amp; vbLf &amp; "  " &amp; Format(cnr, "0 000") &amp; " " &amp; ctrlInfo(ctrl)
             Next
  
          End If
  
         i = i + 1        ' increment letter counter i
      End If
   Next vbc
   ' show result
   Debug.Print sMsg
   Exit Sub
  
   OOPS:
   MsgBox "Error No " &amp; Err.Number &amp; " " &amp; Err.Description &amp; vbNewLine &amp; _
          "Error Line " &amp; Erl
   End Sub
  </code></pre>
  
  <p><strong>Helper function</strong></p>
  
  <pre><code> Private Function ctrlInfo(ctrl As MSForms.Control) As String
   ' Purpose: helper function returning userform control information
     ctrlInfo = Left(TypeName(ctrl) &amp; String(5, " "), 5) &amp; " " &amp; _
             Left(ctrl.Name &amp; String(20, " "), 20) &amp; vbTab &amp; _
             " .." &amp; IIf(TypeName(ctrl.Parent) = "UserForm", "Me    " &amp; String(15, " "), _
                         TypeName(ctrl.Parent) &amp; ": " &amp; _
                             Left(ctrl.Parent.Caption &amp; String(15, " "), 15)) &amp; vbTab &amp; _
             " T " &amp; Format(ctrl.Top, "# 000") &amp; "/ L " &amp; Format(ctrl.Left, "# 000")
   End Function
  </code></pre>