Automação de escritório usando visual C++

Resumo

Este artigo responde a questões comuns relativas à Automação ao Microsoft Office a partir do Visual C++.

Mais Informações

Tabela de Conteúdos

  1. O que é Automação?

  2. Sou novo na Automação, onde posso encontrar bons recursos para aprender mais?

  3. Há maneiras diferentes de usar a Automação?

  4. O que é COM?

  5. Como me adindo à instância de execução de um pedido de escritório?

  6. Como passo parâmetros opcionais?

  7. Como apanho eventos expostos pelas candidaturas do Office?

  8. O meu código de automação é demasiado lento. Como posso acelerar as coisas?

  9. O que significam estes enormes valores de erro, como -2147352573 ou 0x80030002?

  10. O que é uma biblioteca tipo?

  11. O meu código de automação funcionou com o Microsoft Excel 95, mas falha com o Microsoft Excel 97. Porquê?

  12. Porque é que a aplicação que estou a automatizar fica na memória depois do meu programa estar terminado?

  13. Sei o que quero fazer como utilizador de aplicações do Microsoft Office, mas como faço isto programáticamente usando a Automação?

  14. Posso automatizar uma aplicação incorporada do Microsoft Office?

  15. Como acesso as propriedades do meu documento num documento do Microsoft Office?

Perguntas e Respostas

  1. O que é Automação? A Automatização (antiga OLE Automation) é uma tecnologia que lhe permite tirar partido da funcionalidade de um programa existente e incorporá-la nas suas próprias aplicações. Por exemplo, pode utilizar as capacidades de ortografia e verificação de gramática do Microsoft Word na sua aplicação sem que o Microsoft Word seja visível para os seus utilizadores. Pode até utilizar todas as ferramentas de gráfico, impressão e análise de dados do Microsoft Excel. Esta tecnologia pode simplificar e acelerar muito o seu desenvolvimento.

  2. Sou novo na Automação, onde posso encontrar bons recursos para aprender mais? O capítulo 24 de "Inside Visual C+++" (ISBN:1-57231-565-2) fornece uma visão geral, bem como alguns grandes exemplos. Além disso, a Base de Conhecimento da Microsoft é uma boa fonte de informação. Este artigo em si é um bom começo, e você pode encontrar referências mais específicas no seguinte artigo na Base de Conhecimento da Microsoft:

    152023 Localização de Recursos para Estudar Automação OLE Se preferir aprender por exemplo, consulte o seguinte artigo na Base de Conhecimento da Microsoft:

    179706 HOWTO Use MFC para automatizar Excel & criar/formar um novo livro

  3. Há maneiras diferentes de usar a Automação? Existem três formas básicas de utilizar a Automatização: MFC, #import e C/C++:

    • Com o MFC, utilize o Visual C++ ClassWizard para gerar "aulas de invólucro" a partir das bibliotecas do tipo Microsoft Office. Estas aulas, bem como outras classes de MFC, tais como COleVariant, COleSafeArray, COleException, simplificam as tarefas da Automação. Este método é geralmente recomendado sobre os outros, e a maioria dos exemplos da Base de Conhecimento da Microsoft usam MFC.

    • #import, uma nova diretiva que ficou disponível com o Visual C++ 5.0, cria "ponteiros inteligentes" VC++ a partir de uma biblioteca de tipo especificado. É muito potente, mas muitas vezes não recomendado devido a problemas de contagem de referência que normalmente ocorrem quando usados com as aplicações do Microsoft Office.

    • C/C++ A automatização é muito mais difícil, mas por vezes necessária para evitar sobrecargas com MFC, ou problemas com #import. Basicamente, você trabalha com APIs como CoCreateInstance() e interfaces COM como IDispatch e IUnknown.

    É importante notar que existem algumas ligeiras diferenças entre a Automação de C++ em comparação com o C simples, porque a COM foi desenhada em torno da classe C++. Para mais informações, consulte o seguinte artigo na Base de Conhecimento da Microsoft para obter um exemplo C:

    181473 HOWTO: Utilize a automatização OLE a partir de uma aplicação C

  4. O que é COM? A automatização baseia-se no Modelo de Objetos Componentes (COM). A COM é uma arquitetura de software padrão baseada em interfaces, e projetada para ter código separado em objetos autossuficientes. Pense nisso como uma extensão do paradigma de Programação Orientada para o Objeto (OOP), mas aplicável a aplicações separadas. Cada objeto expõe um conjunto de interfaces, e toda a comunicação a um objeto, como inicialização, notificações e transferência de dados, acontece através destas interfaces. A COM é também um conjunto de serviços prestados por bibliotecas de ligações dinâmicas (DLLs) instaladas com o sistema operativo. A automação utiliza muitos desses serviços. Um exemplo é o serviço "Marshalling", que embala as chamadas da aplicação do cliente para as funções dos membros das interfaces da aplicação do servidor e passa-as, com os seus argumentos, para a aplicação do servidor. Faz parecer que as interfaces do servidor estão expostas no espaço de memória do cliente, o que não acontece quando o cliente é um .exe a funcionar no seu próprio espaço de processo. A Marshalling também obtém os valores de devolução dos métodos do servidor de volta através dos limites do processo e com segurança nas mãos da chamada do cliente. Existem muitos outros serviços essenciais à Automação que são fornecidos pelas várias bibliotecas DA. As fontes de informação sobre estas incluem "Inside Ole - Second Edition", de Kraig Brockschmidt, ISBN 1-55615-843-2, "Inside COM" de Dale Rogerson - ISBN 1-57231-349-8, e "Referência do Programador de Automação", ISBN 1-57231-584-9.

  5. Como me adindo à instância de execução de um pedido de escritório? Utilize a API GetActiveObject() Os servidores de automação registam-se na ROT (Tabela de Objetos em Execução), através da API RegisterActiveObject(). Os clientes de automação podem chegar à fase de execução com códigos como:

          // Translate server ProgID into a CLSID. ClsidFromProgID      // gets this information from the registry.      CLSID clsid;      CLSIDFromProgID(L"Excel.Application", &clsid);        // Get an interface to the running instance, if any..      IUnknown *pUnk;      HRESULT hr = GetActiveObject(clsid, NULL, (IUnknown**)&pUnk);      ASSERT(!FAILED(hr));      // Get IDispatch interface for Automation...      IDispatch *pDisp;      hr = pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);      ASSERT(!FAILED(hr));      // Release the no-longer-needed IUnknown...      pUnk->Release();

    NOTA:Se houver várias instâncias a executar a aplicação do Office que pretende anexar, só poderá anexar-se à primeira instância que foi lançada utilizando a API GetActiveObject(). Teoricamente, pode iterar o ROT para cada instância individual, mas as aplicações do Office não se registam se outro caso já estiver no ROT porque o apelido por si só é sempre o mesmo (não poderia ser distinguido de qualquer maneira). Isto significa que não se pode ligar a nenhum caso, exceto o primeiro. No entanto, uma vez que as aplicações do Office também registam os seus documentos no ROT, pode anexar-se com sucesso a outras instâncias, iterando o ROT à procura de um documento específico, anexando-o e, em seguida, obter o objeto de Aplicação do mesmo. Existe algum código no seguinte artigo da Base do Conhecimento do Microsoft para iterar o ROT e procurar um nome de documento:

    190985 HOWTO: Obtenha iDispatch de um Excel ou documento de palavra de um OCX Não precisará de fazer isto para o PowerPoint, porque é uma aplicação de um único exemplo; só pode ter um exemplo a funcionar.

  6. Como passo parâmetros opcionais? Alguns métodos têm parâmetros "opcionais". No Visual Basic, pode omiti-los casualmente ao chamar o método. No entanto, ao ligar para o Visual C++ tem de passar por uma VARIANTE especial cujo campo .vt é VT_ERROR, e o campo .scode é DISP_E_PARAMNOTFOUND. Isso é:

          // VARIANT used in place of optional-parameters.      VARIANT varOpt;      varOpt.vt = VT_ERROR;      varOpt.scode = DISP_E_PARAMNOTFOUND;

    Isto é realmente o que o Visual Basic está a fazer nos bastidores.

  7. Como apanho eventos expostos pelas candidaturas do Office? Basicamente implementa a interface de evento que pretende capturar (a "pia"), e configura uma ligação consultiva com a aplicação (a "fonte"). O seguinte artigo dá-lhe exemplos passo a passo para o Microsoft Word:

    183599 HOWTO: Apanhe eventos de aplicação do Microsoft Word97 utilizando o VC++ Em geral, para configurar a ligação de aviso, obtém o IConnectionPointContainer do servidor e ligue para FindConnectionPoint() com o IID da interface do evento. Isto dá-lhe uma interface IConnectionPoint e tudo o que resta é ligar para o Advise() com uma instância da interface do evento. O servidor ligará de volta através desta interface quando estes eventos ocorrerem.

  8. O meu código de automação é demasiado lento. Como posso acelerar as coisas? Uma causa comum de problemas de velocidade com a Automação é com leitura repetitiva e escrita de dados. Isto é típico para clientes Excel Automation. No entanto, a maioria das pessoas não sabe que estes dados podem geralmente ser escritos ou lidos de uma só vez usando SAFEARRAY. Consulte os seguintes artigos da Base de Conhecimento da Microsoft para obter mais informações e exemplos informativos:

    186120 HOWTO: Use MFC para automatizar excel e encher um alcance com uma matriz

    186122 HOWTO: Use MFC para automatizar o Excel & Obter uma Matriz de uma Gama

    179706 HOWTO: Utilize o MFC para automatizar o Excel e criar/criar/formar um novo livro Além disso, é importante salientar que a utilização da prancheta pode, por vezes, melhorar o desempenho. Por exemplo, pode copiar os seus dados para a área de transferência e, em seguida, utilizar a automatização para dizer ao servidor para colar. Ou vice-versa; diga ao servidor para copiar para a prancheta e colar na sua aplicação.

  9. O que significam estes enormes valores de erro, como -2147352573, ou 0x80030002? Estes valores são conhecidos como HRESULTs e são definidos em winerror.h. Os números são tão grandes porque a primeira parte representa se é ou não um resultado de erro. Pode utilizar o utilitário ErrLook.Exe que vem com o Visual C++ para traduzir estes números em descrições significativas. Se pretender obter uma descrição programática dos erros, pode utilizar a API FormatMessage() API. Consulte os seguintes artigos da Base de Conhecimento do Microsoft para obter mais informações e exemplos sobre a utilização do FormatMessage():

    186063 INFO: Tradução de erros de automatização para VB/VBA

    122957 AMOSTRA: Descodificar32 e Descodificar as ferramentas de descodificador de código de erro OLENOTA:Se estiver a utilizar o Visual C++ 6.0 e tiver uma variável que contenha este valor na janela do relógio depurado, apendam-se " hr" (sem as cotações) para que o Visual C++ o traduza para si!

  10. O que é uma biblioteca tipo? Uma biblioteca tipo é semelhante a um ficheiro de cabeçalho C/C++. Contém as interfaces, métodos e propriedades que um servidor está a publicar. Pode ver a biblioteca tipo com o Visualizador de Objetos OLE/COM (Oleview.exe) que vem com C++. Aqui está uma lista dos nomes de ficheiros da biblioteca do tipo para o Microsoft Office 95, 97 e 2000: Office Application | Type library ------------------------+---------------- Word 95 and prior | wb70en32.tlb Excel 95 and prior | xl5en32.olb Powerpoint 95 and prior | Powerpoint.tlb Access 95 and prior | msaccess.tlb Binder 95 | binder.tlb Schedule+ | sp7en32.olb Project | pj4en32.olb Team Manager | mstmgr1.olb Word 97 | msword8.olb Excel 97 | excel8.olb Powerpoint 97 | msppt8.olb Access 97 | msacc8.olb Binder 97 | msbdr8.olb Graph 97 | graph8.olb Outlook 97 | msoutl8.olb Outlook 98 | msoutl85.olb Word 2000 | msword9.olb Excel 2000 | excel9.olb Powerpoint 2000 | msppt9.olb Access 2000 | msacc9.olb Outlook 2000 | msoutl9.olb Word 2002 | msword.olb Excel 2002 | excel.exe Powerpoint 2002 | msppt.olb Access 2002 | msacc.olb Outlook 2002 | msoutl.olb

  1. O meu código de automação funcionou com o Excel 95, mas falha com o Excel 97. O que está a acontecer? O modelo de objeto para Excel fez uma alteração significativa da versão 95 para 97. O Excel 95 implementou todos os seus métodos e propriedades numa única implementação do IDispatch. Isto significava que muitas vezes se podia chamar métodos destinados ao objeto X, do objeto Y. Este não foi um bom design, por isso, no Office 97, cada objeto tem a sua própria implementação de Idispatch separada. Isto significa que se você pedir um método ou propriedade do objeto X de um objeto separado Y, você obtém o erro 0x80020003, -2147352573, "Membro não encontrado." Para evitar este erro, tem de se certificar de que a interface IDispatch subjacente a que está a fazer chamadas é a que está a corrigir semânticamente. Consulte os seguintes artigos da Microsoft Knowledge Base para obter mais informações:

    172108 HOWTO: Resolução de problemas "Membro não encontrado", 0x80020003 Erro

  2. A aplicação que estou a automatizar fica na memória depois do meu programa estar terminado. O que está a acontecer? O mais provável é que se tenha esquecido de lançar uma interface adquirida e terá de a localizar. Aqui estão algumas sugestões gerais, e coisas a procurar:

    • Se estiver a usar #import, é muito provável que esteja a encontrar um dos bugs de contagem de referências associados a ele. Muitas vezes os bugs podem ser trabalhados, mas normalmente é preferível usar um dos outros métodos de Automação. #import não funciona muito bem com as aplicações do Office, porque as suas bibliotecas tipo e utilização são bastante complexas. Além disso, tais problemas de contagem de referência são difíceis de localizar porque muitas das chamadas COM de nível de interface estão nos bastidores quando se usa #import.

    • Verifique se está a ligar para algum método, como Open, ou New, que devolva um IDispatch * (LPDISPATCH), e ignorando o valor de retorno. Se estiver, estará a abandonar esta interface devolvida e terá de alterar o seu código para que o divulgue quando já não for necessário.

    • Comente gradualmente secções do seu código até que o problema desapareça, em seguida, adicione-o de volta criteriosamente para rastrear onde o problema começa.

    • Note que algumas aplicações permanecerão em execução se o utilizador tiver "tocado" a aplicação. Se isto ocorrer durante a automatização, então a aplicação provavelmente permanecerá em execução depois. As aplicações do Office têm uma propriedade "UserControl" no objeto aplicação que pode ler/escrever para alterar este comportamento.

    • Além disso, algumas aplicações decidirão permanecer em execução se ocorrerem "ação" de interface de utilizador suficiente. Se pretender que a aplicação saia, ligue para o método Quit() no objeto 'Aplicação'. A palavra irá desligar independentemente da sua contagem de referência quando Quit for chamado. Isto não é um comportamento de COM esperado. O Excel, no entanto, irá simplesmente esconder-se, mas permanecerá em execução até que todas as interfaces excecionais sejam lançadas. Em geral, deverá divulgar todas as referências pendentes, e ligue apenas para Quit() se pretender que o pedido de demissão.

  3. Sei o que quero fazer como utilizador de aplicações do Office, mas como faço isto programáticamente através da Automação? O que lhe interessa é que objetos, métodos e propriedades precisa de usar. A melhor forma de aprender a navegar nos modelos de objetos do Word, Excel e Powerpoint, com base no que pretende fazer como utilizador, é utilizar o Macro Recorder. Basta escolher Macro\'Record New Macro' no menu Ferramentas, executar a tarefa que lhe interessa e, em seguida, escolher Macro\'Stop Recording.' Assim que terminar a gravação, escolha Macro\Macros no menu Ferramentas, selecione a macro gravada e, em seguida, clique em Editar. Isto irá levá-lo ao código VBA gerado que irá realizar a tarefa que gravou. Tenha em mente que a macro gravada não será o melhor código possível na maioria dos casos, mas faz muito bem para um exemplo rápido.

  4. Posso automatizar um pedido de escritório incorporado? Sem dúvida. O truque é obter o ponteiro IDispatch: este é dado na Nota Técnica Visual C++ 39 (TN039). Consulte o seguinte artigo da Microsoft Knowledge Base para um exemplo passo a passo:

    184663 HOWTO: Incorporar e automatizar uma folha de cálculo do Microsoft Excel com mFC

  5. Como acesso as propriedades do meu documento num documento do Office? As propriedades do documento são acessíveis através da Automação, ou diretamente através do IPropertyStorage. Os seguintes artigos da Microsoft Knowledge Base demonstram cada método:

    179494 HOWTO: Utilize a automatização para recuperar propriedades de documentos incorporados

    186898 COMO: Ler propriedades de documento composto diretamente com VC++

Precisa de mais ajuda?

Aumente os seus conhecimentos
Explore as formações
Seja o primeiro a obter novas funcionalidades
Aderir ao Microsoft insiders

As informações foram úteis?

Obrigado pelos seus comentários!

×