Para refrescar a memria sobre o assunto leia os artigos: 1. OLE - Conceitos. 2. Usando VBA 3. Excel - Abrindo uma lanil!a e Exportando p" uma tabela ##E $ OLE $ Acti%e& ... Vamos direto a questo : " Como eu posso importar e exportar dados entre minha aplicao Visual Basic e o Excel ? " A primeira coisa que voc vai ter que fazer uma comunicao entre as aplicaes . O Excel estar funcionando como um servidor de dados ( ou cliente de dados ) . Para efetivar esta comunicao voc vai ter que criar um componente na sua aplicao VB que lhe permita acessar as propriedades e mtodos do Excel. Para instanciar um componente com essas propriedades voc ter que conhecer quais os componentes que o Excel expe. Damos abaixo um esquema bem simples do modelo exposto pelo Excel: No topo da hierarquia esta a classe Application ela que temos que instanciar em nossa aplicao Visual Basic para ter acesso as propriedades e mtodos das demais classes expostas pelo Excel. Application - a aplicao Excel WorkBook - o arquivo XLS WorkSheet - a planilha Excel de trabalho claro que que para tudo isto funcionar corretamente , esta classe dever estar registrada na mquina na qual a aplicao ser executada . Trocando em mdos : O Excel tem que estar instalado nesta mquina. A primeira coisa a fazer ao iniciar o seu projeto no Visual Basic habilitar a referncia ao Excel dentro do seu projeto. Para isto, selecione 'e(erences no menu )ools ou ro*ect$ dependendo da verso do VB, e marque uma opo semelhante a +icroso(t Excel x.x Ob*ect Librar,, conforme mostra a figura a seguir: Abrindo uma planil!a Excel e exibindo o conte-do de uma C.lula Vamos atacar logo de cara com um cdigo bem simples para abrir uma planilha Excel e obter o contedo de uma clula da planilha. Vamos devagar e sempre... Crie uma planilha no Excel e coloque qualquer informao na clula da linha 2 e coluna 3. Eu estarei criando o arquivo texte.xls e na planilha Plan1 na clula da linha 2 , coluna 3 estarei informando : Oi eu aqui (salvos no diretrio c:\teste) veja figura abaixo: O nome do nosso arquivo ser : )este.xls O nome da planilha ser : Plan1 O arquivo ser salvo no diretrio : c/0teste Agora vamos ao cdigo para fazer este servio : Dim xl As New Excel.Application Dim xlw As Excel.Workbook 'Abrir o arquivo do Excel Set xlw = xl.Workbooks.Open("c:\teste\teste.xls") ' definir qual a planilha de trabalho xlw.Sheets("Plan1").Select 'Exibe o contedo da clula na posio 2,3 ' variavel = xlw.Application.Cells(2, 3).Value MsgBox xlw.Application.Cells(2, 3).Value
' Fechar a planilha sem salvar alteraes ' Para salvar mude False para True xlw.Close False ' Liberamos a memria Set xlw = Nothing Set xl = Nothing Ao executar o cdigo ao lado, voc ir obter uma caixa de mensagem exibindo o contedo da clula da planilha Plan1 do arquivo teste.xls , localizada na linha 2 e coluna 3. -Primeiro eu criei o componente Application do Excel e o atribui a varivel objeto xl ( poderia ser outro nome ) -Depois eu criei a classe Workbook e atribui a varivel objeto xlw -A seguir abri o arquivo teste.xls atribuindo a xlw -Defini a minha planilha de trabalho (Plan1) -E , obtive o valor (Value) da clula (Cells) da planilha -Para encerrar encerrei a aplicao e liberei memria. Nota : Se voc quiser trabalhar com o contedo da clula pode salv-lo em uma varivel para posterior tratamento(veja de codigo variavel=xlw.Application.Cells(2, 3).Value ) Inserindo dados em uma planil!a Excel e criando um 1r2(ico Vamos para uma tarefa mais interessante: Agora vamos criar uma planilha , inserir alguns valores e montar o grfico dos valores inseridos e exibir o grfico. Inicie um novo projeto no Visual Basic Faa referncia a livraria +icroso( Excel &.3 Ob*ect Librar, Insira no formulrio dois botes de comando : cmdExcel e cmdSair Insira o cdigo no formulrio conforme explicado a seguir: Cdigo da seo 1eneral #eclarations : Option Explicit Dim EApp As Object Dim EwkB As Object Dim EwkS As Object Define as variveis objetos que devero ser visveis em todo o formulrio Cdigo do boto de comando CmdExell - Ativa o Excel insere dados nas clulas e cria o grfico ri%ate 4ub CmdExcel5Clic678 Dim a, b As String Dim i As Integer Dim Exlc As New Chart ' ' Cria a componente da classe application ' inclui um novo arquivo e uma nova planilha ' Set EApp = CreateObject("excel.application") Set EwkB = EApp.Workbooks.Add Set EwkS = EwkB.Sheets(1) ' ' exibe a aplicao Excel ' EApp.Application.Visible = True ' Preenche a primeira e a segunda coluna ' com alguns valores numricos ' For i = 1 To 10 a = "A" b = "B" Range(a & i).FormulaR1C1 = Str(i) Range(b & i).FormulaR1C1 = Str(i / 2) Next i 'seleciona da clula b2 at a b10 Range("B2:B10").Select 'Cria e exibe o grfico Set Exlc = EApp.Charts.Add 'torna o formulrio do VB visvel para poder fechar o Excel frmexcelvb.Show End 4ub -Define as variveis locais -Cria os componentes e atribui as variveis objeto -Torna o Excel Visivel -Inclui valores nas clulas A1 a A10 e B2 a B10 -Selecione a faixa das clulas de B2 a B10 -Cria um grfico de barras com esta seleo -Torna o formulrio do VB visivel Abaixo as clulas com os valores e a seleo Nota: Usamos a instruo CreatOb*ect para criar o objeto Excel , embora Usar Dim com a clusula New seja mais rpido . Cdigo do boto de comando cmd4air - Encerra o Excel e a aplicao VB
Con%ertendo os dados de uma tabela em uma anil!a Excel Que tal agora fazer algo mais prtico : Converter os dados de uma tabela em uma planilha. Vamos converter os dados da tabela )itles presente no banco de dados Biblio.mdb para em uma planilha Excel. Para fazer o servio vamos usar uma funo chamada Copiar)abelaExcel que ir obter os dados da tabela e criar a planilha Excel para receber os dados. (Article I#/ 91:23;< da +icroso(t8 Estaremos a #AO para acessar o banco de dados e a tabela. Vamos criar um recordset do tipo SnapShot. Lembra disto ??? No !!! Ento leia o artigo - Recordsets : Tables, Dynasets e Snapshots. O projeto : Inicie um novo projeto no Visual Basic Faa referncia a livraria +icroso( Excel &.3 Ob*ect Librar, Insira no formulrio dois botes de comando : cmdExcel e cmdSair e uma etiqueta label1. (para exibir mensaens! Insira o cdigo no formulrio conforme explicado a seguir: Vamos ao cdigo : Cdigo da seo 1eneral #eclarations : Define variveis ri%ate 4ub cmdsair5Clic678 Me.Hide ' fecha o arquivo xls ' EwkB.Close ' encerra o excel e sai EApp.Application.Quit End End 4ub - Esconde o formulrio do VB - Fecha o arquivo e encerra o Excel Abaixo o grfico gerado Option Explicit Dim oExcel As Object Dim objExlSht As Object Dim db As Database Dim Sn As Recordset ' Recordset do tipo Snapshot Private Type ExlCell row As Long col As Long End Type -Define as variveis objetos que devero ser visveis em todo o formulrio tanto para o Excel como para o banco de dados
Agora o cdigo do boto de comando cmdExcel : Prepara o Excel , abre o Recordset e chama a funo - Copiar)abelaExcel78. 4ub CmdExcel5Clic678 Dim stCell As ExlCell MousePointer = vbHourglass ' Muda o ponteiro do mouse Set oExcel = CreateObject("Excel.Application") oExcel.Workbooks.Add 'inclui o workbook Set objExlSht = oExcel.ActiveWorkbook.Sheets(1) Set db = OpenDatabase("c:\teste\BIBLIO.MDB") Set Sn = db.OpenRecordset("Titles", dbOpenSnapshot) ' Inclui os dados a partir da celula A1 stCell.row = 1 stCell.col = 1 CopiarTabelaExcel Sn, objExlSht, stCell ' Salva a planilha objExlSht.SaveAs "C:\teste\teste.xls" oExcel.Visible = True frmexcelvb.Show End 4ub O cdigo da Funo Copiar)abelaExcel: A funo recebe como parmetros o Recordset, a planilha e a clula inicial e copia os registros para a planilha ri%ate 4ub Copiar)abelaExcel7rs As 'ecordset$ =s As >or6s!eet$ 4tartin?Cell As ExlCell8 Dim Vetor() As Variant Dim row As Long, col As Long Dim fd As Field rs.MoveLast ReDim Vetor(rs.RecordCount + 1, rs.Fields.Count) ' Copia as colunas do cabecalho para um vetor col = 0 For Each fd In rs.Fields Vetor(0, col) = fd.Name col = col + 1 Next ' copia o rs par um vetor rs.MoveFirst For row = 1 To rs.RecordCount - 1 For col = 0 To rs.Fields.Count - 1 Vetor(row, col) = rs.Fields(col).Value 'O Excel no suporta valores NULL em uma clula. If IsNull(Vetor(row, col)) Then Vetor(row, col) = "" Next rs.MoveNext Next ws.Range(ws.Cells(StartingCell.row, StartingCell.col),ws.Cells(StartingCell.row + rs.RecordCount + 1, _ StartingCell.col + rs.Fields.Count)).Value = Vetor End 4ub Nota: "rimeiro copiamos os nomes dos campos e depois o recordset para o arra#(Vetor!$ a seuir atribuimos os %alores as c&lulas da planilha ( linha de c'dio a(ul! O cdigo do boto cmd4air: Encerra o Excel e libera memria das variveis objeto. ri%ate 4ub cmdsair5Clic678 Label1.Caption = "Encerrando o Excel" Label1.Refresh objExlSht.Application.Quit Set objExlSht = Nothing ' remove a variavel objeto Set oExcel = Nothing ' remove a variavel objeto Set Sn = Nothing ' reomove a variavel objeto Set db = Nothing ' reomove a variavel objeto MousePointer = vbDefault ' Restaura o ponteiro do mouse. Label1.Caption = "Muito bem, deu certo ! " Label1.Refresh End 4ub A tabela )itles exportada para o Excel Agora eu vou mostrar como fazer o mesmo servio usando cdigo mais enxuto: o mtodo Cop,@rom'ecordset do objeto 'an?e. O mtodo Cop,@rom'ecordset do objeto Range muito til para importar dados de uma aplicao externa para uma planilha Excel. O nico problema porm, que ele s funciona com a DAO e no suporta recordsets ADO. Abaixo temos o cdigo que faz o mesmo servio do exemplo acima abordado. Dim oExcel As Object Dim objExlSht As Object Dim Db1 As Database Dim Rs1 As Recordset Set oExcel = CreateObject("Excel.Application") oExcel.Workbooks.Add 'inclui o workbook Set objExlSht = oExcel.ActiveWorkbook.Sheets(1) 'Abrindo o banco de dados Set Db1 = DBEngine.OpenDatabase("c:\teste\biblio.mdb") 'Criamos um recordset selecionando todos os campos da tabela Titles do banco de dados Biblio.mdb onde o cdigo PubId for menor que 10 Set Rs1 = Db1.OpenRecordset(Name:="Select * from titles where PubId < 10", Type:=dbOpenDynaset) 'Limpamos qualquer informao existente na planiha e copiamos o recordset criado With Worksheets("Plan1").Range("A1") .CurrentRegion.Clear .Cop,@rom'ecordset 's1 End With objExlSht.SaveAs "C:\teste\teste.xls" oExcel.Visible = True 'Fechamos o banco de dados Db1.Close set db1=nothing Usando #AO - m.todo Cop,@rom'ecordset Como j disse , se voce quiser a ADO para acessar o banco de dados , no vai poder usar o mtodo Cop,@rom'ecordset , mas calma , podemos usar outro recurso o mtodo )ranspose. A seguir o cdigo que executa a mesma tarefa ( apenas restringimos a quantidade de registros usando uma instruo SQL - Select Title From Titles WHERE pubID < 5 ORDER BY Title ). Dim oExcel As Object Dim objExlSht As Object Dim Rs1 As ADODB.Recordset Set oExcel = CreateObject("Excel.Application") oExcel.Workbooks.Add 'inclui o workbook Set objExlSht = oExcel.ActiveWorkbook.Sheets(1) Set Rs1 = New ADODB.Recordset Rs1.Open Source:="Select Title From Titles WHERE pubID < 5 ORDER BY Title", _ ActiveConnection:="DBQ=C:\TESTE\biblio.MDB;Driver={Microsoft Access Driver (*.mdb)};", _ CursorType:=adOpenStatic, _ LockType:=adLockOptimistic, _ Options:=adCmdText With Worksheets("Plan1") .Range("A1").CurrentRegion.Clear Application.Intersect(.Range(.Rows(1), .Rows(Rs1.RecordCount)), _ .Range(.Columns(1), .Columns(Rs1.Fields.Count))).Value = _ Application.)ranspose(Rs1.GetRows(Rs1.RecordCount)) End With objExlSht.SaveAs "C:\teste\teste901.xls" oExcel.Visible = True Rs1.Close Set Rs1 = Nothing Usando A#O - m.todo )ranspose Observe que: - No fizemos uma referncia direta a um banco de dados no cdigo , na verdade usamos somente o objeto Recordset da ADO - Quando invocamos o mtodo Open do objeto Recordset passamos a informao da conexo com o argumento Acti%eConnection - Usamos outros parmetros do mtodo Open (Cursor)#pe* +oc,)#pe * -ptions) - Os dados do recordset so organizados em um tabela de duas dimenses onde cada coluna representa um registro e cada linha representa um campo. Vamos ento copiar os registros para as linhas e os campos para as colunas. - Usamos o mtodo 1etro=s do objeto Recordset da ADO para gerar um array que passado via mtodo )ranspose para a planilha. Acessando diretamente uma planil!a Excel com A#O E se voce quiser acessar diretamente uma planilha do Excel a partir de sua aplicao Visual Basic ? Tem jeito ? Claro que tem . Vamos mostrar o acesso usando ADO primeiro usando um driver ODBC e depois usando OLE DB. 1- Usando um dri%e O#BC para acessar uma planil!a do Excel Vamos abrir a planilha chamada teste.xls presente no diretrio c:\teste usando um driver ODBC e exibir trs colunas da planilha. (Esta planilha foi gerada pela exportao da tabela )itles do banco de dados Biblio.mdb) Para navegar pela 'planilha' vamos criar dois botes de comando : command1(<) - navega para trs e command2 ( > ) - navega para frente ; quando o usurio clicar nos botes os valores sero exibidos nas caixas de texto. Usaremos um terceiro boto - cmdAcessaExcel - para criar uma conexo com a planilha e gerar um recordset a partir do qual iremos acessar os dados da planilha. -Inicie um novo projeto no VB e insira os controles como indicados acima. Veja abaixo o layout do formulrio do projeto: Primeiro o cdigo da seo 1eneral #eclarations : Declaramos as variveis objeto Connection e Recordset. #im oConn As A#O#B.Connection #im ors As A#O#B.'ecordset O cdigo do evento Click do boto - cmdAcessaExcel - o que vai fazer todo o servio , vejamos : ri%ate 4ub cmdAcessaExcel5Clic678 ' cria uma conexo ADO Set oConn = New ADODB.Connection oConn.Open "Driver={Microsoft Excel Driver (*.xls)};" & _ "FIL=excel 8.0;" & _ "DefaultDir=C:\teste;" & _ "MaxBufferSize=2048;" & _ "PageTimeout=5;" & _ "DBQ=C:\teste\Teste.xls;" ' Cria o Recordset Set ors = New ADODB.Recordset ' abre o recordset pelo nome da planilha ors.Open "[Plan1$]", oConn, adOpenStatic, adLockBatchOptimistic, adCmdTable preenche_controles End 4ub erceba Aue: - Estamos usando o driver ODBC - .ri%er/01icroso2t Excel .ri%er (3.xls!4$ - Informamos o diretrio de localizao da panilha - ".e2ault.ir/C56teste$" 7 8 - A fonte de dados ser o arquivo - ".B9/C56teste6)este.xls$" - O recordset foi criado com base na planilha - Plan1 - ors.-pen ":"lan1;<"* oConn* ad-penStatic* ad+oc,Batch-ptimistic* adCmd)able = A seguir invocamos a procedure preenc!e5controles que ir carregar as caixas de texto com os valores dos trs registros que vamos exibir. O cdigo da Procedura reenc!e5Controles / ri%ate 4ub preenc!e5controles78 Text1.Text = ors(2) 'numero isbn Text2.Text = ors(1) 'ano Text3.Text = ors(0) 'nome publicao End 4ub Onde: ors(2) o campo >SB? , ors(1) o campo @ear "ublished e ors(0) o campo Title. Poderiamos ter usado a sintaxe : ors.2ields(A! * ors.2ields(1! e ors.2ields(B! Finalmente o cdigo associado aos botes command1 ( < ) e command ( > ) que permitem a navegao pela planilha: Private Sub Command1_Click() ors.MovePrevious preenche_controles End Sub Private Sub Command2_Click() ors.MoveNext preenche_controles End Sub BotBo command1 - %ai para o BotBo command2 - %ai para o prCximo re?istro re?istro anterior Agora s executar , veja abaixo a tela com os dados da planilha exibidos no formulrio: 2- Usando um pro%edor OLE #B para acessar uma planil!a do Excel Vamos fazer o mesmo servio usando um provedor OLE DB para acessar a planilha teste.xls que esta no diretrio c:\teste. A novidade o boto Novo , onde podemos incluir dados diretamente na planilha ; O cdigo principal esta associado ao boto que carrega os dados da planilha. O layout do formulrio o seguinte: - Aqui temos um boto que permite incluir registros - O total de registros exibido na label1
Primeiro o cdigo da seo 1eneral #eclarations : Declaramos as variveis objeto Connection e Recordset e command: #im oConn As A#O#B.Connection #im oCmd As A#O#B.Command #im o'4 As A#O#B.'ecordset A seguir o cdigo principal associado ao boto - Acessar lanil!a Excel usando OLE #B. ri%ate 4ub Command;5Clic678 ' abre uma conexao com a planilha excel Set oConn = New ADODB.Connection oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=c:\teste\teste.xls;" & _ "Extended Properties=""Excel 8.0;HDR=Yes;"";" ' cria o objecto command e define a conexao ativa Set oCmd = New ADODB.Command oCmd.ActiveConnection = oConn ' abre a planilha oCmd.CommandText = "SELECT * from [Plan1$]" ' cria o recordset com os dados Set oRS = New ADODB.Recordset oRS.Open oCmd, , adOpenKeyset, adLockOptimistic 'exibe os dados preenche_controles End 4ub Dota : na string de conexo EF#'GHesE significa que existe um cabealho na planilha referente as clulas e o provedor NO vai incluir a primeira linha da seleo no Recordset gerado. Para incluir esta linha defina EF#'GDoE. O cdigo do boto Do%o e AtualiIar permitem a incluso de dados na planilha: ri%ate 4ub Command35Clic678 ' limpa as caixas de texto Text1.Text = "" Text2.Text = "" Text3.Text = "" Command3.Enabled = False End 4ub ri%ate 4ub CommandJ5Clic678 'inclui o registro na planilha oRS.AddNew oRS(0).Value = Text3.Text 'titulo oRS(1).Value = Text1.Text 'isbn oRS(2).Value = Text2.Text 'ano oRS.Update Command3.Enabled = True preenche_controles End 4ub O restante do cdigo apenas permite a navegao pelos dados da planilha: Private Sub Command1_Click() oRS.MovePrevious preenche_controles End Sub Private Sub Command2_Click() oRS.MoveNext preenche_controles End Sub Private Sub Command7_Click() oRS.MoveLast preenche_controles End Sub Private Sub Command8_Click() oRS.MoveFirst preenche_controles End Sub Percebemos ento que temos diversas formas de acessar as informaes de uma planilha Excel usando o Visual Basic. E para acessar uma planilha na Internet , como seria ??? (Cinda %amos mostrar como 2a(er...) Vamos ficando por aqui , voltaremos ao tema num futuro no muito distante... at laaaa....