Olá pessoal…
Na vídeo aula de hoje irei mostrar como construir um Modelo 1 (cadastro que utiliza apenas 1 tabela) em AdvPL, utilizando o conceito de MVC.
Fonte de Exemplo:
//Bibliotecas #Include 'Protheus.ch' #Include 'FWMVCDef.ch' //Variáveis Estáticas Static cTitulo := "Artista" /*/{Protheus.doc} zModel1 Exemplo de Modelo 1 para cadastro de Artistas @author Atilio @since 31/07/2016 @version 1.0 @return Nil, Função não tem retorno @example u_zModel1() /*/ User Function zModel1() Local aArea := GetArea() Local oBrowse Local cFunBkp := FunName() SetFunName("zModel1") //Instânciando FWMBrowse - Somente com dicionário de dados oBrowse := FWMBrowse():New() //Setando a tabela de cadastro de Autor/Interprete oBrowse:SetAlias("ZZ1") //Setando a descrição da rotina oBrowse:SetDescription(cTitulo) //Legendas oBrowse:AddLegend( "ZZ1->ZZ1_COD <= '000005'", "GREEN", "Menor ou igual a 5" ) oBrowse:AddLegend( "ZZ1->ZZ1_COD > '000005'", "RED", "Maior que 5" ) //Filtrando //oBrowse:SetFilterDefault("ZZ1->ZZ1_COD >= '000000' .And. ZZ1->ZZ1_COD <= 'ZZZZZZ'") //Ativa a Browse oBrowse:Activate() SetFunName(cFunBkp) RestArea(aArea) Return Nil /*---------------------------------------------------------------------* | Func: MenuDef | | Autor: Daniel Atilio | | Data: 31/07/2016 | | Desc: Criação do menu MVC | *---------------------------------------------------------------------*/ Static Function MenuDef() Local aRot := {} //Adicionando opções ADD OPTION aRot TITLE 'Visualizar' ACTION 'VIEWDEF.zModel1' OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1 ADD OPTION aRot TITLE 'Legenda' ACTION 'u_zMod1Leg' OPERATION 6 ACCESS 0 //OPERATION X ADD OPTION aRot TITLE 'Incluir' ACTION 'VIEWDEF.zModel1' OPERATION MODEL_OPERATION_INSERT ACCESS 0 //OPERATION 3 ADD OPTION aRot TITLE 'Alterar' ACTION 'VIEWDEF.zModel1' OPERATION MODEL_OPERATION_UPDATE ACCESS 0 //OPERATION 4 ADD OPTION aRot TITLE 'Excluir' ACTION 'VIEWDEF.zModel1' OPERATION MODEL_OPERATION_DELETE ACCESS 0 //OPERATION 5 Return aRot /*---------------------------------------------------------------------* | Func: ModelDef | | Autor: Daniel Atilio | | Data: 31/07/2016 | | Desc: Criação do modelo de dados MVC | *---------------------------------------------------------------------*/ Static Function ModelDef() //Criação do objeto do modelo de dados Local oModel := Nil //Criação da estrutura de dados utilizada na interface Local oStZZ1 := FWFormStruct(1, "ZZ1") //Editando características do dicionário oStZZ1:SetProperty('ZZ1_COD', MODEL_FIELD_WHEN, FwBuildFeature(STRUCT_FEATURE_WHEN, '.F.')) //Modo de Edição oStZZ1:SetProperty('ZZ1_COD', MODEL_FIELD_INIT, FwBuildFeature(STRUCT_FEATURE_INIPAD, 'GetSXENum("ZZ1", "ZZ1_COD")')) //Ini Padrão oStZZ1:SetProperty('ZZ1_DESC', MODEL_FIELD_VALID, FwBuildFeature(STRUCT_FEATURE_VALID, 'Iif(Empty(M->ZZ1_DESC), .F., .T.)')) //Validação de Campo oStZZ1:SetProperty('ZZ1_DESC', MODEL_FIELD_OBRIGAT, Iif(RetCodUsr()!='000000', .T., .F.) ) //Campo Obrigatório //Instanciando o modelo, não é recomendado colocar nome da user function (por causa do u_), respeitando 10 caracteres oModel := MPFormModel():New("zModel1M",/*bPre*/, /*bPos*/,/*bCommit*/,/*bCancel*/) //Atribuindo formulários para o modelo oModel:AddFields("FORMZZ1",/*cOwner*/,oStZZ1) //Setando a chave primária da rotina oModel:SetPrimaryKey({'ZZ1_FILIAL','ZZ1_COD'}) //Adicionando descrição ao modelo oModel:SetDescription("Modelo de Dados do Cadastro "+cTitulo) //Setando a descrição do formulário oModel:GetModel("FORMZZ1"):SetDescription("Formulário do Cadastro "+cTitulo) Return oModel /*---------------------------------------------------------------------* | Func: ViewDef | | Autor: Daniel Atilio | | Data: 31/07/2016 | | Desc: Criação da visão MVC | *---------------------------------------------------------------------*/ Static Function ViewDef() Local aStruZZ1 := ZZ1->(DbStruct()) //Criação do objeto do modelo de dados da Interface do Cadastro de Autor/Interprete Local oModel := FWLoadModel("zModel1") //Criação da estrutura de dados utilizada na interface do cadastro de Autor Local oStZZ1 := FWFormStruct(2, "ZZ1") //pode se usar um terceiro parâmetro para filtrar os campos exibidos { |cCampo| cCampo $ 'SZZ1_NOME|SZZ1_DTAFAL|'} //Criando oView como nulo Local oView := Nil //Criando a view que será o retorno da função e setando o modelo da rotina oView := FWFormView():New() oView:SetModel(oModel) //Atribuindo formulários para interface oView:AddField("VIEW_ZZ1", oStZZ1, "FORMZZ1") //Criando um container com nome tela com 100% oView:CreateHorizontalBox("TELA",100) //Colocando título do formulário oView:EnableTitleView('VIEW_ZZ1', 'Dados - '+cTitulo ) //Força o fechamento da janela na confirmação oView:SetCloseOnOk({||.T.}) //O formulário da interface será colocado dentro do container oView:SetOwnerView("VIEW_ZZ1","TELA") /* //Tratativa para remover campos da visualização For nAtual := 1 To Len(aStruZZ1) cCampoAux := Alltrim(aStruZZ1[nAtual][01]) //Se o campo atual não estiver nos que forem considerados If Alltrim(cCampoAux) $ "ZZ1_COD;" oStZZ1:RemoveField(cCampoAux) EndIf Next */ Return oView /*/{Protheus.doc} zMod1Leg Função para mostrar a legenda @author Atilio @since 31/07/2016 @version 1.0 @example u_zMod1Leg() /*/ User Function zMod1Leg() Local aLegenda := {} //Monta as cores AADD(aLegenda,{"BR_VERDE", "Menor ou igual a 5" }) AADD(aLegenda,{"BR_VERMELHO", "Maior que 5"}) BrwLegenda(cTitulo, "Status", aLegenda) Return
Se quiser fazer o download desse código ou do conteúdo mostrado na vídeo aula, acesse nosso GitHub pelo link github.com/dan-atilio/AdvPL (Exemplos > Vídeo Aulas > 018 – Modelo 1 em MVC).
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Parabéns Daniel!
Boa noite Artur.
Eu que agradeço.
Um grande abraço.
Olá. Muito bom seu post. Eu segui seu exemplo mas o menu não aparece na view. Estou usando o Protheus 11
Boa noite Marcio, tudo bem?
Você está testando no Fórmulas? Se sim, está utilizando o SetFunName?
Lembrando que é recomendável utilizar um nome até 7 caracteres para User Function em MVC.
Fico no aguardo.
Abraços.
eu consegui resolver o problema chamando a função menuDef() dentro da função de usuário. Obrigado pela disponibilidade.
Ai sim.
Um grande abraço.
Boa tarde eu tambem estou com este problema, e estou chamando a função diretamente pelo menu, perem a tela abre mas o menu não aparece
Obrigado pela atenção e parabens pelo post
Boa noite Allan, tudo bem?
Você poderia verificar algumas dessas sugestões:
– O nome do prw e da User Function deve ter 7 caracteres
– A utilização do SetFunName
– Chamar a função MenuDef conforme sugestão do Marcio
Caso continue o problema, me mande o prw para eu dar uma analisada.
Abraços.
ola… bom dia, seria interessante um exemplo de reutilizacao em MVC, utilizando um webservice ou outra aplicacao de fora…. o que achas ?
Boa noite.
Sim, pretendo quando acabar a série de MVC, fazer uma série de WebServices, e postar sobre o assunto.
Um grande abraço.
Teria algum exemplo de reutilizacao de codigo usando o MVC ? seria interessantissimo
Boa noite Divair.
Tente ver a aula 24 – https://terminaldeinformacao.com/2017/01/23/vd-advpl-024/
Ai veja a rotina FWMVCRotAuto.
Um grande abraço.
Olá, tudo bem?
Estou estudando suas vídeo-aulas sobre MVC. Eu baixei o fonte zModel1 e compilei, criei a tabela e ao executa-lo do menu, não mostra as opções do axcadastro, interessante se eu chamo do formulas, funciona.
Tem um outro fonte seu, o zMVCMd1, ele está funcionando normal, abrindo o SBM, ele mostra certinho as opções do axcadastro, eu alterei ele para abrir o ZZ1, e, não mostra as opções. Mudei o modo de chamar no menu incluindo u_zModel1, recriei a tabela e etc.. Nada faz aparecer as opçoes. Tem alguma ideia do que poderia ser?
Leia-se aRotina no lugar de axcadastro.
Boa noite Rodrigues tudo bem?
Rapaz que estranho, geralmente quando o nome da função passa de 7 caracteres pode acontecer isso.
Enfim, me mande o fonte para que eu possa ver se encontro algo.
Abraços.
Boa Tarde Atilio, esta acontecendo a mesma coisa comigo ref. aRotina nao aparecer sendo executada pelo xnu, agora quando executamos por LP-Formulas ele traz aRotina mas não traz o filtro ja fiz de tudo ate segui os seus conselhos de diminuir o nome do fonte e função para 7 posições e mesmo assim nao funciona corretamente. O que podemos fazer ? ABS. Fábio
Boa noite Fabio.
Se possível, me mande o fonte para que eu possa analisar essa questão.
Um grande abraço.
Olá Atilio
ele traz a tela e menu.. mas quando clico em qualquer botao ele nao faz nada e retorna erro
variable is not an object on FWFORMBROWSE:DESTROY(FWFORMBROWSE.PRW) 01/04/2020 19:16:48 line : 2434
Muito obrigado
segue o meu programa
#Include ‘Protheus.ch’
#Include ‘FWMVCDef.ch’
//Variáveis Estáticas
Static cTitulo := “Cadastro de Parceiros”
User Function SBBRWSZ6()
Local aArea := GetArea()
Local oBrowse
//Instânciando FWMBrowse – Somente com dicionário de dados
oBrowse := FWMBrowse():New()
//Setando a tabela de cadastro de Autor/Interprete
oBrowse:SetAlias(“SZ6”)
//Setando a descrição da rotina
oBrowse:SetDescription(cTitulo)
//Legendas
oBrowse:AddLegend( “SZ6->Z6_MSBLQL == ‘2’”, “GREEN”, “Ativo” )
oBrowse:AddLegend( “SZ6->Z6_MSBLQL == ‘1’”, “RED”, “Inativo” )
//Ativa a Browse
oBrowse:Activate()
RestArea(aArea)
Return Nil
Static Function MenuDef()
Local aRot := {}
//Adicionando opções
ADD OPTION aRot TITLE ‘Visualizar’ ACTION ‘PesqBrw’ OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1
ADD OPTION aRot TITLE ‘Legenda’ ACTION ‘VIEWDEF.SBBRWSZ6’ OPERATION 6 ACCESS 0 //OPERATION X
ADD OPTION aRot TITLE ‘Incluir’ ACTION ‘VIEWDEF.SBBRWSZ6’ OPERATION MODEL_OPERATION_INSERT ACCESS 0 //OPERATION 3
ADD OPTION aRot TITLE ‘Alterar’ ACTION ‘VIEWDEF.SBBRWSZ6’ OPERATION MODEL_OPERATION_UPDATE ACCESS 0 //OPERATION 4
ADD OPTION aRot TITLE ‘Excluir’ ACTION ‘VIEWDEF.SBBRWSZ6’ OPERATION MODEL_OPERATION_DELETE ACCESS 0 //OPERATION 5
Return aRot
Static Function ModelDef()
//Criação do objeto do modelo de dados
Local oModel := Nil
//Criação da estrutura de dados utilizada na interface
Local oStSBM := FWFormStruct(1, “SZ6”)
//Instanciando o modelo, não é recomendado colocar nome da user function (por causa do u_), respeitando 10 caracteres
oModel := MPFormModel():New(“SBBRWSZ6”,/*bPre*/, /*bPos*/,/*bCommit*/,/*bCancel*/)
//Atribuindo formulários para o modelo
oModel:AddFields(“FORMSZ6”,/*cOwner*/,oStSBM)
//Setando a chave primária da rotina
oModel:SetPrimaryKey({‘Z6_FILIAL’,’Z6_CUPOM’})
//Adicionando descrição ao modelo
oModel:SetDescription(“Modelo de Dados do Cadastro “+cTitulo)
//Setando a descrição do formulário
oModel:GetModel(“FORMSZ6”):SetDescription(“Formulário do Cadastro “+cTitulo)
Return oModel
Static Function ViewDef()
//Criação do objeto do modelo de dados da Interface do Cadastro de Autor/Interprete
Local oModel := FWLoadModel(“SBBRWSZ6”)
//Criação da estrutura de dados utilizada na interface do cadastro de Autor
Local oStSBM := FWFormStruct(2, “SZ6”) //pode se usar um terceiro parâmetro para filtrar os campos exibidos { |cCampo| cCampo $ ‘SBM_NOME|SBM_DTAFAL|’}
//Criando oView como nulo
Local oView := Nil
//Criando a view que será o retorno da função e setando o modelo da rotina
oView := FWFormView():New()
oView:SetModel(oModel)
//Atribuindo formulários para interface
oView:AddField(“VIEW_SZ6”, oStSBM, “FORMSZ6”)
//Criando um container com nome tela com 100%
oView:CreateHorizontalBox(“TELA”,100)
//Colocando título do formulário
oView:EnableTitleView(‘VIEW_SZ6’, ‘Dados do Grupo de Produtos’ )
//Força o fechamento da janela na confirmação
oView:SetCloseOnOk({||.T.})
//O formulário da interface será colocado dentro do container
oView:SetOwnerView(“VIEW_SZ6″,”TELA”)
Return oView
Analisando por cima, notei uma coisa, o nome da user function e do model estão iguais.
Recomendo deixar o nome da user function e do prw iguais, ambos com 7 caracteres, por exemplo, SZ6BRW.
Ai no seu Model, coloque um M na frente, ficando, SZ6BRW.
Se quiser fazer um teste, entre no Autumn Code Maker, gere um código simples de cadastro em MVC.
Link: https://autumncodemaker.com
oModel := MPFormModel():New(“SBBRWSZ6”,/*bPre*/, /*bPos*/,/*bCommit*/,/*bCancel*/)
Esse MODEL não pode ter mais que 7 caracteres e não pode ser o mesmo nome da Function.
Bom dia jovem, tudo bem?
Acho que não entendi o comentário, se for alguma dúvida quanto ao comentário que citei, é que esse artigo e conteúdo são de agosto de 2016 (na época ainda era o Protheus 11, imagine a LIB ou outros recursos rs).
Enfim, eu lancei um artigo em Janeiro de 2021, explicando o problema de ter o nome da function ser igual ao MPFormModel e nele eu cito que é possível sim usar 8 caracteres, mas eu recomendo para os meus alunos usarem 7, para que fique sobrando um caractere, e eles usem esse no ponto de entrada.
O artigo que mencionei, é este: https://terminaldeinformacao.com/2021/01/06/o-que-pode-ser-quando-botoes-nao-funcionam-em-mvc/
Se não for essa a sua dúvida, e puder detalhar o que esta acontecendo, fico à disposição também.
Grande abraço.