none
How to programtically access controls in subforms on a form? RRS feed

  • Question

  • I have some code that loops through all the controls on a form and locks each control. I gave the code below. However, I have several subforms on the form that the controls backcolor is not being set. How would I modify my code to detect each subform and loop through the controls on each one as well?

    My existing code:

    Function LockForm(strForm As String)
    ' Locks editable controls and subforms, disables buttons...
    On Error GoTo ER
    Dim f As Form, c As Control
    Set f = Forms(strForm)
    If InStr(f.Caption, "only") = 0 Then
       f.Caption = f.Caption & "  (Read-Only)"
    End If

    For Each c In f.Controls
       Select Case c.ControlType
          Case acTextBox, acComboBox
             c.BackColor = -2147483633 'Grey
             c.Locked = True
          Case acListBox, acCheckBox, acSubform, acOptionGroup, acOptionButton
             c.Locked = True
          Case acCommandButton
             ' Most command buttons must still be usable for record navigation,
             ' printing and form closing.
             If c.Name = "butNew" Or c.Name = "butSave" Then
                c.Enabled = False
             Else
                c.Enabled = True
             End If
          Case acToggleButton
             c.Enabled = False
       End Select
    Next
    Set f = Nothing
    Exit Function

    ER:
       MsgBox Err.Description, , "LockForm"
    End Function

    Tuesday, November 8, 2016 6:16 PM

Answers

  • You will need to include an inner loop within the loop through the parent form's Controls collection, which, if the control is a subform control, loops through its form object's Controls collection.  You can add an extra Case statement and include the inner loop within this.  The subform's Form object's Controls collection would be referenced as:  c.Form.Controls

    You should declare a further object variable to return a reference to each control in the subform, not use the existing c object variable for this.

    In cases like this, rather than identifying each control by its ControlType property, I would normally set the Tag property of those controls whose properties I want to change to a string expression which identifies each subset of controls whose same properties I want to change.  It's then merely a question of referencing the controls Tag property in each Case statement rather than multiple possible control types.  It's main advantage, however, is that it allows controls of the same type to be selectively locked.

    Ken Sheridan, Stafford, England

    Tuesday, November 8, 2016 6:37 PM

All replies

  • You will need to include an inner loop within the loop through the parent form's Controls collection, which, if the control is a subform control, loops through its form object's Controls collection.  You can add an extra Case statement and include the inner loop within this.  The subform's Form object's Controls collection would be referenced as:  c.Form.Controls

    You should declare a further object variable to return a reference to each control in the subform, not use the existing c object variable for this.

    In cases like this, rather than identifying each control by its ControlType property, I would normally set the Tag property of those controls whose properties I want to change to a string expression which identifies each subset of controls whose same properties I want to change.  It's then merely a question of referencing the controls Tag property in each Case statement rather than multiple possible control types.  It's main advantage, however, is that it allows controls of the same type to be selectively locked.

    Ken Sheridan, Stafford, England

    Tuesday, November 8, 2016 6:37 PM
  • Excellent! Thanks.
    Tuesday, November 8, 2016 8:53 PM