Olá pessoal…
Hoje vou mostrar como fazer uma Modelo X em MVC (cadsatro com 3 tabelas – Pai, Filho e Neto).
Abaixo o código fonte completo usado na aula:
//Bibliotecas #Include 'Protheus.ch' #Include 'FWMVCDef.ch' //Variáveis Estáticas Static cTitulo := "Artistas (Mod.X)" /*/{Protheus.doc} zModelX Função de exemplo de Modelo X (Pai, Filho e Neto), com as tabelas de Artistas, CDs e Músicas @author Atilio @since 03/09/2016 @version 1.0 @return Nil, Função não tem retorno @example u_zModelX() /*/ User Function zModelX() 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("ZZ1") //Setando a descrição da rotina oBrowse:SetDescription(cTitulo) //Ativa a Browse oBrowse:Activate() RestArea(aArea) Return Nil /*---------------------------------------------------------------------* | Func: MenuDef | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Criação do menu MVC | *---------------------------------------------------------------------*/ Static Function MenuDef() Local aRot := {} //Adicionando opções ADD OPTION aRot TITLE 'Visualizar' ACTION 'VIEWDEF.zModelX' OPERATION MODEL_OPERATION_VIEW ACCESS 0 //OPERATION 1 Return aRot /*---------------------------------------------------------------------* | Func: ModelDef | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Criação do modelo de dados MVC | *---------------------------------------------------------------------*/ Static Function ModelDef() Local oModel := Nil Local oStPai := FWFormStruct(1, 'ZZ1') Local oStFilho := FWFormStruct(1, 'ZZ2') Local oStNeto := FWFormStruct(1, 'ZZ3') Local aZZ2Rel := {} Local aZZ3Rel := {} //Criando o modelo e os relacionamentos oModel := MPFormModel():New('zModelXM') oModel:AddFields('ZZ1MASTER',/*cOwner*/,oStPai) oModel:AddGrid('ZZ2DETAIL','ZZ1MASTER',oStFilho,/*bLinePre*/, /*bLinePost*/,/*bPre - Grid Inteiro*/,/*bPos - Grid Inteiro*/,/*bLoad - Carga do modelo manualmente*/) //cOwner é para quem pertence oModel:AddGrid('ZZ3DETAIL','ZZ2DETAIL',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(aZZ2Rel, {'ZZ2_FILIAL', 'ZZ1_FILIAL'} ) aAdd(aZZ2Rel, {'ZZ2_CODART', 'ZZ1_COD'}) //Fazendo o relacionamento entre o Filho e Neto aAdd(aZZ3Rel, {'ZZ3_FILIAL', 'ZZ2_FILIAL'} ) aAdd(aZZ3Rel, {'ZZ3_CODART', 'ZZ2_CODART'}) aAdd(aZZ3Rel, {'ZZ3_CODCD', 'ZZ2_CODCD'}) oModel:SetRelation('ZZ2DETAIL', aZZ2Rel, ZZ2->(IndexKey(1))) //IndexKey -> quero a ordenação e depois filtrado oModel:GetModel('ZZ2DETAIL'):SetUniqueLine({"ZZ2_CODCD"}) //Não repetir informações ou combinações {"CAMPO1","CAMPO2","CAMPOX"} oModel:SetPrimaryKey({}) oModel:SetRelation('ZZ3DETAIL', aZZ3Rel, ZZ3->(IndexKey(1))) //IndexKey -> quero a ordenação e depois filtrado oModel:GetModel('ZZ3DETAIL'):SetUniqueLine({"ZZ3_CODMUS"}) //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('ZZ1MASTER'):SetDescription('Modelo Artistas') oModel:GetModel('ZZ2DETAIL'):SetDescription('Modelo CDs') oModel:GetModel('ZZ3DETAIL'):SetDescription('Modelo Musicas') //Adicionando totalizadores oModel:AddCalc('TOTAIS', 'ZZ1MASTER', 'ZZ2DETAIL', 'ZZ2_PRECO', 'XX_VALOR', 'SUM', , , "Valor Total:" ) oModel:AddCalc('TOTAIS', 'ZZ2DETAIL', 'ZZ3DETAIL', 'ZZ3_CODMUS', 'XX_TOTAL', 'COUNT', , , "Total Musicas:" ) Return oModel /*---------------------------------------------------------------------* | Func: ViewDef | | Autor: Daniel Atilio | | Data: 03/09/2016 | | Desc: Criação da visão MVC | | Obs.: / | *---------------------------------------------------------------------*/ Static Function ViewDef() Local oView := Nil Local oModel := FWLoadModel('zModelX') Local oStPai := FWFormStruct(2, 'ZZ1') Local oStFilho := FWFormStruct(2, 'ZZ2') Local oStNeto := FWFormStruct(2, 'ZZ3') Local oStTot := FWCalcStruct(oModel:GetModel('TOTAIS')) //Criando a View oView := FWFormView():New() oView:SetModel(oModel) //Adicionando os campos do cabeçalho e o grid dos filhos oView:AddField('VIEW_ZZ1', oStPai, 'ZZ1MASTER') oView:AddGrid('VIEW_ZZ2', oStFilho, 'ZZ2DETAIL') oView:AddGrid('VIEW_ZZ3', oStNeto, 'ZZ3DETAIL') oView:AddField('VIEW_TOT', oStTot, 'TOTAIS') //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_ZZ1', 'CABEC') oView:SetOwnerView('VIEW_ZZ2', 'GRID') oView:SetOwnerView('VIEW_ZZ3', 'GRID2') oView:SetOwnerView('VIEW_TOT', 'TOTAL') //Habilitando título oView:EnableTitleView('VIEW_ZZ1','Artista') oView:EnableTitleView('VIEW_ZZ2','CDs') oView:EnableTitleView('VIEW_ZZ3','Musicas') //Removendo campos oStFilho:RemoveField('ZZ2_CODART') oStNeto:RemoveField('ZZ3_CODART') oStNeto:RemoveField('ZZ3_CODCD') Return oView
Bom pessoal, por hoje é só.
Abraços e até a próxima.
Boa tarde, Prof Daniel!! Ótima aula! Porém minha situação se difere um pouco, gostaria de saber se tens alguma sugestão:
Tenho um cadastro “ALUNOS”, um segundo cadastro “MATÉRIAS” e um terceiro “ALUNOxMATÉRIAS”. Considerando relacionamento de 1 aluno para N matérias, gostaria de saber como posso fazer a relação entre essas três tabelas( “ALUNOS”,”MATÉRIAS” e “ALUNOxMATÉRIAS”).
Como faço para, no cadastro “ALUNOS”, mostrar as matérias em que este está cadastrado, por exemplo?
ou como posso, no cadastro “ALUNOxMATÉRIAS”, ligar 1 registro da tabela “ALUNOS” a um registro da tabela “MATÉRIAS”?
Se alguém puder ajudar, agradeço!
Bom dia Gabriela, tudo bem?
Vamos por partes então rs… Supondo que seu cadastro de Alunos seja a tabela, SZ1. O de matérias seja SZ3. Ai você irá montar um cadastro vinculando os dois, se você fizer em 1 única tabela (chamada Modelo 2), você teria um campo que faz vínculo na SZ1 e 1 campo na SZ2. Agora se você fizer duas tabelas, uma para vincular o aluno e dados no cabeçalho, como semestre (tabela seria SZ3), você teria que ter uma tabela de itens (SZ4), isso chamamos de Modelo 3. Depois disso, as ligações é só usar o SetRelation. Se quiser, me adicione no Skype, é daniel-atilio. Um grande abraço.
Hola Daniel:
Tengo un MVC con 3 tabelas, SC5, SC6 y ZEP, las dos primeras como sabes son de pedidos de venta, la tercera necesito que esté relacionada con cada linea del detalle (esto ya lo tengo solucionado) pero no quiero que la tercera tabela sea obligatoria, o sea puede haber registros de la SC6 sin registros asociados en la ZEP. No encuentro la manera de evitar esta validación y al querer bajar a la segunda linea de la SC6 me da un mensaje de error: EmptyForm El formulario xxxx (GRD2) no está rellenado.
Se puede solucionar esto?
Atentos Saludos
Bom dia Marcelo, tudo joia?
Rapaz, que situação inusitada. No nosso curso de MVC, eu demonstro em como fazer algo parecido na Aula 09 ( https://terminaldeinformacao.com/2022/04/22/curso-mvc-em-advpl/ ).
Porém é com 3 tabelas customizadas, ai no seu caso são 2 tabelas padrões e 1 só customizada.
Você teria algumas alternativas:
+ Tentar usar o SetOptional nessa GRD2
+ Talvez ao invés de usar a SC6 direto, usar uma FWTemporaryTable
Um grande abraço