sql >> Base de Datos >  >> RDS >> Access

Tutorial de control ListView-02

Introducción.

Continuación del Tutorial de control ActiveX ListView-01 de la semana pasada.

En esta sesión del tutorial, aprenderemos cómo buscar y encontrar los valores de fila y columna en particular y mostrarlos en un control de etiqueta en el formulario. Esto es muy útil cuando tenemos un gran volumen de datos en el control ListView. También aprenderemos el uso de algunas configuraciones de propiedades de ListView.

En primer lugar, veremos lo fácil que es reorganizar las columnas, como lo hacemos con Access Datasheet View de la forma en que queremos que estén en ListView Control. Hemos agregado algunos cuadros de texto, cuadros combinados, botones de comando y etiquetas para facilitar la selección de parámetros de búsqueda y la visualización de resultados de búsqueda.

He realizado algunos cambios en los datos de demostración de la semana pasada. Los valores de la primera columna los he tomado de la base de datos de ejemplo de la tabla de empleados de Northwind.accdb. Creó una consulta para unir los valores de apellido y nombre con el nombre de campo Student y EmployeeID utilizados como clave (X01, X02 ...).

Antes de pasar a las operaciones de búsqueda, comprobaremos cómo reorganizar las columnas mediante el método de arrastrar y soltar.

Nota: Si no ha pasado por la página del tutorial anterior y desea continuar con esta sesión, vaya a la página Tutorial-01 de ListView Control y descargue la base de datos de demostración desde la parte inferior de esa página.

Descomprima el archivo y abra la base de datos. El formulario de demostración estará en vista normal.

  1. Abre tu Base de Datos, con el Formulario Demo de la última sesión, o el Formulario que has creado, ábrelo en Vista Normal.

    Ahora, intentaremos arrastrar y mover una columna desde el medio de la lista (por ejemplo, la columna Peso) y soltarla en Edad. columna y ver qué pasa. Lo que se espera que suceda es que la columna Edad se desplace hacia la derecha e inserte la columna entrante en su lugar.

  2. Mueva el puntero del mouse sobre el encabezado de columna con el nombre Peso, haga clic y mantenga presionado el botón izquierdo del mouse. Cuando presiona el botón izquierdo del mouse, el encabezado de la columna se moverá ligeramente hacia abajo.

  3. Ahora, intente arrastrar la columna hacia la izquierda y suéltela en la columna Edad .

    No pasará nada, porque no hemos habilitado esta función en la hoja de propiedades y esa es la única configuración que debemos cambiar para que esta función funcione.

  4. Cambie el formulario en la vista de diseño.

  5. Haga clic con el botón derecho en ListView Control y resalte la opción Objeto ListViewCtrl y seleccione Propiedades.

  6. Hay una opción 'AllowColumnReorder ' en el lado derecho. Coloque una marca de verificación para seleccionarlo, luego haga clic en Aplicar botón seguido de OK para cerrar la vista de propiedades.

  7. Ahora, intente repetir los pasos 2 y 3 anteriores y vea qué sucede.

    Esa es la única configuración que necesita para habilitar esta función en ListView Control. Quizás estés pensando, ¿qué hay de reorganizar las filas?.

    Esa función necesita programar algunos procedimientos de eventos como lo hicimos anteriormente en TreeView Control Drag-Drop Events. Esa parte la haremos después de algún tiempo.

  8. Puede experimentar con cualquier columna para moverla a cualquier lugar que desee, incluida la primera columna también.

Nota: Antes de soltar la columna de origen, compruebe que la columna de destino esté cubierta por el marco de la columna entrante antes de intentar soltarla. De lo contrario, la columna entrante puede cambiar a la siguiente posición de columna en el lado derecho.

A continuación, aprenderemos cómo encontrar información de ListView rápidamente, asumiendo que tenemos un gran volumen de datos en él.

Hemos agregado una subrutina al módulo Tutorial-01 para cargar los nombres de encabezado de columna en un cuadro combinado en el formulario con el color de fondo rojo. El nombre de la columna se usará para encontrar el valor de la columna (edad, altura, peso o clase) de un estudiante.

Nuevo código VBA agregado al módulo de clase de formulario.

El siguiente procedimiento nuevo de VBA se agregó al módulo de clase del formulario de tutorial de la semana pasada:

El txtColCombo crea la lista de etiquetas de encabezado de columna (nombres de campo) en el ComboBox. Uno de estos detalles de la edad, altura, peso del estudiante o Clase se puede encontrar junto con el nombre del estudiante como parte de la operación de búsqueda y hallazgo.

Private Sub txtColCombo()
'Column Header List Combo
Dim lvwColHead As MSComctlLib.ColumnHeader
Dim cboName As ComboBox

Set cboName = Me.txtCol
cboName.RowSourceType = "Value List"

For Each lvwColHead In lvwList.ColumnHeaders
    If lvwColHead.Index = 1 Then
        'Nothing
    Else
        cboName.AddItem lvwColHead.Text
    End If
Next
'cboName.DefaultValue = "=txtCol.Column(0, 0)"

Set lvwColHead = Nothing
Set cboName = Nothing
End Sub

El cuadro combinado no se cargará con un valor predeterminado de nombre de encabezado de columna. Si se selecciona, el valor de la columna del estudiante se muestra en la etiqueta grande debajo del nombre del estudiante. Si se deja en blanco, la operación de búsqueda solo encontrará el nombre del estudiante.

El método de operación de búsqueda es muy flexible y rápido. Tenemos dos métodos para encontrar un registro.

Encuentre el registro proporcionando el texto de búsqueda. El texto de búsqueda puede ser de cualquiera de las columnas, ya sea el texto completo o algunos caracteres parciales de la izquierda. Dado que tenemos dos categorías de miembros de objetos en una fila en el control ListView:ListItem - la primera columna y las demás columnas son ListSubItems. La operación de búsqueda de texto en estos objetos se realiza por separado.

Se proporciona un grupo de opciones con dos casillas de verificación junto al cuadro de texto de entrada de texto de búsqueda en el formulario para seleccionar las opciones de búsqueda y búsqueda. La primera opción está seleccionada por defecto y la búsqueda se realiza en la primera Columna (ListItem ) para buscar el texto dado.

Seleccione la segunda opción para buscar el texto en el ListSubItem columnas.

Nota: Reorganizar las columnas no cambiará los objetos, sino solo su posición de visualización. Arrastrando un ListSubItem columna y colocarla en la primera columna no cambiará en un ListItem objeto.

Si desea recuperar un valor desconocido de una columna en particular, seleccione un nombre de columna del cuadro combinado que se encuentra debajo del primer cuadro de texto en el formulario para el texto de búsqueda. Por ejemplo, si no conoce la medida de altura de un estudiante y le gustaría averiguarlo, seleccione el nombre de columna Altura del cuadro combinado.

Después de configurar los valores anteriores, haga clic en Buscar elemento Botón de comando para ir a la operación de búsqueda. Si la búsqueda fue exitosa, el resultado se mostrará en el control de etiqueta grande debajo del botón de comando.

Haga clic en el botón de comando [Buscar elemento].

Llama a SearchAndFind() Procedimiento.

Private Sub SearchAndFind()
'Find by Student Name
Dim lstItem As MSComctlLib.ListItem
Dim strFind As String
Dim strColName As String
Dim strColVal As String
Dim j As Integer
Dim intOpt As Integer
Dim msgText As String

Me.Refresh
intOpt = Me.Opts


strFind = Nz(Me![txtFind], "")
strColName = Nz(Me![txtCol], "")

Select Case intOpt
    Case 1
        Set lstItem = lvwList.FindItem(strFind, , , lvwPartial)
    
        If Not lstItem Is Nothing Then
            j = lstItem.Index
            'format the display text
            msgText = lvwList.ColumnHeaders.Item(1).Text
            msgText = msgText & " : " & lstItem.Text & vbCr & vbCrLf
        Else
            MsgBox "Text '" & strFind & "' Not Found!", vbOKOnly + vbCritical, "cmdFind_Click()"
            Exit Sub
        End If
    Case 2
        Set lstItem = lvwList.FindItem(strFind, lvwSubItem, , lvwPartial)
        If Not lstItem Is Nothing Then
       'format the display text
            j = lstItem.Index
            msgText = lvwList.ColumnHeaders.Item(1).Text
            msgText = msgText & ": " & lstItem.Text & vbCr & vbCrLf
        Else
            MsgBox strFind & " Not Found!", vbOK + vbCritical, "cmdFind_Click()"
            Exit Sub
        End If
End Select

        If Len(strColName) = 0 Then 'If column name is not selected
            GoTo nextStep
        Else
            'Get the column value
            strColVal = GetColVal(lstItem, strColName)
            msgText = msgText & String(8 - (Len(strColName)), " ") & _
            strColName & ": " & Nz(strColVal, "")
        End If
nextStep:

If Len(msgText) > 0 Then 'assign to form label
    lvwList.ListItems.Item(j).Selected = True
    lblMsg.caption = msgText
End If

End Sub

Al comienzo del programa, tanto el Nombre del estudiante y Nombre de columna ( 0opcional), se copian de los cuadros de texto a las variables strFind y strColName respectivamente después de las comprobaciones de validación.

Nota: El nombre de la columna Combo Box's Non-in-List Property se establece en Sí. Puede seleccionar un valor válido de la lista o escribirlo o dejar el cuadro combinado en blanco. Si ingresa un valor diferente que no está en la lista, no será aceptado.

Según la opción de búsqueda seleccionada (1 - ListItem o 2 - ListSubItem), el método de exploración se dirige a los objetos especificados.

El uso de cualquiera de estos métodos de búsqueda encontrará el Objeto ListItem o fila que contiene el texto de búsqueda. El valor de índice de ListItem se guarda en la variable J para su uso posterior en el programa.

Nota: El sistema crea los números automáticos del índice automáticamente en el momento en que se completan los elementos de control de ListView.

El ListItem.Text se recupera el valor. Esta información se une con el primer encabezado de columna. Texto (como Estudiante:Robert King) y agregado a la cadena Msgtext para mostrar en el control Etiqueta en el Formulario.

Si se selecciona la columna Nombre del encabezado en el ComboBox, entonces GetColVal() La función se llama con el objeto ListItem y el valor del texto del encabezado de columna como parámetros. Esta opción es buena para recuperar información desconocida sobre un estudiante, como la altura del estudiante, del registro.

El código VBA de la función GetColVal().

Private Function GetColVal(lvwItem As MSComctlLib.ListItem, ByVal colName As String) As String
Dim i As Integer
Dim strVal As String
    'first column is student name
    'check for column value from 2nd column onwards
    For i = 2 To lvwList.ColumnHeaders.Count
        If lvwList.ColumnHeaders(i).Text = colName Then 'if col name matches
            strVal = lvwItem.ListSubItems.Item(i - 1).Text 'get column value
            Exit For 'No further scanning required
        End If
    Next
GetColVal = strVal 'return the retrieved the value
End Function

La función anterior pide dos parámetros. El primer parámetro es ListItem, donde se encuentra el nombre del estudiante. El segundo parámetro es el nombre de la columna. La edad, altura, peso, clase del estudiante seleccionado los valores se almacenan en ListItem.ListSubItems Objetos. La función mira a través de lvwList.ColumnHeader valores para encontrar el nombre de columna coincidente, cuando se encuentra que el número de índice de columna se usa para recuperar el valor de columna del objeto ListSubItems y devuelve el valor al programa que llama.

El botón de comando [Buscar por clave] haga clic en el procedimiento de evento.

Hemos agregado otro método para encontrar el nombre del estudiante usando el valor clave único de ListItem si se usa al crear la lista ListItem. Aunque es opcional, es mejor agregar Valor de cadena de clave único (debe comenzar con un carácter alfabético) en lugar de ignorarlo.

Por ejemplo, si tenemos que encontrar la información de alguien por su número de identificación, como el número de seguro social, el número de documento nacional de identidad, el número de pasaporte o el número de licencia de conducir, etc., una de estas informaciones se puede utilizar como valor clave para ListItem. Encontrar un registro con este valor único es muy fácil y rápido en lugar del método de búsqueda por texto anterior.

El procedimiento de evento cmdKey_Click().

Calls FindByKey() Subroutine.
Private Sub FindByKey()
Dim colHeader As MSComctlLib.ColumnHeader
Dim lvItem As MSComctlLib.ListItem
Dim lvKeyVal As String
Dim lvColName As String
Dim txt As String
Dim msgText As String
Dim varcolVal As Variant

lvKeyVal = UCase(Nz(Me!txtKey, ""))
lvColName = Nz(Me!txtCol, "")

If len(lvKeyVal) > 0 then
On Error Resume Next 
Set lvItem = lvwList.ListItems.Item(lvKeyVal) 'get the item by Key
If Err > 0 Then
    Err.Clear
    MsgBox "Key Value: '" & lvKeyVal & "' Not Found!", vbOKOnly + vbCritical, "cmdKey_Click()"
    On Error GoTo 0
    Exit Sub
End If
Else
	MsgBox "Please Provide a Valid Key-Value!",vbOKOnly + vbCritical, "cmdKey_Click()"
    Exit Sub
End If

txt = lvItem.Text 'get the student name
'format message text
msgText = lvwList.ColumnHeaders.Item(1).Text & " : "
msgText = msgText & txt & vbCr & vbCrLf

If Len(lvColName) > 0 Then 'if column name is given
    varcolVal = GetColVal(lvItem, lvColName) 'get column val of student
    msgText = msgText & String(8 - Len(lvColName), " ") & lvColName & ": " & varcolVal ' add it to display
End If

lvItem.Selected = True 'highlight the item on form
Me.lblMsg.caption = msgText 'assign details to form Label
End Sub

Como puede ver en la subrutina anterior, podríamos encontrar directamente el ListItem donde está el nombre del Estudiante, con el uso de la Clave-valor, con una sola instrucción:Establecer lvItem =lvwList.ListItems.Item(xKeyVal).

La siguiente línea lee el texto ListItem (o el nombre del estudiante) en la variable txt . Las siguientes dos líneas crean el texto del mensaje con el nombre del estudiante en la variable de cadena msgText.

El próximo Si . . .Entonces La instrucción comprueba si se ha introducido un valor de nombre de columna en el control del cuadro combinado. Si se encuentra, llama a GetColVal() Función con los parámetros requeridos para encontrar el valor de la columna y recuperarlo en varColVal Variable y vuelve al programa de llamada. El nombre de columna y su valor recuperado se agregan a la variable de cadena msgText para mostrar en el control de etiqueta en el formulario.

La siguiente declaración resalta el registro Fila del estudiante como una indicación visual de que el elemento buscado se encuentra en la fila. El valor de msgText se muestra en la propiedad de título de la etiqueta en el formulario.

El código VBA completo en el módulo de formulario.

Option Compare Database
Option Explicit

Dim lvwList As MSComctlLib.ListView 'ListView Control
Dim lvwItem As MSComctlLib.ListItem '
Dim ObjImgList As MSComctlLib.ImageList
Const prfx As String = "K"

Private Sub Form_Load()
    Call LoadListView
    Call txtColCombo
End Sub

Private Function LoadListView()
'Populate the ListView control with Student Details
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim intCounter As Integer
Dim strKey As String

'Assign ListView Control on Form to lvwList Object
 Set lvwList = Me.ListView1.Object
 
With lvwList
    .AllowColumnReorder = True
    .Enabled = True
    .Font = "Verdana"
    .Font.Bold = True
    .Font.Size = 9
    .ForeColor = vbBlack
    .BackColor = vbWhite
 End With
 
 'Create Column Headers for ListView
 With lvwList
    .ColumnHeaders.Clear 'initialize header area
    
   'Syntax: .ColumnHeaders.Add Index, Key, Text, Width, Alignment, Icon
    .ColumnHeaders.Add , , "Student", 2500
    .ColumnHeaders.Add , , "Age", 1200
    .ColumnHeaders.Add , , "Height", 1200
    .ColumnHeaders.Add , , "weight", 1200
    .ColumnHeaders.Add , , "Class", 1200
    
 End With
 
 'Initialize ListView Control
  While lvwList.ListItems.Count > 0
        lvwList.ListItems.Remove (1)
  Wend

'Student Names and Ids are taken from Employees Table
'through the StudentQ Query.
Set db = CurrentDb
Set rst = db.OpenRecordset("StudentQ", dbOpenDynaset)

With lvwList
    Do While Not rst.EOF And Not rst.BOF
        intCounter = rst![EmployeeID]
        strKey = "X" & Format(intCounter, "00") 'Key Value sample: X01
        
    'Syntax: .ListItems.Add(Index, Key, Text, Icon, SmallIcon)
        Set lvwItem = .ListItems.Add(, strKey, rst![Student])
        
        With lvwItem
    'Syntax: .Add Index,Key,Text,Report Icon,TooltipText
            .ListSubItems.Add , strKey & CStr(intCounter), CStr(5 + intCounter)
            .ListSubItems.Add , strKey & CStr(intCounter + 1), CStr(135 + intCounter)
            .ListSubItems.Add , strKey & CStr(intCounter + 2), CStr(40 + intCounter)
            .ListSubItems.Add , strKey & CStr(intCounter + 3), ("Class:" & Format(intCounter, "00"))

       End With
        rst.MoveNext
    Loop
rst.Close
Set rst = Nothing
Set db = Nothing
Set lvwItem = Nothing
End With
lvwList.Refresh

End Function


Private Sub cmdClose_Click()
   DoCmd.Close acForm, Me.Name
End Sub

Private Sub cmdFind_Click()
Call SearchAndFind

End Sub

Private Sub cmdKey_Click()
Call FindByKey
End Sub

Private Function GetColVal(lvwItem As MSComctlLib.ListItem, ByVal colName As String) As String
Dim i As Integer
Dim strVal As String
    'first column is student name
    'check for column value from 2nd column onwards
    For i = 2 To lvwList.ColumnHeaders.Count
        If lvwList.ColumnHeaders(i).Text = colName Then 'if col name matches
            strVal = lvwItem.ListSubItems.Item(i - 1).Text 'get column value
            Exit For 'No further scanning required
        End If
    Next
GetColVal = strVal 'return the retrieved the value
End Function



Private Sub txtColCombo()
'Column Header List Combo
Dim lvwColHead As MSComctlLib.ColumnHeader
Dim cboName As ComboBox

Set cboName = Me.txtCol
cboName.RowSourceType = "Value List"

For Each lvwColHead In lvwList.ColumnHeaders
    If lvwColHead.Index = 1 Then
        'Nothing
    Else
        cboName.AddItem lvwColHead.Text
    End If
Next
'cboName.DefaultValue = "=txtCol.Column(0, 0)"

Set lvwColHead = Nothing
Set cboName = Nothing
End Sub


Public Sub SearchAndFind()
'Find by Student Name
Dim lstItem As MSComctlLib.ListItem
Dim strFind As String
Dim strColName As String
Dim strColVal As String
Dim j As Integer
Dim intOpt As Integer
Dim msgText As String

Me.Refresh
intOpt = Me.Opts

strFind = Nz(Me![txtFind], "")
strColName = Nz(Me![txtCol], "")

Select Case intOpt
    Case 1
        Set lstItem = lvwList.FindItem(strFind, , , lvwPartial)
        If Not lstItem Is Nothing Then
            j = lstItem.Index
            'format the display text
            msgText = lvwList.ColumnHeaders.Item(1).Text
            msgText = msgText & " : " & lstItem.Text & vbCr & vbCrLf
        Else
           MsgBox "Text '" & strFind & "' Not Found in the List!", vbOKOnly + vbCritical, "cmdFind_Click()"
        Exit Sub
        End If
    Case 2
        Set lstItem = lvwList.FindItem(strFind, lvwSubItem, , lvwPartial)
        If Not lstItem Is Nothing Then
       'format the display text
            j = lstItem.Index
            msgText = lvwList.ColumnHeaders.Item(1).Text
            msgText = msgText & ": " & lstItem.Text & vbCr & vbCrLf
        Else
            MsgBox strFind & " Not Found!", vbOK + vbCritical, "cmdFind_Click()"
            Exit Sub
        End If
End Select

        If Len(strColName) = 0 Then 'If column name is not selected
            GoTo nextStep
        Else
            'Get the column value
            strColVal = GetColVal(lstItem, strColName)
            msgText = msgText & String(8 - (Len(strColName)), " ") & _
            strColName & ": " & Nz(strColVal, "")
        End If
nextStep:

If Len(msgText) > 0 Then 'assign to form label
    lblMsg.caption = msgText
    lvwList.ListItems.Item(j).Selected = True
End If
End Sub

Public Sub FindByKey()
Dim colHeader As MSComctlLib.ColumnHeader
Dim lvItem As MSComctlLib.ListItem
Dim lvKeyVal As String
Dim lvColName As String
Dim txt As String
Dim msgText As String
Dim varcolVal As Variant


lvKeyVal = UCase(Nz(Me!txtKey, ""))
lvColName = Nz(Me!txtCol, "")

On Error Resume Next
If Len(lvKeyVal) > 0 Then
Set lvItem = lvwList.ListItems.Item(lvKeyVal) 'get the item by Key
    If Err > 0 Then
        Err.Clear
        MsgBox "Key Value: '" & lvKeyVal & "' Not Found!", vbOKOnly + vbCritical, "cmdKey_Click()"
       On Error GoTo 0
        Exit Sub
    End If
Else
    MsgBox "Please Provide a Valid Key-Value!", vbOKOnly + vbCritical, "cmdKey_Click()"
    Exit Sub
End If

txt = lvItem.Text 'get the student name
'format message text
msgText = lvwList.ColumnHeaders.Item(1).Text & " : "
msgText = msgText & txt & vbCr & vbCrLf

If Len(lvColName) > 0 Then 'if column name is given
    varcolVal = GetColVal(lvItem, lvColName) 'get column val of student
    msgText = msgText & String(8 - Len(lvColName), " ") & lvColName & ": " & varcolVal ' add it to display
End If

lvItem.Selected = True 'highlight the item on form
Me.lblMsg.caption = msgText 'assign details to form Label
End Sub

Descargue la base de datos de demostración desde el siguiente enlace:



  1. Tutorial de control TreeView de Microsoft
  2. Creación del menú de acceso con TreeView Control
  3. Asignación de imágenes a nodos TreeView
  4. Asignación de imágenes a TreeView Nodes-2
  5. Control de TreeView Marca de verificación Agregar Eliminar
  6. Acceso desplegable de TreeView ImageCombo
  7. Reorganizar los nodos de TreeView arrastrando y soltando
  8. Control ListView con MS-Access TreeView
  9. Eventos de arrastrar y soltar de control ListView
  10. Control TreeView con subformularios