Olá pessoal…
Hoje irei mostrar 3 exemplos de rotinas MVC em AdvPL, uma Modelo 1, uma Modelo 3 e uma Modelo X.
Exemplo de Modelo 1 (apenas SBM – Grupo de Produtos), incluindo função de legenda:
Fonte:
//Bibliotecas #Include 'Protheus.ch' #Include 'FWMVCDef.ch' //Variáveis Estáticas Static cTitulo := "Grp.Produtos (Mod.1)" /*/{Protheus.doc} zMVCMd1 Função para cadastro de Grupo de Produtos (SBM), exemplo de Modelo 1 em MVC @author Atilio @since 17/08/2015 @version 1.0 @return Nil, Função não tem retorno @example u_zMVCMd1() @obs Não se pode executar função MVC dentro do fórmulas /*/ User Function zMVCMd1() 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("SBM") //Setando a descrição da rotina oBrowse:SetDescription(cTitulo) //Legendas oBrowse:AddLegend( "SBM->BM_PROORI == '1'", "GREEN", "Original" ) oBrowse:AddLegend( "SBM->BM_PROORI == '0'", "RED", "Não Original" ) //Ativa a Browse oBrowse:Activate() RestArea(aArea) Return Nil /*---------------------------------------------------------------------* | Func: MenuDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação do menu MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function MenuDef() Local aRot := {} //Adicionando opções ADD OPTION aRot TITLE 'Visualizar' ACTION 'VIEWDEF.zMVCMd1' OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1 ADD OPTION aRot TITLE 'Legenda' ACTION 'u_zMVC01Leg' OPERATION 6 ACCESS 0 //OPERATION X //ADD OPTION aRot TITLE 'Incluir' ACTION 'VIEWDEF.zMVCMd1' OPERATION MODEL_OPERATION_INSERT ACCESS 0 //OPERATION 3 //ADD OPTION aRot TITLE 'Alterar' ACTION 'VIEWDEF.zMVCMd1' OPERATION MODEL_OPERATION_UPDATE ACCESS 0 //OPERATION 4 //ADD OPTION aRot TITLE 'Excluir' ACTION 'VIEWDEF.zMVCMd1' OPERATION MODEL_OPERATION_DELETE ACCESS 0 //OPERATION 5 Return aRot /*---------------------------------------------------------------------* | Func: ModelDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação do modelo de dados MVC | | Obs.: / | *---------------------------------------------------------------------*/ 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, "SBM") //Instanciando o modelo, não é recomendado colocar nome da user function (por causa do u_), respeitando 10 caracteres oModel := MPFormModel():New("zMVCMd1M",/*bPre*/, /*bPos*/,/*bCommit*/,/*bCancel*/) //Atribuindo formulários para o modelo oModel:AddFields("FORMSBM",/*cOwner*/,oStSBM) //Setando a chave primária da rotina oModel:SetPrimaryKey({'BM_FILIAL','BM_GRUPO'}) //Adicionando descrição ao modelo oModel:SetDescription("Modelo de Dados do Cadastro "+cTitulo) //Setando a descrição do formulário oModel:GetModel("FORMSBM"):SetDescription("Formulário do Cadastro "+cTitulo) Return oModel /*---------------------------------------------------------------------* | Func: ViewDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação da visão MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function ViewDef() //Criação do objeto do modelo de dados da Interface do Cadastro de Autor/Interprete Local oModel := FWLoadModel("zMVCMd1") //Criação da estrutura de dados utilizada na interface do cadastro de Autor Local oStSBM := FWFormStruct(2, "SBM") //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_SBM", oStSBM, "FORMSBM") //Criando um container com nome tela com 100% oView:CreateHorizontalBox("TELA",100) //Colocando título do formulário oView:EnableTitleView('VIEW_SBM', '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_SBM","TELA") Return oView /*/{Protheus.doc} zMVC01Leg Função para mostrar a legenda das rotinas MVC com grupo de produtos @author Atilio @since 17/08/2015 @version 1.0 @example u_zMVC01Leg() /*/ User Function zMVC01Leg() Local aLegenda := {} //Monta as cores AADD(aLegenda,{"BR_VERDE", "Original" }) AADD(aLegenda,{"BR_VERMELHO", "Não Original"}) BrwLegenda("Grupo de Produtos", "Procedencia", aLegenda) Return
Exemplo de Modelo 3 (SBM – Grupo de Produtos e SB1 – Produtos):
Fonte:
//Bibliotecas #Include 'Protheus.ch' #Include 'FWMVCDef.ch' //Variáveis Estáticas Static cTitulo := "Grp.Produtos (Mod.3)" /*/{Protheus.doc} zMVCMd3 Função para cadastro de Grupo de Produtos (SBM) e Produtos (SB1), exemplo de Modelo 3 em MVC @author Atilio @since 17/08/2015 @version 1.0 @return Nil, Função não tem retorno @example u_zMVCMd3() @obs Não se pode executar função MVC dentro do fórmulas /*/ User Function zMVCMd3() 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("SBM") //Setando a descrição da rotina oBrowse:SetDescription(cTitulo) //Legendas oBrowse:AddLegend( "SBM->BM_PROORI == '1'", "GREEN", "Original" ) oBrowse:AddLegend( "SBM->BM_PROORI == '0'", "RED", "Não Original" ) //Ativa a Browse oBrowse:Activate() RestArea(aArea) Return Nil /*---------------------------------------------------------------------* | Func: MenuDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação do menu MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function MenuDef() Local aRot := {} //Adicionando opções ADD OPTION aRot TITLE 'Visualizar' ACTION 'VIEWDEF.zMVCMd3' OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1 ADD OPTION aRot TITLE 'Legenda' ACTION 'u_zMVC01Leg' OPERATION 6 ACCESS 0 //OPERATION X //ADD OPTION aRot TITLE 'Incluir' ACTION 'VIEWDEF.zMVCMd3' OPERATION MODEL_OPERATION_INSERT ACCESS 0 //OPERATION 3 //ADD OPTION aRot TITLE 'Alterar' ACTION 'VIEWDEF.zMVCMd3' OPERATION MODEL_OPERATION_UPDATE ACCESS 0 //OPERATION 4 //ADD OPTION aRot TITLE 'Excluir' ACTION 'VIEWDEF.zMVCMd3' OPERATION MODEL_OPERATION_DELETE ACCESS 0 //OPERATION 5 Return aRot /*---------------------------------------------------------------------* | Func: ModelDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação do modelo de dados MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function ModelDef() Local oModel := Nil Local oStPai := FWFormStruct(1, 'SBM') Local oStFilho := FWFormStruct(1, 'SB1') Local aSB1Rel := {} //Criando o modelo e os relacionamentos oModel := MPFormModel():New('zMVCMd3M') oModel:AddFields('SBMMASTER',/*cOwner*/,oStPai) oModel:AddGrid('SB1DETAIL','SBMMASTER',oStFilho,/*bLinePre*/, /*bLinePost*/,/*bPre - Grid Inteiro*/,/*bPos - Grid Inteiro*/,/*bLoad - Carga do modelo manualmente*/) //cOwner é para quem pertence //Fazendo o relacionamento entre o Pai e Filho aAdd(aSB1Rel, {'B1_FILIAL', 'BM_FILIAL'} ) aAdd(aSB1Rel, {'B1_GRUPO', 'BM_GRUPO'}) oModel:SetRelation('SB1DETAIL', aSB1Rel, SB1->(IndexKey(1))) //IndexKey -> quero a ordenação e depois filtrado oModel:GetModel('SB1DETAIL'):SetUniqueLine({"B1_FILIAL","B1_COD"}) //Não repetir informações ou combinações {"CAMPO1","CAMPO2","CAMPOX"} oModel:SetPrimaryKey({}) //Setando as descrições oModel:SetDescription("Grupo de Produtos - Mod. 3") oModel:GetModel('SBMMASTER'):SetDescription('Modelo Grupo') oModel:GetModel('SB1DETAIL'):SetDescription('Modelo Produtos') Return oModel /*---------------------------------------------------------------------* | Func: ViewDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação da visão MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function ViewDef() Local oView := Nil Local oModel := FWLoadModel('zMVCMd3') Local oStPai := FWFormStruct(2, 'SBM') Local oStFilho := FWFormStruct(2, 'SB1') //Criando a View oView := FWFormView():New() oView:SetModel(oModel) //Adicionando os campos do cabeçalho e o grid dos filhos oView:AddField('VIEW_SBM',oStPai,'SBMMASTER') oView:AddGrid('VIEW_SB1',oStFilho,'SB1DETAIL') //Setando o dimensionamento de tamanho oView:CreateHorizontalBox('CABEC',30) oView:CreateHorizontalBox('GRID',70) //Amarrando a view com as box oView:SetOwnerView('VIEW_SBM','CABEC') oView:SetOwnerView('VIEW_SB1','GRID') //Habilitando título oView:EnableTitleView('VIEW_SBM','Grupo') oView:EnableTitleView('VIEW_SB1','Produtos') Return oView
Exemplo de Modelo X (SBM – Grupo de Produtos, SB1 – Produtos e SB2 – Saldo por Produto):
Fonte:
//Bibliotecas #Include 'Protheus.ch' #Include 'FWMVCDef.ch' //Variáveis Estáticas Static cTitulo := "Grp.Produtos (Mod.X)" /*/{Protheus.doc} zMVCMdX Função para cadastro de Grupo de Produtos (SBM), Produtos (SB1) e Saldos dos Produtos (SB2), exemplo de Modelo X em MVC @author Atilio @since 17/08/2015 @version 1.0 @return Nil, Função não tem retorno @example u_zMVCMdX() @obs Não se pode executar função MVC dentro do fórmulas /*/ User Function zMVCMdX() 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("SBM") //Setando a descrição da rotina oBrowse:SetDescription(cTitulo) //Legendas oBrowse:AddLegend( "SBM->BM_PROORI == '1'", "GREEN", "Original" ) oBrowse:AddLegend( "SBM->BM_PROORI == '0'", "RED", "Não Original" ) //Ativa a Browse oBrowse:Activate() RestArea(aArea) Return Nil /*---------------------------------------------------------------------* | Func: MenuDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação do menu MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function MenuDef() Local aRot := {} //Adicionando opções ADD OPTION aRot TITLE 'Visualizar' ACTION 'VIEWDEF.zMVCMdX' OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1 ADD OPTION aRot TITLE 'Legenda' ACTION 'u_zMVC01Leg' OPERATION 6 ACCESS 0 //OPERATION X //ADD OPTION aRot TITLE 'Incluir' ACTION 'VIEWDEF.zMVCMdX' OPERATION MODEL_OPERATION_INSERT ACCESS 0 //OPERATION 3 //ADD OPTION aRot TITLE 'Alterar' ACTION 'VIEWDEF.zMVCMdX' OPERATION MODEL_OPERATION_UPDATE ACCESS 0 //OPERATION 4 //ADD OPTION aRot TITLE 'Excluir' ACTION 'VIEWDEF.zMVCMdX' OPERATION MODEL_OPERATION_DELETE ACCESS 0 //OPERATION 5 Return aRot /*---------------------------------------------------------------------* | Func: ModelDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação do modelo de dados MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function ModelDef() Local oModel := Nil Local oStPai := FWFormStruct(1, 'SBM') Local oStFilho := FWFormStruct(1, 'SB1') Local oStNeto := FWFormStruct(1, 'SB2') Local aSB1Rel := {} Local aSB2Rel := {} //Criando o modelo e os relacionamentos oModel := MPFormModel():New('zMVCMdXM') oModel:AddFields('SBMMASTER',/*cOwner*/,oStPai) oModel:AddGrid('SB1DETAIL','SBMMASTER',oStFilho,/*bLinePre*/, /*bLinePost*/,/*bPre - Grid Inteiro*/,/*bPos - Grid Inteiro*/,/*bLoad - Carga do modelo manualmente*/) //cOwner é para quem pertence oModel:AddGrid('SB2DETAIL','SB1DETAIL',oStNeto,/*bLinePre*/, /*bLinePost*/,/*bPre - Grid Inteiro*/,/*bPos - Grid Inteiro*/,/*bLoad - Carga do modelo manualmente*/) //cOwner é para quem pertence //Fazendo o relacionamento entre o Pai e Filho aAdd(aSB1Rel, {'B1_FILIAL', 'BM_FILIAL'} ) aAdd(aSB1Rel, {'B1_GRUPO', 'BM_GRUPO'}) //Fazendo o relacionamento entre o Filho e Neto aAdd(aSB2Rel, {'B2_FILIAL', 'B1_FILIAL'} ) aAdd(aSB2Rel, {'B2_COD', 'B1_COD'}) oModel:SetRelation('SB1DETAIL', aSB1Rel, SB1->(IndexKey(1))) //IndexKey -> quero a ordenação e depois filtrado oModel:GetModel('SB1DETAIL'):SetUniqueLine({"B1_FILIAL","B1_COD"}) //Não repetir informações ou combinações {"CAMPO1","CAMPO2","CAMPOX"} oModel:SetPrimaryKey({}) oModel:SetRelation('SB2DETAIL', aSB2Rel, SB2->(IndexKey(1))) //IndexKey -> quero a ordenação e depois filtrado oModel:GetModel('SB2DETAIL'):SetUniqueLine({"B2_COD","B2_LOCAL","B2_QATU"}) //Não repetir informações ou combinações {"CAMPO1","CAMPO2","CAMPOX"} oModel:SetPrimaryKey({}) //Setando as descrições oModel:SetDescription("Grupo de Produtos - Mod. X") oModel:GetModel('SBMMASTER'):SetDescription('Modelo Grupo') oModel:GetModel('SB1DETAIL'):SetDescription('Modelo Produtos') oModel:GetModel('SB2DETAIL'):SetDescription('Modelo Saldos') //Adicionando totalizadores oModel:AddCalc('TOT_SALDO', 'SB1DETAIL', 'SB2DETAIL', 'B2_QATU', 'XX_TOTAL', 'SUM', , , "Saldo Total:" ) Return oModel /*---------------------------------------------------------------------* | Func: ViewDef | | Autor: Daniel Atilio | | Data: 17/08/2015 | | Desc: Criação da visão MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function ViewDef() Local oView := Nil Local oModel := FWLoadModel('zMVCMdX') Local oStPai := FWFormStruct(2, 'SBM') Local oStFilho := FWFormStruct(2, 'SB1') Local oStNeto := FWFormStruct(2, 'SB2') Local oStTot := FWCalcStruct(oModel:GetModel('TOT_SALDO')) //Estruturas das tabelas e campos a serem considerados Local aStruSBM := SBM->(DbStruct()) Local aStruSB1 := SB1->(DbStruct()) Local aStruSB2 := SB2->(DbStruct()) Local cConsSBM := "BM_GRUPO;BM_DESC;BM_PROORI" Local cConsSB1 := "B1_COD;B1_DESC;B1_TIPO;B1_UM;B1_LOCPAD" Local cConsSB2 := "B2_LOCAL;B2_QATU" Local nAtual := 0 //Criando a View oView := FWFormView():New() oView:SetModel(oModel) //Adicionando os campos do cabeçalho e o grid dos filhos oView:AddField('VIEW_SBM',oStPai,'SBMMASTER') oView:AddGrid('VIEW_SB1',oStFilho,'SB1DETAIL') oView:AddGrid('VIEW_SB2',oStNeto,'SB2DETAIL') oView:AddField('VIEW_TOT', oStTot,'TOT_SALDO') //Setando o dimensionamento de tamanho oView:CreateHorizontalBox('CABEC',20) oView:CreateHorizontalBox('GRID',40) oView:CreateHorizontalBox('GRID2',27) oView:CreateHorizontalBox('TOTAL',13) //Amarrando a view com as box oView:SetOwnerView('VIEW_SBM','CABEC') oView:SetOwnerView('VIEW_SB1','GRID') oView:SetOwnerView('VIEW_SB2','GRID2') oView:SetOwnerView('VIEW_TOT','TOTAL') //Habilitando título oView:EnableTitleView('VIEW_SBM','Grupo') oView:EnableTitleView('VIEW_SB1','Produtos') oView:EnableTitleView('VIEW_SB2','Saldos') //Percorrendo a estrutura da SBM For nAtual := 1 To Len(aStruSBM) //Se o campo atual não estiver nos que forem considerados If ! Alltrim(aStruSBM[nAtual][01]) $ cConsSBM oStPai:RemoveField(aStruSBM[nAtual][01]) EndIf Next //Percorrendo a estrutura da SB1 For nAtual := 1 To Len(aStruSB1) //Se o campo atual não estiver nos que forem considerados If ! Alltrim(aStruSB1[nAtual][01]) $ cConsSB1 oStFilho:RemoveField(aStruSB1[nAtual][01]) EndIf Next //Percorrendo a estrutura da SB2 For nAtual := 1 To Len(aStruSB2) //Se o campo atual não estiver nos que forem considerados If ! Alltrim(aStruSB2[nAtual][01]) $ cConsSB2 oStNeto:RemoveField(aStruSB2[nAtual][01]) EndIf Next Return oView
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Primeiramente, parabéns pelo site, tem um ótimo conteúdo. Agora algumas perguntas, onde eu posso encontrar material para estudar o modo MVC de programar? Existem cursos? Esta é uma nova tendência para o ERP da TOTVS? O ADVPL morreu??? Obrigado e novamente parabéns.
Boa noite Diego.
Muito Obrigado.
Então, o único material que encontrei pela internet foi pelo TDN: http://tdn.totvs.com/display/public/mp/AdvPl+utilizando+MVC;jsessionid=37539EC97401D95FDC5DEB859A57DB32
Agora, cursos, não sei se existem, acho que não, estava pensando em fazer vídeo-aulas explicando um pouco.
E sim, é uma nova tendência, pois querem facilitar o desenvolvimento.
Quanto ao AdvPL, ele continua vivo e forte, rs… na verdade MVC é apenas uma Tecnologia utilizada pelo AdvPL.
Agradeço novamente e um grande abraço.
Boa noite Diego.
Achei um link que possa te ajudar, são algumas aulas de um amigo meu, o Eurai do UniversoAdvPL. Segue o link:
http://www.universoadvpl.com/2015/05/13-advpl-f-introducao-mvc/
Um grande abraço.
Bom dia Dan, obrigado pelo link, vou lá verificar.
Que isso.
Eu que agradeço.
Abraços.
Gostei muito do seu artigo. Tô com uma dificuldade aqui para mostrar os dados de campos que são virtuais na tabela filha. Esses campos são preenchidos por uma consulta padrão , na edição funciona bem , mas quando volto no cadastro ele não traz os dados, mesmo eu colocando a propriedade “inic. browse” no configutador.
Boa noite Silfar.
Agradeço o apoio.
Primeiramente, teria como mandar aqui o trecho do seu inic browse e do seu inic padrão?
Um grande abraço.
Olá!
Estou utilizando seus fontes para tentar aprender, usei como base a tabela SN1, criei duas tabelas com informações complementares, há algum problema no relacionamento porque a rotina mostra o SN1 normalmente mas os dados das duas tabelas integradas, não. Você tem alguma dica para o relacionamento entre as tabelas ?
Boa noite Adailton, tudo bem?
Se for tabelas padrão, e você precisa descobrir o relacionamento, você pode usar a tabela SX9, e verificar as chaves de relacionamento.
Agora quando é tabelas customizadas e índices customizados, recomendo sempre os campos chave terem o mesmo tamanho, por exemplo, o campo produto tem 15 caracteres, vou criar um campo em uma tabela, com o mesmo tamanho.
Seria essa a dúvida? Ou seria alguma outra observação?
Abraços.
Obrigado pela resposta!
Mais ou menos por ai! As duas tabelas que se relacionam com o SN1 são complementos de ativos que foram penhorados ou garantidos. Acredito que o problema esteja ocorrendo porque a tabela SN1 está compartilhada e as duas tabelas customizadas estão exclusivas. A chave entre elas é Filial+CodigoBase+Item, tentei diferentes maneiras no SetRelation mas não consegui o relacionamento.
Abraços.
Boa noite Adailton ,tudo bem?
Você poderia alterar o Array de relacionamento, por exemplo (vou utilizar a SB1 e SBM):
Você poderia alterar para:
É que nos exemplos que criei, as tabelas estavam todas ou compartilhadas ou exclusivas.
Teste dessa forma e verifique se deu certo.
Um grande abraço.
Boa noite!
Funcionou, obrigado.
Sabe de algum fórum especificamente sobre MVC ?
Se tivesse algum forum, as vezes minhas dúvidas poderiam já ter sido respondidas.
Minha dúvida atual é como preencher um campo automaticamente no detalhe a partir de um dado da master.
Boa noite Adailton, tudo bem?
Vixe, um fórum sobre MVC desconheço, porém se quiser, no meu canal no YouTube, irei postar algumas aulas de MVC, dicas rápidas sabe… se quiser se inscrever e acompanhar, segue o link:
https://www.youtube.com/channel/UCiSSA_yn20tEQdEbfo-yBKw
Quanto ao preencher o dado, irei pesquisar e tentar desenvolver algo.
Um grande abraço.
Bom dia,
Dentro do grid existe a possibilidade de inserirmos legenda?
Boa noite Wanderson.
Tentei verificar as documentações da FWFormView e da MPFormModel, não consegui encontrar nada sobre legenda ou cores nas linhas das grids.
Se eu encontrar algo entro em contato.
Um grande abraço.
Complementando a pergunta do nosso amigo Silfar estou com o mesmo problema:
Tenho 4 tabelas customizadas no meu modelo za1 seria field, e nas 3 grids, no segundo grid eu tenho um campo virtual, que é montado atraves do primeiro campo do segundo grid, a consulta padrao deste campo funciona, traz direitinho, porem quando seleciono, o campo virtual que esta no meu grid nao atualiza com a informação virtual, apesar do campo que o monta estar preenchido.
Como devo fazer??
Boa noite Felipo, tudo bem?
Se eu entendi, você tem um campo F3, e um campo Virtual, é isso? E seu campo virtual não é preenchido, seria isso?
Se sim, tente alterar o atributo de Inicializador Padrão do campo virtual, e também verifique se no dicionário de dados, existem gatilhos criados para a sua tabela, pode ser que falte algum gatilho, ou que algum interfira em outro.
Um grande abraço.
Boa tarde meu amigo, estou usando o MVC e usei o oModel:AddCalc para jogar um campo totalizador na tela, mas nos exemplos que procurei tem apenas 1 campo totalizado, tentei adicionar 2 campos mas não consegui, tem algum modelo que tenha 2 ou mais campos totalizadores na tela?
Boa tarde Alexandre, tudo bem?
Basta, adicionar um embaixo, mudando apenas o nome do get, o campo que quer totalizar, e o tipo de totalização, ficando assim (usei como base o meu exemplo da Modelo X):
Com isso, já será gerado dois campos, como na ViewDef, adicionamos um box para o TOT_SALDO, ele já entenderá que é para buscar os dois gets.
Espero ter ajudado.
Qualquer dúvida, fico à disposição.
Abraços.
Grande Daniel San, acompanho o seu blog e suas dicas sempre que recebo o newsletter, e agradeço pelas dicas que me dá quando necessito.
Um abraço ..
Fala Patini San.
Muito Obrigado jovem.
Um grande abraço.
Boa tarde Daniel, Queria saber como faço para executar um bloco de código assim que desse um Clique duplo na Grid. Abraços
Boa noite Neudo.
Mas ao dar duplo clique na grid, vc iria para a edição de um campo, certo?
Porque dae, você estaria substituindo a tratativa padrão do framework, em teoria é possível, mas na prática nunca precisei fazer.
Obrigado Daniel! Abraços!
Eu que agradeço Neudo.
Um grande abraço.
Ola Daniel estou precisando de um exemplo MVC modelo 2.
Voce tem um para me passar
Boa noite Andrea, tudo bem?
Eu não tenho, mas estou montando, estando disponível, postarei aqui no site.
Aguarde novidades.
Abraços.
Estou precisando utilizar parâmetros, mas da forma que era antes não estou conseguindo (validperg() e pergunte()). Tem alguma dica de como utilizar filtro?
oModel:GetModel( ‘SRDDETAIL’ ):SetLoadFilter( { { ‘RD_DATARQ’, “MV_PAR01”, MVC_LOADFILTER_GREATER_EQUAL }, { ‘RD_DATARQ’, “MV_PAR02”, MVC_LOADFILTER_LESS_EQUAL } } )
Boa tarde Pedroza, tudo bem?
Tentou passar o conteúdo do parâmetro, ao invés do nome dele?
Por exemplo.
Qualquer dúvida, fico à disposição.
Abraços.
Todo material que vejo sobre mvc no advpl é sempre ligado a cadastros, o intuito é so para rotinas de cadastros mesmo? Nao vi grande vantagem… já utilizou em algum outro contexto?
Boa noite Felipe.
Então, não sei se na matriz podem ter outros focos, mas eu como programador em franquia e em clientes, 90% dos casos que utilizei MVC foi em cadastros, os outros 10% foi em Jobs com SchedDef.
Abraços.
Olá gostaria de saber se tem como criar um formulário com duas folders e em cada uma delas utilizar a classe: FWMarkBrowse?
Boa noite Ivan.
Olha, eu nunca fiz com FWMarkBrowse, mas acho q pode ser possível.
O que já fiz, foi nas Dialogs antigas, desenvolver com o MsSelect.
Abraços.
Dan_Atilio,
Você como faço para ocultar os campos virtuais do dicionário no cabeçalho e nos Grids? Por exemplo, no seu código abaixo você diz que se não estiver dentro da variável, o programa remove, de fato remove, mas não os virtuais.
Ex: //Percorrendo a estrutura da SB2
For nAtual := 1 To Len(aStruSB2)
//Se o campo atual não estiver nos que forem considerados
If ! Alltrim(aStruSB2[nAtual][01]) $ cConsSB2
oStNeto:RemoveField(aStruSB2[nAtual][01])
EndIf
Next
Boa noite Regis, tudo bem?
Rapaz, não havia percebido isso.
Tente remover no ModelDef então, além do ViewDef.
Boa tarde Dan_Atilio,
voce teria como disponibilizar o completo do modelo Exemplo de MVC – Modelo X, com as opções de inclusão e alteração??
abc
Boa noite Matheus, tudo bem?
Dê uma olhada na vídeo aula de número 18:
https://terminaldeinformacao.com/2016/08/04/vd-advpl-018/
Abraços.
boa tarde, voce teria algum exemplo com modelo 2 em mvc, preciso criar uma rotina para a src..
Bom dia Breno, tudo bem?
Sim, olhe esse link, tem a vídeo aula que ensino como fazer, e o código fonte:
https://terminaldeinformacao.com/2017/01/30/vd-advpl-025/
Abraços.
Boa tarde professor, gostaria de saber se é possível pegar o valor do campo XX_TOTAL e salvar no banco de dados, como se fosse um campo real, ou fazer tipo um gatilho para alimentar um campo que já esta cadastro no banco
Bom dia Antonio, tudo bem?
Eu nunca fiz, irei tentar fazer aqui em minha base de teste.
O que você pode tentar fazer, é tentar dar um GetModel no cálculo para ver se retorna algo (tendo um tempo irei pesquisar e ver se consigo achar algo nesse sentido).
Bom dia,
Como faço para no totalizar retornar o valor final, fazendo (Credito soma), (Débito diminui) na colua XX_TOTAL, pois estou usando a seguinte:
//Adicionando totalizadores
oModel:AddCalc(‘TOT_SALDO’, ‘SRATITLE’, ‘SZOMASTER’, ‘ZO_QTDE’, ‘XX_TOTAL’, ‘SUM’, , , “Saldo Total:” )
Bom dia.
Conforme documentação no manual oficial ( https://tdn.totvs.com/display/public/PROT/AdvPl+utilizando+MVC ), você deve poderia usar o tipo FORMULA ao invés do SUM, e preencher o bFormula.
Ou você poderia continuar usando o SUM, porém precisaria preencher o bCond para montar a condição.
Página 64 do link citado possui exemplos.
Como faço para colocar uma condições nos dados da minha view principal ?
Então Ricardo, recomendo que veja nossa aula gratuita nesse link – https://www.youtube.com/watch?v=iG1WClMfMiQ
Dan boa noite, tudo bem ? Parabéns pelo conteúdo do site.
Pode me ajudar ? Ao inserir um produto na linha 3, preciso verificar se na linha 1 ou na linha 2 esse produto já existe. Se existir preciso replicar o preço unitário já informado anteriormente para a linha 3. Por exemplo na linha 3, digito o produto e imediatamente pesquisa nas linhas se esse produto já existe. Se existir replico o preço unitário da linha encontrada para a linha 3. Como fazer isso ?
Bom dia Rosange, obrigado pelo feedback.
A lógica para percorrer a grid seria mais ou menos assim:
1. No seu AddGrid no ModelDef, adicione um bloco de código ao validar a linha (bLinePost, por exemplo, {|| u_zSuaFuncao()}
2. Nessa sua função customizada, você vai pegar o modelo de dados ativo (oModel := FWModelActivate())
3. Então irá pegar a grid desse model (oModelDet := oModel:GetModel(“XXXDETAIL”))
4. Irá fazer um laço de repetição, percorrendo do 1 ao tamanho da sua grid (oModelDet:Length())
5. Dentro do laço, você posiciona na linha atual, por exemplo, posiciono na linha 2, 3, 4, etc (oModelDet:GoLine(nSuaLinhaDoForOuWhile))
6. Então, você pode buscar o valor, com GetValue (oModelDet:LoadValue(“CAMPO_PRECO_UNITARIO”))
Ai basta você adaptar com suas necessidades para replicar para outra linha com a lógica ai da empresa.
Espero ter ajudado.
Abraços.
Só passei por aqui para agradecer este site me ajuda muito…
Opa, eu que agradeço pelo comentário Cesar.
Grande abraço.
Atilio você tem um exemplo de PE em MVC que inclua um campo em uma linha de Browse sendo que esse browse foi montado com alguns campos fixados ?
Bom dia Antonio, tudo bem?
Você diz, manipular a Struct da tabela usada em uma grid, e adicionar campos?
Se for, tem um exemplo, de um ponto de entrada gentilmente disponibilizado pelo grande Alison Lemes, segue o link: https://terminaldeinformacao.com/knowledgebase/adicao-de-colunas-em-p-e-mvc-gtpa283/
Um grande abraço.
Isso mesmo, obrigado.