Existem duas formas de programação no que diz respeito ao uso dos objetos em VBA:
Early Binding
Late Binding.
Essas técnicas são definidas no momento da declaração das variáveis, b
asicamente são:
No Early Binding as variáveis são declaradas já com o tipo de dado que ela vai assumir, ou seja, antes de serem invocadas.
No Late Binding, as variáveis são declaradas como objeto e assumem seu tipo no momento em que são utilizadas pela primeira vez que a atribuição for feita.
Imagine que você deseje criar uma pasta de trabalho a partir do MS PowerPoint no MS Excel, além disse quero popular nas linhas as informações de cada Shape: o Slide em que aparece, o tipo de Shape e seu texto, caso tenha.
Segue código com a técnica Late Binding:
Sub ExportaExcel_LateBinding() 'Declarações de objetos do PowerPoint Dim shp As Object Dim sld As Object 'Declarações de objetos do Excel Dim xlApp As Object Dim wb As Object Dim ws As Object Dim n As Long 'Criar instância do Excel Set xlApp = CreateObject("Excel.Application")
Let xlApp.Visible = True Set wb = xlApp.Workbooks.Add Set ws = wb.Sheets(1) With ws .Range("A1:D1") = Array("Nome do Slide", "Nome do shape", "Tipo", "Texto")
Let n = 2
For Each sld In ActivePresentation.Slides For Each shp In sld.Shapes Let .Cells(n, "A") = sld.Name
Let
.Cells(n, "B") = shp.Name
Select Case shp.Type Case msoPicture
Let
.Cells(n, "C") = "Figura (msoPicture)"Case msoPlaceholder
Let
.Cells(n, "C") = "Texto (msoPlaceholder)"
Let
.Cells(n, "D") = shp.TextFrame.TextRange.TextCase Else
Let
.Cells(n, "C") = "Outro tipo"
End Select
Let
n = n + 1
Next shp Next sld
.Columns.AutoFit End With Set ws = Nothing Set wb = Nothing Set xlApp = Nothing Set shp = Nothing Set sld = Nothing End Sub
Perceba que este código é executado a partir do VBA do MS PowerPoint. Observe que tanto os objetos de MS PowerPoint quanto os do MS Excel são declarados como objetos.
Observe que, por exemplo, xlApp só tomou a forma de um Excel Application no momento em que foi invocado o comando que utiliza a variável. Você pode verificar isso escrevendo, na Janela de Verificação Imediata, o comando:
? TypeName(xlApp)
E verificar como a variável toma forma: ela começa com valor Empty, mas logo após executar a linha:
Set xlApp = CreateObject("Excel.Application")
Ela assume um tipo:
Application.
Na técnica do Early Binding, declara-se especificamente o tipo das variáveis antes delas serem usadas no código, conforme mostrado abaixo:
Sub EarlyBinding() 'Declarações de objetos do PowerPoint Dim shp As PowerPoint.Shape Dim sld As PowerPoint.Slide 'Declarações de objetos do Excel Dim xlApp As Excel.Application Dim wb As Excel.Workbook Dim ws As Excel.Worksheet Dim n As Long 'Criar instância do Excel Set xlApp = CreateObject("Excel.Application") xlApp.Visible = True Set wb = xlApp.Workbooks.Add Set ws = wb.Sheets(1) With ws .Range("A1:D1") = Array("Nome do Slide", "Nome do shape", "Tipo", "Texto") n = 2 For Each sld In ActivePresentation.Slides For Each shp In sld.Shapes .Cells(n, "A") = sld.Name .Cells(n, "B") = shp.Name Select Case shp.Type Case msoPicture .Cells(n, "C") = "Figura (msoPicture)" Case msoPlaceholder .Cells(n, "C") = "Texto (msoPlaceholder)" .Cells(n, "D") = shp.TextFrame.TextRange.Text Case Else .Cells(n, "C") = "Outro tipo" End Select n = n + 1 Next shp Next sld .Columns.AutoFit End With Set ws = Nothing Set wb = Nothing Set xlApp = Nothing Set shp = Nothing Set sld = Nothing End Sub
Pouca parte do código está diferente. No entanto, nos depararemos com um problema se tentarmos executar o código, conforme figura abaixo:
Esse problema aconteceu porque a variável xlApp foi declarada por um tipo (que é Excel.Application) que não foi previamente definido ou que não está nas referências das bibliotecas do VBE. Logo, para que esse exemplo funcione, deve-se adicionar a biblioteca Microsoft Excel XX.0 Object Library (onde XX é o número da versão do seu Office).
O motivo do VBE ter encontrado a biblioteca PowerPoint.Shape e não ter encontrado Excel.Application se dá pelo fato do VBE utilizado para executar o código ser do PowerPoint. Logo, a biblioteca Microsoft PowerPoint XX.0 Object Library, por padrão já é uma referência ao VBE do PowerPoint.
Ao adicionar a referência ao MS Excel, tente executar o código novamente. Ele produzirá o mesmo resultado do caso da implementação em Late Binding.
Note que, para o caso do Early Binding, poderíamos fazer as declarações suprimindo os prefixos do MS Excel e MS Powerpoint que o programa funcionaria da mesma forma:
EarlyBinding2()Sub
'Declarações de objetos do PowerPoint
Dim shp As Shape Dim sld As Slide'Declarações de objetos do Excel
Dim xlApp As ApplicationDim wb As WorkbookDim ws As Worksheet'continuação do código...
Pessoalmente, quando trabalho com a integração entre aplicações, gosto de adicionar o sufixo .Excel, .PowerPoint para saber de qual aplicação específica é uma variável.
Dessa forma, elimina-se também a possiblidade de duplicidades de declaração. Por exemplo: suponha que você refira à uma biblioteca do Excel e uma do Word num código e declare uma variável como Range. O problema é que em ambas as bibliotecas existe o ObjetoRange (Excel.Range existe e Word.Range existe) e isso pode causar problemas na execução do código.
Extrapolando ainda mais um pouco, para o exemplo EarlyBinding2, temos uma semi-etapa de Late Binding para a declaração de xlApp, pois ela foi definida como um Application genérico, e só na instrução Set xlApp = CreateObject("Excel.Application") que é especificada que ela é um Application de Excel.
Comparação entre Early Binding e Late Binding
Muitas pessoas adotam o Early Binding. Os motivos principais são:
- As declarações das variáveis ficam mais organizadas, e por consequência a depuração do código é mais fácil;
- A velocidade de execução do código é maior, porque a máquina virtual VBA não faz conversões de tipos de dados de objetos para outros tipos e os tipos de variáveis são pré-compilados (no caso do Late Binding, os tipos de dados são convertidos em tempo de execução);
- Ao escrever o código com uma referência à biblioteca específica adicionada, o recurso intellisense é ativado (intellisense é mostrado abaixo):
- Você tem acesso à modelagem do objeto completa no menu de Ajuda;
- Acesso às constantes das outras aplicações, inclusive por intellisense. Por exemplo,
Option Explicit Sub Exemplo1() Dim objWord As Word.Application Set objWord = New Word.Application With objWord .Visible = True .Activate .WindowState = wdWindowStateMaximize .Documents.Open ("c:\temp\temp.doc") End With End Sub
Essa rotina cria uma instância do Word, maximiza a janela através e abre um documento. Note que, no momento em que se digita o símbolo = do .WindowState =, aparecerá a janela abaixo, caso a referência à biblioteca Word estiver adicionada:
Como a biblioteca está adicionada, o VBE reconhece e atribui valor às constantes. Para esse mesmo caso, no caso de a biblioteca não estar adicionada (Late Binding), obteríamos o erro:
Para esse caso, teríamos que substituir essa constante por seu valor, que é 1. Como saber que o valor é 1? Simples: adicione a referência temporariamente em seu projeto (ou abra o Word) e digite, na Janela de Verificação Imediata, a linha de comando
? wdWindowStateMaximize e pressione Enter:
A questão do recurso do intellisense é uma grande vantagem. No Late Binding, o programador escreve o código praticamente "às escuras" porque o VBE não dá nenhuma dica de quais são as propriedades ou métodos de cada tipo de objeto.
A grande desvantagem do Early Binding é a necessidade de se adicionar referências, o que torna às vezes um empecilho para que macros desenvolvidas em Early Binding sejam utilizadas em outros computadores ou por outras pessoas. No entanto, esse problema pode ser amenizado com algumas técnicas de se adicionar bibliotecas automaticamente através de código. Para saber como adicionar referências programaticamente, clique aqui.
No entanto, se uma Aplicação feita em Early Binding é distribuída para vários usuários finais com diversas versões diferentes, recomenda-se usar o Late Binding porque um computador que tem a versão 5.0 de uma biblioteca não executará nenhuma ação de uma biblioteca versão 6.0, por exemplo. Na melhor das hipóteses, deve-se nivelar a biblioteca por baixo (ou seja, se existem plataformas com bibliotecas 5.0, 6.0, 7.0 e 8.0, o programador deve fazer referência à biblioteca 5.0), para que todas as versões da biblioteca tenham melhor compatibilidade com o código.
Para o caso do Late Binding, suas vantagens são:
- Enquanto a velocidade de execução no Early Binding é maior, no Late Binding a velocidade de compilação é maior porque o VBE não precisa ler bibliotecas adicionais para começar a execução do código;
- O Late Binding atribui a um objeto não só o tipo de biblioteca em tempo de execução, mas também a versão do mesmo. Por exemplo, se você fizer uma referência à biblioteca Microsoft Excel 8.0 Object Library, seu código executará sem problemas num computador que tenha a mesma biblioteca na versão 9.0, ocorrendo essa conversão em tempo de execução.
Para a afirmação acima, no caso do Early Binding, pode ser que uma biblioteca versão 14.0 (Office 2010) não esteja presente num computador que possui apenas o Office 12.0 (2007) e, ao executar o documento no Office 2007, o usuário pode se deparar com bibliotecas ausentes (onde está AUSENTE, na figura abaixo):
Obviamente que a biblioteca não estará presente no projeto. Nesse caso, o usuário deve manualmente remover a biblioteca e adicionar uma compatível, como a Microsoft Word 12.0 Object Library, por exemplo.
Aproveitar Early Binding e Late Binding no Mesmo Código
Que tal aproveitar os benefícios do Early Binding e sua Aplicação em Late Binding? Veja como fazer isso:
#Const blEarlyBinding = True Sub Early_e_Late() #If blEarlyBinding Then Dim appWord As Word.Application Dim doc As Word.document Dim rng As Word.Range Dim prg As Word.Paragraph #Else Dim appWord As Object Dim doc As Object Dim rng As Object Dim prg As Object Dim wdWindowStateMaximize wdWindowStateMaximize = 1 #End If Set appWord = CreateObject("Word.Application") With appWord .Visible = True .Activate .WindowState = wdWindowStateMaximize Set doc = appWord.Documents.Add Set prg = doc.Paragraphs(1) Set rng = prg.Range rng = "Teste!" End With End Sub
Foram usados símbolos de compilação condicional. No exemplo acima, as linhas precedidas de # são compiladas de acordo com o valor atribuído à blEarlyBinding. Em outras palavras, você não terá erros de compilação da parte que pode gerar erros de declaração se o teste condicional de blEarlyBinding não for verdadeiro para o trecho de código.
Durante o tempo de desenvolvimento, adicione a biblioteca do Word e atribua True à blEarlyBinding. Quando concluir seu projeto, atribua False para que o mesmo rode em Late Binding. Fazer manutenção do sistema numa estrutura dessa é bastante simples.