VBA - Artigo 017 - Gerando arquivo de log

Progredindo em VBA no Microsoft Excel

Gerando arquivo de log

Em sistemas computacionais, é comum a geração de arquivos com o registro do funcionamento do sistema, para que possam ser identificadas eventuais anomalias. É possível criarmos arquivos de log em planilhas do Excel, onde podemos gravar informações sobre erros no funcionamento do código (a fim de identificar as causas), data e hora de abertura e fechamento da planilha, quem abriu etc.

Conforme vimos no artigo anterior sobre arquivos sequenciais, podemos abrir arquivos para acrescentar linhas a um arquivo existente, com o parâmetro Append no comando Open. Assim podemos manter todos os registros pelo tempo que for necessário. Caso usássemos o comando Open com o parâmetro Output, seria gerado um arquivo novo a cada uso, o que não é o desejado.

Antes de mais nada, vamos ver alguns detalhes para ajudar na criação de uma sub-rotina que pode ser usada em qualquer planilha. Sabemos que o Excel identifica arquivos externos com um número. Se usarmos um número fixo no código, não poderemos reutilizar o código em planilhas que trabalham com arquivos externos, com o risco de misturar os registros gravados. Felizmente, o VBA tem a função FreeFile, que retorna o próximo número disponível. Se não houver arquivos abertos, ela retornará 1, se houver um aberto, retornará 2 e assim por diante.

Outra ideia é manter o arquivo de log junto ao próprio arquivo da planilha do Excel. Há o método ActiveWorkbook.Path que retorna o caminho do arquivo da planilha ativa. Podemos usar até o próprio nome da planilha como nome do arquivo de log, para ficar mais fácil de identificar.

Com estes detalhes, podemos montar um esboço da sub-rotina:

Sub Teste()

    Dim Diretorio As String
    Dim NomeArquivo As String
    Dim NumeroArquivo As Integer

    Diretorio = ActiveWorkbook.Path
    NomeArquivo = Diretorio & "\" & ActiveWorkbook.Name & ".log"
    NumeroArquivo = FreeFile

    Debug.Print "Diretório = " & Diretorio
    Debug.Print "Nome do arquivo = " & NomeArquivo
    Debug.Print "Número do arquivo = " & NumeroArquivo

End Sub

Com esse esboço você pode testar o funcionamento. Os métodos Debug.Print irão exibir os valores das variáveis após o término da sub-rotina. Não esqueça de testar com uma planilha já salva, porque vai precisar do diretório e nome de arquivo. Não se preocupe com o fato do arquivo terminar com duas extensões " .xlsm.log", pois o Windows só considera como extensão após o último ponto, neste caso ".log". Você pode até remover a extensão ".xlsm", mas para isso precisará de usar as funções de tratamento de strings, o que não vamos ver aqui para não alongar e nem desviar o foco do artigo.

Uma coisa que sempre é bom colocar no início do log é a data e hora do momento em que está sendo gravado. O VBA fornece a função Now, que fornece a data e hora do momento em que é chamada, ou seja, é perfeita para o que precisamos. Como função, podemos enviar o seu retorno para uma variável a fim de armazenar para o momento oportuno. Acrescente as linhas ao esboço e veja o resultado:

    Dim DataHora As String
    DataHora = Now
    Debug.Print "Data e hora = " & DataHora

É possível obter somente a data com DateValue(Now) e somente a hora com TimeValue(Now), mas no log é sempre bom termos os dois dados. Caso queira criar um log mais sofisticado, como por exemplo um arquivo de log diário, use essas funções.

Por fim, precisamos decidir a forma de como será enviado o conteúdo para ser gravado no log. A maneira mais simples é a sub-rotina receber uma variável do tipo string com o texto que será gravado. Vejamos como fica o código:

Sub GravarLog(Mensagem As String)

    Dim Diretorio As String
    Dim NomeArquivo As String
    Dim NumeroArquivo As Integer
    Dim DataHora As String

    Diretorio = ActiveWorkbook.Path
    NomeArquivo = Diretorio & "\" & ActiveWorkbook.Name & ".log"
    NumeroArquivo = FreeFile
    DataHora = Now

    Open NomeArquivo For Append As #NumeroArquivo
   
    Print #NumeroArquivo, DataHora & " - " & Mensagem
   
    Close #NumeroArquivo

End Sub

Primeiramente, observe que a variável NumeroArquivo vem acompanhada do símbolo # nos comandos Open, Print e Close. Se não estiver com o # aparece uma mensagem de erro.

Essa sub-rotina GravarLog irá gravar um registro com a data e hora acompanhada do conteúdo da variável Mensagem recebida. Teste o funcionamento com o código abaixo:

Sub Teste()

    GravarLog "Testando a gravação do log"

End Sub

Execute o teste quantas vezes achar necessário e depois abra o arquivo gerado para ver o conteúdo. Para cada vez que foi executado o teste haverá uma linha com a mensagem informada, cada uma com seu respectivo horário.

Com essa rotina GravarLog simples já dá para fazer coisas bacanas, como gravar o horário que a planilha foi aberta e fechada, além do nome do usuário. Para isso é preciso editar os eventos Open e BeforeClose da pasta de trabalho:

Private Sub Workbook_Open()

    GravarLog "Planilha aberta por " & Environ("USERNAME")

End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)

    GravarLog "Planilha fechada por " & Environ("USERNAME")

End Sub

Perceba que este código deverá ser gravado na pasta de trabalho, não em um módulo ou planilha. Caso contrário não irá funcionar da maneira esperada. Salve sua planilha e feche. O arquivo de log já deverá ter uma linha referente ao fechamento da planilha. Abra a planilha novamente e confira que gerou uma linha referente à abertura dela.

Essa sub-rotina GravarLog é bem simples, basta mandar um texto que ela vai registrar no arquivo. Porém, há ocasiões em que é necessário gravar várias linhas, como por exemplo para registrar um erro que aconteceu. Ainda é possível chamar a rotina várias vezes e registrar as linhas necessárias. Entretanto, o arquivo será aberto e fechado várias vezes durante o processo, causando uma perda de desempenho e sobrecarregando o disco com sucessivas aberturas e fechamentos. Neste caso, podemos alterar a rotina de três maneiras distintas:

- Usando parâmetros opcionais: neste caso será preciso criar estruturas de verificação para checar se os parâmetros adicionais foram enviados para criar as linhas adicionais;

- Usando um objeto do tipo type como parâmetro: neste caso as estruturas de verificação devem checar quais informações foram preenchidas e então gerar as linhas de acordo com  o que for recebido;

- Criar uma classe para a geração de log: este é o método mais sofisticado e que demandará mais habilidade do desenvolvedor, mas uma classe bem feita pode ser exportada e utilizada por virtualmente qualquer planilha.

Você pode exercitar suas habilidades em VBA criando versões diferentes para quaisquer uma das três possibilidades acima. Veja qual atende melhor as suas necessidades para o momento. Use em conjunto com On Error para registrar os erros não tratados no código para facilitar a averiguação de erros e assim poder solucioná-los de forma mais rápida.

Espero que este artigo seja de grande utilidade e que você comece a gerar arquivos de log pelo menos para registrar erros ainda não tratados. O registro dos erros é a melhor forma de descobrir o que deu errado e é o ponto de partida para identificar a causa e buscar a solução.

Quaisquer dúvidas, comentários ou sugestões, use a seção de comentários abaixo. Até o próximo artigo.


Pedro Martins

Formado em Tecnologia em Eletrônica Digital, já trabalhou como artefinalista, eletrotécnico, programador de CLP (para máquinas industriais) e analista de sistemas em sistema bancário, programando em COBOL.
Mexe com computadores e programação desde a segunda metade dos anos 1980, quando teve um MSX e aprendeu a programar em BASIC. É a favor da disseminação do conhecimento.






Catálogo de aulas (NOVIDADE)

Criei um catálogo de aulas para ajudar você em seus estudos. Acesse clicando na imagem abaixo ou clique aqui.


Postagem Anterior Próxima Postagem