Visual Basic 6 - Usando o Controle Listview II


Na primeira parte deste artigo - Usando Listview I - abordamos os conceitos básicos para trabalhar com o controle ListView. Vamos agora fazer a aplicação destes conceitos enfocando aplicações com utilização de banco de dados usando a ADO.

Eu vou usar o banco de dados Nortwind2000.mdb , que vem com o Access ,  e ,  usando controles ListView , exibir os dados de três tabelas relacionadas presentes neste banco de dados , são elas : a tabela Clientes , a tabela Pedidos e a tabela Detalhes do pedido. (A tabela produtos também será utilizada)

O relacionamento entre estas tabelas é o seguinte:

O layout do formulário do nosso projeto é exibo abaixo:

Vamos fazer o seguinte:

1-) O controle ListViewClientes irá exibir os seguintes dados da tabela Clientes : Código do Cliente, Nome da Empresa, Nome do Contato e Cargo do Contato . O controle será preenchido quando da carga do formulário.

2-) Quando o usuário cliclar em um determinado cliente , iremos identificá-lo unicamente pelo código , e , usando o evento DblClick do controle ListView , iremos preencher o controle ListViewPedidos com os pedidos relacionados a este cliente , exibindo : o número do pedido , Nome do Cliente e a data do pedido

3-) Se o usuário clicar em um Pedido , iremos  , também usando o evento DblClick do evento ListView ,  preencher terceiro controle  ListView - ListViewDetalhes - com os dados dos produtos relacionados ao pedido , exibindo : o Nome do Produto e o Preço unitário.

Obs: Para facilitar a visualização utilizamos etiquetas - lblpedidos e lbldetalhes- acima dos controles ListViewPedidos e ListViewDetalhes  para identificar o Código do Cliente e o Número do pedido selecionados

Temos assim um detalhamento da informação onde usuário tem que apenas clicar nos itens para o qual deseja obter a informação.

1-) Definindo a Conexão e os Recordsets utilizados

Vamos fazer a conexão com o banco de dados Nortwind2000.mdb  usando ADO . Vamos também precisar definir três variáveis do tipo Recordset para tratarmos os Recordsets relacionados com cada Controle ListView. Temos então:

A variável Conn será definida na seção General Declarations do formulário , sendo assim visível em todo o formulário , e as demais variáveis serão definidas localmente. Assim temos:

- Na seção General Declarations

Dim conn As New ADODB.Connection 

A conexão será aberto quando da carga do formulário e após a abertura do banco de dados iremos chamar a rotina ListaClientes que irá preencher o primeiro ListView - ListViewClientes. Assim temos:

- No evento Load do formulário

Private Sub Form_Load()
   conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\teste\Nortwind2000.mdb;"
   ListaClientes
End Sub

2 - Preechendo o ListViewClientes com os dados da tabela Clientes

O código para preencher este primeiro ListView é dado a seguir:

Public Sub ListaClientes()
Dim rstClientes As New ADODB.Recordset

'limpa o cabeçalho
ListViewClientes.ColumnHeaders.Clear
ListViewClientes.ListItems.Clear

'define a conexão e abre o Recordset com os dados da tabela Clientes
With rstClientes
    .CursorLocation = adUseClient
    .CursorType = adOpenKeyset
    .LockType = adLockOptimistic
    .CacheSize = 50
    .Source = "Select CódigodoCliente,NomedaEmpresa ,NomedoContato,CargodoContato from Clientes"
    .ActiveConnection = conn
    .Open
End With

'Cria o cabeçalho do controle ListView
ListViewClientes.ColumnHeaders.Add , , "Código", 903
ListViewClientes.ColumnHeaders.Add , , "Nome da Empresa", 2300, lvwColumnLeft
ListViewClientes.ColumnHeaders.Add , , "Nome do Contato", 2300, lvwColumnLeft
ListViewClientes.ColumnHeaders.Add , , "Cargo do Contato", 2300, lvwColumnLeft

'Preenche o controle listview com os dados da tabela
Dim i As Integer
For i = 0 To rstClientes.RecordCount - 1
   Set LIClientesID = ListViewClientes.ListItems.Add(, rstClientes(0), rstClientes(0))
   If Not IsNull(rstClientes(0)) Then
      LIClientesID.SubItems(1) = rstClientes(1) 'nome da empresa
      LIClientesID.SubItems(2) = rstClientes(2) 'nome do contato
      LIClientesID.SubItems(3) = rstClientes(3) 'cargo do contato 
End If
rstClientes.MoveNext
Next i

'fecha o recordset e libera a variável
rstClientes.Close
Set rstClientes = Nothing
End Sub

No código acima você deve tomar cuidado com a seguinte linha de código:

 Set LIClientesID = ListViewClientes.ListItems.Add(, rstClientes(0), rstClientes(0))

Nesta linha estamos criando uma Chave ( Key ) para identificar unicamente um cliente. Para isto usamos o campo Código do Cliente - rsClientes(0) . A chave ( key ) deve ser um dado do tipo STRING , e, como , neste caso os dados do campos são também do tipo string , podemos usar diretamente o campo como chave.

3 - Preenchendo o ListViewPedidos

Quando o usuário clicar duas vezes em um cliente , o segundo ListView - ListViewPedidos - será preenchido com os dados do pedido relacionado. O código estará no evento DblClick do listview - ListViewClientes:

Private Sub ListViewClientes_DblClick()
Dim rstPedidos As New ADODB.Recordset
Dim sql As String
Dim criterio As String

'define o criterio para selecionar os pedidos
criterio = ListViewClientes.SelectedItem.Key
'exibe o codigo do pedido na etiqueta
lblcliente.Caption = criterio

'define a string que será usada na consulta para gerar o recordset
sql = "SELECT Clientes.CódigoDoCliente, Clientes.NomeDoContato, Pedidos.NúmeroDoPedido, Pedidos.DataDoPedido, Pedidos.DataDeEntrega"
sql = sql & " FROM Clientes INNER JOIN Pedidos ON Clientes.CódigoDoCliente = Pedidos.CódigoDoCliente"
sql = sql & " WHERE Clientes.CódigoDoCliente='" & criterio & "'"

'define e gera o recordset da consulta
With rstPedidos
   .CursorLocation = adUseClient
   .CursorType = adOpenKeyset
   .LockType = adLockOptimistic
   .CacheSize = 50
   .Source = sql
   .ActiveConnection = conn
   .Open
End With

'limpa os cabeçalhos
ListViewPedidos.ColumnHeaders.Clear
ListViewPedidos.ListItems.Clear

'cria os cabeçalhos
ListViewPedidos.ColumnHeaders.Add , , "Pedido", 900
ListViewPedidos.ColumnHeaders.Add , , "Nome do Cliente", 2300, lvwColumnLeft
ListViewPedidos.ColumnHeaders.Add , , "Data do Pedido", 2300, lvwColumnCenter

Dim i As Integer
'preenche o listview com os dados da consulta
For i = 0 To rstPedidos.RecordCount - 1
   Set LIPedidosID = ListViewPedidos.ListItems.Add(, "A" & rstPedidos!NúmeroDoPedido, rstPedidos!NúmeroDoPedido)
   If Not IsNull(rstPedidos!NúmeroDoPedido) Then
     LIPedidosID.SubItems(1) = rstPedidos!NomedoContato
     LIPedidosID.SubItems(2) = rstPedidos!DatadoPedido
   End If
   rstPedidos.MoveNext
Next i

' se não há pedidos informa ao usuário
If rstPedidos.RecordCount = 0 Then
MsgBox "Não há pedidos para este cliente"
End If

'fecha o recordset e libera a memoria
rstPedidos.Close
Set rstPedidos = Nothing

End Sub

Neste código chamamos atenção para o seguinte:

A linha de código :  criterio = ListViewClientes.SelectedItem.Key

é que vai definir o critério para seleção dos pedidos relacionados. Quando você clicar no Cliente ,   o código do cliente será usado para montar a instrução SQL que irá selecionar os pedidos relacionados. Isto é possível por que definimos como chave o código do cliente no código anterior.

A linha de código :

Set LIPedidosID = ListViewPedidos.ListItems.Add(, "A" & rstPedidos!NúmeroDoPedido, rstPedidos!NúmeroDoPedido)

Vai definir a chave ( key) para identificar unicamente um pedido. Note que como a chave deve ser uma string , e o campo que vamos usar - NúmerodoPedido - é um campo inteiro Longo , tivemos que montar a nossa chave incluindo a letra A a frente do número do Pedido.

4 - Preenchendo o ListViewDetalhes

Quando o usuário clicar duas vezes em um pedido  o controle ListView - ListViewDetalhes será preenchido com os dados do pedido.  O código estará no evento DblClick do controle ListView - ListViewPedidos:

Private Sub ListViewPedidos_DblClick()
Dim rstdetalhes As New ADODB.Recordset
Dim criterio As Integer
Dim sql As String

'define o criterio e exibe na etiqueta - lbldetalhes
criterio = Mid(ListViewPedidos.SelectedItem.Key, 2, Val(Len(ListViewPedidos.SelectedItem.Key)))
lblpedido.Caption = criterio

'cria a instrução sql para gerar o recordset
sql = "SELECT Produtos.NomeDoProduto, [Detalhes do Pedido].NúmeroDoPedido, [Detalhes do Pedido].PreçoUnitário"
sql = sql & " FROM Produtos INNER JOIN (Pedidos INNER JOIN [Detalhes do Pedido] ON Pedidos.NúmeroDoPedido =
[Detalhes do Pedido].NúmeroDoPedido) ON Produtos.CódigoDoProduto = [Detalhes do Pedido].CódigoDoProduto"
sql = sql & " WHERE Pedidos.NúmeroDoPedido=" & criterio

'gera o recordset
With rstdetalhes
   .CursorLocation = adUseClient
   .CursorType = adOpenKeyset
   .LockType = adLockOptimistic
   .CacheSize = 50  
   .Source = sql
   .ActiveConnection = conn
   .Open
End With

'limpa o cabeçalho
ListViewDetalhes.ColumnHeaders.Clear
ListViewDetalhes.ListItems.Clear
'cria o cabeçalho
ListViewDetalhes.ColumnHeaders.Add , , "Nome do Produto", 1800, lvwColumnLeft
ListViewDetalhes.ColumnHeaders.Add , , "Preço Unitario", 1500, lvwColumnRight

Dim i As Integer
'preenche o controle listview com os dados da consulta
For i = 0 To rstdetalhes.RecordCount - 1
   Set LIDetalhesID = ListViewDetalhes.ListItems.Add(, rstdetalhes!NomedoProduto, rstdetalhes!NomedoProduto)
   If Not IsNull(rstdetalhes!NúmeroDoPedido) Then
      LIDetalhesID.SubItems(1) = rstdetalhes!PreçoUnitário
   End If
   rstdetalhes.MoveNext
Next i

' se não há produtos informa o usuario
If rstdetalhes.RecordCount = 0 Then
   MsgBox "Não há produtos para este Pedido"
End If

'fecha o recordset e libera a memoria
rstdetalhes.Close
Set rstdetalhes = Nothing

End Sub

Observe que :

A linha de código:

criterio = Mid(ListViewPedidos.SelectedItem.Key, 2, Val(Len(ListViewPedidos.SelectedItem.Key)))

que define o critério para selecionar os produtos relacionados , precisa obter somente o número do pedido , pois , esta foi a chave usada para identificar um pedido. Como o campo não é do tipo string , incluimos a letra A na chave do código anterior. Por isso precisamos extrair somente o número do pedido , separando a letra A acrescentada.

Para finalizar veja o projeto em execução:

Aqui terminamos o artigo. O resto é por sua conta...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

  Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter

Referências:


José Carlos Macoratti