Automação comercial com VB, VB.NET e C# - Parte II


Nesta Segunda Parte desta serie de quatro artigos vamos mostrar um pouco sobre o controle de erro no ECF e como fazer TEF de uma forma simples utilizando a DARUMA32.DLL.

 

Identificando os Níveis de ERRO

Existem dois níveis de erro que devem ser verificados em sua aplicação de automação comercial quando você estiver desenvolvendo para o ECF. O primeiro deles é o que a função da dll de comunicação com o ECF (que já analisamos no artigo anterior) devolve para seu aplicativo e outro é o que o ECF devolve de erro ou de aviso de um possível erro.

No primeiro nível é fácil o tratamento, pois todas as funções devolvem sempre um valor inteiro que deve ser tratado.

Vamos imaginar que você necessite identificar se o ECF está ligado ou não, neste caso basta chamar a função Daruma_FI_VerificaImpressoraLigada() que esta função irá devolver 0(zero) se estiver desligada e 1(um) se estiver ligada.

 

Em VB.NET

Private Sub ImpressoraOn_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

 ...

RET =  ECFVBNET.Daruma_FI_VerificaImpressoraLigada()

If( RET = 0 ) then

  MessageBox.Show(“  ECF DELIGADO”)

End If

 

End Sub

 

Em C#

private void Cupom_Click(object sender, System.EventArgs e)

{

   ...

  DARUMA32.RET = DARUMA32.Daruma_FI_VerificaImpressoraLigada();

  If ( DARUMA32.RET = 0)

      MessageBox.Show(“ECF Desligado”);

}

 

 

Vale acrescentar que a função daruma_fi_verificaimpressoraligada() deve estar declarado em um módulo genérico ou em um modulo de classe conforme vimos no artigo anterior.

Com o código acima em menos de 7 segundos você irá verificar se o ECF estiver ligado ou não, ou seja, a função verificaimpressoraliogada irá esperar que o ECF responda em 7 segundos, se não responder devolve ZERO para sua variável inteira.

 

Este exemplo acima ilustra bem o tratamento de um primeiro nível de erro. Porém o uso desta função acima não exige que você entre no segundo nível de tratamento de erro que ;e a decodificação do erro do ecf, isso porque na função acima ( que verifica se o ECF esta ligado ou não) a única necessidade que seu aplicativo tem é analisar se a função devolveu 0(ZERO) ou 1(UM) apenas isso. Porém nas outras funções de envio de comandos para o ECF existe a necessidade de além de decodificar o retorno da função, decodificar também o que o ECF retornou.

 

Vamos dar o exemplo com a função de fechamento rápido de cupom fiscal, a função Daruma_FI_FechaCupomResumido

 

Veja o código Abaixo em VB e C#

 

Em VB

Private Sub Cupom_Click()

Dim Daruma_RET as Integer

Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")

If( Daruma_RET<> 1) then

  Msgbox(“ Erro ao Enviar o Comando para o ECF”)

End If

End Sub

 

Em C#

private void Cupom_Click(object sender, System.EventArgs e)

{

   int DARUMA_RET=0;

   DARUMA_RET = DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");

   If( DARUMA_RET!=1)

      MessageBox.Show(“Erro ao Enviar o Comando para o ECF”)

  

}

 

Note que em ambos os casos houve a necessidade de decodificar o ERRO da função, ou seja, não foi necessário entrar na decodificação de ERRO do ECF porque a função já devolveu alguma coisa diferente de 1(um) onde 1(um) significaria que a função conseguiu enviar o comando para o ECF. A tabela de erro da função é uma Tabela Única para todas as funções da dll de comunicação com o ECF, onde 1(UM) significa OK, 0(Zero) Erro de Comunicação, -1(Menos um) parâmetro invalido, etc. Você poderá encontrar a tabela de erro no site www.daruma.com.br baixando o help interativo.

Agora que já sabemos decodificar o ERRO da função e qual seu objetivo, aqui vem uma armadilha.  A Função pode devolver 1(um)  - indicando que conseguiu enviar o comando para o ECF  - porem o ECF pode ter sinalizado um ERRO e seu aplicativo erroneamente identificou que a operação foi OK (porque a função devolveu 1) mas na verdade não foi, porque mesmo a função devolvendo 1(um) – indicando que a comunicação com o ECF foi OK -  o ECF pode sinalizar um Erro de por exemplo  “Cupom Fiscal Aberto” ou “Alíquota Inexistente” ou “Comando não Executado” e assim por diante.

Sendo assim além de tratar o Erro da Função você deverá chamar uma outra função da DARUAM32.DLL que irá te retornar se o ECF sinalizou erro ou não, veja o código abaixo.

 

Em VB

Private Sub Cupom_Click()

Dim Daruma_RET as Integer

Dim Daruma_ACK, Daruma_ST1, Daruma_ST2

Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")

If( Daruma_RET<> 1) then

  Msgbox(“ Erro ao Enviar o Comando para o ECF”)

End If

Daruma_ACK=0 : Daruma_ST1=0 : Daruma_ST2=0

Daruma_RET = Daruma_FI_RetornoImpressora(Daruma_ACK, Daruma_ST1, Daruma_ST2)

If (Daruma_ACK<>6)

  MsgBox(“Erro de Comunicação com o  ECF”)

End if

If (Daruma_ST1<>0) then

  Msgbox(“Erro no Status 1 do ECF”)

Endif

If (Daruma_ST2<>0) then

  MsgBox) (“Erro no Status 2 do ECF”)

End If

End Sub

 

Em C#

private void Cupom_Click(object sender, System.EventArgs e)

{

   int DARUMA_RET=0;

   int DARUMA_ACK, DARUMA_ST1, DARUMAS_ST2;

   DARUMA_ACK=DARUMA_ST1=DATUMA_ST2=0;

   DARUMA_RET = DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");

   If( DARUMA_RET!=1)

      MessageBox.Show(“Erro ao Enviar o Comando para o ECF”);

   DARUMA_RET = Daruma_FI_RetornoImpressora(ref ACK, ref ST1, ref ST2);

   If (Daruma_ACK!=6) MessageBox.Show(“Erro de comunicacao com o ECF”);

   If (Daruma_ST1!=0) MessageBox.Show(“Erro no Status 1 do ECF”);   

   If (Daruma_ST2!=0) MessageBox.Show(“Erro no Status 2 do ECF”);

}

 

Note então que através da DARUMA32.DLL existira a necessidade de ler mais dois Status importantes do ECF, o ST1 e o ST2, onde estarão contidos os erros do ECF, a tabela de erro você poderá encontrar no help interativo conforme figura abaixo:

 

 

Um Pequeno Truque da Decodificação de Erro!!

Na Dll Daruma32.dll existe a possibilidade de se fazer um atalho no tratamento de erro. Este atalho irá economizar algumas linhas de processamento que são seriam necessárias caso o ECF esteja OK, ou seja, sem sinalizar ERRO. De mais uma olhada no código fonte acima, que acabamos de digitar. Verifique que nele sempre estaremos chamando a Função Daruma_FI_RetornoImpressora, ou seja, mesmo que a função retorne 1(um) – indicando OK – e que o ECF não esteja sinalizando ERRO, estaremos assim mesmo chamando a função de RetornoImpressora e analisando os bytes de status 1 e status 2. Como evitar isso?

Bem, na DARUMA32.DL, existe a possibilidade de verificar o ERRO do ECF apenas se o mesmo sinalizar um Erro, sendo assim a função Daruma_FI_RetornoImpressora será chamada apenas quando o ST1 e ST2 forem diferentes de 0(ZERO). Mas a questão é... “Como saber se o ST1 e ST2 são diferentes de Zero se só posso saber disso após chamar a função Daruma_FI_RetornoImpressora?”

Aqui está o truque:”

Passo 1  - Abre o Registry – Botão Iniciar do Windows – Executar  - RegEdit.exe

Passo 2 – Chave HKEY_LOCAL_MACHINE\SOFTWARE\DARUMA\ECF  note que dentro da Pasta DARUMA\ECF terá uma chave chamada StatusFuncao coloque esta chave com o Valor 1(um) conforme figura abaixo:

 

Passo 2 – Feche o Registry e Reinicie.

 

Existe a possibilidade de se alterar as chaves do Registry da dll também por comandos da dll, sem a necessidade do Usuário ter de Abrir o Registry para configura o ECF, através da Função DARUMA_REGISTRY_STATUSFUNCAO (“1”)  você altera o valor da Chave para 1. Existe na dll uma função para cada chave do registry existente.

 

Com esta Chave StatusFuncao igual a 1(um) TODAS as funções da dll irão devolver -27 caso o ECF sinalize erro, assim você irá chamar a função Daruma_FI_RetornoImpressora somente e somente se a função devolver -27, caso contrario continue chamando os comados da dll sem se preocupar com a decodificação de Erro.

 

Veja agora como fica nossa decodificação de Erro após este truque.

Em VB

Private Sub Cupom_Click()

Dim Daruma_RET as Integer

Dim Daruma_ACK, Daruma_ST1, Daruma_ST2

Daruma_RET = Daruma_FI_FechaCupomResumido("Dinheiro", "Obrigado Volte Sempre!!")

If( Daruma_RET<> 1) then

   Msgbox(“ Erro ao Enviar o Comando para o ECF”)

End If

If(Daruma_RET <> -27)

 Daruma_ACK=0 : Daruma_ST1=0 : Daruma_ST2=0

 Daruma_RET = Daruma_FI_RetornoImpressora(Daruma_ACK, Daruma_ST1, Daruma_ST2)

 If (Daruma_ACK<>6)

  MsgBox(“Erro de Comunicação com o  ECF”)

 End if

 If (Daruma_ST1<>0) then

  Msgbox(“Erro no Status 1 do ECF”)

 Endif

 If (Daruma_ST2<>0) then

  MsgBox) (“Erro no Status 2 do ECF”)

 End If

End If

End Sub

 

Em C#

private void Cupom_Click(object sender, System.EventArgs e)

{

   int DARUMA_RET=0;

   int DARUMA_ACK, DARUMA_ST1, DARUMAS_ST2;

   DARUMA_ACK=DARUMA_ST1=DATUMA_ST2=0;

   DARUMA_RET = DARUMA32.Daruma_FI_FechaCupomResumido("Cheque","Espero que Funcione");

   If( DARUMA_RET!=1)

      MessageBox.Show(“Erro ao Enviar o Comando para o ECF”);

   If( DARUMA_RET !=-27)

{

   DARUMA_RET = Daruma_FI_RetornoImpressora(ref ACK, ref ST1, ref ST2);

   If (Daruma_ACK!=6) MessageBox.Show(“Erro de comunicacao com o ECF”);

   If (Daruma_ST1!=0) MessageBox.Show(“Erro no Status 1 do ECF”);   

   If (Daruma_ST2!=0) MessageBox.Show(“Erro no Status 2 do ECF”);

}

}

 

Observaram a diferença do Código? Ou seja apenas será chamada a função DARUMA_FI_RETORNOIMPRESSORA caso a função devolva -27 ; A função devolverá -27 apenas quando o ECF sinalizar erro, isso pode é perfeitamente possível porque a DLL ela é “Blockante” ou seja ao chamar qualquer função do ECF a DARUMA32.DLL envia o comando para o ECF bloqueando os processos existentes e aguardando a resposta do ECF, com isso ela consegue saber se o ECF sinalizou Erro ou não devolvento para seu aplicativo -27 quando o ECF sinaliza Erro.

 

Algoritmicamente a DLL se comporta assim:

Passo 1  - Envia o Comando para a DLL

Passo 2  - Fica em um Loop esperando a Resposta do ECF (ST1 e ST2) do comando enviado

Passo 3  - Analisa configuração da DLL, Status função é igual a 1?

Passo 3  - Se for igual a 1(um) e ST1 ou ST2 for diferente de 0(zero) então devolve -27, caso contrario devolve 1(um) porque a função teve sucesso em escrever e ler na serial da impressora.

 

Sendo assim a forma de como a dll foi construída permite a adoção de truques como o que acima mostramos que sem duvida economiza muito o tratamento de erro do ECF.

 

No próximo Artigo Explicarmos passo a passo um aplicativo com TEF e como efetuar operações  Credito com TEF e finalizaremos o quarto artigo deste curso com o Padrão XML para Automação Comercial.


Claudenir Andrade é formado pela Academia de Sistemas Informáticos de Madrid, trabalha com automação comercial há Nove Anos anos, foi responsável pela Homologação e aprovação de ECFs Brasileiros em Paises como Equador e Venezuela, gerencia a equipe de desenvolvimento da Daruma Automação, autor do primeiro livro de automação comercial no Brasil – “Automação Comercial com VB.Net e C#”. É MVP da Microsoft, Está criando e definindo o Modelo XML para Automação Comercial, escreve artigos para o site MSDN e pode ser contatado pelo e-mail – claudenir@daruma.com.br.