Problema de recursividade no execauto ctba020 em MVC

Estou implementando o ponto de entrada CTBA020 em MVC, e utilizando o ponto de execução ‘MODELCOMMITNTTS’, para replicar uma conta após a sua gravação, contudo no momento da gravação utilizando a função “CommitData()” e chamado novamente o ponto de entrada CTBA020, o que ocasiona uma recursividade, um loop, que somente e interrompido quando a rotina tenta gravar uma conta que já existe e ocorre um erro na função VldData().
Tentei de diversas formas, mas não consegui solucionar esse problema, alguém tem alguma solução.

2 curtidas

@Marcio_Seiji não deveria executar novamente o Commit dentro do ponto de entrada, por isso está entrando em recursividade. Descreve melhor o que você precisa fazer ou posta o fonte aqui para gente analisar.

Olá Marcio, complicada essa situação ai, talvez se você desacoplar sua função em outra e verificar com FwIsInCallStack se ela foi executada resolva seu problema.
Se não der certo, usao PE FORMCOMMITTTSPOS que é após o commit

User Function CTBA020
if !FwIsInCallStack(“u_fCTBA020”)
fCTBA020()
endif

User Function fCTBA020()
//comita aqui
return

Um exemplo…

User Function CTAB020()
.
.
.
If aParam <> NIL
oObj := aParam[1]
cIdPonto := aParam[2]
cIdModel := aParam[3]
lIsGrid := (Len(aParam) > 3)
nOpcAuto := oObj:GetOperation()

    If cIdPonto == "MODELCOMMITNTTS" 
		Replica(nOpcAuto)
    EndIf

EndIf

Return xRet

Static Function Replica(nOpcAuto)

Local oModelAut := NIL
Local cFilBkp := cFilAnt

If oModelAut == Nil     //somente uma unica vez carrega o modelo CTBA020-Plano de Contas CT1
	oModelAut := FWLoadModel('CTBA020')
EndIf
    
oModelAut:Activate()    //ativa modelo

Do Case
            
	Case nOpcAuto == 3  //Inclusao
		cFilAnt := "12"
		//Preencho os valores da CT1
		oCT1 := oModelAut:GetModel('CT1MASTER') //Objeto similar enchoice CT1 
		oCT1:SETVALUE('CT1_FILIAL',cFilAnt)
		oCT1:SETVALUE('CT1_CONTA' ,"0000001")
		oCT1:SETVALUE('CT1_DESC01',"TESTE")
		oCT1:SETVALUE('CT1_CLASSE',"2")
		oCT1:SETVALUE('CT1_NORMAL',"1")

		//Valido e gravo
		If oModel:VldData() 		//Ocorre recursividade volta para CTA020
			oModel:CommitData()		//ocorre recursividade volta para CTA020
			MsgInfo("Registro INCLUIDO!", "Atenção")
		Else
			VarInfo("",oModel:GetErrorMessage())	//Somente sai quando entra no erro
		EndIf
		
		cFilBkp := cFilAnt

EndCase
        
oModelAut:DeActivate() //desativa modelo

Return

@Marcio_Seiji boa tarde.

Eu fiz isso com outros cadastro na folha de pagamento, utilizando Reclock nesses mesmo ponto de entrada. Fiz um reclock dinâmico que busca a estrutura da tabela.

Leandro,
Testei o PE FORMCOMMITTTSPOS, como sugerido, mas ainda assim entra na recursividade.

@Marcio_Seiji explica melhor o que esta fazendo nesse ponto de entrada, está incluindo novas contas baseado na atual ? Não precisaria chamar o commit dentro do ponto de entrada, ele já faz isso sozinho.

Olá.

Se a réplica deve ser realizada apenas uma vez, você pode fazer um controle da stack para não replicar mais de uma vez, utilizando a função FwIsInCallStack. Exemplo:

If(cIdPonto == "MODELCOMMITNTTS")

   If(!FwIsInCallStack('Replica')) // Se já estiver em um processo de replicação, não entra

	   Replica(nOpcAuto)

   EndIf

EndIf

Dessa forma, a função “Replica” será chamada apenas uma vez, para replicar o cadastro original em outro. Quando o ponto de entrada for chamado a segunda vez, ele não irá chamar a função “Replica” novamente pois ela já está no stack.

Documentação: FWIsInCallStack - Frameworksp - TDN

Estou replicando o cadastro de contas contábeis para as outras filiais do sistema, tabela CT1 (compartilha).

Felipe, boa noite.

Eh, pensei em fazer isso, alias ainda estou pensando, caso não consiga resolver a recursividade de outra forma, pelo menos para entregar a funcionalidade, depois com mais tempo analiso isso melhor.
Mas gostaria de tentar resolver isso… antes de me dar por vencido…

1 curtida

Boa noite.

Sobre a função FWIsInCallStack, e uma boa ideia.
Vou implementar e testar para ver como isso funciona.

Obrigado.

1 curtida

Então a solução é mesmo identificar pela pilha de chamadas se já está vindo de um processo de réplica e então não executar novamente. E nesse caso o ponto ideal é o fora da transação após as gravações FORMCOMMITTTSPOS .