Site da Vetorial Treinamentos

Sistema Cadastro de Clientes

Editable ListView VBA – Criando uma ListView Editável

Nesse tutorial você aprenderá como criar uma ListView Editável (Editable ListView VBA), onde você poderá editar os dados diretamente dentro do Controle ListView e salvar as alterações automaticamente, de dentro do ListView VBA para dentro de sua planilha do Excel.

Editable ListView

Habilitar Listview

Para isso, devemos primeiro preparar nosso ListView. Caso tenha dúvidas em como fazer isso, veja o post ListView VBA – Uso e Aplicação do Controle ListView VBA, ensinando o passo-a-passo de como criar um ListView Personalizado para Controle de Estoque.

Visualizar ListView

Uma vez inserido o UserForm, o Controle ListView e o Controle ImageList à sua aplicação. Copie o código abaixo e cole dentro do seu projeto. Finalizada essa etapa, seu controle ListView já estará pronto para a próxima etapa, que será tornar os subitems do seu ListView editáveis.

Sub CriaCabecalho()

Dim wbk     As Workbook
Dim ptCor   As Variant
Dim cmf As String
Set wbk = Workbooks("ListView-Editavel.xlsm")

ptCor = RGB(69, 39, 255)

ListView1.ForeColor = ptCor

With Me.ImageList1.ListImages

      .Add , "img1", LoadPicture(wbk.Path & "\lvIcons\amarelo.jpg")     '1
      .Add , "img2", LoadPicture(wbk.Path & "\lvIcons\verde.jpg")       '2
      .Add , "img3", LoadPicture(wbk.Path & "\lvIcons\azul.jpg")        '3
      .Add , "img4", LoadPicture(wbk.Path & "\lvIcons\vermelho.jpg")    '4

End With

With ListView1
    .ColumnHeaders.Clear
    .View = lvwReport
    .SmallIcons = ImageList1
    .FullRowSelect = True
    .Gridlines = True
    .ColumnHeaders.Add , , "Id", 0                          '0
    .ColumnHeaders.Add , , "C.Barras", 100, 2               '1
    .ColumnHeaders.Add , , "Descrição do Produto", 280      '2
    .ColumnHeaders.Add , , "Grupo", 140, 2                  '3
    .ColumnHeaders.Add , , "Marca", 140, 2                  '4
    .ColumnHeaders.Add , , "Linha", 140, 2                  '5
    .ColumnHeaders.Add , , "Categoria", 140, 2              '6
    
End With
    
End Sub

Sub TrazDados()

Dim lvItem      As ListItem
Dim Wplan       As Worksheet
Dim lin         As Integer

Set Wplan = Planilha1
lin = 2

ListView1.ListItems.Clear

Wplan.Activate

With Wplan

        While .Cells(lin, 1).Value <> ""
        
                With ListView1
                
                    Set lvItem = ListView1.ListItems.Add(, , Format(Wplan.Cells(lin, "A").Value, "0000"),,1)
                        
                        If Wplan.Cells(lin, "B").Value = "SEM GTIN" Then
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "B").Value, 4
                        Else
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "B").Value, 2
                        End If
                        
                        lvItem.ListSubItems.Add , , Wplan.Cells(lin, "C").Value, 3
                        
                        If Wplan.Cells(lin, "D").Value <> "" Then
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "D").Value, 2
                        Else
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "D").Value, 4
                        End If
                        
                        If Wplan.Cells(lin, "E").Value <> "" Then
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "E").Value, 2
                        Else
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "E").Value, 4
                        End If
                        
                        If Wplan.Cells(lin, "F").Value <> "" Then
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "F").Value, 2
                        Else
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "F").Value, 4
                        End If
                        
                        If Wplan.Cells(lin, "G").Value <> "" Then
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "G").Value, 2
                        Else
                            lvItem.ListSubItems.Add , , Wplan.Cells(lin, "G").Value, 4
                        End If

                        
                End With

            lin = lin + 1
        
        Wend
End With

End Sub

Private Sub UserForm_Initialize()

    Call CriaCabecalho
    Call TrazDados

End Sub

Ao executar a aplicação o seguinte projeto será exibido na tela.

ListView Control VBA

Tornar ListView Editável (Editable ListView)

O evento que iremos utilizar para tornar o ListView Editável (Editable ListView) é o evento ListView1_DblClick(). Ou seja, ao dá um duplo click dentro do ListView será exibido um TextBox para inserção das informações ou dados desejados. Em outras palavras, você poderá digitar o texto desejado.

Por padrão, o controle ListView VBA não permite a edição de dados no modo lvReport, portanto para que possamos tornar esse controle editável, iremos criar um TextBox auto ajustável e auto dimensionável. Funcionará da seguinte forma, sempre que você der um duplo click dentro de um subitem do ListView VBA, o controle ListBox será alinhado e redimensionado as dimensões desse subitem.

Devido ao fato do controle TextBox não se sobrepor ao controle ListView, iremos também estar criando um controle do tipo Frame, pois esse sim, consegue se sobrepor ao Controle ListView. Nesse caso, inserimos o controle TextBox dentro do Controle Frame. Feito isso, já podemos escrever nosso código.

Private Sub ListView1_DblClick()

Dim i           As Integer
Dim ItemSel    As ListItem

If Not ListView1.SelectedItem Is Nothing Then
    Set ItemSel = ListView1.SelectedItem

    i = 2

    With Frame1
        
        .Visible = True
        .Top = ItemSel.Top + ListView1.Top
        .Left = ListView1.ColumnHeaders(i + 1).Left + ListView1.Left
        .Width = ListView1.ColumnHeaders(i + 1).Width
        .Height = ItemSel.Height
        
        .ZOrder msoBringToFront
    End With
    
    With txtEdit
        
        .Visible = True
        .Text = ItemSel.SubItems(i)
        .SetFocus
        .SelStart = 0
        .Left = 0
        .Top = 0
        .Width = ListView1.ColumnHeaders(i + 1).Width
        .Height = ListView1.SelectedItem.Height
        .SelLength = Len(.Text)
    End With
End If

End Sub

Private Sub ListView1_Click()
    Me.Frame1.Visible = False
    Me.txtEdit.Value = ""
    Me.infoCb.value = ""
End Sub

Note que o código acima permitirá que você edite os dados da coluna 2. Para tonar esse processo mais dinâmico e profissional, iremos criar novos recursos que permitira a edição de todas as colunas, para isso criamos alguns botões com o controle Label, e então escrevemos os dois códigos abaixo.

Sub AlinhaIcons()

Dim Cntr    As control
Dim v       As Integer

For v = 1 To ListView1.ColumnHeaders.Count

    For Each Cntr In UserForm1.Controls
            If TypeName(Cntr) = "Label" And Cntr.Name = Left(Cntr.Name, 8) & ListView1.ColumnHeaders(v).Index Then
                Cntr.Width = ListView1.ColumnHeaders(v + 1).Width
                Cntr.Left = ListView1.Left + ListView1.ColumnHeaders(v + 1).Left
                Cntr.Top = ListView1.Top - Cntr.Height
            End If
    Next Cntr
    
Next v
Set Cntr = Nothing

lblFoco.Left = lblZinza1.Left
lblFoco.Width = lblZinza1.Width
lblFoco.Top = ListView1.Top - lblFoco.Height

End Sub
Private Sub lblZinza1_Click()

    Dim vi      As Integer
    
    txtIndex.Value = 1
    vi = txtIndex.Value
    lblFoco.Left = Controls("lblZinza" & vi).Left
    lblFoco.Width = Controls("lblZinza" & vi).Width
    lblFoco.Top = Controls("lblZinza" & vi).Top
    Frame1.Visible = False
    txtEdit.Value = ""

End Sub

Private Sub lblZinza3_Click()

    Dim vi      As Integer
    
    txtIndex.Value = 3
    vi = txtIndex.Value
    lblFoco.Left = Controls("lblZinza" & vi).Left
    lblFoco.Width = Controls("lblZinza" & vi).Width
    lblFoco.Top = Controls("lblZinza" & vi).Top
    Frame1.Visible = False
    txtEdit.Value = ""

End Sub

Private Sub lblZinza4_Click()

    Dim vi      As Integer
    
    txtIndex.Value = 4
    vi = txtIndex.Value
    lblFoco.Left = Controls("lblZinza" & vi).Left
    lblFoco.Width = Controls("lblZinza" & vi).Width
    lblFoco.Top = Controls("lblZinza" & vi).Top
    Frame1.Visible = False
    txtEdit.Value = ""

End Sub

Private Sub lblZinza5_Click()

    Dim vi      As Integer
    
    txtIndex.Value = 5
    vi = txtIndex.Value
    lblFoco.Left = Controls("lblZinza" & vi).Left
    lblFoco.Width = Controls("lblZinza" & vi).Width
    lblFoco.Top = Controls("lblZinza" & vi).Top
    txtEdit.Value = ""

End Sub

Private Sub lblZinza6_Click()

    Dim vi      As Integer
    
    txtIndex.Value = 6
    vi = txtIndex.Value
    lblFoco.Left = Controls("lblZinza" & vi).Left
    lblFoco.Width = Controls("lblZinza" & vi).Width
    lblFoco.Top = Controls("lblZinza" & vi).Top
    txtEdit.Value = ""

End Sub

Salvar alterações da (Editable ListView) para Planilha

Por fim, escrevemos um código que salvará as alterações feitas no ListView VBA para dentro da Planilha do Excel automaticamente.

Sub EditaDados()
    
Dim lin         As Integer
Dim col         As Integer
Dim nValor      As String
Dim cod         As Long
Dim WPlan       As Worksheet
Dim R           As Range
Dim ItemSel    As ListItem

Set WPlan = Planilha1
Set ItemSel = ListView1.SelectedItem

On Error Resume Next


If txtIndex.Value = 1 Then
    
    If txtEdit.Value <> "" Then
 
        col = txtIndex.Value
        lin = ItemSel.Index
        ItemSel.SubItems(col) = txtEdit.Value
        cod = ListView1.ListItems(lin)
        nValor = ItemSel.SubItems(col)
        
        WPlan.Activate
        
        '------------------------------------------------------------------------------------------------
        With WPlan.Range("A:A")
            Set R = .Find(cod, LookIn:=xlValues, LookAt:=xlWhole)
                If Not R Is Nothing Then
                    R.Select
                    R.Offset(0, col).Value = nValor
                    
                Else
                End If
        End With
        
        Set ItemSel = Nothing
        
    End If
    
End If


If txtIndex.Value >= 3 Then
    
    If infoCb.Value <> "" Then
 
        col = txtIndex.Value
        ItemSel.SubItems(col) = infoCb.Value
        lin = ItemSel.Index
        cod = ListView1.ListItems(lin).Text
        nValor = ItemSel.SubItems(col)
        
        WPlan.Activate
        
        '------------------------------------------------------------------------------------------------
        With WPlan.Range("A:A")
            Set R = .Find(cod, LookIn:=xlValues, LookAt:=xlWhole)
                If Not R Is Nothing Then
                    R.Select
                    R.Offset(0, col).Value = nValor
                    
                Else
                End If
        End With
        
        Set ItemSel = Nothing
        
    End If
    
End If

Set WPlan = Nothing
Set ItemSel = Nothing

Frame1.Visible = False

End Sub
Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
    
    With ListView1
        .SortKey = ColumnHeader.Index - 1
        If .SortOrder = lvwAscending Then
            .SortOrder = lvwDescending
        Else
            .SortOrder = lvwAscending
        End If
        .Sorted = True
    End With
    
End Sub

Por fim, escrevemos o código abaixo para classificar as colunas em ordem crescente ou de

10 thoughts on “Editable ListView VBA – Criando uma ListView Editável”

  1. Pingback: ListView com Gráfico de Barras usando Excel VBA - Projeto Aberto

  2. Pingback: Sistema de agendamento de visitas com Excel VBA - Projeto Aberto

  3. Caramba…. melhor conteúdo VBA que já busquei na internet. Já tem algum tempo que estou procurando exatamente isso e como foi dito no video no youtube não tem ainda. Parabéns ao desenvolvedor.

    Sou iniciante em VBA. Consegui concluir todo o projeto… só não entendo pq não grava para a minha planilha. O resto está funcionando perfeitamente. Já vi e revi os dois videos varias vazes. No mais já me atendeu bastante.

  4. Fato, como o amigo acima disse, conteúdo esplêndido… eu estou assistindo o teu vídeo faz três dias adaptando à necessidade da empresa onde estou atuando e vai dar super certo, incrível, parabéns continue assim que você vai longe
    Já consultei informações com MVPs Microsoft Excel que não fizeram algo tão ‘mágico’ como o que vc fez aqui

  5. Felicitaciones a esta pagina , de verdad,lo adecue en el proyecto de mi trabajo,esta funcionando,grande amigo Do Nascimento,exitos,Dios lo bendiga,es ud. un maestro.

  6. FREDDIE TADEU SANTOS ROCHA

    Prezado, assim como os demais, funciona 99% – mesmo repetindo todos os passos não salva.
    Coloquei uma msgbox para consultar o valor da variável “cod” e está vazia.
    Fora isso, conteúdo excelente.

    1. Boa noite, Freddie.
      Sugiro acompanhar o vídeo, pois há umas alterações no código que não constam no blog.
      O prof. Nascimento alterou a Sub ListView1_DblClick e fez chamada à Sub EditaDados nos componentes txtEdit e infoCb.
      Espero ter ajudado.

  7. Hector Julio Hernandez

    Hola desde Colombia, agradezco inmensamente que compartas este tipo de conocimientos y a la vez felicitarle por la explicación de este trabajo aunque no es mi idioma, entiendo la explicación del video.

  8. Só falta fazer o UPDATE da Listview quando altero “C.Barras” porque posso introduzir “SEM GTIN” e o icon devia fazer o update, de resto está fantástico

  9. Muito bom o conteúdo.
    Consegui fazer com que a coluna seja selecionada a partir do lugar do click e não sendo necessário clicar no label acima do listview. Segue o código de como fazer isso. No meu caso somente as colunas 4 a 7 podem ser alteradas e o label L_Coluna que tem o valor da coluna a ser alterada. Esse fator (53/40) foi por experiementação de qual o valor da posição x no click do mouse está na posição mais a direita da coluna do listview.

    Private Sub LV_Ponto_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As stdole.OLE_XPOS_PIXELS, ByVal y As stdole.OLE_YPOS_PIXELS)
    Dim col1 As Long, col2 As Long, col3 As Long, col4 As Long, col5 As Long, col6 As Long, col7 As Long, col8 As Long
    col1 = Me.LV_Ponto.ColumnHeaders(1).Width * (53 / 40)
    col2 = col1 + Me.LV_Ponto.ColumnHeaders(2).Width * (53 / 40)
    col3 = col2 + Me.LV_Ponto.ColumnHeaders(3).Width * (53 / 40)
    col4 = col3 + Me.LV_Ponto.ColumnHeaders(4).Width * (53 / 40)
    col5 = col4 + Me.LV_Ponto.ColumnHeaders(5).Width * (53 / 40)
    col6 = col5 + Me.LV_Ponto.ColumnHeaders(6).Width * (53 / 40)
    col7 = col6 + Me.LV_Ponto.ColumnHeaders(7).Width * (53 / 40)
    col8 = col7 + Me.LV_Ponto.ColumnHeaders(8).Width * (53 / 40)
    If x < col4 Then
    Me.L_Coluna.Caption = 4
    ElseIf x < col5 Then
    Me.L_Coluna.Caption = 5
    ElseIf x < col6 Then
    Me.L_Coluna.Caption = 6
    Else
    Me.L_Coluna.Caption = 7
    End If
    End Sub

Leave a Comment

O seu endereço de email não será publicado. Campos obrigatórios marcados com *