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 (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

2 Responses

  1. Breno Nogueira disse:

    Bom dia Daniel, consigo bloquear para que o usuário logado não consiga abrir a mesma tela duas vezes ? o usuário em outra máquina pode acessar, quero apenas bloquear que o mesmo usuário abra a rotina duas vezes.

    • Bom dia Breno, tudo joia?

      Existem algumas formas, uma ideia seria ter um arquivo de controle, tipo um TXT dentro da Protheus Data, com o código do usuário.

      Nisso você teria dois pontos de entrada, o ChkExec, que iria gravar a rotina que abriu.

      E teria o MSFinal, que é para limpar essas aberturas.

      Ai no ChkExec, você valida se a rotina já foi aberta e impede ele de abrir novamente.

      Essa é uma ideia, mas daria para implementar de outras formas.

      Tenha uma ótima e abençoada terça feira.

      Um forte abraço.

Deixe uma resposta

Terminal de Informação