Desenvolvimento - Office

Como evitar processos pendurados na automação do Excel

Este artigo mostra como evitar o erro (comum) de deixar processos pendurados no Windows quando se faz automação do Excel.

por Luiz Cláudio Cosenza V. Rocha



Em linhas gerais, a automação é o mecanismo que permite um aplicativo (chamado cliente) acessar e manipular objetos e recursos de outro aplicativo (chamado servidor). Via de regra, a automação é algo tecnicamente complexo nos bastidores, pois pode envolver diversas interfaces entre cliente, servidor e sistema operacional.

O Office é um dos mais importantes (se não o mais importante) servidores de automação, pois além de oferecer recursos avançados (editor de textos, planilha eletrônica/gráficos, apresentações, etc.) que complementam vários tipos de soluções, conseguiu encapsular a complexidade da automação tornando-a bastante simples ao desenvolvedor. Se compararmos o MS-Office a outros pacotes concorrentes, a facilidade na programação agrega mais valor ainda ao MS-Office, já que praticamente todos seus recursos estão disponíveis programaticamente.

De todas as ferramentas do pacote Office, o Excel é a mais usada como servidor de automação, especialmente por ser um produto muito versátil (troca de dados, cálculos, gráficos, relatórios, etc.) e usado no mercado em praticamente todos os ramos de atividade.

Abrir e fechar o aplicativo servidor

Embora a automação do Office seja fácil de se implementar, o desenvolvedor necessita de uma atenção especial: ao abrir um aplicativo, deve cuidar de fechá-lo.

De certa forma, a automação funciona como se um usuário abrisse e manipulasse o aplicativo servidor. Se pegarmos o Excel como exemplo, a automação funciona de maneira semelhante a um usuário que aciona a aplicação Excel, abre uma pasta de trabalho, escolhe uma planilha, lê e preenche células. Assim, um processo do Excel é iniciado no Windows e, quando o usuário fecha o Excel, o processo é finalizado.

Nos cenários de automação, porém, é muito comum o aplicativo servidor ser executado nos bastidores, de forma invisível ao usuário que, na maioria das vezes, nem sabe que o Excel (ou seja lá qual aplicativo for) está sendo executado. Se o usuário não tem a janela do Excel ativa para poder fechar, quem deve fazer isto é a própria aplicação que o abriu, caso contrário o processo ficará pendurado no Windows. Além de consumir memória, isto pode ter um efeito mais nocivo: deixar a pasta de trabalho do usuário bloqueada de forma que ele não consiga acessá-la nem abrindo o Excel manualmente, nem por outro processo de automação.

Este erro é bastante comum nos fóruns de discussão: “[meu arquivo] está bloqueado para edição”. O usuário diz que fechou todos os programas (e de fato fechou), abriu seu arquivo do Excel e recebeu esta mensagem de erro.

Ao abrirmos o Windows Task Manager na guia processos e classificarmos por nome da imagem, encontramos repetidas vezes o “EXCEL.EXE”. Finalizamos os processos e, momentaneamente, o problema está resolvido. Mais tarde, porém, o problema volta a se repetir. Motivo: algum aplicativo que usa o Excel como servidor de automação está falhando em fechá-lo. Geralmente ocorre algum erro em tempo de execução no código depois que a aplicação foi instanciada, deixando-a pendurada.

Como evitar o processo pendurado

Para evitar este cenário descrito acima, recomendo uma destas duas práticas, por ordem de prioridade:

a) Trazer a aplicação Excel para a tela do usuário: se o objetivo da rotina de automação for preparar um arquivo e exibir o resultado final ao usuário, nada mais óbvio que torná-lo visível, certo? Porém, muitas vezes o desenvolvedor não faz isto: ele abre o Excel, executa as rotinas de preenchimento, salva, fecha e, por fim, executa o comando Shell para abrir o arquivo em uma nova instância do Excel.

O que recomendo, nestes casos, é deixar visível a própria instância usada no preenchimento, e fazer isto logo no início do código. Desta forma, se ocorrer algum erro durante a execução do código, o processo não ficará perdido no Windows, pois o usuário terá domínio da janela.

Sub MySub1()

Dim xlApp As Excel.Application

Dim xlWkb As Excel.Workbook

On Error GoTo ErrHandler

"Instancia o Excel

Set xlApp = New Excel.Application

"Deixa o Excel visível para o usuário

xlApp.Visible = True

"Seu código aqui...

ExitHere:

Exit Sub

ErrHandler:

MsgBox Err.Description & vbCrLf & Err.Number & vbCrLf & Err.Source, vbCritical, "MySub"

Resume ExitHere

End Sub

b) Controlar se a aplicação está instanciada e fazer a finalização no tratamento de erro: é comum alguns desenvolvedores colocarem um comando para finalizar (Quit) o Excel no tratamento de erro. Porém, se o erro ocorrer por outro motivo que não a automação e o Excel não tiver instanciado no momento, este tratamento vai gerar outro erro (“Object variable or With block variable not set”):

 

Para que não ocorra este erro, o mais correto é, antes de fazer o Quit, verificar se o Excel foi instanciado:

Sub MySub2()

Dim xlApp As Excel.Application

Dim xlWkb As Excel.Workbook

Dim blnIsOpen As Boolean

On Error GoTo ErrHandler

"Instancia o Excel

Set xlApp = New Excel.Application

blnIsOpen = True

"Seu código aqui...

"Finaliza a aplicação

xlApp.Quit

blnIsOpen = False

ExitHere:

Exit Sub

ErrHandler:

"Verifica se o Excel está instanciado

If blnIsOpen = True Then

    xlApp.Quit

End If

MsgBox Err.Description & vbCrLf & Err.Number & vbCrLf & Err.Source, vbCritical, "MySub"

Resume ExitHere

End Sub

 

Conclusão

Estas duas técnicas são bastante simples, mas ajudam a evitar problemas muito comuns e recorrentes quando fazemos automação de aplicativos, especialmente do Excel. Podem ser usadas a partir de qualquer linguagem, seja VBA (como nos exemplos acima), seja VB6, VB.Net, C# ou outra linguagem.

Luiz Cláudio Cosenza V. Rocha

Luiz Cláudio Cosenza V. Rocha - Diretor da IT Lab Consultoria (www.itlab.com.br), em São Paulo, especializada em desenvolvimento customizado, .NET, Office (VBA/VSTO), SharePoint e ALM. Nomeado pela Microsft como MVP de Office System desde 2003, tem dezenas de artigos publicados, material de treinamento, participa diariamente dos fóruns MSDN e escreve o blog OfficeDev (http://msmvps.com/blogs/officedev/).