VB6 e ADO - Usando o Controle ListView e SQL


Usando o Controle ListView

Nos velhos tempos do VB3 , há muiiiiitooo tempo atrás , existiam tarefas que exigiam do programador verdadeiro malabarismo com o código para alcançar determinado objetivo . Muitas vezes era preciso desenvolver rotinas extensas para que determinado efeito fosse alcançado. Se por um lado isto mostrava toda a criatividade do programador por outro era uma tarefa que demandava tempo. Muitas vezes tudo estava pronto mas faltava um controle que permitisse um determinado comportamento ao sistema que o faria especial . Então as vezes gastavasse mais tempo com aspectos que iriam criar um impacto na apresentação dos dados e no usuário mas que podia até afetar a performance do sistema sem falar na possibilidade de aumentar os 'bugs' (que palavra engraçada) do sistema.

Mas voltando ao presente, estamos na versão 6.0 do Visual Basic e ela trouxe alguns controles interessantes. Um deles - o ListView - embora já presente desde a versão 5.0, será abordado neste artigo e mostraremos uma aplicação usando ADO com opção do usuário usar instruções SQL para realizar as mesmas tarefas: incluir, atualizar e excluir dados. O projeto final em tempo de execução tera a seguinte aparência :

Fig 1.0 - Formulário frmcustomers.frm em execução

O projeto consiste em dois formulários: frmcustomers.frm e frmconfig.frm . O formulário principal - frmcustomers.frm , visto acima na fig. 1.0 - contém os seguintes controles:

  1. Um controle Listview - para exibir os dados como em um grid
  2. Seis controles TextBox e seis controles Label - para exibir os registros da tabela
  3. Quatro botões de comando - Para Incluir , Atualizar , Excluir dados e o botão para encerrar o sistema
  4. Um controle CheckBox - Para o usuário selecionar o uso do método Execute.

Criamos um menu (CTRL+E) no formulário frmcustomers.frm com a opção Configurar->Visualização de dados que chama o formulário frmconfig.frm o qual permite ao usuário ativar/desativar algumas configurações do controle ListView

O formulário frmconfig.frm possui os seguintes controles:

Controles usados no formulário:
  1. Um controle Frame
  2. Seis controles CheckBox
  3. Um botão de comando

Usamos a base de dados Nwind.mdb e o acesso e feito a tabela customers , que foi 'ajeitada' para nossos propósitos. A estrutura da tabela customers ficou assim:

O projeto funciona da seguinda maneira:

  1. A ideia básica é permitir alterar , incluir e excluir registros da tabela customers. Iremos fazer isto usando as propriedades do objeto Recordset ADO e usando comandos SQL que serão executados via método execute
  2. Ao ser carregado o formulario frmcustomers preenche o controle listview com os dados da tabela customers
  3. O usuário tem então a opção de incluir , alterar e excluir registros
  4. A opção configurar permite mostrar algumas propriedades interessantes do controle Listview

Vamos abordar somente as partes relevantes do código usado no projeto. Então vamos lá...

Option Explicit
Private mConn As Connection
Private mbNeedSave As Boolean
Private mbNewRecord As Boolean
Private msCurrentRecord As String
Private Sub Form_Load()
    Dim rs As Recordset
    Dim NewItem As ListItem
    'abre uma conexao
    Set mConn = New Connection
    
     mConn.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=c:\teste\nwind.mdb"
    
    'cria um recordset com os dados a serem exibidos
     Set rs = New Recordset
     rs.Open "Select * from customers", mConn, adOpenForwardOnly, adLockReadOnly
    
    'preenche o controle listview com os dados do recordset
    Do Until rs.EOF
        Set NewItem = Listcustomers.ListItems.Add(, rs("customerid"), rs("name"))
        NewItem.SubItems(1) = "" & rs("Address")
        NewItem.SubItems(2) = "" & rs("City")
        NewItem.SubItems(3) = "" & rs("Country")
        NewItem.SubItems(4) = "" & rs("zip")
        rs.MoveNext
   Loop

    'fecha e limpa variaveis
    rs.Close
    Set rs = Nothing
    'define o primeiro item
    listcustomers_ItemClick Listcustomers.ListItems(1)

End Sub
Private Sub cmdnew_Click()
'limpa as variaves
    txtid.Text = ""
    txtname.Text = ""
    txtaddress.Text = ""
    txtcity.Text = ""
    txtcountry.Text = ""
    txtzip.Text = ""
    'define as variaves para controle
    mbNewRecord = True
    mbNeedSave = True
    'nada para excluir
    cmddelete.Enabled = False
    'nenhum registro selecionado
    Set Listcustomers.SelectedItem = Nothing
    'joga foco para o codigo
    txtid.SetFocus
End Sub
Private Sub cmdupdate_Click()
  UpdateRecord
End Sub
Private Function UpdateRecord() As Boolean
    Dim sCmd As String
    Dim rs As Recordset
    If mbNewRecord Then
        'tenta inserir
        If chkexecute.Value = vbChecked Then
            'usa o método Execute do objeto connection
            sCmd = "insert into customers " & _
                "(customerid,name,address" _
                & ",city,country,zip)"

            sCmd = sCmd + " values ("
            sCmd = sCmd + "'" + txtid.Text + "'"
            sCmd = sCmd + ",'" + txtname.Text + "'"
            sCmd = sCmd + ",'" + txtaddress.Text + "'"
            sCmd = sCmd + ",'" + txtcity.Text + "'"
            sCmd = sCmd + ",'" + txtcountry.Text + "'"
            sCmd = sCmd + ",'" + txtzip.Text + "'"
            sCmd = sCmd + ")"

            'intercepta o erro , se houver
            On Error GoTo UpdateFailed:
            mConn.Execute sCmd
            On Error GoTo 0

        Else
            'usa o objeto recordset para incluir - 'método tradicional
            Set rs = New Recordset
            On Error GoTo UpdateFailed
            rs.Open "select * from customers where customerid = '" _
                + txtid.Text + "'", mConn, adOpenKeyset, _
                adLockOptimistic
            rs.AddNew
            rs!customerid = txtid.Text
            rs!Name = txtname.Text
            rs!address = txtaddress.Text
            rs!city = txtcity.Text
            rs!country = txtcountry.Text
            rs!zip = txtzip.Text
            rs.Update

            'desabilita o tratamento de erros
            On Error GoTo 0
            'fecha e limpa memoria
            rs.Close
            Set rs = Nothing

       End If

        'nào ha mais um novo registro ha inserir sinaliza a variavel para false
        mbNewRecord = False
        'adiciona o novo item a lista
        Dim NewItem As ListItem
        Set NewItem = Listcustomers.ListItems.Add(, txtid.Text, txtname.Text)
        NewItem.SubItems(1) = txtaddress.Text
        NewItem.SubItems(2) = txtcity.Text
        NewItem.SubItems(3) = txtcountry.Text
        NewItem.SubItems(4) = txtzip.Text
        Set Listcustomers.SelectedItem = NewItem
    Else
        'tenta atualizar
        If chkexecute.Value = vbChecked Then
            'usa o metodo execute do objeto connection
            sCmd = "update customers"
            sCmd = sCmd + " set "
            sCmd = sCmd + " customerid = '" + txtid.Text + "'"
            sCmd = sCmd + ",name = '" + txtname.Text + "'"
            sCmd = sCmd + ",address = '" + txtaddress.Text + "'"
            sCmd = sCmd + ",city = '" + txtcity.Text + "'"
            sCmd = sCmd + ",country = '" + txtcountry.Text + "'"
            sCmd = sCmd + ",zip = '" + txtzip.Text + "'"
            sCmd = sCmd + " where customerid = '"
            sCmd = sCmd + msCurrentRecord + "'"

            On Error GoTo UpdateFailed:
             mConn.Execute sCmd
            On Error GoTo 0

        Else
            'usa o objeto Recordset para realizar mudancas - método tradicional
            Set rs = New Recordset
            On Error GoTo UpdateFailed
            rs.Open "select * from customers where customerid = '" _
                + msCurrentRecord + "'", mConn, adOpenKeyset _
                , adLockOptimistic
            'Somente atualiza a chave primaria se ela mudar

            If rs("customerid") <> txtid.Text Then
                rs!customerid = txtid.Text
            End If

            rs!Name = txtname.Text
            rs!address = txtaddress.Text
            rs!city = txtcity.Text
            rs!country = txtcountry.Text
            rs!zip = txtzip.Text
            rs.Update

            On Error GoTo 0
            rs.Close
            Set rs = Nothing

        End If

        'atualiza o item da lista
        Dim OldItem As ListItem
        Set OldItem = Listcustomers.ListItems.Item(msCurrentRecord)
        OldItem.Key = txtid.Text
        OldItem.Text = txtname.Text
        OldItem.SubItems(1) = txtaddress.Text
        OldItem.SubItems(2) = txtcity.Text
        OldItem.SubItems(3) = txtcountry.Text
        OldItem.SubItems(4) = txtzip.Text

    End If

    'nao precisa mais salvar
    mbNeedSave = False
    cmdupdate.Enabled = False
    cmddelete.Enabled = True
    UpdateRecord = True

UpdateComplete:
    Exit Function
UpdateFailed:
    ShowADOError
    GoTo UpdateComplete

End Function

Note que ao montamos a instrução SQL para atualizar e para incluir registros . A sintaxe é:

Atualizar:

SET nomedatabela campo1=texto1, campo2=texto2, ... WHERE condição

Incluir:

INSERT INTO nomedatabela cpo1,cpo2,cpo2,... VALUES cpo1=texto1,cpo2=texto2,...

Private Sub listcustomers_ItemClick(ByVal Item As MSComctlLib.ListItem)
   Dim rs As Recordset
   Set rs = New Recordset

    'se precisar salvar...
    If mbNeedSave Then
        If Not UpdateRecord() Then
            Set Listcustomers.SelectedItem = _
                Listcustomers.ListItems.Item(msCurrentRecord)
            Exit Sub
        End If
    End If

    'abre o recordset com o registro selecionado no listview
    Set rs = New Recordset
    rs.Open "select * from customers where customerid = '" & Item.Key & _
       "'", mConn, adOpenForwardOnly, adLockReadOnly

    Do Until rs.EOF
        'atualiza o listview se houve mudanças
        Item.Text = rs("name")
        Item.SubItems(1) = "" & rs("address")
        Item.SubItems(2) = "" & rs("city")
        Item.SubItems(3) = "" & rs("country")
        Item.SubItems(4) = "" & rs("zip")
        'preenche os controle para edicao
        txtid.Text = rs("customerid")
        txtname.Text = rs("name")
        txtaddress.Text = "" & rs("address")
        txtcity.Text = "" & rs("city")
        txtcountry.Text = "" & rs("country")
        txtzip.Text = "" & rs("zip")
        rs.MoveNext
    Loop

    rs.Close
    Set rs = Nothing
    mbNeedSave = False
    cmdupdate.Enabled = False
    cmddelete.Enabled = True
    msCurrentRecord = txtid.Text

End Sub

O código é simples mas permite aprender algo de útil , sem falar que o control Listview é ótimo para visualizar dados. A partir de agora quem sabe você não passe a usá-lo em seus projetos. Para referênciá-lo em seu projeto Selecione a opção Project -> Components... e ative a caixa de seleção para Microsoft Windows Commons Controls 6.0 (SP3) - MSCOMCTL.OCX. Essa OCX dá acesso a alguns controles ainda desconhecidos por muitos usuários ( ImageCombo, ImageList, Slider, TreeView, etc..) e que na medida do possível estaremos abordando em breve.

Antes que você me xingue, clique no link abaixo para fazer o download do código completo do projeto no formato texto . (O projeto completo está no super cd vb) .

listview.zip (2 KB)

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 ?

 

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti