Caso não nos resguardemos bem ao escrevermos as nossas aplicações com o MS Excel, podemos incorrer no erro, muito comum, de permitir que processos fiquem soltos e perdidos na memória RAM do nosso sistema operacional.
Ao construirmos aplicações que acessam e manipulam objetos e recursos de outro aplicativos, dependendo do nosso nível de conhecimento, podemos tornar tais automações tecnicamente complexas, pois às vezes envolverão diversas interfaces entre a aplicação cliente, e a aplicação servidor, além do próprio sistema operacional.
Já estamos bem acostumados a usar o MS Office como servidor de automações. E ele é excelente nisso, pois além de oferecer recursos avançados como editor de textos, planilha eletrônica, modelos gráficos, apresentações, etc... que complementam vários tipos de soluções, ainda consegue encapsular complexos aplicativos de automação, tornando os processos mais simples para nós, desenvolvedores. E um alívio e tanto para os usuários que não precisam dedicar centenas de horas no ano para processos repetitivos, que imploram por erros.
Uma vez que praticamente todos os recursos estejam disponíveis programaticamente não há simplesmente como comparar MS Office a outros pacotes concorrentes. Encontramos sim, um enorme abismo que o diferencia e distancia das demais suites. É nítido o que a programação lhe agrega, acrescentando-lhe ainda mais facilidade e valor.
Também não é por acaso, que de todos os softwares do pacote MS Office, o MS Excel seja o mais usado como servidor de automação, especialmente por ser um produto versátil (repositório de dados, motor de cálculos, gerador de gráficos, Dashboards e Scorecards, etc...), usado de ponta a ponta no mercado, em praticamente todos os modelos de negócio.
Cuidado...
A automação é fácil de ser implementada, mas, precisa receber especial atenção ao fato de que ao abrirmos um aplicativo, o mesmo deve ser fechado a posteriori. Neste artigo, que é aplicável em qualquer outro módulo da suite, usaremos o MS Excel:
ManualA automação funcionará de modo similar a quando um usuário aciona uma aplicação MS Excel, abre uma pasta de trabalho, escolhe uma planilha, e começa a ler e preencher as células. Com estes passos simples e muito comuns um processo do MS Excel é iniciado no Windows e, quando um usuário fecha-o, o processo é finalizado.
AutomatizadoNum cenário automatizado porém, é muito comum o aplicativo servidor ser executado nos bastidores, de modo invisível ao usuário que, na maioria das vezes, sequer imagina que o MS Excel (ou seja lá qual for o aplicativo) está sendo executado. Como o usuário não tem a janela do MS 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. Mas há um cenário ainda mais perturbador para o Cliente e conseqüentemente para o desenvolvedor: Deixar a pasta de trabalho do usuário bloqueada de forma que não consiga acessá-la nem abrindo o MS Excel manualmente, nem por outro processo de automação.
Este é um erro muito comum nos fóruns mundo a fora: "Minha planilha [neste caso] está travada, não consigo editar nada!". O usuário diz que fechou todos os programas (e de fato fechou), abriu seu arquivo do MS Excel e recebeu esta mensagem de erro.
Mas, quando solicitamos que ele abra o seu WTM (Windows Task Manager) indo para a guia processos, e classificando-a por nome, estes invariavelmente encontram listadas repetidas vezes o arquivo "EXCEL.EXE". Os processos são finalizados e, momentâneamente, o problema está resolvido.Mais tarde, porém, o problema volta a se repetir. Por quê? Algum aplicativo que usa o MS Excel como servidor de automação falha em fechá-lo 'completamente'. Geralmente ocorre algum erro em tempo de execução no código depois que a aplicação foi instanciada, deixando-a pendurada na memória.
Como evitar...
Antes que o cenário constrangedor descrito acima ocorra trazendo vitupério para todos os desenvolvedores da plataforma VBA, pois dirão: "O VBA não é estável!".
Recomendo uma das seguintes simples práticas, por prioridade:
a) DEIXE A APLICAÇÃO VISÍVEL: Se o objetivo da automação for preparar um arquivo exibindo o resultado final ao usuário, nada mais óbvio que torná-lo visível, certo? Mas, algumas vezes o desenvolvedor não faz isto: ele abre o MS 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 MS Excel.O recomendado é deixar a instância visível, fazendo isso logo no início do código. Deste modo, caso ocorra 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.ApplicationDim xlWkb As Excel.WorkbookOn Error GoTo ErrHandler"Instancia o ExcelSet xlApp = New Excel.Application"Deixa o Excel visível para o usuárioxlApp.Visible = True"Seu código aqui...ExitHere:Exit SubErrHandler:MsgBox Err.Description & vbCrLf & Err.Number & vbCrLf & Err.Source, vbCritical, "MySub"Resume ExitHere
End Sub
b) CONTROLE A APLICAÇÃO E FAÇA A FINALIZAÇÃO DO TRATAMENTO DO ERRO: Também é comum alguns colocarem um comando para finalizar o MS Excel (tal como Quit) no tratamento de erro. Porém, se o erro ocorrer por outro motivo que não a automação e o MS Excel não estiver instanciado no momento, este tratamento gerará outro erro: Object variable or With block variable not set. Para que esse erro não ocorra, o mais correto é, antes de fazer o Quit, verificar se o MS Excel foi instanciado:
Sub MySub2()
Dim xlApp As Excel.ApplicationDim xlWkb As Excel.WorkbookDim blnIsOpen As BooleanOn Error GoTo ErrHandler"Instancia o ExcelSet xlApp = New Excel.ApplicationblnIsOpen = True"Seu código aqui..."Finaliza a aplicaçãoxlApp.QuitblnIsOpen = FalseExitHere:Exit SubErrHandler:"Verifica se o Excel está instanciadoIf blnIsOpen = True ThenxlApp.QuitEnd IfMsgBox Err.Description & vbCrLf & Err.Number & vbCrLf & Err.Source, vbCritical, "MySub"Resume ExitHere
End Sub
Checando...
Com o código abaixo poderá testar se uma instância do MS Excel está aberta e caso esteja, poderá evocá-la:
Dim ExcelApplication As ObjectDim TimeoutTime As LongOn Error Resume NextSet ExcelApplication = GetObject(, "Excel.Application")On Error GoTo 0If ExcelApplication Is Nothing ThenShell "Excel.exe"Let TimeoutTime = Timer + 5On Error Resume NextDoDoEventsErr.ResetSet ExcelApplication = GetObject(, "Excel.Application")Loop Until Not ExcelApplication Is Nothing Or Timer > TimeoutTimeOn Error GoTo 0End IfIf ExcelApplication Is Nothing ThenMsgBox "Unable to launch Excel."Else' Do something with the Excel instance...End If
Inspired in:
Luiz Cláudio C Rocha
Tags: VBA, Office, automation, Excel, Clean, memory,automação, Advanced
Nenhum comentário:
Postar um comentário