VBA Advanced - Adicionando referências dinamicamente no VBA.



Introdução
Em diversos projetos mostram-se necessários a utilização de referências. As referências nos permitem habilitar recursos de outras aplicações. 

Por exemplo: 

Caso queiramos atualizar uma apresentação Powerpoint com tabelas e gráficos, onde tais dados estejam conectados a bancos de dados no MS Access. Isso exigiria uma referência a biblioteca do Microsoft Active Data Objects.

Agora suponhamos que a versão ADO utilizada na máquina onde a apresentação será feita é uma versão antiga, desatualizada ou incompatível?

Ou digamos que os arquivos necessários, aqueles com extensão .OCX, ou .DLL não estejam na máquina.

Certamente ocorrerão erros que inviabilizarão a apresentação, podendo até comprometer a credibilidade de quem fará a apresentação.

Um dos objetivos deste artigo é fazê-lo conhecer um modo de verificar essas referências através do código VBA. 

Para que possa compreender o poder daquilo que está aprendendo, basta informá-lo que através do VBA podemos manipular não somente objetos e eventos contidos na própria aplicação que estamos usando no momento, antes podemos, através do próprio VBA, criar módulos, classes, formulários, controles ou mesmo criar referências em qualquer um dos aplicativos da suíte MS Office.

Implementando o acesso
A conexão entre os aplicativos da suíte MS Office e mesmo com recursos de outras aplicações não é natural. Para podermos usufruir é necessário configurarmos isso em Ferramentas | Macro | Segurança. Aparecerá uma caixa de diálogo similar a demonstrada abaixo:


Acione a aba Fontes confiáveis e veja logo abaixo a opção Confiar no acesso ao projeto doVisual Basic. Por padrão está desabilitada. Habilite-a para poder prosseguir com os exemplos e clique em OK.

 Testando o aplicativo
 Para tornar o teste idôneo, é interessante ter disponível mais de uma versão do Office. Para este exemplo, vamos construir o aplicativo em Excel-VBA em que criaremos um novo arquivo doWord.

 Abra o Excel e acione o editor do VBA pelo menu Ferramentas->Macros->Editor do Visual Basic  ou com o atalho Alt+F11. No VBA, acione ao menu Ferramentas->Referências para visualizar as referências existentes e disponíveis. Procure pela referência Microsoft Word XX.0 Object Library onde XX é o numero da versão do Office instalada em seu computador:

Office
Nº Versão
Microsoft Office 97
8.0
Microsoft Office 2000
9.0
Microsoft Office XP
10.0
Microsoft Office 2003
11.0

Como estou fazendo este aplicativo na versão 2003, a biblioteca referenciada será a MicrosoftWord 11.0 Object Library conforme mostra a figura:

 

Figura 2: Referências do aplicativo
 Agora, insira um módulo convencional indo ao menu Inserir->Módulo. Nesse módulo, coloque o seguinte código:

  Public Sub AbreWord()
    Dim versao As String
    
'Declara uma variável do tipo Word.Application (aplicativo)
    Dim arqWord As Word.Application
    'Declara uma variável do tipo Word.Document (documento)    Dim docWord As Word.Document
    'Cria uma nova instância do Word
 
   arqWord = CreateObject("Word.Application")
    'Esta linha serve para criar um documento em branco
    docWord = arqWord.Documents.Add
    'Torna o Word Visível    arqWord.Visible = True    'Captura a versão do Word
    Versao = arqWord.Version
    'Escreve texto no arquivo

    arqWord.Selection.TypeText("Olá Word " & versao & "!")
  End Sub

Se a referência estiver sido feita corretamente. será possível usufruir dos recursos do Intellisense para escrever o código. No Word 2003, o resultado da execução do código é uma nova instância e um novo documento do Word com o seguinte texto:

 

Figura 3: Arquivo de Word gerado pela Macro "AbreWord" no Word 2003

A Macro pegou a versão do Word referenciada, criou um novo documento colocando o texto que foi composto com o número da versão do Word, neste caso, 11.0.

 Com a Macro funcionando, vamos agora testá-la em outra versão do Office. Neste caso, utilizarei a versão 2000. Abra a planilha no Excel 2000 e tente executar a Macro. Facilite o acesso com o atalho Alt+F8 para mostrar a Macro e clique em executar:

 
Figura 4: Executando a Macro

Se tudo der certo (ou errado), surgirá a seguinte mensagem:
 

Figura 5: Erro gerado pela Macro executada no Excel 2000
 Clique em OK e veja que o editor parou a execução do código na linha em declaramos o ObjetoWord.Application. 

Figura 6: Vericando a linha de erro da Macro 
Verifique as referências feitas inda à caixa de diálogo de referências (Ferramentas->Referências o VBA) e veja que a biblioteca Microsoft Word 11.0 Object Library está marcada como AUSENTE: 

Figura 7: Vericando a ausência da referência 

Para resolver o problema de funcionamento da Macro, bastaria desfazer essa referência e procurar a Microsoft Word 9.0 Object Library que é correspondente ao Office instalado. Após isso, tente executar novamente a Macro. O resultado deverá ser este: 


Figura 8: Arquivo de Word gerado pela Macro AbreWord no Word 2000 
Veja que o texto gerado dinamicamente pela Macro obedeceu ao critério de versão e alterou o número colocado no texto (Se executar a Macro no Office XP, a versão apresentada será 10.0). Feche o arquivo do Word, salve a planilha no Excel 2000 e abra-a no Excel 2003 novamente. Ao executar a Macro, ela funcionará normalmente. Porque? Abra o VBA, acione o menu Ferramentas->Referências e veja que a referência foi atualizada para o Microsoft Word 11.0 Object Library

Neste ponto, chegamos a algumas conclusões e soluções para o problema: 
Desenvolver sempre numa versão mais antiga para garantir o funcionamento em qualquer versão do Office?
O problema é que limitaríamos aos recursos de uma versão mais antiga além do fato de se a o aplicativo for aberto em alguma versão superior e for salvo, ele manterá a referência da última versão do aplicativo em que foi aberto provocando novamente o problema de versionamento. 

Ter instalada todas as versões do Office para incluir todas as referências?
Talvez desse certo, mas quem se disponibiliza tanto financeiramente como em recursos de máquina e conflitos gerados a ter instalada todas as versões do aplicativo? 

Cria e manter a referências dinamicamente?
Essa creio eu ser a melhor saída. Não é completamente infalível, mas já testei em vários ambientes e se comportou muito bem. 





Como adicionar as referências via código 
Além dos conceitos de segurança e permissões discutidos no começo do artigo, é preciso se acostumar um pouco com os elementos das referências. Para que a manipulação funcione, é preciso fazer referência à bilbioteca Microsoft Visual Basic for Applications Extensibility 5.3. Essa é a biblioteca que permite manipular objetos do VBA, tanto do VBA como desde outras ferramentas como Visual Basic 6 ou Visual Basic .NET. Essa bilbioteca é instalada juntamente com o VBA e a garantia que ela esteja presente na máquina cliente é de quase 100%, já que na instalação padrão do Office o VBA é também instalado. 
Vamos fazer um exemplo que use objetos dessa biblioteca. Insira um módulo convencional na mesma planilha que fizemos anteriormente no Excel 2003 e coloque o seguinte código: 

  Public Sub ChecaReferencias()
     Dim mensagem As String
    'Faz a referência ao projeto VBA    Dim vbProj As VBProject
    'A referencia em si
    Dim chkRef As Reference 
    'Seta a variável para o projeto da pasta de trabalho ativa.
    vbProj = ActiveWorkbook.VBProject
 
    'Checa as referências selecionadas (veja na caixa de diálogo Referências)
    
For Each chkRef In vbProj.References
      
'monta a string que conterá o nome de todas as referências
      mensagem = mensagem & " " & chkRef.Name & Chr(13)
    Next    'Mostra a mensagem com o nome das referência selecionadas
    MsgBox(mensagem)
  End Sub

Execute a Macro. Não se esqueça de adicionar a referência à biblioteca de manipulação, como dito anteriormente. O resultado deverá ser algo parecido com este: 
Figura 9: Resultado gerado pela Macro ChecaReferencias 

Você pode fazer uma equivalência do resultado desta Macro abrindo a caixa de diálogo Referências do VBA: 
Figura 10: Verificando as referências

Teoricamente está tudo OK. Com esse código, podemos saber e aprender mais sobre as referências e seus atributos. Modifique a linha de código que monta a mensagem para o seguinte: 
mensagem = mensagem & "Nome: " & chkRef.Name & " - Caminho: " & chkRef.FullPath & " - Descrição: " & chkRef.Description & Chr(13)

Execute a Macro desta vez. O resultado deve ser o seguinte: 


Figura 11: Resultado gerado pela Macro ChecaReferencias com a mensagem alterada 
Agora temos uma forma simples de obter mais informações sobre as referências com que trabalhamos no VBA. Os atributos mais importantes a serem trabalhados para este artigo são oIsBrokenGUID, Major e Minor
A propriedade IsBroken retorna False se a referência estiver OK e True se estiver quebrada, por exemplo, quando a caixa de diálogo acusa que a referência está AUSENTE, é um caso em que o IsBroken retornará True. Isso nos ajuda a verificar a existência de uma referência que nos disponibiliza determinada funcionalidade, por exemplo, uma .OCX que contenha um controle ActiveX como o Calendar Control. Dependendo do resultado, você pode optar por rodar ou não o projeto. 
A propriedade GUID retorna o identificador único para a referência. Para ver esta identificação, modifique a linha de código que monta a mensagem para o seguinte: 
mensagem = mensagem & "Nome: " & chkRef.Name & " - GUID: " & chkRef.GUID & " - Major: " & chkRef.Major & " - Minor: " & chkRef.Minor & Chr(13)

 Veja o resultado: 

Figura 12: Resultado gerado pela Macro ChecaReferencias com a mensagem alterada 
Com alguma pesquisa, pude confirmar que esse identificador é o mesmo independente de versão. Se você testar em qualquer outra versão o mesmo código, verá que os GUIDs não serão alterados. É essa propriedade que usaremos para adicionar e remover as referências em nossos aplicativos. As propriedades Major e Minor não requerem maiores estudos e serão usadas somente para a execução do método que adiciona a referência, conforme veremos a seguir. 

Os métodos utilizados para adicionar e remover referências são o AddFromGUIDAddFromFileRemove

O método AddFromFile adiciona a referência com base no caminho do arquivo. É uma opção, mas pode ser problemática, pois precisaríamos saber qual o diretório em que foi instalado o aplicativo, o que à vezes pode ser um mistério. Para contornar a situação, podemos usar o métodoApplication.Path que retorna o diretório em que foi instalado o Office para adicionar a referência. 

O método AddFromGUID adiciona a referência com três parâmetros: GUID, Major e Minor, que são as propriedades discutidas anteriormente. O GUID pode ser passado como String e as variáveis Major e Minor devem ser passadas como Long

Pegar os dados requer código como fizemos anteriormente. Com isso, temos para a biblioteca Microsoft Word os seguintes valores: 

GUID: {00020905-0000-0000-C000-000000000046}
Major: 8
Minor: Depende da versão. 

A variável Minor possui um valor que varia conforme a versão do aplicativo. Para regularizar esse valor, a melhor maneira que encontrei foi pegando o valor do Application.Version. A diferença entre os dois valores é sempre de 8 unidades, portanto podemos fazer uma analogia para determinar o valor do parâmetro. Veja a diferença do resultado da Macro ChecaReferenciasexecutada no Excel 2000 e no Excel 2003: 

Figura 13: Resultado gerado pela Macro ChecaReferencias no Excel 2000 

Figura 14: Resultado gerado pela Macro ChecaReferencias no Excel 2003  

O método Remove remove a referência em si. É preciso passar uma variável do tipo Referencepara que funcione. 

Tendo visto todas estas opções, consegui chegar à seguintes soluções para nosso problema. Abaixo proponho um modelo de código que pode tornar o aplicativo VBA praticamente universal para todas as versões do Office: 
  Public Sub AdicionaReferenciaWord()
     'Faz a referência ao projeto VBA
    Dim vbProj As VBProject
    'A referencia em si    Dim versao As Long
 
    'Seta a variável para o projeto da pasta de trabalho ativa.    vbProj = ActiveWorkbook.VBProject 
    'Pega a versão atual do Office e corrige a variável    versao = CLng(Application.Version) / 10 
    'Adiciona a referência do Word via GUID:    vbProj.References.AddFromGuid("{00020905-0000-0000-C000-000000000046}", 8, versao - 8) 
  End Sub
   Public Sub RemoveReferenciaWord() 
    'Faz a referência ao projeto VBA
    Dim vbProj As VBProject
    'A referencia em si    Dim chkRef As Reference
    'Seta a variável para o projeto da pasta de trabalho ativa.    vbProj = ActiveWorkbook.VBProject
    For Each chkRef In vbProj.References
      
'Verifica se a referência é do Word:
      
If chkRef.GUID = "{00020905-0000-0000-C000-000000000046}" Then
        'Se for, remove        vbProj.References.Remove(chkRef)
      End If    
Next
  End Sub

Insira esse código em um módulo vazio de uma na planilha em que estamos trabalhando adicionando a referência ao Microsoft Visual Basic for Applications Extensibility 5.3. Insira também o código para gerar o novo arquivo no Word conforme no começo do artigo. Agora, basta colocar a chamado da Macro AdicionaReferenciaWord no evento Workbook_Open e a Macro RemoveReferenciaWord no Workbook_BeforeClose. O código emEstapasta_de_trabalho fica assim: 
  Private Sub Workbook_BeforeClose(ByVal Cancel As Boolean)
    Call RemoveReferenciaWord()
  End Sub
  Private Sub Workbook_Open()
    
Call AdicionaReferenciaWord()
  End Sub

Agora, feche a planilha e salve no Excel 2003. Em seguida, abra no Excel 2000 ou XP (ativando as Macros) e sem mexer em nada, execute a Macro AbreWord. Veja que o Word é aberto corretamente não gerando mais o erro de versionamento. As Macros trataram de adicionar a referência para a versão correta do aplicativo sem intervenção do usuário. Faça isso várias vezes em diversas versões do aplicativo para testar sua eficácia. 

Você pode também fazer implementações com o método AddFromFile, embora em testes eu tenha concluído que o AddFromGUID é mais eficiente e menos sujeito e erros. 

As funções e recursos oferecidos pela biblioteca Microsoft Visual Basic for Applications Extensibility 5.3 permite ir mais além do que mostrei neste artigo. É possível estender a funcionalidade a outras bibliotecas mais comuns como o ADO e o Microsoft Outlook. A partir da versão 97, o Office teve suas versões regularizadas para todos os aplicativos e isso nos auxilia a trabalhar com as opções de versões como fizemos nos códigos de exemplo. 

Conclusão 
Procurei explanar de maneira enxuta um meio para resolver o problema de versionamento e ausência de componentes que em muito nos auxiliam e azucrinam no desenvolvimento de nossas soluções. 


Referências 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbext98/html/vamthaddfromguid.asp



TagsMicrosoft Office Access, Access, Format




Nenhum comentário:

Postar um comentário

diHITT - Notícias