Access
 sql >> Base de Dados >  >> RDS >> Access

Tutorial de controle ListView-02

Introdução.


Continuação do Tutorial-01 de controle ActiveX ListView da semana passada.

Nesta sessão do Tutorial, aprenderemos como pesquisar e encontrar os valores de linha e coluna específicos e exibi-los em um controle de rótulo no formulário. Isso é muito útil quando temos um grande volume de dados no controle ListView. Também aprenderemos o uso de algumas configurações de propriedade ListView.

Em primeiro lugar, veremos como é fácil reorganizar as colunas, como fazemos com o Access Datasheet View da maneira que queremos que sejam no ListView Control. Adicionamos alguns TextBoxes, ComboBox, Command Buttons e Label para facilitar a seleção dos parâmetros de pesquisa e a exibição dos resultados da pesquisa.

Fiz algumas alterações nos dados de demonstração da semana passada. Os valores da primeira coluna que tirei da tabela de funcionários do banco de dados de exemplo Northwind.accdb. Criou uma Query para unir os valores LastName e FirstName com o nome do campo Student e EmployeeID usados ​​como Chave (X01, X02...).

Antes de ir para as operações de pesquisa, vamos verificar como reorganizar as colunas pelo método de arrastar e soltar.

Observação: Se você não passou pela Página Tutorial anterior e gostaria de continuar com esta sessão, então vá para a Página Tutorial-01 de Controle ListView e baixe o banco de dados de demonstração na parte inferior dessa Página.

Descompacte o arquivo e abra o banco de dados. O formulário de demonstração estará na visualização normal.

  1. Abra seu Banco de Dados, com o Demo Form da última sessão, ou o Form que você criou, abra-o em Normal View.

    Agora, tentaremos arrastar e mover uma coluna do meio da lista (digamos, a coluna Peso) e soltá-la na Idade coluna e veja o que acontece. O que se espera que aconteça é que a coluna Idade se desloque para a direita e insira a coluna de entrada em seu lugar.

  2. Mova o ponteiro do mouse no cabeçalho da coluna com o nome Peso, clique e segure o botão esquerdo do mouse. Quando você pressiona o botão esquerdo do mouse, o cabeçalho da coluna se move ligeiramente para baixo.

  3. Agora, tente arrastar a coluna para a esquerda e soltá-la na coluna Idade .

    Nada acontecerá, pois não habilitamos esse recurso na Folha de Propriedades e essa é a única configuração, precisamos alterar para que esse recurso funcione.

  4. Altere o formulário no modo de design.

  5. Clique com o botão direito do mouse no controle ListView e destaque a opção ListViewCtrl Object e selecione Propriedades.

  6. Existe uma opção 'AllowColumnReorder ' do lado direito. Coloque uma marca de seleção para selecioná-lo e clique em Aplicar botão seguido pelo OK botão para fechar a Visualização de Propriedades.

  7. Agora, tente repetir os passos 2 e 3 acima e veja o que acontece.

    Essa é a única configuração necessária para habilitar esse recurso no controle ListView. Talvez você esteja pensando, que tal reorganizar as linhas?.

    Essa função precisa programar alguns Event Procedures como fizemos anteriormente em TreeView Control Drag-Drop Events. Essa parte faremos depois de algum tempo.

  8. Você pode experimentar qualquer coluna para mover para onde quiser, incluindo a primeira coluna também.

Observação: Antes de descartar a coluna de origem, verifique se a coluna de destino está coberta pelo quadro da coluna de entrada antes de tentar descartar. Caso contrário, a coluna de entrada pode mudar para a próxima posição da coluna no lado direito.

A seguir, aprenderemos a encontrar algumas informações do ListView rapidamente, assumindo que temos um grande volume de dados nele.

Adicionamos uma sub-rotina ao módulo Tutorial-01 para carregar os nomes do cabeçalho da coluna em uma caixa de combinação no formulário com a cor de fundo vermelha. O nome da coluna será usado para encontrar o valor da coluna (idade, altura, peso ou classe) de um aluno.

Novo código VBA adicionado ao módulo Form Class.


O novo procedimento VBA a seguir foi adicionado ao módulo de classe do Tutorial Form da semana passada:

O txtColCombo cria a lista de rótulos de cabeçalho de coluna (nomes de campo) no ComboBox. Um desses detalhes da idade, altura, peso, do aluno ou Classe pode ser encontrado junto com o nome do aluno como parte da operação de busca e localização.
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

A caixa de combinação não será carregada com um valor padrão do nome do cabeçalho da coluna. Se selecionado, o valor da coluna do Aluno é exibido no Rótulo Grande abaixo do Nome do Aluno. Se for deixado em branco, a operação de pesquisa encontrará apenas o nome do aluno.

O método de operação de pesquisa é muito flexível e rápido. Temos dois métodos para encontrar um registro.

Encontre o registro fornecendo o texto de pesquisa. O texto de pesquisa pode ser de qualquer uma das colunas, seja o texto completo ou parcial de alguns caracteres à esquerda. Como temos duas categorias de membros de objeto em uma linha no controle ListView:ListItem - a primeira coluna e outras colunas são ListSubItems. A operação de pesquisa de texto nesses objetos é realizada separadamente.

Um grupo de opções com dois CheckBoxes é fornecido ao lado do TextBox de entrada de texto de pesquisa no formulário para selecionar as opções de pesquisa e localização. A primeira opção é selecionada por padrão e a pesquisa é realizada na primeira Coluna (ListItem ) para procurar o texto fornecido.

Selecione a segunda opção para pesquisar o texto no ListSubItem colunas.

Observação: Reorganizar as colunas não alterará os objetos, mas apenas sua posição de exibição. Arrastar um ListSubItem coluna e trazê-la para a primeira coluna não mudará em um ListItem objeto.

Se você deseja recuperar um valor desconhecido de uma coluna específica, selecione um nome de coluna do ComboBox fornecido abaixo do primeiro TextBox no formulário para o texto de pesquisa. Por exemplo, você não sabe a medida da Altura de um aluno e gostaria de descobrir, selecione o nome da coluna Altura da ComboBox.

Depois de definir o(s) valor(es) acima, clique no botão Localizar item Botão de comando para ir para a operação de pesquisa. Se a pesquisa for bem-sucedida, o resultado será exibido no grande controle Label abaixo do botão de comando.

O clique do botão de comando [Localizar item].

Chama o SearchAndFind() Procedimento.
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

No início do programa, tanto o Nome do Aluno e Nome da coluna ( 0opcional), são copiados dos TextBoxes para as Variáveis ​​strFind e strColName respectivamente após as verificações de validação.

Observação: A propriedade Not-in-List da caixa de combinação do nome da coluna está definida como Sim. Você pode selecionar um valor válido na lista ou digitá-lo ou deixar a caixa de combinação em branco. Se você digitar um valor diferente que não esteja na lista, ele não será aceito.

Com base na opção de pesquisa selecionada (1 - ListItem ou 2 - ListSubItem) o método de varredura é direcionado para o(s) Objeto(s) especificado(s).

Usando qualquer um desses métodos de pesquisa, você encontrará o ListItem Object ou linha que contém o texto de pesquisa. O valor do índice do ListItem é salvo na variável J para uso posterior no programa.

Observação: O sistema cria os números automáticos de índice automaticamente no momento em que os itens de controle do ListView são preenchidos.

O ListItem.Text valor é recuperado. Essas informações são unidas ao primeiro ColumnHeader. Text (como Student:Robert King) e adicionado à string Msgtext para exibir no controle Label no Form.

Se o nome do cabeçalho da coluna estiver selecionado no ComboBox, então o GetColVal() A função é chamada com o objeto ListItem e o valor Column Header Text como parâmetros. Esta opção é boa para recuperar informações desconhecidas sobre um Aluno, como a Altura do Aluno, do registro.

O código VBA da função 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

A função acima pede dois parâmetros. O primeiro parâmetro é o ListItem, onde se encontra o nome do Aluno. O segundo parâmetro é o Nome da Coluna. A Idade, Altura, Peso, Classe do aluno selecionado os valores são armazenados em ListItem.ListSubItems Objetos. A função examina o lvwList.ColumnHeader valores para localizar o nome da coluna correspondente, quando encontrado que o número de índice da coluna é usado para recuperar o valor da coluna do objeto ListSubItems e retorna o valor para o programa de chamada.

O procedimento de evento de clique do botão de comando [Localizar por chave].


Adicionamos outro método para encontrar o nome do aluno usando o valor-chave exclusivo de ListItem se usado ao criar a ListItem List. Mesmo que seja opcional, é melhor adicionar um valor de string de chave exclusivo (deve começar com um caractere alfabético) em vez de ignorá-lo.

Por exemplo, se tivermos que encontrar as informações de alguém pelo seu número de identificação, como número do CPF, número da carteira de identidade, número do passaporte ou número da carteira de motorista e assim por diante, uma dessas informações pode ser usada como o valor da chave para o ListItem. Encontrar um registro com esse valor exclusivo é muito fácil e rápido, em vez do método de pesquisa por texto acima.

O procedimento 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 você pode ver na sub-rotina acima, podemos encontrar diretamente o ListItem onde está o nome do aluno, com o uso do valor-chave, com uma única instrução:Set lvItem =lvwList.ListItems.Item(xKeyVal).

A próxima linha lê o texto ListItem (ou nome do aluno) na variável txt . As próximas duas linhas criam o texto da mensagem com o Nome do Aluno na variável de string msgText.

O próximo Se . . .Então verifica se um valor de nome de coluna é inserido no controle de caixa de combinação. Se for encontrado, então chama o método GetColVal() Função com os parâmetros necessários para encontrar o valor da coluna e recuperá-lo em varColVal Variável e retorna ao programa de chamada. O nome da coluna e seu valor recuperado são adicionados à variável de string msgText para exibir no controle Label no formulário.

A próxima declaração destaca o registro Fila do Aluno como uma indicação visual de que o item pesquisado foi encontrado na fileira. O valor msgText é exibido na propriedade de legenda do rótulo no formulário.

O código VBA completo no módulo de formulário.

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

Baixe o banco de dados de demonstração no seguinte link:


  1. Tutorial de controle do Microsoft TreeView
  2. Criando menu de acesso com controle TreeView
  3. Atribuindo imagens a nós TreeView
  4. Atribuindo imagens aos nós TreeView-2
  5. Marca de seleção de controle TreeView Adicionar exclusão
  6. Acesso suspenso do TreeView ImageCombo
  7. Reorganizar nós TreeView por arrastar e soltar
  8. Controle de ListView com MS-Access TreeView
  9. Eventos de arrastar e soltar do controle ListView
  10. Controle TreeView com subformulários