Search code examples
vbatreeviewlimit

Limit Treeview selection VBA


I would like to limit my Treeview selection to max 8 child nodes. i have a following code it does uncheck the box but immediately after selects the box again. any idea?.

Thanks.

Private Sub TreeView1_NodeCheck(ByVal node As MSComctlLib.node)

If Not node.Parent Is Nothing Then
    If node.Checked = True Then
      couT = couT + 1
      If couT <= 8 Then
          'MsgBox node.Text & "_Checked !"
      Else
          node.Checked = False
      End If
    Else
      couT = couT - 1
    End If
End If

End Sub


Solution

  • This TreeView NodeCheck object doesn't handle events like other objects, setting the .Checked = False has no meaning after the Sub finishes. However, there is a work around using a Public variable and Sub in a normal Module, and most important Application.OnTime to do the unchecking (does not trigger the _NodeCheck when it's done within macro).

    So, in your UserForm module with the TreeView object:

    Private couT As Integer
    Private Const MAX_NODES As Integer = 8
    
    Private Sub TreeView1_NodeCheck(ByVal Node As MSComctlLib.Node)
        Dim bSchUncheckNode As Boolean
        bSchUncheckNode = False
        If Not Node.Parent Is Nothing Then
            If Node.Checked = True Then
                couT = couT + 1
                If couT <= MAX_NODES Then
                    'Debug.Print Node.Text & "_Checked !"
                Else
                    couT = couT - 1 ' Assuming the scheduled task completes successfully (or move the variable to standard module).
                    bSchUncheckNode = True
                    iNodeToUncheck = Node.Index
                End If
            Else
                couT = couT - 1
            End If
        End If
        ' Schedule Sub call only if it should uncheck a node
        If bSchUncheckNode Then Application.OnTime Now, "UncheckNode"
    End Sub
    
    Sub UserForm_Initialize()
        couT = 0 ' Resets the counter to zero
        '... Other things you have had
    End Sub
    

    In a normal vba module (change the name of the UserForm and TreeView object accordingly):

    Public iNodeToUncheck As Integer
    
    Sub UncheckNode()
        ' Assuming this is only be called by the UserForm scheduling
        UserForm1.TreeView1.Nodes(iNodeToUncheck).Checked = False
    End Sub