65

Click here to load reader

SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Embed Size (px)

Citation preview

Page 1: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

Série “Como Fazer”

Formulários no Excel Utilizando VBA:

Listbox e Combobox

Parte 1

por Robert Friedrick Martim

Page 2: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Criando menus, barras de comando e botões personalizados no Excel

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

i

Nota sobre direitos autorais Este eBook é de autoria de Robert F Martim, sendo comercializado através do site

www.juliobattisti.com.br ou através do site de leilões Mercado Livre:

www.mercadolivre.com.br.

Ao adquirir este eBook você tem o direito de lê-lo na tela do seu computador e de imprimir

quantas cópias desejar, desde que sejam para uso pessoal. É vetada a distribuição deste eBook,

mediante cópia ou qualquer outro meio de reprodução, para outras pessoas. Se você recebeu

este eBook através de e-mail ou via FTP de algum site da Internet, ou através de CD de Revista,

saiba que você esta com uma cópia pirata, não autorizada. Se for este o seu caso entre em

contato com o autor através do e-mail [email protected] ou comunique diretamente ao nosso

site através do e-mail [email protected].

Ao regularizar a sua cópia, você estará remunerando, mediante uma pequena quantia, o trabalho

do autor e incentivando que novos trabalhos sejam disponibilizados.

Visite periodicamente o site www.juliobattisti.com.br para ficar por dentro das novidades!

Page 3: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

ii

Pré-requisitos Para completar este curso é necessário um conhecimento intermediário de VBA, funções de

planilha (tais como PROCV) e estar familiarizado com os controles básicos da caixa de

ferramentas do VBA tais como botão de comando (CommandButton), caixa de texto (TextBox) e

rótulo (Label). Embora boa parte do material envolva VBA mais avançado um grande esforço foi

feito para que mesmo com um conhecimento mínimo, o leitor possa tirar grande proveito do

material.

Como este curso não tem por objetivo ensinar qualquer outra coisa a não ser listbox e

combobox em formulários utilizando VBA, qualquer outro controle utilizado não terá prioridade

nas explicações. Entre os controles que aparecerão no decorrer deste módulo estão label

(rótulo), textbox (caixa de texto), CommandButton (botão de comando) e Frame (moldura). O

módulo vai do mais simples ao mais complexo estilo de listbox e combobox que pode ter

diversas utilidades em seu trabalho diário.

Como formulários não param somente aqui, este assunto precisou ser dividido em partes onde

controles similares serão discutidos em conjunto.

Os leitores interessados podem adquirir o curso básico de Excel em 120 lições no seguinte

endereço: www.juliobattisti.com.br/excel120/excel120.asp que servirá como trampolim

para um melhor aproveitamento e desenvolvimento deste módulo.

Este curso pode ser adquirido em conjunto com outros cursos do CD04. Para maiores

informações, visite www.juliobattisti.com.br ou envie um e-mail para

[email protected].

Page 4: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Criando menus, barras de comando e botões personalizados no Excel

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

iii

Objetivos deste eBook Este eBook foi dividido em módulos. Este módulo visita a utilização de listbox e combobox em

formulário no Excel usando o Visual Basic for Application (VBA).

O trabalho foi desenvolvido a partir da demanda dos usuários do site www.juliobattisti.com.br. O

material procura analisar questões pertinentes ao dia-a-dia de seu trabalho. Vários exemplos são

retirados das dúvidas colocadas no fórum do site ou enviadas diretamente para o autor pelos

assinantes do site.

A linguagem utilizada é descontraída e com o mínimo de jargão possível. O objetivo é ter um

eBook com conteúdo relevante e de fácil compreensão.

Qualquer dúvida referente a este módulo podem ser colocadas diretamente no fórum Excel

avançado no endereço: http://www.juliobattisti.com.br/forum/default.asp

Comentários e sugestões para melhora do material podem ser enviados diretamente para o autor

no endereço [email protected]

Page 5: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

iv

ÍNDICE ANALÍTICO

Introdução ........................................................................................................................................1 Bem-vindo a série “Como Fazer”. ...........................................................................................1 Antes de continuar ..................................................................................................................1

1. O que são listbox e combobox................................................................................................2

2. Visão geral dos controles........................................................................................................4

3. Adicionando itens....................................................................................................................7

4. Adicionando eventos.............................................................................................................12

5. Classificando itens em uma combobox e listbox ..................................................................22

6. Adicionando itens únicos ......................................................................................................27

7. Passando itens entre listboxes .............................................................................................31 7.1. Movendo itens dentro de listboxes...............................................................................34

8. Conectando e interagindo com o MS Outlook ......................................................................38

9. Conectando e interagindo com o MS Access .......................................................................45

10. Sobre o autor ........................................................................................................................60

Page 6: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

1

SÉRIES: COMO FAZER

Formulários no Excel Utilizando VBA: Listbox e Combobox por Robert Friedrick Martim

Introdução

Bem-vindo a série “Como Fazer”.

Nas séries que serão escritas estaremos olhando aspectos distintos do Excel de acordo com a

demanda do fórum Excel Júlio Battisti (http://www.juliobattisti.com.br). A intenção principal é

fornecer ao internauta uma ferramenta que concentre a atenção na solução de um problema

específico.

Nesta série estaremos vendo a criação de diversos listbox e combobox. Iremos utilizar

métodos manuais e dinâmicos para criar e manipular estes controles. Estaremos olhando os

elementos que compõem estes dois controles e como podemos utilizá-los para nosso benefício de

forma dinâmica e eficiente.

Antes de continuar

O trabalho desenvolvido foi testado para compatibilidade com Excel 2002 e 2003. Devido à rápida

mudança em termos de tecnologia de software, atenção sempre será dada às versões mais

recentes do aplicativo Excel.

Não existe um pré-requisito per se; porém, o leitor deve estar ciente do que foi dito na parte de

pré-requisito no início deste módulo. Sem o devido conhecimento de algumas partes básicas este

módulo se tornará mais laborioso e difícil do que realmente é para aqueles sem o conhecimento

básico.

Sugestões serão sempre bem-vindas e esperamos que o leitor participe de forma proativa no

desenvolvimento do material aqui apresentado.

Finalmente, quando objetos e variáveis são dimensionados nesta apostila é utilizada a convenção

de dimensionamento dos objetos e variáveis. Por exemplo, um botão é dimensionado como Dim

btn.

Page 7: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

2

1. O que são listbox e combobox

Caixa de Combinação (ComboBox) e Caixa de Listagem (ListBox). Caixa de Combinação e

Caixa de Listagem são controles fornecidos através da "caixa de ferramentas de controle"

(Controls Toolbox) do Visual Basic for Application (VBA) disponível nos produtos

que compõem o Microsoft Office.

Caixa de listagem, como o nome sugere, é uma caixa contendo uma lista de itens. Estes itens

podem estar listados em uma ou mais colunas e conter diversas linhas, por exemplo. Dependendo

do tamanho da caixa de listagem vários itens podem ser mostrados simultaneamente. Caso os

itens excedam o tamanho da caixa, barras de rolagem são disponibilizadas para que o usuário

possa navegar pelos itens.

Caixa de combinação (combobox -também referido como dropdown list) mostra,

diferentemente da caixa de listagem, apenas um item por vez. Para acessar os itens da lista

precisamos “abrir” a lista, como mostra a figura abaixo:

Figura 1-1

Cada um dos controles possui os seus nomes na figura acima.

Nesta figura, podemos ver uma utilidade destes controles. Vamos supor que para cada item da

combobox existe uma lista. E para cada item da lista exista uma descrição. O que faremos é

construir o formulário de forma que quando um item for selecionado na combobox os itens da lista

mudem para refletir esta mudança. Da mesma forma, criaremos código para lidar com a seleção

de um item na listbox de forma que a label (rótulo) passe a descrição do item.

Page 8: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

3

Como o módulo não se preocupará com formatos e layout de formulário, o leitor deve estudar a

estrutura do formulário acima antes de continuar.

Para todos os formulários desenvolvidos será boa prática analisar a estrutura e códigos antes de

continuar para uma melhor compreensão.

O formulário acima pode ser acessado na planilha Form1.xls.

O trabalho que desenvolveremos a seguir será construído em cima deste primeiro formulário.

Page 9: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

4

2. Visão geral dos controles

Antes de nos aprofundarmos em combobox e listbox, precisamos passar por uma introdução

aos dois objetos (controles) que estaremos utilizando. Combobox e listbox são controles. Estes

dois controles possuem várias propriedades e métodos iguais; e cada um possui seus próprios

métodos e propriedades distintas. A figura abaixo mostra algumas destas propriedades:

Figura 2-1

Algumas propriedades podem ser consideradas mais importantes do que outras, porém, cada

uma desempenha um papel na programação. Veja, por exemplo, a propriedade BoundColumn.

Esta propriedade instrui o VBA a “amarrar” os dados a coluna um. Obviamente, ela não tem

nenhuma utilidade se temos apenas uma coluna (como na figura acima). Porém, ao modificarmos

a propriedade referente ao número de colunas (ColumnCount), ela passa a ter significado.

A propriedade name é outra de grande importância. Muitas vezes é fácil simplesmente aceitar o

nome sugerido; contudo, quando o número de controles aumenta se os nomes não têm um

significado além de ListBox ou Combobox, ficará difícil compreender o papel de cada um em

nosso código. Como convenção, o nome de uma listbox vem prefixada com lst e combobox

com cbo. O fato é que no formulário é óbvio quem é quem, isto é, o que é uma combobox e uma

listbox. Já no código, sem o prefixo, pode ser complicado saber quem é quem. Por exemplo, se

temos uma textbox, uma listbox e uma combobox em um formulário, sem o prefixo, e o

nome do objeto é teste. No código temos que teste.text = “teste”. Bom, sem o prefixo

precisamos ver quem é o tal teste, pois todos os três controles possuem a propriedade text. Se

ao invés tivéssemos txtTeste.text = “teste”, saberíamos que o controle é uma textbox.

Pode parecer um detalhe e querer ser pedante, mas somente apreciamos a importância destes

detalhes quando o volume de código cresce.

Page 10: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

5

A propriedade ColumnHeads é comumente utilizada em listboxes. Ela retorna o cabeçalho das

colunas, como mostra a figura:

Figura 2-2

Infelizmente, esta propriedade somente funciona com dados de um range na planilha. Quando os

dados são carregados através de loops ou métodos dinâmicos o cabeçalho fica em branco.

Portanto, se você pretende utilizar cabeçalhos em seu projeto tenha isso em mente.

Uma propriedade que aparece na Figura 2-1 e que pode causar confusão é a ControlSource.

ControlSource, diferentemente do que o nome pode sugerir, retorna o índice do valor

selecionado. Como a listbox é uma matriz cuja base é zero, o primeiro item selecionado na

matriz retorna um índice igual a zero. Ao anexarmos este índice a uma célula na planilha, esta

célula assume o índice atual selecionado.

Continuando a descer, a propriedade List tem o formato de uma matriz-tabela. Em outras

palavras, se temos um conjunto de dados dentro de uma Array (tabela) os valores podem ser

descarregados de uma só vez para esta propriedade.

A seguir temos a propriedade MultiSelect. Esta propriedade permite a múltipla seleção de

itens em uma listbox. Esta propriedade é útil quando desejamos passar itens de uma listbox

para outra (ou para uma localidade qualquer) com um clique apenas.

Logo abaixo de MultiSelect vem a propriedade RowSource. RowSource indica a fonte de

dados que preencherá a listbox ou combobox. RowSource pode receber como argumentos

um range, ie A1:E10, um “nome” referente a um range, ou uma referência a um range em uma

planilha qualquer.

RowSource funciona muito bem quando utilizamos nomes dinâmicos. Caso contrário, ficamos

presos ao tamanho da matriz que contém os dados.

Page 11: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

6

Além do formato básico, listbox e combobox podem possuir botões de opção e caixas de

seleção. A diferença entre os dois está na propriedade MultiSelect. Se a propriedade for para

seleção simples, o botão será de opção e se houver multi-seleção o botão será de seleção. Este

estilo pode ser modificado na propriedade ListStyle.

Figura 2-3

Na figura acima, na primeira listbox somente podemos selecionar um item por vez. Na segunda

listbox, podemos selecionar um ou mais itens por vez (A pasta de trabalho contendo este

modelo pode ser acessada em Form1.1.xls)

Page 12: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

7

3. Adicionando itens

Há diversas formas de se adicionar itens a combobox e listbox. Estaremos vendo cada uma

destas formas separadamente. Quando as formas estão relacionadas, elas ficarão sob o mesmo

título do tópico. Quando a construção for completamente diferente, elas serão tratadas sob títulos

diferentes.

A maneira mais fácil de adicionar um item a uma combobox ou listbox é utilizar o método

AddItem:

Private Sub UserForm_Activate() cbo.AddItem "Adicionando itens a combobox" lst.AddItem " Adicionando itens a listbox " End Sub

Os itens acima são inseridos quando o UserForm é ativado (Activate). Quando o formulário é

carregado os itens são adicionados (este formulário está na pasta Form2.xls):

Figura 3-1

Podemos adicionar quantos itens forem necessários utilizando este método, porém, como o leitor

reconhecerá depois de algumas tentativas é que adicionar uma lista no código através deste

método pode representar um problema se a lista for muito grande.

Para solucionar este problema podemos utilizar a propriedade RowSource para carregar os itens

(este formulário está na pasta Form3.xls). Esta propriedade pode ser resolvida de duas formas:

a) diretamente na caixa de propriedade do controle que desejamos alocar a lista (ie listbox ou

combobox) e b) diretamente no código onde fazemos a referência ao controle. A figura abaixo

mostra como isso pode ser feito:

Page 13: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

8

Figura 3-2

Na figura acima, modificamos a propriedade RowSource do controle combobox para carregar os

itens contidos na planilha cboItens que se encontram nas células A1, A2 e A3 (no intervalo

A1:A3). Como listbox e combobox têm esta propriedade em comum, se desejamos criar uma

lista para a listbox, basta modificar a propriedade RowSource como feito acima.

A alternativa é utilizar uma linha de comando para preencher a lista:

Private Sub UserForm_Activate() Cbo.RowSource = "cboItens!A1:A3" End Sub

Independentemente do método utilizado o resultado é o mesmo:

Figura 3-3

Além do método AddItem e da propriedade RowSource, podemos utilizar a propriedade List

para obter o mesmo resultado. A propriedade List recebe uma matriz contendo todos os itens.

Estes itens são, então, descarregados de uma só vez para o controle. Novamente, tanto a

listbox quando a combobox compartilham esta propriedade e ambos são, portanto, carregados

da mesma forma.

Para que esse método seja viável precisamos construir a matriz contendo os dados. O exemplo a

seguir mostra como isso pode ser feito:

Page 14: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

9

Private Sub UserForm_Activate() Dim ws As Worksheet Dim matriz() Set ws = ThisWorkbook.Sheets("lstItens") últimaLinha = ws.Range("A65536").End(xlUp).Row ReDim matriz(últimaLinha) With ws For i = 0 To últimaLinha - 1 matriz(i) = .Cells(i + 1, 1) Next End With lst.List = matriz End Sub

Primeiramente, precisamos dizer ao programa onde os dados estão. Assim como no RowSource

dizemos que os dados estão na planilha cboItens, aqui definimos a planilha como sendo

lstItens. Se isso não for feito o programa carregará as linhas da planilha que estiver ativa

quando chamamos o formulário.

A definição da matriz é deixada em aberto, isto é matriz(), porque não sabemos quantos itens

serão carregados. Após descobrimos qual a última linha (últimaLinha =

ws.Range("A65536").End(xlUp).Row) redimensionamos a matriz (ReDim

matriz(últimaLinha)).

A partir daí criamos o loop que preencherá a matriz com as informações que desejamos e

finalmente preenchemos a listbox (lst.List = matriz).

O processo pode parecer complicado, mas não é. Na verdade, o processo representa uma grande

vantagem sobre o RowSource ou AddItem. Observe que se a lista aumentar ou diminuir,

precisamos modificar a propriedade RowSource para levar isso em conta. Já com o método

AddItem precisamos remover/adicionar diretamente no código. Contudo, o método utilizando a

matriz não apresenta este problema.

Se uma linha é adicionada ou removida, não importa. Ao localizar a última linha não vazia, sempre

teremos o número correto de itens em nossa combobox ou listbox no redimensionamento da

matriz.

Além disso, podemos preencher a listbox e combobox simultaneamente, bastando apenas

criar uma matriz para a combobox e uma para listbox.

Page 15: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

10

Os itens carregados por este método:

Figura 3-4

Se a criação do código é uma dor de cabeça para você, ainda há uma solução através de

fórmulas da planilha combinada com RowSource.

Para isso, precisamos criar um “nome” dinâmico para a área que representará nosso RowSource.

Utilizaremos uma combinação das funções Desloc e Cont.Valores para criar esta fórmula

mágica. Vamos supor que o RowSource esteja na planilha cboItens na coluna A. Selecione uma

célula qualquer na coluna A e vá até Nomes Definir. Dê um nome qualquer à sua área de

dados e para a área contendo os dados entre a seguinte fórmula:

=DESLOC(cboItens!$A$1,0,0,CONT.VALORES(cboItens!$A:$A),1)

A figura abaixo mostra como isso é feito:

Page 16: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

11

Figura 3-5

Observe que não desejamos um deslocamento lateral, apenas vertical. A função

Cont.Valores() define este tamanho vertical. No último argumento da função podemos definir

a largura da matriz retornada pela função DESLOC. Por exemplo, se desejamos uma matriz com

quatro colunas, basta modificar o número 1 para 41.

Agora, precisamos modificar o código. Na linha referente ao RowSource o definimos como:

Private Sub UserForm_Activate() Cbo.RowSource = "cbotItem" End Sub

Com a utilização das funções Desloc e Cont.Valores quando itens são acrescentados o nome

é automaticamente atualizado para incluir ou excluir valores na coluna A. Se o usuário acrescenta

um item ele é adicionado ao RowSource e se um item é removido no “nome” este item é removido

do RowSource.

A beleza deste método é que não mais precisamos nos preocupar com o RowSource e o código

fica bem mais leve com uma linha de código apenas.

Este exemplo encontra-se na pasta de trabalho Form3.xls.

Partimos, agora, para a criação de eventos.

1 Ao modificar o número de colunas no “nome”, não esquecer de modificar a propriedade ColumnCount para o número de colunas desejadas.

Page 17: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

12

4. Adicionando eventos

Até agora vimos o que são e como preencher estes dois controles. Nesta parte estamos

interessados em controlar os eventos destes controles. Os códigos desenvolvidos nesta parte

podem ser acessados na pasta de trabalho Form4.xls. Esta pasta de trabalho contém 3

planilhas, cujas guias são mostradas abaixo:

Figura 4-1

A intenção é utilizar estas guias para preencher a combobox. Para fazer isso é bem simples:

Private Sub UserForm_Activate() Dim ws As Worksheet Dim wb As Workbook Set wb = ThisWorkbook For Each ws In wb.Sheets cbo.AddItem ws.Name Next End Sub

Após o loop os itens são adicionados à combobox:

Figura 4-2

A combobox é carregada quando o evento Activate do formulário ocorre. Como desejamos que

a listbox seja preenchida conforme selecionamos um item em nossa combobox, precisamos

utilizar o evento Change do combobox para fazer isso.

Page 18: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

13

Em cada planilha desta pasta de trabalho há itens para a listbox e a descrição do item, em

suas respectivas planilhas. Como cada planilha contém os itens e respectivas descrições e cada

planilha é o nome na combobox, fica relativamente fácil resolver este problema através do evento

Change:

Private Sub cbo_Change() Dim ws As Worksheet Dim wb As Workbook Dim matriz() Set wb = ThisWorkbook Set ws = wb.Sheets(cbo.Text) 'limpa a lista anterior antes de adicionar uma nova lst.Clear 'encontra a última linha não-vazia na coluna A últimaLinha = ws.Range("A65536").End(xlUp).Row n = últimaLinha - 1 ReDim matriz(n) With ws 'vamos até o "n - 1" porque a primeiro item da matriz é 0 For i = 0 To n - 1 matriz(i) = .Cells(i + 2, 1) & " da planilha " & ws.Name Next End With lst.List = matriz End Sub

A matriz é preenchida iniciando-se na linha i+2, pois a primeira linha contém o cabeçalho dos

itens e das descrições. Caso contrário, o cabeçalho será incluído na matriz.

Quando um item é selecionado na combobox os respectivos itens da listbox são preenchidos:

Page 19: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

14

Figura 4-3

A mesma lógica segue para a descrição dos itens. Quando um item é selecionado na listbox o

rótulo mostra a descrição do item. Portanto, o nosso código no evento Click da listbox fica:

Private Sub lst_Click() Dim ws As Worksheet Dim wb As Workbook Set wb = ThisWorkbook Set ws = wb.Sheets(cbo.Text) lbl.Caption = ws.Cells(lst.ListIndex + 2, 2) _ & " da planilha " & cbo.Text End Sub

O código neste caso é bem mais simples do que o anterior. Apenas definimos em qual planilha

encontram-se as informações da lista e depois passamos o valor da descrição para o rótulo.

Como o ListIndex inicia-se em 0 (zero) e as informações iniciam-se na segunda linha,

precisamos ajustar isso. As descrições encontram-se na coluna 2 de cada planilha.

Ao clicar em um item qualquer em nossa lista a respectiva descrição é apresentada no rótulo,

como mostra a figura:

Page 20: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

15

Figura 4-4

Este exemplo mostra como passar o valor em um célula da planilha para um rótulo (label).

Contudo, esta mesma lógica pode ser aplicada para preencher textbox, por exemplo.

Vamos supor que tenhamos uma lista de clientes em uma planilha. Esta planilha contém os

nomes dos clientes e dados pessoais como endereço, telefone, fax, CPF, etc. Queremos

selecionar um nome em uma combobox e todos os detalhes serem preenchidos em textboxes

no formulário.

O nosso formulário terá a seguinte aparência (este formulário pode ser acessado na pasta de

trabalho Form5.xls):

Figura 4-5

Neste exemplo, estarei utilizando fórmulas, ao invés de código, para preencher os valores das

textboxes. Os valores para a combobox são carregados utilizando um “nome” como foi

Page 21: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

16

mostrado anteriormente. Porém, a nossa fórmula para o nome mudará, pois neste caso nós temos

um cabeçalho o qual não queremos em nossa combobox. O “nome” deve se construído desta

forma:

=DESLOC(Clientes!$A$2,0,0,CONT.VALORES(Clientes!$A:$A)-1)

Neste caso estamos iniciando na segunda célula (A2) e subtraindo 1 (um) dos valores contados.

Ao subtrair 1, estamos removendo o cabeçalho, pois a contagem total inclui todos os valores na

coluna A.

Portanto, o código que será executado quando o formulário é aberto será2:

Private Sub UserForm_Initialize() cboNome.RowSource = "Clientes" cboNome.ListIndex = 0 End Sub

A linha referente ao ListIndex força a seleção do primeiro item da lista, isto é, o nome do cliente

cujo índice é zero:

Figura 4-6

Caso o leitor não queira ter nenhum nome selecionado, basta remover a linha de código referente

ao ListIndex ou passar o valor para –1 (este valor refere-se ao valor que não existe na lista).

O nosso próximo passo é preencher as textboxes conforme nomes sejam selecionados na

combobox. Novamente, utilizaremos o evento Change para isso. Contudo, ao invés de utilizarmos

código, utilizaremos a função PROCV para fazer isso. Em VBA a funções PROCV é VLOOKUP.

2 O nome “Clientes” pode ser entrado diretamente na caixa de propriedades da combobox, bastando apenas digitar o nome na caixa de propriedade, isto é digitar “Clientes” (sem as aspas) para a propriedade RowSource.

Page 22: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

17

O código a ser executado após o evento Change é:

Private Sub cboNome_Change() txtEndereco = WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:D100"), 2, False) txtTelefone = WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:D100"), 3, False) txtEmail = WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:D100"), 4, False) End Sub

O texto da combobox é o valor procurado, o intervalo A2:D100 é a área onde a busca ocorrerá, o

valor seguinte refere-se a coluna onde o valor deve ser procurado e o último item diz que o valor

procurado deve ser exato. Aqui, preferi escrever False. Não obstante, False tem o valor

numérico 0 (zero) . Quando fórmulas são grandes é preferível utilizar o valor numérico ao valor

literal.

Os valores para as textboxes são os valores encontrados. Ao selecionar um cliente diferente na

lista, os dados são automaticamente preenchidos:

Figura 4-7

Para o botão atualizar, encontramos um pequeno problema. Se utilizarmos o ListIndex da

combobox para achar a linha onde os dados se encontram, iremos “corrigir” os dados para o

cliente errado. O que ocorre é que quando modificamos o valor da combobox, como este valor

não se encontra na lista, o valor da combobox passa para –1 (ListIndex = – 1). Ou seja,

precisamos encontrar uma outra solução.

A solução é criar um índice para os clientes. Neste exemplo, há um índice na coluna E (veja a

pasta de trabalho referente a este exemplo). Porém, para o índice também temos um pequeno

problema: e se o número for repetido? Se o número for repetido, temos mais uma dor de cabeça.

Page 23: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

18

Para resolver isso, temos que criar uma validação nas células que receberão os índices para

evitar a repetição dos índices. No exemplo, o número de cliente foi limitado a 99. Portanto, para

criar a validação dos dados selecione a área que vai de E2:E100 e entre a fórmula conforme

mostra a figura:

Figura 4-8

O que a fórmula faz é contar todos os valores no intervalo E2:E100 que sejam iguais a célula

atual (na figura, a célula atual é a E2). Se o resultado for igual a 1, o usuário pode continuar. Caso

contrário, ele precisa entrar o valor novamente.

Feito isso, estamos prontos para criar o código que atualizará os nossos dados. Primeiramente,

crie mais uma textbox no formulário (esta textbox está para visible = false, neste

exemplo). Veja a figura abaixo:

Page 24: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

19

Figura 4-9

Com a textbox, no evento Change da combobox, rearrumamos o código para levar em

consideração este novo controle:

Private Sub cboNome_Change() txtEndereco = WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:E100"), 2, False) txtTelefone = WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:E100"), 3, False) txtEmail = WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:E100"), 4, False) txtíndice= WorksheetFunction.Vlookup _ (cboNome.Text, Range("A2:E100"), 5, False) End Sub

Como o texto da textbox conterá o valor do índice e como sabemos que os nomes estão em

uma linha a mais do que o índice (o índice inicia-se em 1). Isto é, para índice igual a um o cliente

está na linha “índice +1”. Assim sendo, o código para o botão de atualização fica:

Private Sub cmdAtualizar_Click() Dim ws As Worksheet Set ws = ThisWorkbook.Sheets("Clientes") linha = txtíndice + 1 With ws .Cells(linha, 1) = cboNome .Cells(linha, 2) = txtEndereco .Cells(linha, 3) = txtTelefone .Cells(linha, 4) = txtEmail End With cboNome.RowSource = "Clientes" cboNome.ListIndex = txtíndice - 1 End Sub

Page 25: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

20

Primeiramente, definimos a planilha onde o código deve ser atualizado através do Set. A seguir,

definimos a linha como sendo o txtíndice + 1. Com a planilha (ws) atualizamos os dados de

acordo com as informações contidas nos textboxes.

O próximo passo é atualizar o RowSource e finalmente definir o cliente a ser selecionado como

sendo o índice – 1, pois o ListIndex inicia-se em 1. Desta forma, o cliente com índice igual a

1 é, na verdade, o cliente 0 (zero) na combobox.

A figura abaixo mostra a atualização sendo feita:

Figura 4-10

Os valores circundados no userform são os novos valores (antes de se pressionar o botão

Atualizar). Os valores circundados na planilha são os valores antigos. Após a atualização, temos:

Figura 4-11

Page 26: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

21

O índice, contido na coluna E, não é mostrado na figura por falta de espaço, porém, ele é

mostrado na textbox. Na pasta contendo este exemplo, este controle está para visible =

false. O índice, aqui, funciona de uma forma similar à chave-primária de um banco de dados.

Porém, a eficiência e confiabilidade deste método são muito mais limitadas.

Page 27: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

22

5. Classificando itens em uma combobox e listbox

Um problema encontrado por todos aqueles que utilizam listbox e combobox é ordenação,

alfabética ou numérica, dos itens que serão adicionados aos dois controles.

Uma solução bastante óbvia é gravar uma macro que coloque os itens na ordem que desejamos e

depois criar um loop para carregá-los. Ainda na mesma lógica, seria copiar todos os itens, jogá-

los em uma planilha temporária, ordená-los, passá-los para o controle e limpar a planilha

temporária.

É desnecessário dizer que após algumas tentativas com erros e acertos, chegaremos a conclusão

que o método não é muito eficiente, embora ele resolva o nosso problema.

Para aqueles que leram o meu tutorial sobre este mesmo assunto, eles devem entender o porquê

da conclusão do tutorial. Lá foram apresentadas formas de se preencher estes controles e aqui

existem formas mais eficientes e completamente diferentes das apresentadas no tutorial. Se você

não possui o tutorial ele pode ser baixado gratuitamente em

http://www.juliobattisti.com.br/artigos/colunas/Robert/coluna01.asp

Primeiramente, não estaremos interessados em ordenar os itens diretamente nos controles.

Iremos, porém, analisar como isso é feito. Faça uma busca no Ajuda do VBA por ASCII. Na lista,

veremos como os itens são tratados em ordem crescente. Na lista, veremos que A < B < C... Os

quais são menores que a < b < c...

Uma ordenação segue esta tabela. Portanto, uma classificação do maior para o menor analisará

os itens de trás para frente e vice versa, pois ou vamos a uma direção ou noutra. Este é o nosso

primeiro passo para a compreensão de como a ordenação funciona.

O segundo requer entender como o Excel manipulará os dados conforme eles são ordenados.

É desnecessário dizer que o Excel é uma grande matriz. Como tal, tudo que é manipulado é

jogado em uma matriz. Como não sabemos de antemão o tamanho desta matriz, precisamos

deixar a parte superior da matriz (UBound) em aberto e calcular este valor em tempo de

execução.

Aqui entra em cena a propriedades List. Como visto anteriormente, esta propriedade tem o

formato de uma matriz e os dados que ela recebe devem vir de uma matriz também. Como a

propriedade é chamada de List, estaremos chamando a matriz que conterá os itens de List,

também.

Page 28: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

23

Iniciamos, então, a construção de nossa função:

Function Ordenar(Lista As Range) As Variant Dim List() n = Lista.Count ReDim List(n - 1) End Function

A nossa função é Variant porque não sabemos as dimensões que ela tomará ao resolver o

problema. A lista é um range que virá de nossa planilha. A princípio a List é aberta pois não

temos o tamanho da lista. Ao definirmos n como sendo o número de itens contido na lista,

redimensionamos a List como sendo n – 1. Como a base é Option Base 0, o primeiro item

da matriz é 0 (zero). Se não subtrairmos 1 de n, a matriz conterá um item a mais do que o range.

No próximo passo, preenchemos a lista (List):

Function Ordenar(Lista As Range) As Variant i = 0 For Each Item In Lista List(i) = Item 'Debug.Print Item i = i + 1 Next End Function

O Debug.Print Item serve para jogar cada Item na janela imediata. Utilizei este método de

depuração para visualizar os dados sendo carregados para a matriz. Com a List pronta,

podemos iniciar o processo de ordenação das variáveis contidas na lista:

Function Ordenar(Lista As Range) As Variant For i = 0 To UBound(List) - 1 For j = i + 1 To UBound(List) If List(i) > List(j) Then Temp = List(j) List(j) = List(i) List(i) = Temp End If Next j Next i End Function

Primeiramente, definimos os loops. Como não sabemos o limite superior da matriz3, utilizamos a

função UBound(matriz) para descobrir qual o último valor da lista. A matriz inicia-se em 0

(zero), pois o estamos utilizando Option Base 0. Se você deseja ser pedante, pode-se utilizar

LBound(Matriz) para achar o limite inferior da matriz, o qual retornará zero.

3 Na verdade, nós sabemos, pois a matriz é redimensionada como sendo n – 1. Porém, é sempre boa idéia utilizar este método para evitar erros.

Page 29: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

24

A seguir testamos (utilizando o formato da tabela ASCII), se o valor i é maior do que o valor i +

1 (j), pois queremos uma lista em ordem crescente. Se a lista for em ordem decrescente, basta

trocar o sinal de maior (>) pelo sinal de menor (<).

Finalmente, definimos a nossa função como sendo igual a List. Contudo, ao construir a lista, a

matriz é transposta, pois os itens são avaliados na vertical e colocados lado a lado (horizontal).

Assim sendo, precisamos devolver a matriz para o formato original. O código final fica, portanto:

Function Ordenar(Lista As Range) As Variant Dim List() n = Lista.Count ReDim List(n - 1) i = 0 For Each Item In Lista List(i) = Item 'Debug.Print Item i = i + 1 Next For i = 0 To UBound(List) - 1 For j = i + 1 To UBound(List) If List(i) > List(j) Then Temp = List(j) List(j) = List(i) List(i) = Temp End If Next j Next i Ordenar = WorksheetFunction.Transpose(List) End Function

A matriz List poderia ser transposta em um loop. Não obstante, a função Transpose faz a

mesma coisa com muito mais eficiência.

Como estamos falando de uma função, ela pode ser colocada em um planilha para checarmos os

resultados. Como estamos falando de uma matriz-tabela é importante selecionar a área que

receberá o resultado e apertar CTRL+SHIFT+ENTER após entrar a fórmula:

Page 30: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

25

Figura 5-1

Este primeiro exemplo é mostrado para que o leitor entenda o que está ocorrendo. Para adicionar

os itens a uma listbox, por exemplo, fica muito simples.

O arquivo Form 5.1.xls contém o formulário abaixo:

Figura 5-2

Como foi observado na lista ASCII, R < r; portanto, se você ordenar os nomes robert1 e

ROBERT2 em ordem crescente ROBERT2 virá antes de robert1. Em ordem alfabética crescente,

seria ao contrário, pois estaríamos ignorando maiúsculo/minúsculo. Portanto, sem ter a lista em

mãos, você não entenderá a lógica por trás da ordenação.

Page 31: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

26

Se você achou a parte de ordenação difícil demais. Para preencher a lista, você achará

ridiculamente fácil:

Private Sub UserForm_Activate() ListBox1.List = Ordenar(Range("A2:A21")) End Sub

Como a ordenação requer matrizes, a operação fica complexa pelo fato de não podermos

visualizar a matriz. A melhor saída é utilizar o Debug.Print para resolver isso.

Finalmente, a escolha por uma função ao invés de uma sub-rotina foi apenas para mostrar como

ela pode ser utilizada na planilha e para visualização do resultado antes de passá-lo para a

listbox. Não há nada que impeça a utilização de uma sub-rotina para retornar a mesma matriz.

Page 32: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

27

6. Adicionando itens únicos

Já passamos pela parte onde adicionamos itens ao combobox/listbox e classificamos os itens.

Porém, há situações especiais onde queremos que os valores sejam únicos.

Vamos supor que no exemplo anterior, além dos dados já cadastrados também tenhamos a

Unidade Federativa (UF) de cada cliente. É fácil ver que este valor se repetirá na coluna referente

a UF. Estão-se passando este valor para uma textbox não há problemas, pois é isso mesmo que

desejamos fazer. Contudo, estaremos analisando o mesmo problema de uma ótica diferente.

Estaremos vendo como preencher uma combobox com valores únicos onde várias cidades sob a

mesma UF são colocadas em uma listbox a partir da UF selecionada.

Valores únicos podem ser adicionados de duas formas: 1) através de fórmulas ou 2) uma função

customizada (personalizada) pelo usuário. Em ambos os casos, porém, o resultado é uma matriz

contendo todos os itens únicos. Primeiramente, avaliamos uma função que retorna uma matriz

contendo todos os valores únicos. Esta matriz, como na caso da classificação, é jogada de uma

só vez para a propriedade List do controle.

Para criarmos uma lista única utilizaremos uma coleção (Collection). Ao utilizar uma nova

coleção (New Collection), podemos associar um item da lista a uma chave, evitando assim a

repetição do item.

Os modelos aqui desenvolvidos encontram-se na pasta de trabalho Form 6.2.xls.

Como sempre, iniciamos com a declaração das variáveis:

Private Function matriz(lista As Range) As Variant Dim matrizSaída() As Variant Dim Item As Variant Dim matrizÚnica As New Collection End Function

Estaremos utilizando, primeiramente, uma função para fazer o que desejamos. A matriz de saída

é deixada em aberto porque desconhecemos o tamanho da lista. Uma vez que a lista tenha sido

passada para a função, preenchemos o nova coleção de dados:.

Page 33: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

28

Private Function matriz(lista As Range) As Variant On Error Resume Next For Each Item In lista If Item.Formula <> "" Then matrizÚnica.Add Item.Value, CStr(Item.Value) End If Next Item matriz = "" End Function

Aqui, acrescentamos os itens a nova coleção de dados (matrizÚnica). A chave (similar a chave-

primária de um BD) é dada como sendo a String do valor do Item atual. Observe que se a

chave for igual ocorrerá um erro. Para evitar isso, utilizamos o On Error Resume Next (No erro

executar próximo comando). Ao executar o próximo comando o item onde o erro ocorreu é pulado

e somente os itens que não retornam um erro são adicionados a nova coleção. A última linha

apenas define a matriz como sendo vazia.

Private Function matriz(lista As Range) As Variant If matrizÚnica.Count > 0 Then ReDim matrizSaída(1 To matrizÚnica.Count) For i = 1 To matrizÚnica.Count matrizSaída(i) = matrizÚnica(i) Next i matriz = matrizSaída End If End Function

Finalmente, checamos se o número de itens da coleção é maior do que zero. Se for, redimensiona

a matriz de saída. Aqui, utilizo um forma diferente de se declarar o intervalo da matriz. Como

Option Base é zero, teríamos que subtrair 1 do número total de itens. Ao dimensionar a matriz

com sendo de 1 ao número total (1 To matrizÚnica.Count) não há necessidade de subtração

é a dimensão é explícita, pois sabemos o limite inferior (LBound) e limite superior (UBound).

A função completa:

Page 34: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

29

Private Function matriz(lista As Range) As Variant Dim matrizSaída() As Variant Dim Item As Variant Dim matrizÚnica As New Collection On Error Resume Next For Each Item In lista If Item.Formula <> "" Then matrizÚnica.Add Item.Value, CStr(Item.Value) End If Next Item matriz = "" If matrizÚnica.Count > 0 Then ReDim matrizSaída(1 To matrizÚnica.Count) For i = 1 To matrizÚnica.Count matrizSaída(i) = matrizÚnica(i) Next i matriz = matrizSaída End If End Function

O nosso próximo passo e preencher a combobox.

Private Sub UserForm_Initialize() Linha = Range("A65536").End(xlUp).Row Dim valores As Variant Dim i As Long valores = matriz(Range("A2:A" & Linha)) With cbo1 For i = 1 To UBound(valores) .AddItem valores(i) Next End With cbo1.ListIndex = 0 End Sub

Primeiramente, procuramos pela última linha na coluna A. Em seguida definimos a variável

valores como sendo o resultado da matriz anterior e finalmente damos um loop em cada valor

e preenchemos a combobox. O primeiro item da combobox que é selecionado é aquele cujo

ListIndex é zero.

Aperte o “pause” do VBA e pense um pouco... Será que não há nada de estranho neste código?

Para que criar uma matriz chamada valores e dizer que essa matriz é igual a função? Pior ainda,

para que fazer um loop quando temos em mão a matriz completa!

O código funciona bem, mas estamos repetindo o trabalho já feito pela função.

Como a função matriz resolvida, podemos facilmente preencher a combobox, com a seguinte

sub-rotina:

Page 35: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

30

Private Sub UserForm_Initialize() Linha = Range("A65536").End(xlUp).Row cbo1.List = matriz(Range("A2:A" & Linha)) cbo1.ListIndex = 0 End Sub

Com apenas três linhas resolvemos o problema!

Agora, dê um “rewind” até a função. Embora a função seja ideal (por retornar valores que podem

ser divididos com outros procedimentos), o mesmo resultado poderia ter sido obtido diretamente

no evento Initialize do formulário.

Como o processo é similar a criação da função é desnecessário repetir todo o código no papel.

Contudo, o material foi desenvolvido na pasta de trabalho e está disponível para o leitor.

Page 36: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

31

7. Passando itens entre listboxes

Uma característica interessante de listboxes é que podemos passar itens de uma lista para

outra. Em algum ponto, o usuário já deve ter tido esta experiência. Por exemplo, quando

utilizamos o Outlook para enviar e-mails, temos uma listbox e três textboxes. Uma contém a

lista de e-mail em nosso computador e a outra recebe os e-mails das pessoas para as quais

desejamos enviar a mensagem.

Por incrível que pareça, transferir itens entre listboxes é bem simples. Primeiramente, vamos

iniciar com a construção de nosso formulário. O formulário do usuário deve ter o formato a seguir:

Figura 7-1

A listbox da esquerda conterá a lista completa e a da direita receberá os itens. Além disso,

temos quatro botões de comando. O botão com duas setas para a direita insere na segunda

listbox todos os itens da primeira listbox. O botão com uma seta insere apenas o item

selecionado.

A mesma lógica serve para os botões de remover. Uma seta remove o item selecionado e duas

setas remove todos os itens. Então, vamos iniciar pela parte mais fácil: passar/remover todos os

itens da lista.

Entre no código do primeiro botão, onde entraremos o código:

Private Sub cmdAdicionarTodos_Click() On Error Resume Next lstRecebeItens.List = lstItens.List End Sub

Tudo que fazemos é definir a List da listbox da direita (lstRecebeItens) como sendo igual

a lista dos da primeira listbox. A linha On Error Resume Next apenas assegura que se

houver um erro o código continuará a rodar.

Se passar toda a lista foi simples, remover todos os itens da segunda lista é mais fácil ainda:

Page 37: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

32

Private Sub cmdRemoverTodos_Click() On Error Resume Next lstRecebeItens.Clear End Sub

Não precisamos da um loop em cada item da lista e remover um a um. Basta utilizar o método

Clear e resolvido o problema!

A nossa próxima parada é adicionar um item por vez, isto é, adicionar o item selecionado. Abra a

área de edição do código para o botão de adicionar o item selecionado. O nosso código, neste

caso, ficará:

Private Sub cmdAdicionarUm_Click() On Error Resume Next If lstItens.ListCount >= 1 Then If lstItens.ListIndex = -1 Then lstItens.ListIndex = _ lstItens.ListCount - 1 End If lstRecebeItens.AddItem (lstItens.Text) End If n = lstItens.ListIndex + 1 If n >= lstItens.ListCount Then

lstItens.ListIndex = 0 Else: lstItens.ListIndex = n End If End Sub

O código primeiramente checa se há algo na lista (lstItens.ListCount >= 1). Se sim, checa

o valor da seleção (lstItens.ListIndex = -1). Se o valor for -1, então o último item da lista

é selecionado e o texto deste item é passado para a segunda lista.

A seguir checamos qual o item atualmente selecionado. Após este item ser passado para a

segunda listbox, o item seguinte é selecionado. Se este for o último item da lista; então, o

primeiro item da lista é selecionado.

Para remover um item apenas é relativamente fácil. Tudo que precisamos saber é o índice do item

e utilizar o método RemoveItem para fazer isso:

Private Sub cmdRemoverUm_Click() On Error Resume Next If lstRecebeItens.ListCount >= 1 Then If lstRecebeItens.ListIndex = -1 Then lstRecebeItens.ListIndex = _ lstRecebeItens.ListCount - 1 End If lstRecebeItens.RemoveItem (lstRecebeItens.ListIndex) End If End Sub

Novamente checamos se há algum item na lista (lstRecebeItens.ListCount >= 1). Se

houver itens na lista, mas nenhum estiver selecionado, o último item da lista é removido. Se algum

item estiver selecionado, o item cujo índice está selecionado é removido.

Page 38: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

33

Figura 7-2

A imagem mostra um item sendo passado por vez. Após passar o Item 1, o segundo item da

primeira lista é automaticamente selecionado.

Além de passarmos um item por vez, podemos habilitar a multi-seleção para passar todos os itens

selecionados de uma só vez. Tanto o exercício anterior quanto este se encontram na pasta de

trabalho Form6.xls.

Antes de tudo precisamos modificar a propriedade da listbox para que ela aceite múltipla

seleção de itens. Na caixa de propriedade, modifique como segue:

Figura 7-3

A propriedade Multiselect é composta por três estados:

• frmMultiSelectSingle • frmMultiSelectMulti • frmMultiSelectExtended

O primeiro estado é padrão e permite apenas uma seleção por vez (como feito anteriormente). O

segundo, permite a seleção de vários itens através do clique do mouse, isto é, em cada item que o

usuário clicar ele será selecionado. O terceiro, o qual estaremos utilizando, o usuário precisa

pressionar e segurar a tecla CTRL enquanto clica em cada item para efetuar uma múltipla seleção.

Page 39: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

34

Não estaremos modificando o código para adicionar e remover todos os itens da lista

simultaneamente.

Para se passar um item selecionado, precisamos utilizar a propriedade Selected. Esta

propriedade não é opcional e, portanto, precisamos definir o item selecionado. Para passar os

itens selecionados, procederemos da seguinte forma:

Private Sub cmdAdicionarSel_Click() On Error Resume Next n = lstItens.ListCount - 1 If lstItens.ListCount >= 1 Then If lstItens.ListIndex = -1 Then lstItens.ListIndex = _ lstItens.ListCount - 1 End If For i = 0 To n If lstItens.Selected(i) = True Then lstRecebeItens.AddItem lstItens.List(i) End If Next End If End Sub

Primeiramente, contamos todos os itens da lista. Como estamos utilizando Option Base 0

(opção padrão para matrizes), o índice sempre é iniciado em zero. Assim sendo, o valor de n será

igual a lstItens.ListCount - 1. Novamente, checamos se há algo selecionado para depois

fazer um loop nos itens selecionados.

Durante o loop checamos se o item i está selecionado e se este for o caso, acrescentamos o item

i da primeira lista a segunda lista.

7.1. Movendo itens dentro de listboxes

Acima vimos como passar um ou mais itens entre duas listboxes. Agora, nos voltamos para a

passagem de itens dentro de uma listbox. Neste caso, o que estamos fazendo é mover a

posição atual do item.

O nosso formulário terá o seguinte aspecto:

Page 40: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

35

Figura 7-4

Com o nosso layout feito, estamos prontos para iniciar a nossa análise do problema.

Como já sabemos, a propriedade List define a matriz contendo os itens de nossa lista. Embora os

itens tenham sido adicionados um a um, o resultado é uma matriz. Portanto, para fazer o que

desejamos precisaremos manipular e reconstruir a matriz a cada passo.

Ao utilizarmos o Option Base padrão (Option Base 0), temos que a propriedade ListIndex

= 0 para o Item 1, ListIndex = 1 para Item 2 e ListIndex = 2 para o Item 3.

Se construirmos uma matriz contendo os itens acima, ela terá o mesmo formato. Se capturarmos

o ListIndex e o texto do Item 1, temos: ListIndex = 0 e Text = Item 1. Portanto,

precisamos guardar estas duas variáveis para movimentar os itens na nova matriz.

Vamos chamar nossa matriz de List. Ela é redimensionada de acordo com o número de itens na

listbox. O texto é igual ao texto da posição atual em nossa nova lista. O Item 1 passa para a

posição do Item 2 da lista atual. A nossa lista tem o formato atual:

• Item 1 • Item 2 • Item 3

Portanto, o Item 1 passa a ser igual a ListIndex + 1 (Item 2). E nossa matriz, passa a ser

• Item 2 • Item 2 • Item 3

Como havíamos guardado o Item 1 em Text, o Item 1 passa para posição onde ListIndex + 1.

Isto é List(ListIndex + 1) e igual a Text. E a nova matriz fica:

• Item 2 • Item 1 • Item 3

Page 41: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

36

Observe que o itens não moveram. O que fizemos foi escrever Item 2 na posição onde se

encontrava o Item 1. E depois, escrevemos Item 1 sobre o segundo Item 2 (pois ficamos com o

Item 2 repetidos duas vezes nas posições 0 e 1).

O código desenvolvido utiliza o Debug.Print para mostrar o processo durante a execução:

Figura 7-5

O problema é bastante simples. Talvez a parte mais difícil seja visualizar o processo conforme ele

ocorre. Com as explicações dadas, podemos partir para a escrita de nosso código:

Private Sub imgParaBaixo_Click() Dim List() If lstItens.ListIndex = lstItens.ListCount - 1 Then Exit Sub End If n = lstItens.ListCount ReDim List(n - 1) 'Guarda a matriz original na "List" For i = 0 To n - 1 List(i) = lstItens.List(i) Next 'Guarda o índice da seleção atual ItemNúm = lstItens.ListIndex 'Item temporário é igual ao item selecionado TempItem = List(ItemNúm) 'Item atual da lista passa ser o item seguinte List(ItemNúm) = List(ItemNúm + 1) 'Utilize o Debug.Print para ver a mudanca na matriz 'Debug.Print "Primeiro Debug na janela imediata:" 'For i = 0 To n - 1 'Debug.Print List(i) 'Next

Page 42: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

37

'Aqui, temos dois itens repetidos. Um na posição nova ItemNúm - 1 'E outro na posição original ItemNúm 'Portanto, ItemNúm + 1 na nova lista é igual ao TempItem List(ItemNúm + 1) = TempItem 'Debug.Print vbCr & "Segundo Debug na janela imediata:" 'For i = 0 To n - 1 'Debug.Print List(i) 'Next 'Define a nova List da listbox como sendo a List lstItens.List = List 'Seleciona o item que está sendo movido. Como a posição original é 'ListIndex (ItemNúm) ao mover para baixo ele passa a ser ItemNúm + 1 lstItens.ListIndex = ItemNúm + 1 End Sub

Como utilizei uma imagem com a seta, o evento é baseado no “click” sobre a figura. Se o

movimento para baixo envolve uma soma, o inverso é verdadeiro para o movimento para cima.

Portanto, ao compreender como o método acima funciona, criar o movimento inverso é um

passeio no parque:

Private Sub imgParaCima_Click() Dim List() If lstItens.ListIndex = 0 Then Exit Sub End If n = lstItens.ListCount ReDim List(n - 1) For i = 0 To n - 1 List(i) = lstItens.List(i) Next ItemNum = lstItens.ListIndex TempItem = List(ItemNum) List(ItemNum) = List(ItemNum - 1) List(ItemNum - 1) = TempItem lstItens.List = List lstItens.ListIndex = ItemNum - 1 End Sub

A pasta de trabalho contendo este exemplo pode ser acessada em Form6.1.xls.

Page 43: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

38

8. Conectando e interagindo com o MS Outlook

Para os usuário do MS Office, há várias formas de se interagir com outros aplicativos deste

pacote. Neste tópico e no próximo estaremos vendo exatamente isso.

Neste primeiro tópico, estaremos vendo como carregar para uma listbox os e-mails e nomes

dos contatos contidos em seu Outlook. Além disso, como bônus, uma pasta de trabalho contendo

um pequeno aplicativo para envio de e-mail do Excel foi criado. Não estaremos discutindo os

detalhes de como o programa foi feito ou como configurar a sua máquina para envio de e-mails.

Afinal, nosso foco está nas listboxes e comboboxes. Porém, o código está aberto para análise

e uso pelo usuário.

O formato de nosso formulário será o seguinte:

Figura 8-1

A caixa da esquerda é uma listbox e as três caixas da direita são textboxes. Este layout foi

escolhido para manter um formato similar ao do Outlook 2002 (Outlook XP).

Como os botões “Para”, “Cc” e “BCc” passam os valores da listbox para as respectivas caixas

de texto, não estaremos reconstruindo estes botões neste tópico, pois eles já foram tratados

anteriormente.

Os objetivos deste exercício estão listados abaixo:

Page 44: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

39

1. Carregar o nome do contato e seu respectivo endereço de e-mail a partir da lista de

contatos do Outlook;

2. Passar da listbox somente o endereço de e-mail para a respectiva caixa de acordo com

o botão clicado;

3. Permitir que o usuário passe um item para o destinatário através de um duplo-clique sobre

o nome do contato;

A primeira parte requer uma rotina que seja capaz de ler os dados contidos na pasta de contatos

do Outlook e passe os valores para uma matriz. Como estamos interessados no nome e e-mail,

precisamos modificar as propriedades da listbox como segue:

1. Passar o valor da ColumnCount para 2 (duas colunas, uma para os nomes e outra para

os e-mails);

2. MultiSelect deve estar para frmMultiselectExtended para permitir múltipla

seleção de destinatários que serão passados para as respectivas caixas de texto;

Para se acessar os objetos do Outlook podemos ir no escuro ou utilizar a referência a biblioteca

do Outlook4. Embora a utilização da biblioteca do Outlook facilite a nossa vida, estaremos criando

o nosso código no escuro. O motivo por esta escolha é para evitar incompatibilidade entre

sistemas dos leitores. Como não temos o benefício da biblioteca, teremos que criar os objetos. Os

objetos que precisaremos neste caso são:

• olApp (O aplicativo Outlook) • olNameSpace (NameSpace referente ao Outlook) • olContatos (os contatos) • olListaEnd (Lista de endereços) • olItensEnd (Itens da lista de endereços – olListaEnd)

O prefixo “ol” é para identificar os objetos relacionados ao Outlook Application (olApp).

Como o código é relativamente extenso, é interessante utilizar Option Explicit5 para evitar

erro em nossas variáveis.

Primeiramente, vamos dimensionar os nossos objetos:

Private Sub UserForm_Initialize() Dim olApp As Object 'Aplicativo Dim olNameSpace As Object 'NameSpace6 Dim olContatos As Object 'Itens Dim olListaEnd As Object 'Lista de endereços

4 Pra se fazer uma referência aos objetos do Outlook vá até Ferramentas --> Referências e selecione Microsoft Outlook <versão> Object Library. 5 Para forçar Option Explicit em todos os trabalhos vá até Ferramentas --> Opções --> Editor e selecione “Requer Declaração de Variáveis”. 6 Namespace é um conjunto de nomes no qual todos os nomes são únicos.

Page 45: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

40

Dim olItensEnd As Object 'Itens da lista de endereços End Sub

Como não temos a biblioteca, todos os itens são tratados como objetos. Com os objetos,

dimensionados, precisamos criá-los para que o código possa fazer sua mágica. O primeiro objeto

a ser criado é o olApp (o código segue a ordem de desenvolvimento e os códigos anteriores não

serão repetidos):

Private Sub UserForm_Initialize() 'A declaração dos objetos entra aqui Set olApp = CreateObject("Outlook.Application") End Sub

Como o olApp pode ser qualquer objeto precisamos criar o objeto Outlook. Isto é feito como

mostrado acima. Como os objetos seguintes são dependentes do primeiro objeto, podemos

continuar com o Set dos objetos:

Private Sub UserForm_Initialize() 'O NameSpace é definido em cima do aplicativo Set olNameSpace = olApp.GetNamespace("MAPI") 'A lista é definida em cima do NameSpace 'nomeDaPasta refere-se ao nome da pasta AddressLists 'o nome pode ser modificado pelo índice da pasta. O índice para a 'pasta padrão é 1 Set olListaEnd = olNameSpace.AddressLists("nomeDaPasta") 'Os itens contidos na lista (Entries) são definidos em cima da lista Set olItensEnd = olListaEnd.AddressEntries End Sub

A lista de nossa listbox será carregada a partir de uma matriz (utilizaremos a propriedade List

para isso). Desta forma precisamos criar tal matriz. Como não sabemos o tamanho da matriz em

termos de linhas (sabemos que teremos 2 colunas, uma para o nome e outra para o e-mail),

precisamos dimensionar (Dim) e redimensionar (ReDim) a matriz:

Private Sub UserForm_Initialize() Dim matriz() n = olItensEnd.Count ReDim matriz(n, 2) 'Faz um "loop" em cada cadastro do AddressBook 'e adiciona os itens "Name" e "Address" à nossa matriz For i = 0 To n - 1 Set olContatos = olItensEnd.Item(i + 1) nome = olContatos.Name endEmail = olContatos.Address 'Acrescenta o item "nome" a linha "i" na coluna 1 (índice 0) matriz(i, 0) = nome 'Acrescenta o item "endEmail" a linha "i" na coluna 2 (índice 1) matriz(i, 1) = endEmail Next 'Carrega os valores na lista. Onde a propriedade "list" é uma matriz lstContatos.List = matriz End Sub

Page 46: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

41

Uma vez carregada a matriz, nosso trabalho está quase pronto. Como criamos vários objetos na

memória de nosso computador, não é uma boa idéia deixá-los consumindo a nossa preciosa

capacidade de processamento. Para cada objeto criado, faremos o seguinte:

Private Sub UserForm_Initialize() Set nomeDoObjeto = Nothing End Sub

O processo acima deve ser feito para cada objeto criado.

O código completo fica, portanto:

Private Sub UserForm_Initialize() Dim olApp As Object 'Aplicativo Dim olNameSpace As Object 'NameSpace Dim olContatos As Object 'Itens Dim olListaEnd As Object 'Lista de endereços Dim olItensEnd As Object 'Item da lista de endereços Dim blnListaExiste As Boolean Dim matriz() Dim nome As String, endEmail As String, índiceListEnd As Integer Set olApp = CreateObject("Outlook.Application") Set olNameSpace = olApp.GetNamespace("MAPI") 'O índice 2 refere-se ao valor em meu PC. Modifique o índice para 1 'para utilizar o AddressBook padrão: Set olListaEnd = olNameSpace.AddressLists(2) Set olItensEnd = olListaEnd.AddressEntries n = olItensEnd.Count ReDim matriz(n, 2) For i = 0 To n - 1 Set olContatos = olItensEnd.Item(i + 1) nome = olContatos.Name endEmail = olContatos.Address matriz(i, 0) = nome matriz(i, 1) = endEmail Next lstContatos.List = matriz Set olContatos = Nothing Set olListaEnd = Nothing Set olItensEnd = Nothing Set olNameSpace = Nothing Set olApp = Nothing End Sub

O nosso formulário, após rodarmos o código, carrega os dados de todos os contatos em nosso

AddressBook:

Page 47: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

42

Figura 8-2

Para evitar problemas com a minha lista de e-mails, foi necessário obliterar os detalhes.

O código final utilizado neste exemplo contem rotinas para lidar com erros e dá a flexibilidade de

se escolher o AddressBook a ser utilizado.

Esta pasta de trabalho contém um outro formulário que permite o usuário escrever e enviar um e-

mail. Este aplicativo utiliza o IIS (Internet Information Services) com um servidor SMTP virtual. O

aplicativo pode ser adaptado para enviar e-mail via Outlook. Contudo, ao enviar pelo Outlook

precisamos permissão para cada mensagem enviada. A utilização do servidor SMTP virtual

resolve o DNS (Domain Name Server) e envia a mensagem sem a necessidade do “prompt” do

Outlook.

Se você tem algum dúvida sobre como instalar e configurar o IIS, uma boa pedida é o livro

Windows Server 2003 – Curso Completo de Júlio Battisti, capítulos 22, 23 e 24. Para os usuários

de Windows XP Professional, veja o livro Windows XP Home & Professional, também de Júlio

Battisti.

O aplicativo (se é que podemos chamá-lo disso) para envio de e-mail é mostrado abaixo:

Page 48: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

43

Figura 8-3

Ele não é nenhuma Brastemp, mas quando estamos trabalhando com diversas planilhas e

precisamos enviá-las sem a chata mensagem do Outlook é que apreciamos a versatilidade deste

método. O código é extremamente fácil e o aplicativo pode ser adaptado para enviar anexos

também.

Ao utilizar a biblioteca do Outlook é possível criar um aplicativo de e-mail bem profissional no

Excel; porém, este assunto vai além do escopo deste módulo.

A aplicativo somente funciona se o IIS estiver instalado e o servidor virtual SMTP estiver

resolvendo DNS corretamente.

Uma última palavra sobre o envio de e-mails utilizando um servidor SMTP é que existe um

diferença entre o método utilizado no WinXP Pro e em um servidor Windows.

O WinXP Pro utiliza CDO.Message para criar a mensagem e servidor Windows 2000 utiliza

CDONTS. Já para o servidor Windows 2003, CDOSYS é o método utilizado para criar o objeto.

Neste dois últimos casos é necessário referenciar o servidor para que a mensagem seja criada.

Page 49: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

44

Page 50: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

45

9. Conectando e interagindo com o MS Access

Para aqueles que participam do fórum Júlio Battisti (www.juliobattisti.com.br/forum/default.asp),

todos já sabem o que eu penso: Excel não é banco de dados. Se você possui informações que

precisam de um armazenamento mais avançado dos dados, utilize um Bando de Dados. Se você

trabalha com o Office, utilize o Access. Afinal, o Excel é para análise de dados e não para a coleta

de dados.

Contudo sempre existe aquela pergunta sobre como utilizar o Excel para acessar dados em um

BD. Há várias formas de se fazer isso. A mais simples é criar uma consulta que traz os dados

para um planilha do Excel. Feito isso, podemos manipular estas informações e fazer nossas

análises.

Não obstante, a consulta é passiva. Vamos supor que desejamos ler e escrever para o banco de

dados. Uma consulta não resolve este problema. Nesta parte, estaremos vendo exatamente isso,

isto é, como coletar informações de uma forma ativa em nosso banco de dados de forma que

possamos modificar ou acrescentar informações diretamente no BD. Obviamente, não temos

como modificar a estrutura do BD, mas com esta flexibilidade, podemos acrescentar mais um item

importante em nossa busca por um entendimento melhor de como estes programas interagem.

Embora o Excel venha com as classes que utilizaremos para construir a conexão ao BD do

Access, elas não são automaticamente referenciadas. Estaremos utilizando a biblioteca ADO

neste caso. Para referenciar a esta biblioteca, vá até (no VBE) Ferramentas --> Referências e

selecione a versão mais recente do Microsoft ActiveX Data Objects Library:

Page 51: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

46

Figura 9-1

Uma vez que a referência esteja criada, estamos prontos para iniciar o nosso trabalho. Os nossos

objetivos estão relacionados abaixo:

• Conectar ao BD

• Extrair os dados de uma tabela qualquer

• Passar os dados de um dos campos da tabela para uma combobox.

• Ao selecionar um dos registros na combobox, passar os resultados para textboxes em

nosso formulário

Este é o primeiro exercício que estaremos fazendo. Nele estamos apenas preocupados com a

leitura dos dados. Mais adiante veremos como modificar estas informações no banco de dados.

Como sempre iniciamos pela declaração de nossas variáveis. Estaremos precisando do seguinte:

• Conexão ao Banco de Dados (o qual chamaremos de conn)

• Recordset (registros, os quais chamaremos de rs)

• Um contador (para contar os registros, linhas, colunas, etc.)

Após a conexão ao banco de dados, o formulário terá o seguinte aspecto:

Page 52: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

47

Figura 9-2

Os dados de cada textbox são modificados conforme escolhemos um funcionário novo.

Quando conectamos a banco de dados, se o volume é grande o desempenho da conexão cairá.

Para tentar reduzir o problema, carregaremos o formulário antes de ele ser mostrado. Ao fechar,

ao invés de descarregar o formulário, simplesmente o esconderemos. Portanto, o primeiro código

a ser escrito deve ser na pasta de trabalho:

Private Sub Workbook_Open() Load frmDB End Sub

Os dados podem ser carregados através de uma função ou sub-rotina. A escolha fica a critério do

programador e não interfere com o resultado final. Estaremos utilizando uma sub-rotina para

resolver o nosso problema.

Sub carregarDados(nomeBD As String, Tabela As String) Dim conn As ADODB.Connection Dim rs As ADODB.Recordset End Sub

Sem a referência à biblioteca ADO, não temos como dimensionar os objetos Connection e

Recordset.

A nossa sub-rotina recebe dois argumentos (ambos textos) nomeDB e Tabela. O nomeDB refere-

se não só ao nome como também ao caminho (path) onde o banco de dados de encontra. O

Page 53: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

48

banco de dados sendo utilizado está na pasta BD e é chamado FPNWIND.MDB7. Portanto, este

argumento será entrado como ThisWorkbook.Path & "\DB\FPNWIND.MDB".

Com os objetos dimensionados, passamos para o próximo item. Precisamos, agora, definir (Set)

os objetos.

Sub carregarDados(nomeBD As String, Tabela As String) Set conn = New ADODB.Connection conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & nomeBD & ";" Set rs = New ADODB.Recordset End Sub

Primeiro criamos uma nova conexão (New ADODB.Connection) e em seguida abrimos a conexão

utilizando o Driver apropriado e a fonte de dados (Data Source). Feito isso, criamos um rs

(Recorset) novo (New ADODB.Recordset). Assim como abrimos a conexão, precisamos agora

abrir o rs:

Sub carregarDados(nomeBD As String, Tabela As String) rs.Open "Select * FROM " & Tabela & " ORDER BY FirstName", conn sobrenome = "LastName": priNome = "FirstName" título = "TitleOfCourtesy" End Sub

Aqui, utilizamos comando SQL para abrir (ler) as informações. Ao abrir, nós selecionamos da

tabela (Select * From Tabela) e ordenamos pelo primeiro nome da pessoa (Order by

FirstName).

Observe que campos (LastName, FisrtName e TitleOfCourtesy) são os nomes dos campos

mesmo! Com isso quero dizer que este não é o cabeçalho do campo na tabela. Embora muitas

vezes estes sejam iguais, neste caso específico eles não são e é preciso entrar em modo de

edição da tabela no Access para saber o nome correto campo.

A seguir, é definido três variáveis que correspondem aos campos que nos interessam: sobrenome

(LastName), priNome (FirstName) e título (TitleOfCourtesy). Com estas variáveis,

passamos para o próximo estágio:

Sub carregarDados(nomeBD As String, Tabela As String) With rs If Not .BOF Then .MoveFirst While Not .EOF nomeCompleto = .Fields(título) & " " & .Fields(priNome) _ & " " & .Fields(sobrenome) frmDB.cboNome.AddItem nomeCompleto .MoveNext Wend End With

7 Este é um banco de dados gratuíto que acompanha o MS Office e serve de base para vários exemplos dados no Office.

Page 54: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

49

End Sub

Aqui, utilizamos o bloco With-End With com o Recordset (rs) para trabalhar com as

propriedades e métodos da classe. Primeiramente, checamos para saber se estamos no início do

arquivo (If Not .BOF8), pois não queremos iniciar o loop a meio caminho. Se não for

verdadeiro, move-se para o primeiro registro (MoveFirst). Feita a checagem, iniciamos o loop

utilizando EOF.

O nome completo do funcionário é composto pelo título, primeiro nome e sobrenome. A cada

passo do loop um nome completo é adicionado à nossa combobox.

Finalmente, terminamos o nosso código fechando todas as conexões:

Sub carregarDados(nomeBD As String, Tabela As String) frmDB.cboNome.ListIndex = 0 rs.Close: Set rs = Nothing conn.Close: Set conn = Nothing End Sub

Na própria sub-rotina, o primeiro valor da combobox é o valor cujo índice é zero. Observe que

utilizei os dois-pontos (:) para colocar na mesma linha o fechamento e limpeza dos objetos rs e

conn. Se isso lhe parecer complicado para leitura, coloque cada um em sua devida linha e

remova os dois-pontos.

O nosso código completa ficar, portanto:

8 BOF é a abreviação em inglês de “Beginning of File” (Início do Arquivo). O oposto é EOF “End of File”.

Page 55: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

50

Sub carregarDados(nomeBD As String, Tabela As String) Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Set conn = New ADODB.Connection conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _ & nomeBD & ";" Set rs = New ADODB.Recordset rs.Open "Select * FROM " & Tabela & " ORDER BY FirstName", conn sobrenome = "LastName": priNome = "FirstName" título = "TitleOfCourtesy" With rs If Not .BOF Then .MoveFirst While Not .EOF nomeCompleto = .Fields(título) & " " & .Fields(priNome) _ & " " & .Fields(sobrenome) frmDB.cboNome.AddItem nomeCompleto .MoveNext Wend End With frmDB.cboNome.ListIndex = 0 rs.Close: Set rs = Nothing conn.Close: Set conn = Nothing End Sub

Os dados foram carregados para a combobox e agora precisamos distribuí-los para as caixas de

texto em nosso formulário. Novamente, estaremos criando uma sub para conectar ao nosso banco

de dados. Porém, desta vez, desejamos filtrar os dados de acordo com o um critério qualquer.

Para este exemplo, utilizaremos o primeiro nome (FirstName). Contudo, o filtro pode ser feito

com qualquer um dos campos disponíveis na tabela.

Como já passamos pelo processo de conexão ao BD, vamos direto ao código para filtrar os

dados:

Page 56: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

51

Sub AtualizarDados(nomeBD As String, Tabela As String, _ filtro As String)

Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Set conn = New ADODB.Connection conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _ & nomeBD & ";" Set rs = New ADODB.Recordset rs.Open "SELECT * FROM " & Tabela & " WHERE FirstName = '" _ & filtro & "'", conn, , , adCmdText With frmDB .txtEnd.Text = rs.Fields("Address") .txtCidade.Text = rs.Fields("City") .txtCEP.Text = rs.Fields("PostalCode") .txtFone = rs.Fields("HomePhone") .txtMemo = rs.Fields("Notes") End With rs.Close: Set rs = Nothing conn.Close: Set conn = Nothing End Sub

Aqui, pouco muda. A “maior” diferença está no argumento adicional da sub-rotina (filtro) e em

como abrimos o Recordset (rs). Desta vez, ao invés de selecionar tudo na tabela, selecionamos

da tabela (Select*From Tabela) onde (Where) os registros sejam iguais ao filtro. Feita a

seleção dos itens que compõem o registro, distribuímos estes campos para as respectivas caixas

de textos.

Com as duas sub-rotinas prontas, precisamos agora colocá-las em uso. Primeiramente,

carregaremos os itens para a combobox:

Private Sub UserForm_Initialize() carregarDados ThisWorkbook.Path & "\DB\FPNWIND.mdb", "Employees" End Sub

Ao chamar a rotina que carrega os dados, entramos os dois argumentos pertencentes a sub-

rotina, isto é, o nome do banco de dados e a tabela que desejamos pesquisar.

Quando selecionamos um nome novo em nossa combobox, queremos que os dados do

funcionários sejam filtrados de acordo com o primeiro nome. Para tanto, utilizamos o evento

Change de nossa combobox para fazer isso:

Page 57: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

52

Private Sub cboNome_Change() priNome = Split(cboNome.Text, " ") AtualizarDados ThisWorkbook.Path & "\DB\FPNWIND.mdb", _ "Employees", CStr(priNome(1)) End Sub

Mais uma vez precisamos chamar a rotina e acrescentar os argumento. Neste caso específico,

estamos usando o primeiro nome. Para obter o primeiro nome, utilizei a função Split9 para

separar os três itens que compõem o nome completo. Como Split retorna uma matriz e a base é

zero, o título está na posição 0, o primeiro nome na posição 1 e o sobrenome na posição 2. O

valor retornado e convertido para String (CStr), pois o argumento da sub-rotina é uma String.

A nossa conexão está feita. O primeiro nome da lista é mostrado quando acionamos o formulário:

Figura 9-3

Ao escolher um outro nome qualquer, as informações são atualizadas nos respectivos objetos:

9 A função Split não está disponível nas versões anteriores ao Excel 2002.

Page 58: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

53

Figura 9-4

OK, conectamos ao banco de dados, maneiro... mas só estamos lendo e nada mais. Embora seja

interessante ler as informações, é interessante também manipular tais informações. Isto é, como

acrescentamos um novo funcionário a nossa lista?

Antes de iniciarmos a nossa próxima questão, observe que estamos filtrando por primeiro nome.

O que ocorre quando o primeiro é igual? Bom, temos um grande problema! A verdade é que

nomes se repetem com muita freqüência e precisamos utilizar algo que seja único no filtro. A

figura abaixo mostra o que ocorre quando nomes são repetidos:

Figura 9-5

Ao invés de mostrar os dados para Robert Martin, ele mostra para Robert King.

Page 59: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

54

Para resolver o problema, utilizaremos a chave-primária, pois ela nos fornece um número único

em toda a tabela de funcionários.

O modelo desenvolvido adiante pode ser acessado em Form9.xls. Não abra o Form8 e Form9

simultaneamente. Embora cada um faça coisas distintas, ambos os arquivos contém os mesmos

formulários, com os mesmos nomes e sub-rotinas . Isso causará erros durante execução.

Antes de continuarmos, contudo, precisaremos modificar algumas coisas em nosso formulário.

Primeiramente modifique as seguintes propriedades da combobox, conforme a figura:

Figura 9-6

A primeira coluna da combobox guardará a chave-primária. Ao definir BoundColumn como sendo

2, estaremos mostrando o nome do funcionário ao invés da chave-primária. Defina a largura das

colunas (ColumnWidths) conforme a necessidade. Feita as mudanças, precisamos modificar

algumas coisas em nosso código, conforme abaixo:

Private Sub cboNome_Change() ID = cboNome.List(cboNome.ListIndex, 0) AtualizarDados ThisWorkbook.Path & "\DB\FPNWIND.mdb", _ "Employees", CLng(ID) End Sub

O ID é definido como sendo o valor que se encontra no índice “x” da combobox na coluna 1

(coluna 0, pois estamos usando Option Base 0). Como na tabela o tipo de dado para o ID é

Long (Longo) precisamos convertê-lo para evitar erro, pois os tipos de dados precisamos ser os

mesmos.

O código para carregamento dos dados para a combobox também precisa ser modificado. As

modificações não serão muitas, mas precisamos nos assegurar que os dados serão passados

corretamente.

O código completo é repetido abaixo (as partes novas em itálico):

Page 60: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

55

Sub carregarDados(nomeBD As String, Tabela As String) Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Dim List() Set conn = New ADODB.Connection conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _ & nomeBD & ";" Set rs = New ADODB.Recordset rs.Open "Select * FROM " & Tabela & " ORDER BY FirstName", conn sobrenome = "LastName": priNome = "FirstName" Título = "TitleOfCourtesy" If Not rs.BOF Then rs.MoveFirst n = 0 While Not rs.EOF n = n + 1 rs.MoveNext Wend ReDim List(n - 1, 1) i = 0 With rs If Not .BOF Then .MoveFirst While Not .EOF nomeCompleto = .Fields(Título) & " " & .Fields(priNome) _ & " " & .Fields(sobrenome) List(i, 0) = .Fields("EmployeeID") List(i, 1) = nomeCompleto 'Debug.Print List(i, 0) & " " & List(i, 1) i = i + 1 .MoveNext Wend End With With frmDB .cboNome.List = List .cboNome.ListIndex = 0 End With rs.Close: Set rs = Nothing conn.Close: Set conn = Nothing End Sub

A primeira modificação refere-se a nova variável List. O primeiro loop apenas serve para contar

o número de registros na vertical. Após a contagem, a matriz List é redimensionada e passa a

ter (n–1) linhas e duas colunas.

O próximo loop completa a matriz List com os dados que desejamos na coluna 1 (índice = 0) e

coluna 2 (índice = 1). O Debug.Print utilizei para assegurar que a matriz estava sendo

preenchida corretamente.

Page 61: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

56

Finalmente, com o formulário, defino a lista da combobox como sendo a List e inicio a

combobox no índice 0.

Agora, precisamos modificar algumas coisas na rotina que filtra os dados. Desta vez, será

repetido somente a parte modificada. Novamente, as partes críticas estão em itálico:

Sub AtualizarDados(nomeBD As String, Tabela As String, filtro As Long) rs.Open "SELECT * FROM " & Tabela & " WHERE EmployeeID =" _ & filtro, conn, , , adCmdText End Sub

A primeira modificação refere-se ao tipo de dado do filtro. Anteriormente, utilizamos String.

Como estamos avaliando um valor numérico Long, o filtro é definido como longo. A próxima

modificação é no SQL. Aqui, é necessário retirar o apóstrofo (‘). Se deixarmos o apóstrofo como

no primeiro exemplo, haverá um erro por incompatibilidade no formato dos dados.

Resolvido o problema da leitura dos dados, partiremos para o código que apagará e atualizará

registros no banco de dados.

Crie os novos botões conforme a figura abaixo:

Figura 9-7

Para o código do botão de remoção (Del. Registro), entraremos o seguinte código:

Private Sub cmdApagar_Click() ID = cboNome.List(cboNome.ListIndex, 0) delRegistro ThisWorkbook.Path & "\DB\FPNWIND.mdb", _ "Employees", CLng(ID) End Sub

Page 62: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

57

Como podemos ver o código é igual ao utilizado na combobox, pois estamos procurando o

funcionário referente à ID para apagá-lo do BD. A evento chama o sub-rotina delRegistro.

Como já estamos proficientes em conexões ao BD, o código fica:

Sub delRegistro(nomeBD As String, Tabela As String, filtro As Long) Msg = "Ao apagar um registro, você não terá como desfazer a operação!" Msg = Msg & vbCr & vbCr & "Você tem certeza que deseja continuar?" Estilo = vbYesNo + vbInformation + vbDefaultButton2 Título = "Apagar registro..." Res = MsgBox(Msg, Estilo, Título) If Res = vbNo Then Exit Sub Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Set conn = New ADODB.Connection conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _ & nomeBD & ";" Set rs = New ADODB.Recordset rs.Open "DELETE * FROM " & Tabela & " WHERE EmployeeID = " _ & filtro, conn, , , adCmdText Set rs = Nothing conn.Close Set conn = Nothing carregarDados ThisWorkbook.Path & "\DB\FPNWIND.mdb", "Employees" End Sub

Antes de tudo, queremos saber se o usuário realmente deseja apagar o registro. Se sim, o

processo continua caso contrário a sub-rotina é cancelada10.

A única coisa nova é o SQL. Ao invés de SELECT, utilizamos DELETE para apagar o registro. A

última linha recarrega os dados.

Estamos quase chegando ao final de nossa longa jornada no mundo do Excel e Access. Para

terminar, veremos como acrescentar um novo item ao nosso banco de dados. Para isso, foi criado

um novo formulário, conforme o modelo abaixo:

10 Exemplos com o estilo de MsgBox utilizado podem ser encontrados no Ajuda do VBA (procure por MsgBox Function)

Page 63: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

58

A combobox Título utiliza os TitlesOfCourtesy do banco de dados. Adicione os títulos

utilizando um dos métodos já ensinados.

Para o botão Novo Registro, entraremos o seguinte código:

Private Sub cmdNovo_Click() novoRegistro ThisWorkbook.Path & "\DB\FPNWIND.mdb", "Employees" End Sub

Aqui, estamos chamando a sub-rotina novoRegistro da mesma forma que fizemos com todas

as sub-rotinas anteriores:

Sub novoRegistro(nomeBD As String, Tabela As String) Dim conn As ADODB.Connection Dim rs As ADODB.Recordset Set conn = New ADODB.Connection conn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" _ & nomeBD & ";" Set rs = New ADODB.Recordset rs.Open Tabela, conn, adOpenKeyset, adLockOptimistic, adCmdTable With frmNovoReg rs.AddNew rs.Fields("TitleOfCourtesy") = .txtTítulo rs.Fields("LastName") = .txtSobrenome rs.Fields("FirstName") = .txtPriNome rs.Fields("Address") = .txtEnd rs.Fields("City") = .txtCidade rs.Fields("PostalCode") = .txtCEP rs.Fields("HomePhone") = .txtFone

Page 64: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

59

rs.Fields("Notes") = .txtMemo rs.Update End With Set rs = Nothing conn.Close Set conn = Nothing MsgBox "Registro adicionado com sucesso!", vbInformation, _ "Registro adicionado..." Unload frmNovoReg frmDB.Show 0 End Sub

Feito. Um novo registro é adicionado à tabela do banco de dados.

Em todas as sub-rotinas utilizadas para conexão ao BD, as rotinas requerem passagem de

parâmetros antes de continuar. Isso não é necessário. Se o leitor desejar rodar toda a sub-rotina

sem a passagem de parâmetros basta colocar os parâmetros dentro da própria sub-rotina.

A passagem de parâmetros flexibiliza a manipulação dos parâmetros que desejamos avaliar.

Terminamos aqui mais um passeio pelo mundo do Excel.

Page 65: SÉRIES COMO FAZER - FORMULÁRIOS COM LISTBOX E COMBOBOX.pdf

Série “Como Fazer”: Formulários no Excel utilizando VBA – Listbox e Combobox

Autor: Robert F Martim Criado em: 3/6/2004 11:03:00 Publicado: www.juliobattisti.com.br Última edição: 3/7/2004 20:18:00 Contato: [email protected]

60

10. Sobre o autor

Abaixo o leitor encontra um pequeno resumo do currículo e atividades do autor deste módulo:

FORMAÇÃO ACADÊMICA:

• Formado e Pós-Graduado em Finanças pela Universidade de Londres, Reino Unido

• Membro da Sociedade Brasileira de Econometria

LINGUAGENS DE PROGRAMAÇÃO E PLATAFORMAS:

• Visual Basic, Calculadores Programáveis Casio e Sharp

• BDs: MS Access and Lotus Approach

• Plataformas: Windows NT, 2000, XP, Linux Red Hat

EXPERIÊNCIA PROFISSIONAL

outubro 02- FAIRCOURT CAPITAL LIMITED (REINO UNIDO)

• Diretor TI

fev96-maio02 MELVALE GROUP (REINO UNIDO)

• Gerente de Exportação para a África Ocidental • Gerente de TI

OUTRAS ESPECIALIZAÇÕES

• Inspeção e regulamentações Nigerianas para importação e exportação (Nigerian-British Chamber of Commerce & Cotecna International)

• Procedimentos de exportação no Reino Unido (The Institute of Export, Reino Unido)

• ICC 500 e Incoterms (The Institute of Export, Reino Unido)

OUTRAS ATIVIDADES

Fornece suporte pro bono em TI à entidade de caridade Nigeriana NIDOE (Nigerians in Diaspora Organisation Europe) desde 2001. Participou ativamente na organização da conferência sobre Boa Governância e Responsabilidade Fiscal promovida pelo ONG em Abuja, Nigéria, em Novembro 2003. Foi um dos principais colaboradores na elaboração do relatório final sobre a conferência entregue a presidência da República Nigeriana em maio de 2004.

Autor do livro Excel e VBA na Modelagem Financeira: Uma abordagem prática (no prelo). Editora Axcel Books, 2004.

Colaborador ativo do fórum Excel Avançado do site www.júliobattisti.com.br, onde divide seu conhecimento e experiência com outros membros do espaço.