VBA – Preenchendo um listbox com mais de 10 colunas

Eis um tópico polêmico, como não poderia deixar de ser. E tem motivação melhor para gerar um artigo? Claro que não! Então vamos em frente!

Muitos que começam a explorar um pouco mais o uso do ListBox em seus formulários VBA percebe que ele tem muito mais a oferecer do que uma simples lista de dados. Pessoalmente, no VBA, eu uso ele como controle oficial até mesmo para grids. Os motivos eu explico outra hora.

Voltando ao assunto do título, muitos culpam o ListBox por ser um controle incompleto por ele não permitir adicionar mais de 10 colunas nele. Isso é verdade, mas também não é. Existe sim essa limitação, mas ela está atrelada ao como você coloca os dados no Listbox. Como tudo no mundo da programação, o melhor jeito de demonstrar isso é por um exemplo. Pois bem, considere a seguinte planilha:

VBA - Preenchendo um listbox com mais de 10 colunas

Aqui temos 10 colunas e algumas linhas. Sem enrolação, crie um userform, adicione um listbox nele (com uma largura suficiente para ver as colunas) e coloque o seguinte código:

Private Sub UserForm_Initialize()
    With Planilha1
        Me.ListBox1.ColumnCount = .UsedRange.Columns.Count
        For linha = 1 To .UsedRange.Rows.Count
            ListBox1.AddItem ""
            For coluna = 1 To .UsedRange.Columns.Count
                ListBox1.List(linha - 1, coluna - 1) = .Cells(linha, coluna)
            Next coluna
        Next linha
    End With
End Sub

Onde Planilha1 é o nome do objeto da sua planilha. Sem ir muito a fundo no código, ele faz dois laços For, um para as linhas da planilha e um para as colunas. A propriedade UsedRange define a área usada da planilha, ou seja, vai funcionar bem para planilha que só contenha dados como o exemplo.

Se rodar o codigo, o resultado será isso:

VBA - Preenchendo um listbox com mais de 10 colunas 2

O listbox funcionando. Lindo! Agora, vamos ao problema. Se adicionarmos mais uma coluna na nossa planlha, como mostra abaixo:

VBA - Preenchendo um listbox com mais de 10 colunas 3

Receberemos o seguinte erro:

VBA - Preenchendo um listbox com mais de 10 colunas 4

Se usado dessa forma, ou seja, adicionar itens através do método AddItem, o Listbox se limitará a no máximo 10 colunas.

Existem duas formas de contornar isso:

  1. Usar a propriedade RowSource (fuja!)
  2. Usar arrays (eba!)

Obviamente, vamos para a segunda. Sem alterar a planilha, altere o código do formulário para o seguinte:

Private Sub UserForm_Initialize()
    Dim arrayItems()
    With Planilha1
        ReDim arrayItems(1 To .UsedRange.Rows.Count, 1 To .UsedRange.Columns.Count)
        Me.ListBox1.ColumnCount = .UsedRange.Columns.Count
        For linha = 1 To .UsedRange.Rows.Count
            Me.ListBox1.AddItem
            For coluna = 1 To .UsedRange.Columns.Count
                arrayItems(linha, coluna) = .Cells(linha, coluna).Value
            Next coluna
        Next linha
        
        Me.ListBox1.List = arrayItems()
    End With
End Sub

Execute o formulário novamente e….

VBA - Preenchendo um listbox com mais de 10 colunas 5
Voilá! Um ListBox com mais de 10 colunas!

O que aconteceu? Ao invés de jogar os dados direto no listbox, alimento um array com os dados e depois jogo os dados no Listbox através da propriedade List. O ListBox é esperto para entender um Array, o que não é o caso do AddItem.  O Array, obviamente, tem as dimensões da área ocupada na planilha (mais uma vez , o UserRange é utilizado aqui).

É isso. Bom proveito!

Download do arquivo:

VBA – Preenchendo um listbox com mais de 10 colunas.zip (265.24 KiB)

VBA – EXEMPLO DE SETFOCUS E SAÍDA DO CONTROLE QUANDO ESTE ESTIVER VAZIO

Devido ao número de solicitações em referente a Propriedade Setfocus, ou como dizem, evitar de sair de um controle se ele estiver em branco, e geralmente utilizam somente o Evento EXIT, só que dependendo da estrutura, cria-se o inconveniente de quando o controle estiver em branco e clicar em um Botão para fechar o Formulário recebemos a mensagem que o preenchimento é obrigatório, só que não queremos preenche-lo no momento e sim somente fechar o formulário.

Baseando-me nestas solicitações montei um modelo onde utilizo um Frame e uma Variável para anular a Propriedade Cancel do Evento Exit, e aproveitei para deixar o textbox com aceitação só de numeros/ datas e somente texto.

Com certeza existem outras formas, mas a que eu geralmente utilizo é esta, então segue para quem precisar.

  • Userfom Eventos Exit – KeyPres – Change
  • Userform sem o “X” para fechar o formulário.
  • Controles somente Datas e Textos

Evento Exit - SetFocus

Download do arquivo

SetFocus Evento Exit.zip (74.64 KiB)

Post no fórum

http://www.tomasvasquez.com.br/forum/viewtopic.php?p=18978