Exemplos de rotinas MVC em AdvPL

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:

Exemplo de MVC - Modelo 1
Exemplo de MVC – Modelo 1

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):

Exemplo de MVC - Modelo 3
Exemplo de MVC – Modelo 3

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):

Exemplo de MVC - Modelo X
Exemplo de MVC – Modelo X

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

Esses e outros códigos, estão disponíveis gratuitamente no nosso GitHub, acesse em github.com/dan-atilio/AdvPL.

Bom pessoal, por hoje é só.
Abraços e até a próxima.

About Dan_Atilio

Analista e desenvolvedor de sistemas. Técnico em Informática pelo CTI da Unesp. Graduado em Banco de Dados pela Fatec Bauru. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor do projeto Terminal de Informação, onde são postados tutoriais e notícias envolvendo o mundo da tecnologia.

33 opiniões sobre “Exemplos de rotinas MVC em AdvPL

  • agosto 26, 2015 em 3:54 pm
    Permalink

    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.

    Resposta
  • setembro 22, 2015 em 1:45 pm
    Permalink

    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.

    Resposta
    • setembro 22, 2015 em 10:12 pm
      Permalink

      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.

      Resposta
  • dezembro 17, 2015 em 3:12 pm
    Permalink

    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 ?

    Resposta
    • dezembro 20, 2015 em 10:23 pm
      Permalink

      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.

      Resposta
      • dezembro 21, 2015 em 7:03 am
        Permalink

        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.

        Resposta
        • dezembro 21, 2015 em 9:55 pm
          Permalink

          Boa noite Adailton ,tudo bem?
          Você poderia alterar o Array de relacionamento, por exemplo (vou utilizar a SB1 e SBM):

          aAdd(aSB1Rel, {'B1_FILIAL', 'BM_FILIAL'} )
          aAdd(aSB1Rel, {'B1_GRUPO',  'BM_GRUPO'}) 
          

          Você poderia alterar para:

          aAdd(aSB1Rel, {'B1_FILIAL', 'FWxFilial("SB1")'} )
          aAdd(aSB1Rel, {'B1_GRUPO',  'BM_GRUPO'}) 
          

          É 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.

        • dezembro 22, 2015 em 4:08 pm
          Permalink

          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.

        • dezembro 27, 2015 em 9:58 pm
          Permalink

          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.

  • fevereiro 17, 2016 em 11:25 am
    Permalink

    Bom dia,

    Dentro do grid existe a possibilidade de inserirmos legenda?

    Resposta
    • fevereiro 17, 2016 em 11:52 pm
      Permalink

      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.

      Resposta
  • abril 13, 2016 em 7:03 pm
    Permalink

    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??

    Resposta
    • abril 21, 2016 em 10:46 pm
      Permalink

      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.

      Resposta
  • julho 8, 2016 em 6:27 pm
    Permalink

    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?

    Resposta
    • julho 10, 2016 em 6:08 pm
      Permalink

      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):

      	//Adicionando totalizadores
      	oModel:AddCalc('TOT_SALDO', 'SB1DETAIL', 'SB2DETAIL', 'B2_QATU', 'XX_TOTAL',  'SUM',   , , "Saldo Total:" )
      	oModel:AddCalc('TOT_SALDO', 'SB1DETAIL', 'SB2DETAIL', 'B2_QATU', 'XX_TOTAL2', 'COUNT', , , "Cont. Total:" )
      

      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.

      Resposta
  • julho 15, 2016 em 6:17 pm
    Permalink

    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 ..

    Resposta
  • outubro 25, 2016 em 7:04 pm
    Permalink

    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

    Resposta
    • outubro 27, 2016 em 12:37 am
      Permalink

      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.

      Resposta
      • outubro 27, 2016 em 12:03 pm
        Permalink

        Obrigado Daniel! Abraços!

        Resposta
        • novembro 6, 2016 em 4:07 pm
          Permalink

          Eu que agradeço Neudo.
          Um grande abraço.

  • novembro 14, 2016 em 7:32 pm
    Permalink

    Ola Danilo estou precisando de um exemplo MVC modelo 2.

    Voce tem um para me passar

    Resposta
    • novembro 17, 2016 em 11:48 pm
      Permalink

      Boa noite Andrea, tudo bem?
      Eu não tenho, mas estou montando, estando disponível, postarei aqui no site.
      Aguarde novidades.
      Abraços.

      Resposta
  • dezembro 5, 2016 em 9:03 pm
    Permalink

    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 } } )

    Resposta
    • dezembro 11, 2016 em 3:20 pm
      Permalink

      Boa tarde Pedroza, tudo bem?
      Tentou passar o conteúdo do parâmetro, ao invés do nome dele?
      Por exemplo.

      Pergunte("SuaPergunta", .F.)
      oModel:GetModel( 'SRDDETAIL' ):SetLoadFilter( { { 'RD_DATARQ', MV_PAR01, MVC_LOADFILTER_GREATER_EQUAL }, { 'RD_DATARQ', MV_PAR02, MVC_LOADFILTER_LESS_EQUAL } } )
      

      Qualquer dúvida, fico à disposição.
      Abraços.

      Resposta
  • janeiro 19, 2017 em 7:49 pm
    Permalink

    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?

    Resposta
    • janeiro 19, 2017 em 11:51 pm
      Permalink

      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.

      Resposta
  • março 14, 2017 em 7:10 pm
    Permalink

    Olá gostaria de saber se tem como criar um formulário com duas folders e em cada uma delas utilizar a classe: FWMarkBrowse?

    Resposta
    • março 16, 2017 em 11:55 pm
      Permalink

      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.

      Resposta

Deixe uma resposta