VBA - Integrando aplicativos Office

Além de fornecer uma plataforma de desenvolvimento RAD o Visual Basic conta com a vantagem de poder usar sua facilidade de integração com outros aplicativos Microsoft , em especial da suite office , que , quer queiram ou não tem uma enorme base instalada . Assim como Word é sinônimo de processador de textos , Excel de planilha eletrônica , PowerPoint de programa para apresentações , Access de Banco de dados e Visual Basic linguagem de programação visual. Por que não usar todo o poder destes aplicativos e suas funcionalidades em aplicativos Visual Basic.

Para poder usar o mesmo conteúdo em aplicações diferentes do Office , precisamos estabelecer uma comunicação entre eles; é aqui que entra o VBA - Visual Basic for Applications. Como ele podemos fazer uma conexão entre dois aplicativos usando as funções CreateObject ou GetObject ou ainda a palavra-chave New em uma declaração ; feito isto podemos usar o conteúdo de um aplicativo em outro.

Embora o assunto já tenha sido abordado por mim em artigos anteriores , nunca é demais lembrar os fundamentos para os que estão iniciando com o VBA . Se você quer lembrar ou esta chegando agora o mundo VBA leia os artigos abaixo para se inteirar:

Geralmente quem é novo fica um tanto confuso e não sabe direito por onde começar quando quer usar VBA para integrar uma aplicação office no seu projeto Visual Basic. Não sabia !!! Abaixo eu estou listando uma relação de tarefas a serem realizadas e uma descrição de como atingir este objetivo:

Tarefa a ser realizada              Descrição de como realizar a tarefa usando VBA
Eu quero criar um instância de um objeto (Word,Excel, Access etc...)     Use a função CreateObject para retornar uma referência para o objeto ; a seguir faça uma referência para uma variável com a declaração Set. Ex:

Set appExcel = CreateObject("Excel.Application")

Como fazer referência ás bibliotecas de objetos dos aplicativos office. No Visual Basic , clique no menu Project e a seguir em References... . Na caixa de diálogo marque a referência para a biblioteca de objetos de aplicativos com o qual deseja trabalhar. Ex: Microsoft PowerPoint 9.0 Object Library
Eu quero declarar uma variável como um objeto do tipo específico.(Ex: tipo Word , Excel , etc...) Apos selecionar a biblioteca de objetos do aplicativo com o qual deseja trabalhar digite :
  • Dim appPPT As PowerPoint.Application
  • Dim appExc As Excel.Application
  • Dim appWd As Word.Application
  • Dim appAcc As Access.Application
  • Dim appOut As Outlook.Application
Eu quero declarar uma variável como um objeto do tipo genérico (Exemplo de  ligação tardia ou late binding). Não recomendado. Digite o nome da variável usando a palavra-chave Dim e a seguir defina a variável como objeto: Ex: Dim objVar As Object
Como eu posso declarar uma variável objeto e em seguida definir uma ocorrência do objeto de uma única vez. Apenas digite:

Dim appWord as New Word.Application

Eu quero declarar a ocorrência de um objeto que já esta carregado. Use a função GetObject e a seguir atribua a referência para a variável objeto:Ex:

Set AppWord = GetObject(,"Word.Application")

Eu quero iniciar um aplicativo , abrir um arquivo existente e a seguir atribuí-lo para uma variável de objeto de uma única vez. Ex:

Set wrkBook = GetObject("Book1.xls")

Eu quero desconectar uma variável de um objeto Ex: Set appWord = Nothing

Nota: A palavra-chave New não pode ser usada para declarar outros tipos de dados , só pode ser usada para declarar variáveis de objeto.

Em todos os aplicativos Office temos pelo menos um objeto que pode ser criado pela função CreateObject. O Word e o Excel também permitem a criação de outros tipos de objeto , conforme a tabela a abaixo:

Aplicativo Tipo de Objeto Classe Cria nova ocorrência Propriedade Visible
Access Application Access.Application Sim Sim
Excel Application Excel.Application Sim Sim
Excel Worksheet Excel.Sheet -- Sim
Excel Chart Excel.Chart -- Sim
Outlook Application Outlook.Application Não Não
PowerPoint Application PowerPoint.Application Não Sim
Word Application Word.Application Sim Sim
Word Document Word.Document --- Sim

Nota : Você deve saber que quando você usa CreatObject ou a palavra-chave New para criar uma ocorrência de um aplicativo Office , o Visual Basic cria uma nova ocorrência do aplicativo no sistema para todos os aplicativos , com exceção do PowerPoint e do Outlook. Além disto cada objeto Application possui uma propriedade Visible que permite que você exiba a janela do aplicativo depois da criação do mesmo com exceção do Outlook.

Quando eu devo usar a função GetObject ?

Você deve usá-las em duas situações :

  1. Quando quiser acessar uma ocorrência de um objeto que já esta carregado. Assim você evita a carga de uma nova ocorrência.
  2. Quando quiser iniciar um aplicativo e carregar um arquivo existente de uma única vez.

Fora destas duas ocasiões use a função CreateObject ou a palavra-chave New.

Após você usar a função CreateObject , GetObject ou a palavra New para atribuir um objeto a uma variável , o objeto fica na memória do computador. Para desconectar a variável de objeto de um objeto defina a variável do objeto para a palavra Nothing.

Todos os aplicativos Office possuem como membro do objeto Application , um método Quit que no Visual Basic tem o mesmo efeito que a opção Sair do aplicativo ; mas em alguns casos o método Quit não libera a referência ao objeto atual até que você defina explicitamente a variável objeto como Nothing.

Da Teoria para a Prática - Gerando uma tabela no Word com os dados de uma tabela

O modelo de programação do Word esta centrado no objeto Range que representa uma área de texto adjacente. O objeto Range permite que você recupere ou defina textos e aplique formatações em textos em qualquer posição em um documento.

Vamos então por a mão na massa e mostrar como podemos gerar uma tabela no Word com os dados de uma tabela de um banco de dados Access. Para este exemplo eu criei um banco de dados chamado bancos.mdb e uma tabela saldos com a seguinte estrutura e dados:

Meu objetivo é criar uma tabela no Microsoft Word com os dados desta tabela. Para isto eu vou criar um modelo de documento no Word com o nome de extrato.dot e usar este modelo para preencher com os dados da minha tabela saldos. Abaixo o modelo extrato.dot criado previamente no Word.

Meu objetivo é mostrar o código VBA usado para gerar a tabela .

1- Inicie um novo projeto no VB do tipo Standard EXE e inclua as seguintes referências no projeto: ( Menu Project|References...)

2- Inclua também no projeto os seguintes componente:

2- no formulário padrão que vou chamar - frmextrato - inclua o seguintes controles :

O layout do formulário deverá ser parecido com a figura abaixo:

- Eu estou usando os controles DataGrid vinculado ao controle ADODC para exibir os dados .

- Eu defino uma conexão com o banco de dados no controle ADODC e no controle DataGrid eu atribuo a propriedade DataSource ao controle adodc1.

 

Na seção - General Declarations - do formulário inclua as declarações das variáveis usadas no projeto:

Dim db As Database
Dim tabela As Recordset
Dim oWordApp As New Word.Application
Dim oWordDoc As Word.Document
Dim gcaminho As String
Dim gvalorTotal As Single

No Evento Load do formulário insira o código a seguir

Private Sub Form_Load()

gcaminho = "c:\_vba"

'abre a base de dados no modo compartilhado
Set db = DBEngine.Workspaces(0).OpenDatabase(gcaminho & "\bancos.mdb")
Exit Sub

'tratamento de erros
trata_erro:
MsgBox Err.Number & " : " & Errors(0).Description, , "ERRO - ATENÇÃO "
End Sub
- Estou definindo o caminho do banco de dados , do template

- O arquivo extrato.doc também será salvo no caminho definido em gcaminho

- Estou abrindo o banco de dados via DAO , mas isto é indiferente.

No evento Click do botão de comando - cmdWord - insira o seguinte código :

Private Sub cmdword_Click()

lblstatus.Caption = "Criando uma aplicação e um documento no Word..."
criarDocumentoWord
lblstatus.Caption = "Gerando a tabela no Word com informações da tabela saldos. Aguarde... "
MontaDados
lblstatus.Caption = "Incluindo o valor total na tabela gerada no Word..."
incluiValorTotal

End Sub
- Aqui eu vou invocar cada uma das rotinas que irão
criar efetivamente o documento no Word , preencher a
tabela e incluir o valor total.

Neste código eu estou usando três procedimentos : criarDocumentoWord , MontaDados e incluiValorTotal.

A rotina criarDocumentoWord apenas cria um documento no Word com base no template extrato.dot.

Private Sub criarDocumentoWord()

'cria documento no word baseado em um modelo extrato.dot
Set oWordDoc = oWordApp.Documents.Add(Template:=gcaminho & "\extrato.dot", newtemplate:=False)

End Sub

Na rotina MontaDados() fazendo o seguinte :

  1. Abrindo a tabela Saldos e selecionando todos os registros da mesma = Set tabela = db.OpenRecordset("Select * from Saldos")
  2. Percorro a fonte de dados até o fim e invoca a rotina criarTabelaWord com o parâmetros que são os campos da tabela saldo. - Call criarTabelaWord(tabela(0), tabela(1), tabela(2), tabela(3))
  3. Efetuo a totalização do incluir o valor total na tabela - gvalorTotal = gvalorTotal + tabela(3)
Private Sub MontaDados()

'abre o banco a tabela saldos
Set tabela = db.OpenRecordset("Select * from Saldos")

DoEvents

'inicia a variável para calculo do valor total com zero
gvalorTotal = 0

'percorre a tabela até o último registro
Do While Not tabela.EOF
Call
criarTabelaWord(tabela(0), tabela(1), tabela(2), tabela(3))
gvalorTotal = gvalorTotal + tabela(3)

tabela.MoveNext

Loop

End Sub

Na rotina criarTabelaWord eu estou recebendo 4 argumentos ( codigo, data, historico e valor) e a seguir eu faço o seguinte :

  1. Uso a tabela já existente no documento Word ( o meu template ) - With oWordDoc.Tables(1)
  2. Vou para última linha da tabela -    With .Rows.Last
  3. Incluo os parametros recebidos nas células da tabela

          .Cells(1).Range.Text = codigo
           .Cells(2).Range.Text = data
           .Cells(3).Range.Text = historico
           .Cells(4).Range.ParagraphFormat.Alignment = wdAlignParagraphRight
           .Cells(4).Range.Text = Format$(valor, "###0.00")

  4. Ao final eu incluo a linha na tabela : .Rows.Add
Private Sub criarTabelaWord(codigo As Integer, data As String, historico As String, valor As Currency)

'
inclui os dados da tabela saldos na tabela gerada no word
With oWordDoc.Tables(1)
   With .Rows.Last
       .Cells(1).Range.Text = codigo
       .Cells(2).Range.Text = data
       .Cells(3).Range.Text = historico
       .Cells(4).Range.ParagraphFormat.Alignment = wdAlignParagraphRight
       .Cells(4).Range.Text = Format$(valor, "###0.00")
   End With
   .Rows.Add
End With

End Sub

Na rotina incluiValorTotal eu estou incluindo na última linha da tabela um texto e o valor total da coluna Valor. O código esta comentado para maiores esclarecimentos..

Private Sub incluiValorTotal()

On Error GoTo trata_erro

With oWordDoc.Tables(1).Rows.Last
   'formata o texto a ultima linha : Negrito , fonte com tamanho 12 e a borda da célula é uma linha dupla
    .Range.Bold = True
    .Range.Font.Size = 12
    .Borders.Item(wdBorderTop).LineStyle = wdLineStyleDouble

     'inclui o total na tabela na terceira célula e formatar para o padrão monetário
     .Cells(3).Range.Text = "Total"
     .Cells(4).Range.Text = gvalorTotal
     .Cells(4).Range.Text = Format$(gvalorTotal, "###0.00")

End With
'Salvo o documento criado no caminho definido
If MsgBox("Deseja salvar o arquivo gerado no Word", vbYesNo, "Macoratti") = vbYes Then
    oWordDoc.SaveAs caminho & "extrato.doc"
End If

lblstatus.Caption = ""
oWordApp.Visible = True
' exibo o Word com a tabela gerada
Exit Sub

trata_erro:
If Err.Number = 5356 Then
     MsgBox "Não é possivel salvar o arquivo pois ele esta aberto por outro aplicativo !", vbCritical, "Macoratti"
Else
     MsgBox Err.Number & " - " & Err.Description, vbCritical, "Macoratti"
End If
End Sub

Após executar o projeto e clicar no botão que gera a tabela , após alguns segundos você deverá obter o seguinte resultado:

Voilá !!!, como vemos o template - extrato.dot -  foi usado e a tabela - extrato.doc - gerada conforme os dados da tabela saldos. Você pode incrementar ainda mais o exemplo adicionando recursos para tornar mais poderosa sua aplicação.

Aguarde mais um artigo VBA pare breve , tchau...  


José Carlos Macoratti