Salve salve pessoal…
Você já precisou identificar se um fonte é em MVC, se sim, já precisou desenvolver um Ponto de Entrada pra ele? E se eu disser que existe uma forma fácil e rápida de se fazer isso?
Eu criei uma função jovens, chamada zIsMVC(), nessa função é exibido detalhes da rotina em MVC, o ponto de entrada padrão, e dados do Modelo de Dados. Para utilizá-la, crie um ponto de entrada após o login, e adicione em algum atalho do Protheus, por exemplo, eu adicionei no Shift+F7:
...
User Function AfterLogin()
SetKey(K_SH_F7, { || u_zIsMVC() }) //Shift + F7
Return
...
Depois disso, basta entrar na rotina que você deseja, e clicar em alguma opção, como Incluir, Alterar e Excluir, e pressionar Shift + F7, se tudo der certo, será mostrado a tela inicial, que contém dados da tela, e alguns botões com links interessantes de MVC.
A segunda aba, contém o Ponto de Entrada gerado no padrão MVC.
A terceira, contém dados do Modelo de Dados, caso precise de alguma informação.
Se houver algum erro na interpretação do modelo de dados, será mostrado uma mensagem (provavelmente é String Size Over Flow).
E se a rotina não for em MVC (não tiver modelo de dados), será mostrado um alerta avisando.
Abaixo o fonte completo.
//Bibliotecas
#Include "Protheus.ch"
/*/{Protheus.doc} zIsMVC
Função que verifica se a função executada atualmente é em MVC
@author Atilio
@since 14/04/2018
@version 1.0
@type function
@obs Essa função, apenas pega e verifica se existe um modelo de dados ativo aberto, caso exista, ela mostra uma tela com observações
Inicializar ele em um ponto de entrada, por exemplo, no ChkExec ou AfterLogin:
...
User Function AfterLogin()
SetKey(K_SH_F7, { || u_zIsMVC() }) //Shift + F7
Return
...
/*/
User Function zIsMVC()
Local lMVC := .F.
Local oModelPad := FWModelActive()
Local cOperacao := ""
Local oBtnL001
Local oBtnL002
Local oBtnL003
Local oBtnL004
Local oBtnL005
Local cError := ""
Local bError := ErrorBlock({ |oError| cError := oError:Description})
Private cPontoEnt := ""
Private cVarInfo := ""
Private oDlgPvt
Private oFolderPvt
Private oEditCod
Private oEditMod
//Tamanho da janela
Private nJanLarg := 600
Private nJanAltu := 420
//Fontes
Private cFontUti := "Arial"
Private oFontSub := TFont():New(cFontUti,,-20)
Private oFontSubN := TFont():New(cFontUti,,-20,,.T.)
//Se for diferente de nulo, realmente a tela é em MVC
If oModelPad != Nil
lMVC := .T.
//Definindo a operação
cOperacao := cValToChar(oModelPad:nOperation)
If oModelPad:nOperation == 3
cOperacao += " - Inclusão"
ElseIf oModelPad:nOperation == 4
cOperacao += " - Alteração"
ElseIf oModelPad:nOperation == 5
cOperacao += " - Exclusão"
EndIf
//Pegando o texto do ponto de entrada
cPontoEnt := fPontoEnt(Alltrim(oModelPad:cID))
//Inicio a utilização da tentativa
Begin Sequence
cVarInfo := VarInfo("Modelo", ClassDataArr(oModelPad, .T.), , .T., )
End Sequence
//Restaurando bloco de erro do sistema
ErrorBlock(bError)
//Se houve erro, será mostrado ao usuário
If Empty(cVarInfo)
cVarInfo := "Houve um erro ao gerar o VarInfo!<br>Verifique o tamanho da String, se necessário, aumente o tamanho na MaxStringSize - <b>http://tdn.totvs.com/pages/viewpage.action?pageId=161349793</b><br>"
cVarInfo += "Pode ser ainda, que existam muitos componentes recursivos na tela, e a função VarInfo não conseguiu interpretar."
EndIf
//Criando a janela
DEFINE MSDIALOG oDlgPvt TITLE "zIsMVC" FROM 000, 000 TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL
//Labels gerais
@ 004, 003 SAY "zIsMVC - Consulta de objeto em MVC" SIZE 200, 030 FONT oFontSubN OF oDlgPvt COLORS RGB(031,073,125) PIXEL
@ 014, 003 SAY "https://terminaldeinformacao.com" SIZE 200, 030 FONT oFontSub OF oDlgPvt COLORS RGB(031,073,125) PIXEL
//Abas
@ 027, 003 FOLDER oFolderPvt SIZE (nJanLarg/2)-03, (nJanAltu/2)-030 OF oDlgPvt ITEMS ;
"Geral",;
"Ponto de Entrada",;
"Modelo de Dados" COLORS 0, 14215660 PIXEL
//Aba Geral
@ 003, 006 SAY "ID: " + oModelPad:cID SIZE 200, 030 FONT oFontSub OF oFolderPvt:aDialogs[1] COLORS RGB(031,073,125) PIXEL
@ 013, 006 SAY "Descrição: " + oModelPad:cDescription SIZE 200, 030 FONT oFontSub OF oFolderPvt:aDialogs[1] PIXEL
@ 023, 006 SAY "Operação: " + cOperacao SIZE 200, 030 FONT oFontSub OF oFolderPvt:aDialogs[1] PIXEL
@ 043, 006 SAY "Links Interessantes: " SIZE 200, 030 FONT oFontSub OF oFolderPvt:aDialogs[1] COLORS RGB(031,073,125) PIXEL
@ 056, 006 BUTTON oBtnL001 PROMPT "Vídeo Aula - Conceitos de MVC em AdvPL" SIZE 285, 016 FONT oFontSub OF oFolderPvt:aDialogs[1] ACTION (fLink(1)) PIXEL
@ 076, 006 BUTTON oBtnL002 PROMPT "TDN - Lista de Fontes em MVC" SIZE 285, 016 FONT oFontSub OF oFolderPvt:aDialogs[1] ACTION (fLink(2)) PIXEL
@ 096, 006 BUTTON oBtnL003 PROMPT "TDN - Ponto de Entrada no Padrão MVC" SIZE 285, 016 FONT oFontSub OF oFolderPvt:aDialogs[1] ACTION (fLink(3)) PIXEL
@ 116, 006 BUTTON oBtnL004 PROMPT "Vídeo Aula - Como criar um ponto de entrada em MVC" SIZE 285, 016 FONT oFontSub OF oFolderPvt:aDialogs[1] ACTION (fLink(4)) PIXEL
@ 136, 006 BUTTON oBtnL005 PROMPT "Vídeo Aula - Como criar ExecAuto em MVC" SIZE 285, 016 FONT oFontSub OF oFolderPvt:aDialogs[1] ACTION (fLink(5)) PIXEL
//Aba Ponto de Entrada
oEditCod := tSimpleEditor():New(0, 0, oFolderPvt:aDialogs[2], 295, 160)
oEditCod:Load(cPontoEnt)
//Aba do Modelo de Dados
oEditMod := tSimpleEditor():New(0, 0, oFolderPvt:aDialogs[3], 295, 160)
oEditMod:Load(cVarInfo)
//Mostrando a janela
ACTIVATE MSDIALOG oDlgPvt CENTERED
Else
MsgAlert("Não há indícios dessa tela ser em MVC (utilize dentro de uma tela de Inclusão/Alteração/Exclusão)!", "Atenção")
EndIf
Return lMVC
Static Function fLink(nBotao)
Local cLink := ""
//Vídeo Aula - Conceitos de MVC em AdvPL
If nBotao == 1
cLink := "https://terminaldeinformacao.com/2016/04/24/vd-advpl-017/"
//Lista de Fontes em MVC
ElseIf nBotao == 2
cLink := "http://tdn.totvs.com/display/public/PROT/Fontes+em+MVC"
//Ponto de Entrada no Padrão MVC
ElseIf nBotao == 3
cLink := "http://tdn.totvs.com/pages/releaseview.action?pageId=208345968"
//Vídeo Aula - Como criar um ponto de entrada em MVC
ElseIf nBotao == 4
cLink := "https://terminaldeinformacao.com/2017/01/16/vd-advpl-023/"
//Vídeo Aula - Como criar ExecAuto em MVC
ElseIf nBotao == 5
cLink := "https://terminaldeinformacao.com/2017/01/23/vd-advpl-024/"
EndIf
//Abrindo o link
ShellExecute("Open", cLink, "", "", 1)
Return
Static Function fPontoEnt(cID)
Local cPonto := ""
Local cQuebra := "<br>"
Local cTab := Replicate(" ", 4)
Local cAbreComent := '<font color="green">'
Local cFechComent := '</font>'
Local cAbreString := '<font color="red">'
Local cFechString := '</font>'
//Cria o fonte do ponto de Entrada
cPonto := '<font face="consolas" size="4">'
cPonto += cAbreComent + '//Bibliotecas' + cFechComent + cQuebra
cPonto += '#Include "Protheus.ch" ' + cQuebra
cPonto += ' ' + cQuebra
cPonto += cAbreComent
cPonto += '/*/{Protheus.doc} ' + cID + cQuebra
cPonto += 'Exemplo de Ponto de Entrada em MVC ' + cQuebra
cPonto += '<b>@author</b> zIsMVC ' + cQuebra
cPonto += '<b>@since</b> ' + dToC(Date()) + cQuebra
cPonto += '<b>@version</b> 1.0 ' + cQuebra
cPonto += '<b>@type</b> function ' + cQuebra
cPonto += '<b>@obs</b> Deixar o nome do prw como: ' + cID + '_pe.prw ' + cQuebra
cPonto += '/*/ ' + cQuebra
cPonto += cFechComent
cPonto += ' ' + cQuebra
cPonto += 'User Function ' + cID + '() ' + cQuebra
cPonto += cTab + 'Local aParam := PARAMIXB ' + cQuebra
cPonto += cTab + 'Local xRet := .T. ' + cQuebra
cPonto += cTab + 'Local oObj := Nil ' + cQuebra
cPonto += cTab + 'Local cIdPonto := ' + cAbreString + '""' + cFechString + ' ' + cQuebra
cPonto += cTab + 'Local cIdModel := ' + cAbreString + '""' + cFechString + ' ' + cQuebra
cPonto += cTab + 'Local nOper := 0 ' + cQuebra
cPonto += cTab + 'Local cCampo := ' + cAbreString + '""' + cFechString + ' ' + cQuebra
cPonto += cTab + 'Local cTipo := ' + cAbreString + '""' + cFechString + ' ' + cQuebra
cPonto += cTab + ' ' + cQuebra
cPonto += cTab + cAbreComent + '//Se tiver parâmetros' + cFechComent + cQuebra
cPonto += cTab + 'If aParam != Nil ' + cQuebra
cPonto += cTab + cTab + 'ConOut("> "+aParam[2]) ' + cQuebra
cPonto += cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Pega informações dos parâmetros' + cFechComent + cQuebra
cPonto += cTab + cTab + 'oObj := aParam[1] ' + cQuebra
cPonto += cTab + cTab + 'cIdPonto := aParam[2] ' + cQuebra
cPonto += cTab + cTab + 'cIdModel := aParam[3] ' + cQuebra
cPonto += cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Valida a abertura da tela' + cFechComent + cQuebra
cPonto += cTab + cTab + 'If cIdPonto == ' + cAbreString + '"MODELVLDACTIVE"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + 'xRet := .T. ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//nOper := oObj:nOperation' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//Se for Exclusão, não permite abrir a tela' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//If nOper == 5' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + 'xRet := .F.' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//EndIf' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Pré configurações do Modelo de Dados' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"MODELPRE"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + 'xRet := .T. ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Pré configurações do Formulário de Dados' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"FORMPRE"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + 'xRet := .T. ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//nOper := oObj:GetModel(cIdPonto):nOperation' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//cTipo := aParam[4]' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//cCampo := aParam[5]' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//Se for Alteração' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//If nOper == 4' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//Não permite alteração dos campos' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + 'If cTipo == "CANSETVALUE" .And. Alltrim(cCampo) $ ("CAMPO1;CAMPO2;CAMPO3")' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + cTab + 'xRet := .F.' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + 'EndIf' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//EndIf' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + '' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Adição de opções no Ações Relacionadas dentro da tela' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"BUTTONBAR"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + 'xRet := {}' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//aAdd(xRet, {"* Titulo 1", "", {|| Alert("Botão 1")}, "Tooltip 1"})' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//aAdd(xRet, {"* Titulo 2", "", {|| Alert("Botão 2")}, "Tooltip 2"})' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//aAdd(xRet, {"* Titulo 3", "", {|| Alert("Botão 3")}, "Tooltip 3"})' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Pós configurações do Formulário' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"FORMPOS"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + 'xRet := .T. ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Validação ao clicar no Botão Confirmar' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"MODELPOS"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + 'xRet := .T. ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//Se o campo de contato estiver em branco, não permite prosseguir' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//If Empty(M->CAMPO1)' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + 'Aviso("Atenção", "Por favor, informe o Campo!", {"OK"}, 03)' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + 'xRet := .F.' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//EndIf' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Pré validações do Commit' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"FORMCOMMITTTSPRE"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Pós validações do Commit' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"FORMCOMMITTTSPOS"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Commit das operações (antes da gravação)' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"MODELCOMMITTTS"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cAbreComent + '//Commit das operações (após a gravação)' + cFechComent + cQuebra
cPonto += cTab + cTab + 'ElseIf cIdPonto == ' + cAbreString + '"MODELCOMMITNTTS"' + cFechString + ' ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//nOper := oObj:nOperation' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + ' ' + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//Se for inclusão, mostra mensagem de sucesso' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//If nOper == 3' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//' + cTab + 'Aviso("Atenção", "Registro incluido com sucesso!", {"OK"}, 03)' + cFechComent + cQuebra
cPonto += cTab + cTab + cTab + cAbreComent + '//EndIf' + cFechComent + cQuebra
cPonto += cTab + cTab + 'EndIf ' + cQuebra
cPonto += cTab + 'EndIf ' + cQuebra
cPonto += 'Return xRet'
cPonto += '</font>'
//Palavras reservadas deixando em negrito
cPonto := StrTran(cPonto, "ElseIf", "<b>ElseIf</b>")
cPonto := StrTran(cPonto, "EndIf", "<b>EndIf</b>")
cPonto := StrTran(cPonto, "If", "<b>If</b>")
cPonto := StrTran(cPonto, "Return", "<b>Return</b>")
cPonto := StrTran(cPonto, ":=", "<b>:=</b>")
cPonto := StrTran(cPonto, "!=", "<b>!=</b>")
cPonto := StrTran(cPonto, "==", "<b>==</b>")
cPonto := StrTran(cPonto, "Local", "<b>Local</b>")
cPonto := StrTran(cPonto, "User Function", "<b>User Function</b>")
cPonto := StrTran(cPonto, "#Include", "<b>#Include</b>")
Return cPonto
Bom pessoal, por hoje é só.
Abraços e até a próxima.





Parabens pelo Material Daniel!!!
Valeu Serginho.
Um grande abraço.
Show mestre!
Valeu Vinicião.
Abraços.
Muito 10 !!!!Vlw
Eu que agradeço Lucimar.
Um grande abraço.
Show mesmo, parabém e muito obrigado pela ajuda 🙂
Eu que agradeço Leandro.
Um grande abraço.
Mestre, excelente rotina, parabéns, você é o cara!. Um grande abraço.
Obrigado mano Charles, é nozes.
Um grande abraço.
Sensacional, como sempre.
Obrigado!
Salve salve Rafinha.
Muito obrigado jovem.
Abraços.
Excelente!!! Cara… você é D+
Obrigado!
Que isso jovem, muito obrigado pelas palavras.
Um grande abraço.
Grande Mestre,otina show para variar! rsrsrs É de grande ajuda.
Que isso Georgito.
Muito obrigado jovem.
Um grande abraço.
Como criar um ponto de entrada após o login?
Boa noite Sidelcino, tudo bem?
Note que no trecho que tem Shift F7, logo abaixo tem um botão Expandir Código, clique nele, ai basta você criar um fonte com ele.
Um grande abraço.
Esse cara é sensacional!! Muitas coisas excelentes e úteis publicadas… ajuda demais!!! Parabéns..
Eu que agradeço Fabricio.
Um grande abraço.
M A R A V I L H O S O!
Parabéns e obrigada!
Abraço!
Opa, eu que agradeço pelo comentário e feedback. Grande abraço.
Obrigado, mas fui tentar usar aqui e da esse erro. Vc saberia dizer o porque?
stack depth overflow in function MKALLTOCHAR on MKALLTOCHAR(APWEX050.APL) 08/06/2022 16:53:22 line : 382
[build: 7.00.210324P-20220608]
[environment: AP12TSTNEW]
[thread: 2856]
[dbthread: 4192]
[dbversion: 21.1.1.4]
[dbapibuild: 20210202-20220603]
[dbarch: 64]
[dbso: WINDOWS]
[rpodb: top]
[localfiles: CTREE]
[remark: Emp :01/02 Logged :Administrador SIGAPCP Obj :PCPA200 – Estrutura]
[threadtype: RmtSockThread]
Called from VARINFO(APWEX050.APL) 08/06/2022 16:53:22 line : 382
Called from VARINFO(APWEX050.APL) 08/06/2022 16:53:22 line : 366
Called from VARINFO(APWEX050.APL) 08/06/2022 16:53:22 line : 366
Called from VARINFO(APWEX050.APL) 08/06/2022 16:53:22 line : 366
Boa tarde Mauricio.
Geralmente isso ocorre quando a VarInfo entra em loop nela mesmo, quando as telas são bem pesadas e possuem muitos detalhes e componentes.
Mas se eu não me engano essa tela de Estrutura (PCPA200), ela é em MVC com objetos normais no AddOtherObject.
Então não tem jeito…é em MVC mais eu queria pegar os detalhes dela para usar em um ponto de entrada que tenho que fazer. Na verdade precisava pegar no PE o conteudo do codigo PAI de uma estrutura na alteração, para validar se deixa ou não alterar. Obrigado
Ah entendi Mauricio.
Nesse caso, você poderia solicitar o exemplo do PE no TDN para a TOTVS criar.