|
|
 |
| Tecnologias :: Visual FoxPro |
 |
|
| |
|
| VFP e a Automação do MS-Outlook |
Por José Cavalcanti, artigo originalmente publicado na revista UTMag/RapoZine. |
Introdução
Motivei-me a escrever esse artigo há algum tempo (aliás, BASTANTE tempo), vendo centenas (ou milhares) de mensagens no Grupo FoxBrasil abordando o tema "Como mando uma mensagem de dentro do VFP?". Quem me conhece do Grupo já sabe, que eu adoro estudar, pesquisar e, principalmente, usar OLE Automation . Bom, e afinal, o que significa essa sigla? OLE é o acrônimo para Object Linking and Embedding. Legal, fiquei na mesma, diria você. OLE Automation é a possibilidade que uma determinada aplicação tem, de expor o seu funcionamento (PEM - Propriedades, Eventos e Métodos) para uma outra aplicação qualquer. É como fosse pudéssemos, por exemplo, empacotar o Microsoft Word em um objeto e incluí-lo dentro de nossa aplicação VFP (ou VB, ou VBA, ou JavaScript, etc).
Digamos que em um sistema para controle de assinaturas de uma revista, seja necessário lembrar o responsável pelo setor de cobrança que em um determinado dia ele tem que verificar se os boletos bancários enviados aos assinantes foram pagos. Esse dia não é fixo para todos os assinantes e é determinado pelo dia da inscrição. Assim, teríamos que montar uma agenda dentro do sistema para que essa pessoa seja avisada, certo? Não necessariamente, pois esse usuário utiliza o Microsoft Outlook 2000 e o Microsoft Outlook 2000 é um OLE Server, ou seja, podemos, de dentro do VFP, instruir o Microsoft Outlook 2000 a executar uma determinada tarefa, tal como, abrir uma entrada no Calendário, preencher os dados necessários e salvá-los.
E isso é difícil? Não, não é, desde que você tenha em mãos a documentação do OLE Server (Object Model) e, em muitas vezes, essa é a tarefa mais árdua.
Pretendo, de acordo com as horas vagas e com a paciência da família, escrever artigos sobre o Object Model do Microsoft Outlook, Microsoft Internet Explorer e do Lotus Notes, mas como comecei a estudar esse último há pouco tempo, não sei se será possível. Por motivos didáticos, começaremos essa série de artigos pelo Microsoft Outlook, e gostaria de dizer que essa séria foi baseada em uma outra escrita por Andrew Ross MacNeill para a revista Foxpro Advisor.
O Microsoft Outlook
O Outlook é uma ferramenta de produtividade que inclui Calendário, Correspondências (e-mail), Contatos e Tarefas (itens principais). Utilizo a versão mais recente, o Outlook 2000, assim todas as referências serão em relação à essa versão. O Object Model do Outlook 2000, pode ser encontrado no arquivo VBAOUTL9.CHM, quem não tiver esse arquivo instalado, me manda uma mensagem para que eu possa enviá-lo. Como se pode ver na Figura 1 abaixo, o objeto Application é o primeiro na hierarquia. Esse objeto não serve para muita coisa, mas é a porta de entrada para o acesso ao Outlook. Embora o Outlook seja usado para uma série de coisas, ele é primordialmente um pacote de e-mail. Assim, ele usa MAPI, Messaging Application Programming Interface. Ao abrir o Outlook, ele cria uma referência a um objeto MAPI NameSpace. Esse objeto armazena referências à localização dos Folders, itens e configurações usadas pelo Outlook. Vamos começar a brincar então? Vamos lá, dêem uma olhada no código abaixo:
LOCAL loApplication, loNameSpace, loContacts, loInbox, lcMessage
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loContacts = loNameSpace.GetDefaultFolder(10)
loInbox = loNameSpace.GetDefaultFolder(6)
lcMessage = "Nome do Folder 'Contacts': " + CHR(9) + loContacts.Name + CHR(13) + CHR(10)+;
"Nome do Folder 'Inbox': " + CHR(9) + loInbox.Name
MSGSVC(lcMessage)
RELEASE ALL
RETURN
Figura 1 - Microsoft Outlook 2000 Object Model
Primeiro, chamamos o Outlook e criamos o objeto NameSpace (sempre começamos assim), depois, usamos o método GetDefaultFolder para obter uma referência (outro objeto) a alguns Folders mais usados e finalmente, mostramos o nome desses Folders. A Tabela 1 mostra a lista dos parâmetros possíveis para o método GetDefaultFolder.
| Parâmetro | Folder
|
| 3 | Deleted Itens (Itens Excluídos)
|
| 4 | OutBox (Caixa de Saída)
|
| 5 | Sent Itens (Itens Enviados)
|
| 6 | Inbox (Caixa de Entrada)
|
| 9 | Calendar (Calendário)
|
| 10 | Contacts (Contatos)
|
| 11 | Journal (Diário)
|
| 12 | Notes (Anotações)
|
| 13 | Tasks (Tarefas)
|
| 16 | Drafts (Rascunhos)
|
Essa estratégia funciona bem com os Folders "padrão" , mas e se desejássemos saber os Folders contidos dentro da Caixa de Entrada? Para isso vamos usar a propriedade Folders que todo objeto Folder possui, veja o exemplo abaixo:
LOCAL loApplication, loNameSpace, loInbox, lnContador, loFolder
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loInbox = loNameSpace.GetDefaultFolder(6)
FOR lnContador = 1 TO loInbox.Folders.Count
loFolder = loInbox.Folders(lnContador)
MSGSVC("Folder: " + loFolder.Name)
ENDFOR
RELEASE ALL
RETURN
Primeiro selecionamos a Caixa de Entrada, verificamos o número de Folders contidos e mostramos o nome desses Folders. É bom lembrar que podemos nos referenciar um Folder pelo número (Folders(4)) ou pelo nome (Folders("Caixa de Entrada")).
Cada Folder tem uma coleção de Items. Use a propriedade Count para identificar o número desses Itens. Assim, poderíamos modificar ligeiramente nosso programa para que ele também mostrasse o número de Itens contidos em cada Folder:
LOCAL loApplication, loNameSpace, loInbox, lnContador, loFolder, lcMensagem
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loInbox = loNameSpace.GetDefaultFolder(6)
FOR lnContador = 1 TO loInbox.Folders.Count
loFolder = loInbox.Folders(lnContador)
lcMensagem = "Folder: " + CHR(9) + loFolder.Name + CHR(13) + CHR(10) +;
"Itens: " + CHR(9) + STR(loFolder.Items.Count)
MSGSVC(lcMensagem)
ENDFOR
RELEASE ALL
RETURN
Trabalhando com Contatos
O Item Contacts (ContactItem no nosso Object Model) armazena diversas informações sobre um determinado Contato. Para cada item, é possível armazenar 3 endereços, 3 endereços de e-mail, 19 números de Fax, Telefone, etc e muitas outras informações. Ainda assim, se esses campos não forem suficientes, podemos criar outros definidos pelo usuário (propriedade UserProperties). Campos definidos pelo usuário são armazenados em cada Item individualmente, ou seja, um determinado campo pode ter um campo que os outros não tenham. Assim, para recuperar algumas informações sobre nossos Contatos teríamos:
LOCAL loApplication, loNameSpace, loContacts, lnContador, loContact, lcMensagem
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loContacts = loNameSpace.GetDefaultFolder(10)
FOR lnContador = 1 TO loContacts.Items.Count
loContact = loContacts.Items(lnContador)
lcMensagem = "Contato: " + CHR(9) + STR(lnContador) + CHR(13) + CHR(10) +;
"Nome: " + CHR(9) + loContact.FirstName + CHR(13) + CHR(10) +;
"Sobrenome: " + CHR(9) + loContact.LastName + CHR(13) + CHR(10) +;
"Empresa: " + CHR(9) + loContact.CompanyName
MSGSVC(lcMensagem)
ENDFOR
RELEASE ALL
RETURN
Incluindo e Alterando Contatos
Para adicionarmos um novo Contato usamos o método Add e para salvarmos as alterações feitas usamos o método Save (até que faz sentido). Assim, faríamos:
LOCAL loApplication, loNameSpace, loContacts, loNewContact
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loContacts = loNameSpace.GetDefaultFolder(10)
loNewContact = loContacts.Items.Add()
loNewContact.FirstName = "Filippo"
loNewContact.LastName = "Cavalcanti"
loNewContact.FullName = "Filippo Cavalcanti"
loNewContact.CompanyName = "Global Connection"
loNewContact.Save()
RELEASE ALL
RETURN
Podem checar, meu filho agora faz parte do seu arquivo de Contatos. Para excluí-lo, use o método Delete.
Navegando, Classificando e Procurando Informações
O Object Model do Outlook provê métodos para facilitar a navegação dentro de um Folder. No primeiro método, contamos o número de itens dentro de um determinado Folder e depois, vamos passando um a um até o último:
LOCAL loApplication, loNameSpace, loContacts, loNewContact
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loContacts = loNameSpace.GetDefaultFolder(10)
loItens = loContacts.Items
FOR lnContador = 1 TO loItens.Count
lcMensagem = "Nome: " + CHR(9) + loItens.Item(lnContador).FirstName +;
CHR(13) + CHR(10) +;
"Sobrenome: " + CHR(9) + loItens.Item(lnContador).LastName +;
CHR(13) + CHR(10) +;
"Empresa: " + CHR(9) + loItens.Item(lnContador).CompanyName
MSGSVC(lcMensagem)
ENDFOR
RELEASE ALL
RETURN
Podemos incluir o método Sort para classificar os itens pelo campo especificado no primeiro parâmetro. O segundo parâmetro indica se desejamos classificar em ordem crescente (.F.) ou decrescente (.T). Assim, teríamos:
LOCAL loApplication, loNameSpace, loContacts, loNewContact
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loContacts = loNameSpace.GetDefaultFolder(10)
loItens = loContacts.Items
loItens.Sort("[CompanyName]", .T.)
FOR lnContador = 1 TO loItens.Count
lcMensagem = "Nome: " + CHR(9) + loItens.Item(lnContador).FirstName +;
CHR(13) + CHR(10) +;
"Sobrenome: " + CHR(9) + loItens.Item(lnContador).LastName +;
CHR(13) + CHR(10) +;
"Empresa: " + CHR(9) + loItens.Item(lnContador).CompanyName
MSGSVC(lcMensagem)
ENDFOR
RELEASE ALL
RETURN
No segundo método, usamos os métodos GetFirst e GetLast, que retornam referências ao primeiro e último itens de um Folder, respectivamente. Depois de posicionados, usamos os métodos GetNext e GetPrevious para mover-nos para baixo e para cima dentro de um Folder.
Para localizarmos um determinado Item, usamos o método Find. O critério de seleção é passado como o único parâmetro. Assim, para listarmos os contatos cujos nomes (FirstName) comecem com a letra "J", teríamos:
LOCAL loApplication, loNameSpace, loContacts, loItens, loItem, lcMensagem
loApplication = CREATEOBJECT("Outlook.Application")
loNameSpace = loApplication.GetNameSpace("MAPI")
loContacts = loNameSpace.GetDefaultFolder(10)
loItens = loContacts.Items
loItens.Sort("[FirstName]", .F.)
loItem = loItens.Find("[FirstName]>='J'")
DO WHILE .T.
IF LEFT(loItem.FirstName, 1) <> "J"
EXIT
ENDIF
lcMensagem = "Nome: " + CHR(9) + loItem.FirstName + CHR(13) + CHR(10) +;
"Sobrenome: " + CHR(9) + loItem.LastName + CHR(13) + CHR(10) +;
"Empresa: " + CHR(9) + loItem.CompanyName
MSGSVC(lcMensagem)
loItem = loItens.FindNext()
ENDDO
RELEASE ALL
RETURN
Conclusão
Esse artigo é o primeiro de uma série sobre OLE Automation e mais coisas interessantes estão por vir. Usando o Outlook para armazenar informações sobre Contatos, é possível economizar programas para entrada de dados e eliminar dados redundantes. No próximo artigo iremos dar uma olhada em mais 2 áreas do Microsoft Outlook: Tarefas e Calendário.
José Augusto Cavalcanti é sócio-diretor da Global Connection Consultoria em Informática Ltda. e Gerente de Informática de Daniel Advogados. É membro dos grupos FoxBrasil e Universal Thread e desenvolve usando o Visual Foxpro desde a versão 2.5 para DOS. Especializou-se em desenvolvimento utilizando "frameworks" e OLE Automation. Pode ser contatado pelos e-mails jose.cavalcanti@globalconnection.com.br e jose.cavalcanti@daniel-advogados.com.br.
topo
|
|
 |