Pragiva — Tecnologia na prática

MT100GRV o ponto de entrada da gravação do Documento de Entrada

MT100GRV dispara antes da gravação física do cabeçalho, com cabeçalho e itens ainda em memória, não em registro.

Desenvolvimento Referência técnica 3 min de leitura

Assista o vídeo

MT100GRV em resumo

Onde fica
função a103Grava(), do MATA103 (Documento de Entrada — a tela que abre quando um pedido de compra vira nota fiscal de entrada).
Quando dispara
antes da gravação física do cabeçalho (SF1) — o próprio comentário do fonte TOTVS chama o momento de “ponto de entrada anterior à gravação”. Em caso de exclusão, dispara depois das rotinas que excluem título (SB5), mas ainda antes da exclusão física do documento.
PARAMIXB
{lDeleta} — um único elemento, lógico: .T. quando a gravação é uma exclusão.
Retorno
usado — .F. interrompe a gravação.
Serve para bloquear?
Sim, e nesse momento ainda dá tempo: o cabeçalho e os itens seguem em memória, não foram escritos como registro.
Consulta rápida5 seções

Para o mecanismo geral de ponto de entrada, veja Ponto de entrada no Protheus. Este artigo cobre só o MT100GRV do MATA103 (tela MVC do Documento de Entrada). A tela clássica de entrada de notas (MATA100) tem um PE de mesmo nome, mas sem PARAMIXB e sem captura de retorno — é outro comportamento e fica fora deste texto.

O que já aconteceu antes dele

A chamada no fonte é direta:

ADVPL / TLPP
//Ponto de entrada anterior a gravacao do Documento de Entrada
If (ExistBlock("MT100GRV")) .AND. lContinua
	lRetGrv := ExecBlock("MT100GRV",.F.,.F.,{lDeleta})
	If ValType( lRetGrv ) == "L"
		lContinua := lRetGrv
	EndIf
EndIf

O comentário do próprio padrão é literal: “ponto de entrada anterior à gravação do Documento de Entrada”. Dentro da mesma a103Grava(), o RecLock/gravação do cabeçalho SF1 — seja em inclusão, seja em alteração — acontece depois desse trecho, e a exclusão física do documento também. Quando o caso é exclusão, as rotinas que excluem título vinculado (SB5 e o que depende dele) já rodaram, mas o registro do próprio documento ainda não foi apagado.

Na prática, o MT100GRV é o lugar certo para decidir se o documento pode ser gravado ou excluído: cabeçalho e itens ainda estão em memória — nos parâmetros e arrays que a rotina MVC montou —, e não como registro escrito. Bloquear aqui evita a escrita, não apenas a confirmação de uma escrita que já ocorreu.

O que ele recebe

PosiçãoTipoConteúdo
PARAMIXB[1]Lógico.T. quando a gravação corrente é uma exclusão do documento; .F. em inclusão ou alteração

Um PARAMIXB de uma posição só é raro entre os pontos de entrada de gravação — a maioria carrega cabeçalho e itens. Aqui, cabeçalho e itens não vêm no bloco: quem precisa deles lê direto das áreas de trabalho (, ) ou do contexto de memória que a rotina MVC deixou posicionado. Como o registro do cabeçalho ainda não foi gravado nesse ponto, confirme no seu ambiente o estado real da área antes de presumir travamento ou conteúdo já persistido.

Sobre como o PARAMIXB muda de posição e de tipo entre pontos de entrada diferentes, veja PARAMIXB: o array que às vezes não é seu.

Exemplo

ADVPL / TLPP
#Include "Protheus.ch"

/*/{Protheus.doc} MT100GRV
Executado em a103Grava(), antes da gravação física do cabeçalho (SF1) do
Documento de Entrada.
Bloqueia a exclusão do documento quando ele já tem apontamento de produção
vinculado.
@type user function
@return logical, .F. interrompe a gravação
/*/
User Function MT100GRV()

    Local aArea    := GetArea()
    Local lContinua := .T.
    Local lDeleta   := .F.

    If Type("PARAMIXB") <> "A" .Or. Len(PARAMIXB) < 1 .Or. ValType(PARAMIXB[1]) <> "L"
        ConOut("[MT100GRV] PARAMIXB inesperado. Regra ignorada.")
        RestArea(aArea)
        Return .T.
    EndIf

    lDeleta := PARAMIXB[1]

    // A regra só vale para exclusão. Inclusão e alteração seguem intactas.
    If !lDeleta
        RestArea(aArea)
        Return .T.
    EndIf

    // Chave de desligamento: sempre exista um jeito de desativar a
    // customização sem recompilar.
    If !SuperGetMv("MV_XDOCVIN", .F., .F.)
        RestArea(aArea)
        Return .T.
    EndIf

    If SF1->(FieldPos("F1_XAPONTO")) > 0 .And. !Empty(SF1->F1_XAPONTO)
        Help(" ", 1, "MT100GRV",, ;
            "Documento com apontamento vinculado. Exclusão não permitida.", 1, 0)
        lContinua := .F.
    EndIf

    RestArea(aArea)

Return lContinua

O exemplo usa um campo customizado (F1_XAPONTO) só para ilustrar o padrão de leitura direto da área — troque pelo campo ou condição reais do seu ambiente antes de compilar.

Confira no seu ambienteSQL
SELECT X6_VAR, X6_TIPO, X6_DESCRIC, X6_CONTEUD
  FROM SX6010
 WHERE X6_VAR = 'MV_XDOCVIN'

Armadilhas específicas

Presumir que o cabeçalho já foi gravado. O comentário do próprio fonte diz “anterior à gravação”, e é literal: o RecLock do SF1 (ou a exclusão do registro) acontece depois do PE. Uma regra que lê SF1 esperando um registro já persistido pode estar lendo um estado que ainda não existe como tal — confirme no seu ambiente antes de assumir o contrário.

Ignorar lDeleta. Sem checar PARAMIXB[1], uma regra pensada para inclusão acaba rodando também na exclusão do mesmo documento, e vice-versa.

Esquecer o Return. O retorno é usado: If ValType(lRetGrv) == "L" Then lContinua := lRetGrv. Sem Return explícito, o tipo do retorno muda e o padrão ignora a tentativa de bloqueio.

Bloquear sem mensagem. Como em qualquer PE de bloqueio, bloquear calado faz o usuário achar que o sistema travou.

Quando outro ponto de entrada é mais adequado

O MT100GRV já atende quem precisa decidir a operação antes da escrita do cabeçalho — é justamente o que ele faz. Se a regra precisa de algo mais cedo no fluxo, como validar dados antes que a tela de Documento de Entrada monte o cabeçalho em memória, o MT100GRV não serve: confirme no seu ambiente qual PE atende esse momento anterior.

A tela clássica MATA100 tem seu próprio ponto de entrada MT100GRV, mas sem PARAMIXB e sem uso do retorno — implementar a mesma regra para as duas telas exige tratar cada uma separadamente.

Continue por aqui