1. Introdução
Hist) do E3 é como reagir quando a gravação falha — por exemplo, disparar um alarme se um registro não chegar ao banco de dados. A tentativa natural é olhar o valor de retorno do método WriteRecord(), esperando um código de sucesso ou de erro.O problema é que WriteRecord() não retorna um valor que indique sucesso ou falha na gravação: ele sempre devolve 0, independentemente do resultado. Portanto, não existe um código de status a ser verificado logo após a chamada.Este artigo explica por que isso acontece — o Histórico grava por meio de um buffer interno — e apresenta as estratégias recomendadas para detectar uma falha de gravação e acionar uma lógica de alarme.
2. Por que o WriteRecord() sempre retorna 0
O método WriteRecord() do objeto Histórico grava um registro imediatamente (mesmo quando o ScanTime é 0, ou seja, gravação apenas manual). O que ele faz, na prática, é enfileirar o registro no buffer interno do Histórico — não escrever diretamente na tabela do banco e aguardar a confirmação do SGBD.
Como a chamada apenas entrega o registro ao buffer, ela retorna antes de o banco confirmar a gravação. Por isso o retorno é sempre 0: no momento em que WriteRecord() devolve o controle ao script, o E3 ainda não sabe se o registro foi persistido no banco.
Consequência prática
Qualquer lógica de sucesso/falha que dependa do valor devolvido por WriteRecord() é inválida. A verificação precisa ser feita de forma indireta, conforme a seção 4.
3. Como o Histórico grava os dados (buffer interno)
O Histórico do E3 grava os dados através de um buffer interno. Quando WriteRecord() é chamado, o registro é enviado para esse buffer. Se o banco de dados estiver disponível, o registro é persistido em seguida. Caso o banco esteja indisponível no momento, o registro fica retido no buffer até a conexão ser restabelecida — e só então é gravado.
Esse buffer é materializado em arquivos temporários na pasta raiz do domínio, com as extensões .e3i e .e3o. Em condições normais (banco respondendo rápido), esses arquivos são criados e apagados quase imediatamente. Quando o banco está indisponível, eles persistem — e essa persistência é justamente o sinal observável de que a gravação não está sendo concluída.
4. Estratégias para detectar falha na gravação
Como não há retorno a verificar, a detecção precisa ser feita de forma indireta, confirmando se o registro chegou ao banco (ou se o buffer está acumulando). A seguir, três abordagens, da mais direta à mais robusta.
4.1. Consulta SELECT após o WriteRecord()
A verificação mais simples é fazer, logo após a gravação, uma consulta ao banco para confirmar se o registro foi realmente persistido. Se a consulta não trouxer o registro esperado, trata-se de um indício de falha.
4.2. Monitorar o RecordCount
Em vez de validar o conteúdo, compara-se o número total de registros antes e depois da gravação. Guarde a contagem atual, chame WriteRecord() e, após um curto intervalo, verifique se a contagem aumentou. Se o contador não subiu como deveria, há indício de falha.
' No clique do botão: guarda a contagem ANTES de gravar Sub Botao_Click() Dim RS Set RS = Parent.Item("Consulta1").GetADORecordset() Screen.Item("R1").Value = RS.RecordCount ' contagem antes Application.GetObject("Hist1").WriteRecord() ' grava o registro Screen.Item("TagContador1").Enabled = True ' dispara a verificação End Sub
' TagContador1: tag de tempo com Enabled = False e Preset = 2 s. ' Ao ser habilitado, dispara OnPreset após 2 s e faz a verificação. Sub TagContador1_OnPreset() Dim RS Set RS = Parent.Item("Consulta1").GetADORecordset() Parent.Item("R2").Value = RS.RecordCount ' contagem depois If Parent.Item("R2").Value > Parent.Item("R1").Value Then MsgBox "Registro inserido com sucesso" Else MsgBox "O registro não foi inserido" ' aqui é possível acionar o alarme End If Screen.Item("TagContador1").Enabled = False ' verifica apenas uma vez End Sub
4.3. Monitorar os arquivos de buffer (.e3i / .e3o)
A abordagem mais confiável para detectar indisponibilidade prolongada do banco é observar a presença dos arquivos de buffer (.e3i / .e3o) na pasta raiz do domínio. Como eles somem quase imediatamente quando o banco responde, a persistência deles ao longo de várias verificações seguidas indica que o banco está indisponível.
A ideia é executar o script periodicamente (por exemplo, a cada minuto, usando um TimerTag) e contar quantas vezes seguidas os arquivos aparecem. Se o contador atingir um limite X (por exemplo, 5 verificações = 5 minutos), dispara-se o alarme; assim que os arquivos somem, o contador é zerado.
Dim fso, pasta, arq, achouBuffer, caminhoDominio, contador caminhoDominio = "C:\MeuDominio\" ' AJUSTAR para o caminho real da pasta do domínio Set fso = CreateObject("Scripting.FileSystemObject") achouBuffer = False If fso.FolderExists(caminhoDominio) Then Set pasta = fso.GetFolder(caminhoDominio) For Each arq In pasta.Files If LCase(fso.GetExtensionName(arq.Name)) = "e3i" _ Or LCase(fso.GetExtensionName(arq.Name)) = "e3o" Then achouBuffer = True Exit For End If Next End If contador = Application.GetObject("Dados.ContadorBufferPersistente").Value If achouBuffer Then contador = contador + 1 Else contador = 0 ' zera assim que os arquivos somem (banco respondeu) End If Application.GetObject("Dados.ContadorBufferPersistente").Value = contador ' Se os arquivos persistirem por N checagens seguidas (ex.: 5 min, a cada 1 min), ' dispara o alarme: If contador >= 5 Then Application.GetObject("Dados.AlarmeGravacaoFalhou").Value = True Else Application.GetObject("Dados.AlarmeGravacaoFalhou").Value = False End If
5. Observações e boas práticas
- Não confie no retorno do
WriteRecord(). Ele é sempre0e não reflete o resultado da gravação no banco. Qualquer lógica de sucesso/falha baseada nesse retorno é inválida. - A ausência momentânea do buffer não garante sucesso permanente. Os arquivos
.e3i/.e3oexistem normalmente por instantes mesmo com o banco saudável; por isso a detecção por buffer deve contar ocorrências seguidas, não uma única presença. - Escolha a estratégia pela finalidade. Para confirmar um registro pontual (ex.: evento de batch), a consulta
SELECTou oRecordCountbastam. Para monitorar a saúde contínua da gravação (banco caindo por períodos), o monitoramento do buffer é o indicador mais robusto. - Dê um intervalo entre gravar e verificar. Como a persistência passa pelo buffer, uma verificação imediata pode ocorrer antes de o registro chegar ao banco. Um pequeno atraso (como o
Presetde 2 s do exemplo) reduz falsos negativos.
