Como bloquear uma rotina, se ela já estiver aberta via AdvPL

Hoje vou mostrar uma forma de bloquear uma função para que apenas um usuário utilize por vez no Protheus.

Essa solução foi desenvolvida pelo grande Rodrigo R Fernandes ( LinkedIn ) e disponibilizada aqui para o Ti como exemplo.

Basicamente, se for uma rotina customizada, aí é mais fácil de se fazer o controle, mas e se for uma rotina padrão? Para esse caso, você pode fazer via ponto de entrada, caso a rotina tenha um antes de abrir a tela.

Ou você pode fazer conforme o exemplo abaixo, onde é feito o seguinte procedimento:

  1. Verifica se a rotina já não se encontra travada, se tiver mostra mensagem
  2. Do contrário é atualizado o arquivo com o nome do usuário que está usando, seta o nome da função padrão e chama ela

A partir disso, basta você colocar essa User Function no Menu, e com isso você consegue que apenas 1 usuário por vez utilize a rotina.

Abaixo o exemplo:

#Include "TOTVS.ch"

/*/{Protheus.doc} zPCPP03
Função para substituir a chamada original da rotina MATA650.
O objetivo é obter acesso exclusivo a rotina.
Apenas 1 usuário por vez.
@author Rodrigo R Fernandes
@since 20/11/2020
@version 1.0
/*/

User Function zPCPP03()
	Local aArea     := GetArea()
    Local cRotAux   := "MATA650"                            // Nome da Rotina
    Local cUserAux  := "Sem nome de Usuário"                // Nome do Usuário
    Local cArqAux   := "\" + Alltrim(cRotAux) + ".txt"      // Arquivo que será responsável por armazenar o usuário que está com a rotina em USO

    // Se não conseguir acessar a rotina (ela já estiver em uso)
    If ! LockByName(cRotAux, .F., .F., .T.)

        //Se o arquivo existir no servidor, busca o nome gravado no txt
        If File(cArqAux)
            cUserAux := Alltrim(MemoRead(cArqAux))
        EndIf
    
        //Exibe mensagem que já está em uso
        MsgAlert("Rotina Ordem de Produção em uso pelo usuário: " + cUserAux, "Atenção)

	Else
		//Grava o nome do usuário no arquivo de log
		MemoWrite(cArqAux, UsrRetName(RetCodUsr()))

		//Agora seta o nome da função no menu, como a rotina e faz a chamada dela
		SetFunName(cRotAux)
		&(cRotAux + "()")  

		//Após sair da função padrão, o arquivo com o nome do usuário será excluído
		If File(cArqAux)
			fErase(cArqAux)
		EndIf
		
		//Libera o acesso para que a rotina seja aberta novamente
		UnLockByName(cRotAux, .F., .F., .T.)
    EndIf

	RestArea(aArea)
Return

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan Atilio (Daniel Atilio)
Especialista em Engenharia de Software pela FIB. Entusiasta de soluções Open Source. E blogueiro nas horas vagas.

Deixe uma resposta