Jump to content

dev botao

Programa fecha esporadicamente ao utilizar a dll ACBrNFe32.dll


lcarakaki
Go to solution Solved by Rafael Dias,
  • Este tópico foi criado há 1384 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Bom dia a todos!

Estou migrando minha emissão de NFe do AcbrMonitorPlus para AcbrNfeLib, tudo está funcionando perfeitamente com a LIB, o único problema que tenho atualmente é do programa fechar esporadicamente.

As vezes fecha logo na primeira emissão de nfe, as vezes fecha na segunda ou terceira NFe.

Meu programa é em xHarbour, e optei em carregar a DLL sempre quando vou utiliza-la e em seguida descarrego, mas já tentei carregar ela na abertura do programa e descarregar no fechamento do programa, assim como os métodos NFE_Inicializar e NFE_Finalizar, também tentei trocar DllLoad() por LoadLibrary(), LibLoad() e DllPrepareCall(), e a DllUnLoad() por LibFree() e FreeLibrary().
Tentei utilizar a dll Cdecl e também a StdCall.

Já fiz todas as combinações possíveis.

Creio que essa ajuda é para xHarbour e não para a lib, pois no log da lib todos os métodos são executados.
Agradeço a todos desde já.

 

FUNCTION ACBR_CRIA_ASSINA_VALIDA_ENVIA(xTxt,xChaveNfe)
	LOCAL nRetMet,cRet,xLocalXml,xXml,lAssinaValidaEnvia:=.T.
	LOCAL xPara,xCopias,xAssunto,xMensagem
	LOCAL pDllNfe:=DllLoad("ACBrNFe32.dll")
	
	** Nome do XML e local de onde será salvo
	xXml:=xChaveNfe+"-nfe.xml"
	xLocalXml:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\XML\"
	xPdf:=xChaveNfe+"-nfe.pdf"
	xLocalPdf:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	cRet:=space(1024)
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Consultar",xChaveNfe,.T.,cRet)	//Retorno 0
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	
	if at("Autorizado o uso da NF-e",cRet)>0
		lAssinaValidaEnvia:=.F.
		
		** Pega a data correta em que a Nfe foi emitida
		q:="select concat(year(b09demi),lpad(month(b09demi),2,'0')) as pasta from nfec where chavenfe='"+xChaveNfe+"'"
		v:=F_GETCON(q)
		xPastaAno:=v[1,1]
		xLocalXml:=xLocalXml+xPastaAno+"\"
		xLocalPdf:=xLocalPdf+xPastaAno+"\"
	else
		xLocalXml:=xLocalXml+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
		xLocalPdf:=xLocalPdf+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
	endif
	
	if lAssinaValidaEnvia
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_CarregarINI",xTxt) //Retorno 0
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Assinar") //Retorno 0
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Validar") //Retorno 0
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_GravarXml",0,xXml,xLocalXml) //Retorno 0
		cRet:=space(1024)
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_Enviar",0,.T.,.T.,.F.,cRet) //Retorno 0
	else
		** Se o XML já está autorizado apenas o carrga
		** Para poder imprimir e enviar por e-mail
		nRetMet:=DLLCALL(pDllNfe,32,"NFE_CarregarXML",xLocalXml+xXml,"") //Retorno 0
	endif

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_ImprimirPDF") //Retorno 0
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_EnviarEmail",xPara,xLocalXml+xXml,.T.,xAssunto,xCopias,,xMensagem) //Retorno 0
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	DllUnload(pDllNfe)
	
	RETURN .T.

 

 

 

Link to comment
Share on other sites

@Rafael Dias, eu sempre consulto a chave antes de emitir a nfe, reparei que no log, a consulta da segunda Nfe emitida retorna SetRetorno(-10, 
Access violation), os métodos de validar, assinar, enviar que são chamados em seguida retorna 0, mas ao finalizar a lib o programa se fecha.

 

Seria a segunda NFE nesta estrutura que dá o erro:

	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Inicializar",pUnidadeUf+"_NFE.INI","") //Retorno 0
	cRet:=space(1024)
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Consultar",xChaveNfe,.T.,cRet)	//Retorno 0 //Na segunda NFE retorna -10 Access violation
	nRetMet:=DLLCALL(pDllNfe,32,"NFE_Finalizar",pUnidadeUf+"_NFE.INI","") //Retorno 0

 

 

Log: ACBrLibNFE-20201221.log

Link to comment
Share on other sites

Sua chamada do NFE_Consultar esta errada, olhe a classe xHarbour que tem no svn lá os métodos estão implementados de forma correta.

bufferLen := 1024
cRet := Space(1024)   
hResult := DllCall(pDllNfe, 32, "NFE_Consultar", hb_StrToUTF8(xChaveNfe), .T., @cRet, @bufferLen)

svn.code.sf.net/p/acbr/code/trunk2/Projetos/ACBrLib/Demos/Harbour/NFe/ACBrNFe.prg

 

Link to comment
Share on other sites

@Rafael Dias, adaptei meu programa para usar o PRG do  exemplo do SVN, e estou tendo o retorno  "-10, Access violation" no método de validar regras de negócio.

o Erro é na chamada do método CheckResult, coloquei em vermelho as linhas que o xHarbour destaca ao fechar o programa.

 

METHOD ValidarRegrasdeNegocios() CLASS ACBrNFe
    local hResult
    hResult := DllCall(::hHandle, DLL_OSAPI, "NFE_ValidarRegrasdeNegocios")
    ::CheckResult(hResult)
    RETURN nil

 

METHOD CheckResult(hResult) CLASS ACBrNFe
    local buffer, bufferLen, oErr
    if hResult >= 0 
       RETURN nil
    endif    

    bufferLen := STR_LEN
    buffer := Space(bufferLen)

    DllCall(::hHandle, DLL_OSAPI, "NFE_UltimoRetorno", @buffer, @bufferLen)
    if bufferLen > STR_LEN
        buffer := Space(bufferLen)
        DllCall(::hHandle, DLL_OSAPI, "NFE_UltimoRetorno", @buffer, @bufferLen)        
    endif    

    oErr := ErrorNew()
    oErr:Severity := ES_ERROR
    oErr:Description := hb_UTF8ToStr(buffer)
    Throw(oErr)
    RETURN nil

 

Abaixo está o meu PRG modificado.

 

Log ACBR:  ACBrLibNFE-20201223.log

 

FUNCTION ACBR_CRIA_ASSINA_VALIDA_ENVIA(xTxt,xChaveNfe)
	LOCAL cRet,xLocalXml,xXml,lAssinaValidaEnvia:=.T.
	LOCAL xPara,xCopias,xAssunto,xMensagem
	
	** Nome do XML e local de onde será salvo
	xXml:=xChaveNfe+"-nfe.xml"
	xLocalXml:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\XML\"
	xPdf:=xChaveNfe+"-nfe.pdf"
	xLocalPdf:=pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"
	
	** Iniciar arquivo de configurações do ACBR
	nfe:=ACBrNFe():New(pUnidadeUf+"_NFE.INI","")
	
	** Consulta a chave para saber se já é uma NFe Autorizada para uso
	cRet:=nfe:Consultar(xChaveNfe,.T.)	
	if at("Consumo Indevido",cRet)>0
		alert("Consumo Indevido;;Aguarde alguns minutos e tente novamente")
		nfe:Destroy()
		RETURN .F.
	endif
	
	if at("Autorizado o uso da NF-e",cRet)>0
		lAssinaValidaEnvia:=.F.
		
		** Pega a data correta em que a Nfe foi emitida
		q:="select concat(year(b09demi),lpad(month(b09demi),2,'0')) as pasta from nfec where chavenfe='"+xChaveNfe+"'"
		v:=F_GETCON(q)
		if len(v)==0
			alert("Erro ao localizar a chave no Nfec;"+xChaveNfe)
			nfe:Destroy()
			RETURN .F.
		endif
		xPastaAno:=v[1,1]
		xLocalXml:=xLocalXml+xPastaAno+"\"
		xLocalPdf:=xLocalPdf+xPastaAno+"\"
		
		** Verifica se o arquivo XML existe na pasta
		if ! FILE(xLocalXml+xXml)
			** Para garantir cria a pasta do anomes do XML e PDF
			FT_MKDIR(xLocalXml)
			FT_MKDIR(xLocalPdf)
			alert("NFe autorizada, porem arquivo xml nao localizado na pasta:;"+xLocalXml+xXml+";Faca o download pelo site do SEFAZ e coloque na pasta indicada")
			nfe:Destroy()
			RETURN .F.
		endif
	else
		xLocalXml:=xLocalXml+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
		xLocalPdf:=xLocalPdf+strZero(year(date_sql()),4)+strZero(month(date_sql()),2)+"\"
	endif
	
	** Para garantir cria a pasta do anomes do XML e PDF
	FT_MKDIR(xLocalXml)
	FT_MKDIR(xLocalPdf)
	
	if lAssinaValidaEnvia
		** Carrega o arquivo TXT da NFe
		nfe:CarregarINI(xTxt)
		
		** Valida regras de negócio da NFe
		cRet:=nfe:ValidarRegrasdeNegocios()
		cRet:=strTran(cRet,chr(0),"")	//Elimina um quadrado "[]" do retrono 
		cRet:=strTran(cRet,chr(32),"")	//Elimina um quadrado "[]" do retrono 
	
		if ! empty(cRet)
			alert(cRet)
			nfe:Destroy()
			RETURN .F.
		endif
		
		** Assina NFe que está carregada pelo NFE_CarregarINI
		nfe:Assinar()

		** Validar XML assinado na pasta correta
		nfe:Validar()

		** Grava XML assinado na pasta correta
		nfe:GravarXml(0,xXml,xLocalXml)
		
		** Enviar XML par ao SEFAZ
		nfe:Enviar(0,.T.,.T.,.F.)
	else
		** Se o XML já está autorizado apenas o carrga
		** Para poder imprimir e enviar por e-mail
		nfe:CarregarXML(xLocalXml+xXml)
	endif
	
	nfe:ImprimirPDF()
	FileCopy(pDisco+":\xHB\nfe\"+UPPER(pUnidadeUf)+"\PDF\"+xPdf,xLocalPdf+xPdf)

	mVar:=ACBR_EMAIL(xChaveNfe)
	xPara:=mVar[1]
	xCopias:=mVar[2]
	xAssunto:=mVar[3]
	xMensagem:=mVar[4]

	nfe:EnviarEmail(xPara, xLocalXml+xXml,.T.,xAssunto,xMensagem,xCopias)
	nfe:Destroy()
	
	RETURN .T.

 

Link to comment
Share on other sites

@Rafael Dias, fiz algumas modificações no prg acbrnfe.prg e funcionou!

São elas:

Método ValidarRegrasdeNegocios não tinha variável para o retorno.
Método EnviarEmail estava com variáveis invertidas na chamada do método do prg e do método da dll
Destroy() não era um método e sim uma procedure, mudei para método

 

As correções ficaram assim:

METHOD ValidarRegrasdeNegocios() CLASS ACBrNFe
    local hResult, buffer, bufferLen
    bufferLen := STR_LEN
    buffer := Space(bufferLen)
    hResult := DllCall(::hHandle, DLL_OSAPI, "NFE_ValidarRegrasdeNegocios", @buffer, @bufferLen)
    ::CheckResult(hResult)
    RETURN ::ProcessResult(buffer, bufferLen)

 

METHOD EnviarEmail(ePara, eChaveNFe, aEnviaPDF, eAssunto, eCc, eAnexos, eMensagem) CLASS ACBrNFe
    local hResult
    hResult := DllCall(::hHandle, DLL_OSAPI, "NFE_EnviarEmail", hb_StrToUTF8(ePara), hb_StrToUTF8(eChaveNFe), aEnviaPDF, eAssunto, hb_StrToUTF8(eCc), hb_StrToUTF8(eAnexos),  eMensagem)
    ::CheckResult(hResult)
    RETURN nil

METHOD Destroy CLASS ACBrNFe
    DllCall(::hHandle, DLL_OSAPI, "NFE_Finalizar")
    DllUnload(::hHandle)
    RETURN nil

 

obrigado pela ajuda!

Link to comment
Share on other sites

  • Este tópico foi criado há 1384 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.
Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.

The popup will be closed in 10 seconds...