Introducción.
En este episodio del Tutorial de control de vista de árbol, aprenderemos cómo Agregar/Eliminar Nodos. La posición del elemento candidato Agregar/Eliminar estará marcada, donde queremos Agregar() el nuevo Nodo o para Eliminar() el Nodo marcado. La adición del Nodo puede ser en el mismo nivel que el Nodo marcado o como un Nodo secundario.
Las sesiones del tutorial de TreeView Control hasta ahora.
- Tutorial de control TreeView de Microsoft
- Creación del menú de acceso con TreeView Control
- Asignación de imágenes al control TreeView
- Asignación de imágenes a TreeView Control-2
La vista normal del control de vista de árbol de demostración en el formulario de MS-Access, con otros controles, se muestra a continuación.

La tabla de datos para la demostración de TreeView Control.
La Tabla con el nombre Muestra, que hemos usado en la primera Sesión de Tutorial, también lo pondremos en uso aquí. Es una pequeña tabla con registros de estructura de controles de base de datos de acceso, tabla, formulario e informe, organizada en orden jerárquico y fácil de entender.

La identificación columna (Vista de árbol Clave ) es un campo Autonumérico.
Los nuevos visitantes se actualizan para esta sesión de tutorial.
Si no ha realizado la primera sesión del tutorial, puede descargar la base de datos de demostración desde la página de la segunda sesión:Creación del menú de acceso con control de vista de árbol. Hay una Tabla en esa Base de Datos con el nombre:Muestra y Formulario frmSample . Puede importarlos a su base de datos actual. Hay otro formulario con el nombre frmMenu allí y puede copiar los botones de comando Expandir todo, Ocultar todo, y sus procedimientos de evento de clic de botón de comando de frmMenu al frmSample Módulo de código para continuar con esta sesión.
Como mencioné anteriormente, podemos compartir el control ImageList con las imágenes cargadas en otros proyectos, haremos una copia del control ImageList de la última sesión del tutorial y lo traeremos aquí, con todas las imágenes cargadas, y lo usaremos en el Nodos de control de vista de árbol en frmSample .
Importación del control ImageList con imágenes.
Puede incorporar el control ImageList que ya tiene, con imágenes cargadas en otra base de datos, de las siguientes maneras:
-
Importe el formulario con el control ImageList a la base de datos activa, desde la base de datos donde tiene el control ImageList con imágenes cargadas manualmente. Copie y pegue el control ImageList en el formulario, donde lo desee.
-
O bien, primero copie el Control ImageList en el Portapapeles, desde la Base de datos, donde lo tiene. Si descargó la base de datos de demostración de la sesión de tutorial anterior, entonces ya tiene el control ImageList con las imágenes cargadas. Cierre la base de datos después de copiar el control ImageList en el portapapeles.
-
Abra la base de datos de destino y abra el formulario donde desea el control ImageList y péguelo en el formulario.
Con las siguientes líneas de código en CreateTreeView() Subrutina, puede pasar la referencia del objeto ImageList al control de vista de árbol.
Dim tv As MSComctlLib.TreeView Dim ImgList As MSComctlLib.ImageList Set tv = Me.TreeView0.Object tv.Nodes.Clear Set ImgList = Me.ImageList0.Object tv.ImageList = ImgList
Cambie los nombres de objetos resaltados en el código, si son diferentes en el formulario.
Después de eso, puede agregar los nombres de clave de imagen en TreeView Nodes.Add() los dos últimos parámetros del método.
Estos ejercicios ya los hemos hecho en las sesiones anteriores. Para recordarle que estamos usando el control de vista de tabla y árbol que hemos creado en la primera sesión del tutorial e implementado con los cambios explicados anteriormente.
Mostrando los valores de propiedad de los nodos marcados.
La clave del nodo seleccionado , Clave principal, y Texto Las propiedades se muestran en los cuadros de texto en el lado derecho del control de vista de árbol. La casilla de verificación con el Título:Nodo secundario, el Eliminar Nodo, y Añadir nodo Los botones de comando son nuevas incorporaciones al formulario. Sus funciones se explicarán en breve.
Mostrar casillas de verificación en el control TreeView.
Normalmente, la casilla de verificación no se muestra en el control TreeView, a menos que habilitemos una propiedad en la hoja de propiedades del control TreeView. Aquí solo tiene algunas funciones limitadas. Cualquier cosa que vayamos a hacer aquí también se puede hacer sin la casilla de verificación.
Un mejor enfoque para el uso de casillas de verificación puede ser, como la preparación de un informe sobre ubicaciones de sucursales seleccionadas de los negocios de la empresa, basado en opciones aleatorias de sucursales seleccionables por el usuario, desde el menú Acceder al proyecto.
Aquí, el objetivo es dar a conocer esta función y realizar una demostración de su uso.
- Abra el formulario con el control TreeView en la vista de diseño.
- Haga clic derecho en el Control TreeView, resalte el Objeto TreeCtrl , seleccione las Propiedades opción para mostrar la hoja de propiedades.
- Ponga una marca de verificación en las casillas de verificación opción en el control de propiedades como se muestra en la imagen que se muestra a continuación.
La imagen TreeView de demostración que se muestra en la parte superior, Detalles.
Veamos lo que tenemos en el formulario de demostración frmSample presentado en la parte superior de esta página. El control de vista de árbol y los dos botones de comando superiores, Expandir todo y Contraer todo, al hacer clic, Expande o Contrae los nodos y hemos visto sus funciones en el último episodio.
En el lado derecho hay tres cuadros de texto, debajo del encabezado Etiqueta:Valores de propiedad , para mostrar la clave del nodo marcado , Clave principal, y Texto Valores.
La eliminación de nodo El botón de comando elimina el nodo marcado o el nodo y sus nodos secundarios.
Antes de seleccionar el botón de comando Agregar nodo , el Texto El valor de propiedad debe editarse para reemplazarlo con el nuevo valor de texto para el nuevo nodo.
Arriba de Agregar nodo Botón de comando, hay una casilla de verificación con la etiqueta Nodo secundario. El Añadir nodo y nodo secundario Las casillas de verificación funcionan juntas para establecer la regla, en cuanto a dónde debe aparecer el nuevo nodo.
Comprender la acción Agregar nodo.
Suponga que desea agregar un nuevo nodo para hipervínculo campo debajo de Campos lista de tipos de datos de grupo (o nodo principal). Mire la imagen de demostración que se encuentra en la parte superior de esta página, donde he marcado el campo de fecha Node, entre otros Child-Nodes. Las hojas de propiedades del lado derecho muestran su clave:X15 , Clave principal:X4 &Texto:Campo de fecha Descripción.
Cambiar el texto:Campo de fecha al hipervínculo en el cuadro de texto de visualización de propiedades y haga clic en Agregar nodo Botón de comando. La salida será como se muestra a continuación:

Si marcas los campos elemento del nodo principal y coloque una marca de verificación en el nodo secundario opción, encima de Agregar nodo Botón de comando, obtendrá el mismo resultado.
En cambio, si mantiene la marca de verificación Nodo en el Campo de fecha y establezca la marca de verificación en el Nodo secundario opción sobre Agregar nodo Botón de comando, obtendrá el resultado como se muestra a continuación.

El nodo secundario se creará bajo el nodo marcado.
Las acciones Agregar nodo deben crear primero un nuevo registro en la tabla subyacente.
Se crea un nuevo registro en la muestra Tabla, con el nuevo Texto:HyperLink y ID de padre Valores. El campo Autonumérico genera un nuevo número y lo recuperamos y lo usamos como valor clave para el nodo.
El código VBA de la subrutina Agregar nodo se proporciona a continuación:
Private Sub cmdAdd_Click() Dim strKey As String Dim lngKey As Long Dim strParentKey As String Dim lngParentkey As Long Dim strText As String Dim lngID As Long Dim strIDKey As String Dim childflag As Integer Dim db As DAO.Database Dim strSql As String Dim intflag As Integer Dim tmpnode As MSComctlLib.Node Dim i As Integer i = 0 For Each tmpnode In tv.Nodes If tmpnode.Checked Then tmpnode.Selected = True i = i + 1 End If Next If i > 1 Then MsgBox "Selected Nodes: " & i & vbCr & "Select only One Node to mark Addition.", vbCritical, "cmdAdd()" Exit Sub End If 'Read Property Values from Form strKey = Trim(Me![TxtKey]) lngKey = Val(Mid(strKey, 2)) strParentKey = Trim(Me![TxtParent]) lngParentkey = IIf(Len(strParentKey) > 0, Val(Mid(strParentKey, 2)), 0) strText = Trim(Me![Text]) 'Read child Node Option setting childflag = Nz(Me.ChkChild.Value, 0) intflag = 0 strSql = "INSERT INTO Sample ([Desc], [ParentID] ) " If lngParentkey = 0 And childflag = 0 Then 'Add Root-level Node, ParentKey is Blank strSql = strSql & "SELECT '" & strText & "' AS [Desc], '" & " " strSql = strSql & "' AS ParentID FROM Sample WHERE ((Sample.ID = 1));" intflag = 1 ElseIf (lngParentkey >= 0) And (childflag = True) Then 'Inserts a child Node to the Check-marked Node, here Key value used as ParentKey strSql = strSql & "SELECT '" & strText & "' AS [Desc], '" & lngKey strSql = strSql & "' AS ParentID FROM Sample WHERE ((Sample.ID = 1));" intflag = 2 ElseIf (lngParentkey >= 0) And (childflag = False) Then 'Inserts Node at the check-marked level, Add item under the same ParentKey strSql = strSql & "SELECT '" & strText & "' AS [Desc], '" & lngParentkey strSql = strSql & "' AS ParentID FROM Sample WHERE ((Sample.ID = 1));" intflag = 3 End If Set db = CurrentDb db.Execute strSql 'Get newly created autonumber to use as Key lngID = DMax("ID", "Sample") strIDKey = KeyPrfx & CStr(lngID) On Error GoTo IdxOutofBound Select Case intflag Case 1 'Add Root-level Node, ParentKey is Blank tv.Nodes.Add , , strIDKey, strText, "folder_close", "folder_open" Case 2 'Inserts a child Node to the Check-marked Node, here Key value used as ParentKey tv.Nodes.Add strKey, tvwChild, strIDKey, strText, "left_arrow", "right_arrow" Case 3 'Inserts Node at the check-marked level, Add item under the same ParentKey tv.Nodes.Add strParentKey, tvwChild, strIDKey, strText, "left_arrow", "right_arrow" End Select tv.Refresh 'Erase Property Values from Form With Me .TxtKey = "" .TxtParent = "" .Text = "" End With Set db = Nothing cmdExpand_Click cmdAdd_Click_Exit: Exit Sub IdxOutofBound: CreateTreeView Resume cmdAdd_Click_Exit End Sub
Examinemos el Código VBA. Después de las declaraciones de variables locales, los nodos TreeView se escanean en busca de marcas de verificación y toman un recuento de los elementos marcados. Si los nodos marcados son más de uno, muestra un mensaje y cancela el programa.
Los valores de propiedad del nodo marcado se leen desde los controles de formulario en strKey , strParentKey, y strText. El ID, los valores numéricos de ParentID se extraen y se guardan en lngKey y lngParentKey Variables para usar en SQL String.
A continuación, el nodo secundario El valor de la casilla de verificación se guarda en ChildFlag variables.
Se crean tres conjuntos diferentes de cadenas SQL en función del nodo seleccionado y el nodo secundario Opción de casilla de verificación sobre el botón de comando Agregar nodo.
- Si ID de padre El valor de propiedad en el formulario está vacío y el nodo secundario Si la casilla de verificación no está marcada, se creará un nuevo registro de nivel raíz porque el usuario marcó un nodo de nivel raíz.
- Si ID de padre Valor de propiedad>=0 y Nodo secundario la casilla de verificación está seleccionada (marcada ), luego se crea un nuevo registro como un nodo secundario para el nodo marcado. La clave del nodo marcada (ID) se usa como ParentID en el nuevo registro para el nuevo nodo.
- Si ID de padre Valor >=0 y Nodo secundario opción de casilla de verificación no seleccionada (no marcada ), luego se crea el nuevo registro para el nuevo nodo, al mismo nivel que el nodo marcado.
La intFlag La variable se establece con uno de los tres valores:1, 2 o 3, dependiendo de la ejecución de SQL, como una indicación del tipo de Nodo a crear en el Control de vista de árbol.
A continuación, en función de la selección de opciones, se ejecuta SQL para crear un nuevo registro en la muestra. Tabla, con un nuevo valor de campo de ID de autonumérico.
A continuación, el DMax() La función devuelve el ID de registro único como valor clave para el nuevo nodo.
Según la opción de tipo de nodo (1, 2 o 3), el nodo se crea en el control de vista de árbol.
El contenido del cuadro de texto de visualización de propiedades se borra.
Eliminar nodo o nodo con hijos.
El Eliminar nodo La opción es mucho más fácil que el ejercicio anterior. Simplemente elimina el nodo marcado y sus hijos, si están presentes, del control de vista de árbol. Los registros relacionados también se eliminan de la tabla.
El código VBA para la eliminación de nodos se proporciona a continuación:
Private Sub cmdDelete_Click() Dim nodId As Long, nodParent As Long Dim strSql As String Dim db As DAO.Database Dim j As Integer Dim tmpnode As MSComctlLib.Node Dim strKey As String Dim strMsg As String j = 0 ' Get check-marked Nodes count For Each tmpnode In tv.Nodes If tmpnode.Checked Then tmpnode.Selected = True strKey = tmpnode.Key j = j + 1 End If Next If j > 1 Then MsgBox "Selected Nodes: " & j & vbCr & "Select Only One Node to Delete.", vbCritical, "cmdDelete()" Exit Sub End If Set tmpnode = tv.Nodes.Item(strKey) tmpnode.Selected = True Set db = CurrentDb 'check the presense of Child Node(s) of marked Node If tmpnode.Children > 0 Then 'Warnings: ' Deleting Nodes at Random will leave orphaned Nodes ' in the Table and end up with errors, during next Tree View loading process strMsg = "The Marked Node have " & tmpnode.Children & " Children. " & vbCr & "Delete the Child Nodes also?" If MsgBox(strMsg, vbYesNo + vbCritical, "cmdDelete()") = vbYes Then 'Double check and get confirmation. strMsg = "Delete Only the deepest set of Child Nodes" & vbCr strMsg = strMsg & "and their Parent Node at one time." & vbCr & vbCr strMsg = strMsg & "Are you sure to Proceed..?" If MsgBox(strMsg, vbYesNo + vbCritical, "cmdDelete()") = vbYes Then Do Until tmpnode.Children = 0 nodId = Val(Mid(tmpnode.Child.Key, 2)) 'Delete Child Node tv.Nodes.Remove tmpnode.Child.Index 'Delete the related record strSql = "DELETE Sample.*, Sample.ID FROM Sample WHERE (((Sample.ID)= " & nodId & "));" db.Execute strSql Loop Else Exit Sub End If Else Exit Sub End If End If nodId = Val(Mid(tmpnode.Key, 2)) 'Delete Parent tv.Nodes.Remove tmpnode.Key tv.Refresh 'Delete Marked Record strSql = "DELETE Sample.*, Sample.ID FROM Sample WHERE (((Sample.ID)= " & nodId & "));" db.Execute strSql 'Erase Property Values from Form With Me .TxtKey = "" .TxtParent = "" .Text = "" End With Set db = Nothing End Sub
Después de las declaraciones de variables locales, For Each . . . Siguiente Loop cuenta los nodos con marcas de verificación. Si se encuentra más de un elemento marcado, se muestra un mensaje y se cancela el programa.
Si solo hay un elemento marcado, la verificación de validación del segundo paso busca la presencia de nodos secundarios del nodo seleccionado. Si se encuentran nodos secundarios, se muestra un mensaje sobre ese efecto. El usuario debe volver a confirmar su intención de proceder a eliminar primero los nodos secundarios y luego el nodo principal marcado.
Los nodos secundarios se eliminan uno por uno y los registros correspondientes en la tabla también se eliminan, uno tras otro. Luego elimina el registro principal marcado.
Si el nodo marcado no tiene nodos secundarios, se elimina inmediatamente después de las comprobaciones de validación y también se elimina el registro de la tabla correspondiente.
Se borran los contenidos del cuadro de texto de visualización de propiedades en el formulario.
El código VBA del módulo de clase completo de Form frmSample.
A continuación se muestra el código VBA completo en frmSample Class Module de , con otras pequeñas subrutinas para expandir los nodos colapsados, TreeView0_NodeCheck Procedimiento de evento, cmdExit Evento de clic de botón de comando, Form_Load() Procedimientos y CreateTreeView() Subrutina:
Option Compare Database Option Explicit Dim tv As MSComctlLib.TreeView Dim ImgList As MSComctlLib.ImageList Const KeyPrfx As String = "X" Private Sub cmdAdd_Click() Dim strKey As String Dim lngKey As Long Dim strParentKey As String Dim lngParentkey As Long Dim strText As String Dim lngID As Long Dim strIDKey As String Dim childflag As Integer Dim db As DAO.Database Dim strSql As String Dim intflag As Integer Dim tmpnode As MSComctlLib.Node Dim i As Integer i = 0 For Each tmpnode In tv.Nodes If tmpnode.Checked Then tmpnode.Selected = True i = i + 1 End If Next If i > 1 Then MsgBox "Selected Nodes: " & i & vbCr & "Select only One Node to mark Addition.", vbCritical, "cmdAdd()" Exit Sub End If 'Read Property Values from Form strKey = Trim(Me![TxtKey]) lngKey = Val(Mid(strKey, 2)) strParentKey = Trim(Me![TxtParent]) lngParentkey = IIf(Len(strParentKey) > 0, Val(Mid(strParentKey, 2)), 0) strText = Trim(Me![Text]) 'Read child Node Option setting childflag = Nz(Me.ChkChild.Value, 0) intflag = 0 strSql = "INSERT INTO Sample ([Desc], [ParentID] ) " If lngParentkey = 0 And childflag = 0 Then 'Add Root-level Node, ParentKey is Blank strSql = strSql & "SELECT '" & strText & "' AS [Desc], '" & " " strSql = strSql & "' AS ParentID FROM Sample WHERE ((Sample.ID = 1));" intflag = 1 ElseIf (lngParentkey >= 0) And (childflag = True) Then 'Inserts a child Node to the Check-marked Node, here Key value used as ParentKey strSql = strSql & "SELECT '" & strText & "' AS [Desc], '" & lngKey strSql = strSql & "' AS ParentID FROM Sample WHERE ((Sample.ID = 1));" intflag = 2 ElseIf (lngParentkey >= 0) And (childflag = False) Then 'Inserts Node at the check-marked level, Add item under the same ParentKey strSql = strSql & "SELECT '" & strText & "' AS [Desc], '" & lngParentkey strSql = strSql & "' AS ParentID FROM Sample WHERE ((Sample.ID = 1));" intflag = 3 End If Set db = CurrentDb db.Execute strSql 'Get newly created autonumber to use as Key lngID = DMax("ID", "Sample") strIDKey = KeyPrfx & CStr(lngID) On Error GoTo IdxOutofBound Select Case intflag Case 1 'Add Root-level Node, ParentKey is Blank tv.Nodes.Add , , strIDKey, strText, "folder_close", "folder_open" Case 2 'Inserts a child Node to the Check-marked Node, here Key value used as ParentKey tv.Nodes.Add strKey, tvwChild, strIDKey, strText, "left_arrow", "right_arrow" Case 3 'Inserts Node at the check-marked level, Add item under the same ParentKey tv.Nodes.Add strParentKey, tvwChild, strIDKey, strText, "left_arrow", "right_arrow" End Select tv.Refresh 'Erase Property Values from Form With Me .TxtKey = "" .TxtParent = "" .Text = "" End With Set db = Nothing cmdExpand_Click cmdAdd_Click_Exit: Exit Sub IdxOutofBound: CreateTreeView Resume cmdAdd_Click_Exit End Sub Private Sub cmdClose_Click() DoCmd.Close End Sub Private Sub cmdDelete_Click() Dim nodId As Long, nodParent As Long Dim strSql As String Dim db As DAO.Database Dim j As Integer Dim tmpnode As MSComctlLib.Node Dim strKey As String Dim strMsg As String j = 0 ' Get check-marked Nodes count For Each tmpnode In tv.Nodes If tmpnode.Checked Then tmpnode.Selected = True strKey = tmpnode.Key j = j + 1 End If Next If j > 1 Then MsgBox "Selected Nodes: " & j & vbCr & "Select Only One Node to Delete.", vbCritical, "cmdDelete()" Exit Sub End If Set tmpnode = tv.Nodes.Item(strKey) tmpnode.Selected = True Set db = CurrentDb 'check the presense of Child Node(s) of marked Node If tmpnode.Children > 0 Then 'Warnings: ' Deleting Nodes at Random will leave orphaned Nodes ' in the Table and end up with errors, during next Tree View loading process strMsg = "The Marked Node have " & tmpnode.Children & " Children. " & vbCr & "Delete the Child Nodes also?" If MsgBox(strMsg, vbYesNo + vbCritical, "cmdDelete()") = vbYes Then 'Double check and get confirmation. strMsg = "Delete Only the deepest set of Child Nodes" & vbCr strMsg = strMsg & "and their Parent Node at one time." & vbCr & vbCr strMsg = strMsg & "Are you sure to Proceed..?" If MsgBox(strMsg, vbYesNo + vbCritical, "cmdDelete()") = vbYes Then Do Until tmpnode.Children = 0 nodId = Val(Mid(tmpnode.Child.Key, 2)) 'Delete Child Node tv.Nodes.Remove tmpnode.Child.Index 'Delete the related record strSql = "DELETE Sample.*, Sample.ID FROM Sample WHERE (((Sample.ID)= " & nodId & "));" db.Execute strSql Loop Else Exit Sub End If Else Exit Sub End If End If nodId = Val(Mid(tmpnode.Key, 2)) 'Delete Parent tv.Nodes.Remove tmpnode.Key tv.Refresh 'Delete Marked Record strSql = "DELETE Sample.*, Sample.ID FROM Sample WHERE (((Sample.ID)= " & nodId & "));" db.Execute strSql 'Erase Property Values from Form With Me .TxtKey = "" .TxtParent = "" .Text = "" End With Set db = Nothing End Sub Private Sub cmdExpand_Click() Dim nodExp As MSComctlLib.Node For Each nodExp In tv.Nodes nodExp.Expanded = True Next End Sub Private Sub cmdCollapse_Click() Dim nodExp As MSComctlLib.Node For Each nodExp In tv.Nodes nodExp.Expanded = False Next End Sub Private Sub Form_Load() CreateTreeView cmdExpand_Click End Sub Private Sub CreateTreeView() Dim db As Database Dim rst As Recordset Dim nodKey As String Dim ParentKey As String Dim strText As String Dim strSql As String Set tv = Me.TreeView0.Object tv.Nodes.Clear 'Pass ImageList control reference to TreeView's ImageList Property. Set ImgList = Me.ImageList0.Object tv.ImageList = ImgList strSql = "SELECT ID, Desc, ParentID FROM Sample;" Set db = CurrentDb Set rst = db.OpenRecordset("sample", dbOpenTable) Do While Not rst.EOF And Not rst.BOF If Nz(rst!ParentID, "") = "" Then nodKey = KeyPrfx & CStr(rst!ID) strText = rst!desc tv.Nodes.Add , , nodKey, strText, "folder_close", "folder_open" Else ParentKey = KeyPrfx & CStr(rst!ParentID) nodKey = KeyPrfx & CStr(rst!ID) strText = rst!desc tv.Nodes.Add ParentKey, tvwChild, nodKey, strText, "left_arrow", "right_arrow" End If rst.MoveNext Loop rst.Close On Error GoTo 0 Set rst = Nothing Set db = Nothing End Sub Private Sub TreeView0_NodeCheck(ByVal Node As Object) Dim xnode As MSComctlLib.Node Set xnode = Node If xnode.Checked Then xnode.Selected = True With Me .TxtKey = xnode.Key If xnode.Text = xnode.FullPath Then .TxtParent = "" Else .TxtParent = xnode.Parent.Key End If .Text = xnode.Text End With Else xnode.Selected = False With Me .TxtKey = "" .TxtParent = "" .Text = "" End With End If End Sub
La vista de diseño del formulario frmSample se muestra a continuación:

Sus Observaciones, Comentarios, Sugerencias son bienvenidas.
La base de datos de demostración se adjunta para su descarga.
OBJETO DE DICCIONARIO
- Conceptos básicos de los objetos del diccionario
- Conceptos básicos de objetos de diccionario-2
- Ordenar elementos y claves de objetos del diccionario
- Mostrar registros del diccionario
- Agregar objetos de clase como elementos de diccionario
- Actualizar elemento del diccionario de objetos de clase