ADVPL MVC - Comandos
Autor: Eurai Criado: 16/09/2023 Atualizado: 17/07/2024
1. Browser
Para iniciar, precisamos criar um browser na tela; onde será usado as funções dos menus como INCLUIR / ALTERAR / ETC.
Para isso, crie um fonte com nome, EX: UAMVC001.PRW
No e-book será usado tabela ZAA, crie uma tabela customizado com alguns campos para estudo:
Ex: FILIAL | ID | DESC | ATIVO | DATA | HORA | IDUSR
Para isso use o seguinte código:
#INCLUDE "TOTVS.CH"
User Function UAMVC001()
Local oBrowse := Nil
oBrowse := FWMBrowse():New()
oBrowse:SetAlias("ZAA")
oBrowse:SetDescription("Cadastro de Grupo")
oBrowse:Activate()
Return( Nil )
Para criar como MarkBrowse, ou seja, ter uma coluna de marcação, use:
#INCLUDE "TOTVS.CH"
User Function UAMVC001()
oMark := FWMarkBrowse():New()
oMark:SetAlias("ZAA")
oMark:SetDescription( "Cadastro de Grupo" )
oMark:SetFieldMark( "ZAA_OK" )
oMark:Activate()
Return( Nil )
2. Menu - MenuDef
Após criação do browser. Precisamos do MENU, ou seja, os botões que irão aparecer.
Pode ser criado do jeito abaixo, usando sintaxe clipper:
Static Function MenuDef()
Local aRotina := {}
ADD OPTION aRotina Title 'Visualizar' Action 'VIEWDEF.UAMVC001' OPERATION 2 ACCESS 0
ADD OPTION aRotina Title 'Incluir' Action 'VIEWDEF.UAMVC001' OPERATION 3 ACCESS 0
ADD OPTION aRotina Title 'Alterar' Action 'VIEWDEF.UAMVC001' OPERATION 4 ACCESS 0
ADD OPTION aRotina Title 'Excluir' Action 'VIEWDEF.UAMVC001' OPERATION 5 ACCESS 0
ADD OPTION aRotina Title 'Imprimir' Action 'VIEWDEF.UAMVC001' OPERATION 8 ACCESS 0
ADD OPTION aRotina Title 'Copiar' Action 'VIEWDEF.UAMVC001' OPERATION 9 ACCESS 0
Return( aRotina )
Ou, poderia ser usado com sintaxe ADVPL:
Static Function MenuDef()
Local aRotina := {}
aAdd( aRotina, { 'Visualizar', 'VIEWDEF.UAMVC001', 0, 2, 0, NIL } )
aAdd( aRotina, { 'Incluir' , 'VIEWDEF.UAMVC001' , 0, 3, 0, NIL } )
aAdd( aRotina, { 'Alterar' , 'VIEWDEF.UAMVC001', 0, 4, 0, NIL } )
aAdd( aRotina, { 'Excluir' , 'VIEWDEF.UAMVC001', 0, 5, 0, NIL } )
aAdd( aRotina, { 'Imprimir' , 'VIEWDEF.UAMVC001', 0, 8, 0, NIL } )
aAdd( aRotina, { 'Copiar' , 'VIEWDEF.UAMVC001', 0, 9, 0, NIL } )
Return( aRotina )
Ambos os casos permitem manipulação e adição de outros botões, como por exemplo:
Adicionar EXPORTAR, PROCESSAR, PARAMETROS; são outros botões além dos padrões.
E tanto na sintaxe clipper quanto no ADVPL o efeito será o mesmo. É questão de preferência de cada desenvolvedor.
Uma terceira forma de criar o MENU seria a função abaixo. A mesma retorna os botões padrões. Incluir / Alterar / Excluir / Imprimir e Copiar.
Static Function MenuDef()
Return FWMVCMenu( "UAMVC001" )
3. Modelo – ModelDef
Precisamos criar o modelo de dados, para isso usamos o código:
Static Function ModelDef()
Local oModel := Nil
Local oStructZAA := FWFormStruct(1, "ZAA")
oModel := MPFormModel():New("MODELO") //Não adicionar mesmo nome do fonte/user function
oModel:AddFields("MODEL_ZAA", NIL, oStructZAA)
oModel:SetPrimaryKey({ 'ZAA_FILIAL', 'ZAA_ID' })
Return( oModel )
Sempre informe a chave primária para o modelo, em último caso, se não for possível, deixe em branco da seguinte forma:
oModel:SetPrimaryKey({ })
4. Visão – ViewDef
Muito bom, já criamos o Menu e o Modelo.
Agora vamos criar a visão. ViewDef.
Note que são três funções estática padrões para criação do MVC => MenuDef / ModelDef / ViewDef.
Static Function ViewDef()
Local oModel := ModelDef()
Local oView := FWFormView():New() // Criacao da Interface
Local oStructZAA:= FWFormStruct(2, "ZAA")
oView:SetModel(oModel)
oView:AddField( 'VIEW_ZAA', oStructZAA, "MODEL_ZAA" )
oView:CreateHorizontalBox( "MASTER" , 100 )
oView:SetOwnerView( 'VIEW_ZAA', "MASTER" )
oView:EnableTitleView('VIEW_ZAA', 'Dados' )
Return( oView )
5. Seu primeiro Fonte MVC - Completo
Pronto, agora temos nosso primeiro fonte em MVC funcionando.
Com browser, menu e ações
Segue abaixo o mesmo completo até o momento:
#INCLUDE "TOTVS.CH"
User Function UAMVC001()
Local oBrowse := Nil
oBrowse := FWMBrowse():New()
oBrowse:SetAlias("ZAA")
oBrowse:SetDescription("Cadastro de Grupo")
oBrowse:Activate()
Return( Nil )
Static Function MenuDef()
Local aRotina := {}
aAdd( aRotina, { 'Visualizar', 'VIEWDEF.UAMVC001', 0, 2, 0, NIL } )
aAdd( aRotina, { 'Incluir' , 'VIEWDEF.UAMVC001' , 0, 3, 0, NIL } )
aAdd( aRotina, { 'Alterar' , 'VIEWDEF.UAMVC001', 0, 4, 0, NIL } )
aAdd( aRotina, { 'Excluir' , 'VIEWDEF.UAMVC001', 0, 5, 0, NIL } )
aAdd( aRotina, { 'Imprimir' , 'VIEWDEF.UAMVC001', 0, 8, 0, NIL } )
aAdd( aRotina, { 'Copiar' , 'VIEWDEF.UAMVC001', 0, 9, 0, NIL } )
Return( aRotina )
Static Function ModelDef()
Local oModel := Nil
Local oStructZAA := FWFormStruct(1, "ZAA")
oModel := MPFormModel():New("MODELO")
oModel:AddFields("MODEL_ZAA", NIL, oStructZAA)
oModel:SetPrimaryKey({ 'ZAA_FILIAL', 'ZAA_ID' })
Return( oModel )
Static Function ViewDef()
Local oModel := ModelDef()
Local oView := FWFormView():New() // Criacao da Interface
Local oStructZAA:= FWFormStruct(2, "ZAA")
oView:SetModel(oModel)
oView:AddField( 'VIEW_ZAA', oStructZAA, "MODEL_ZAA" )
oView:CreateHorizontalBox( "MASTER" , 100 )
oView:SetOwnerView( 'VIEW_ZAA', "MASTER" )
oView:EnableTitleView('VIEW_ZAA', 'Dados' )
//oView:EnableTitleView( 'VIEW_ZAA', 'Dados', RGB( 224, 30, 43 ) )
Return( oView )
6. Adicionando Legenda no Browser
Para adicionar legenda no seu browser, ou seja, uma nova coluna com imagens coloridas de status e além de ser mostrado no filtro.
oBrowse:AddLegend( "ZAA_ATIVO=='1'", "GREEN" , "Ativo" )
oBrowse:AddLegend( "ZAA_ATIVO=='2'", "RED" , "Inativo" )
Browser completo:
#INCLUDE "TOTVS.CH"
User Function UAMVC001()
Local oBrowse := Nil
oBrowse := FWMBrowse():New()
oBrowse:SetAlias("ZAA")
oBrowse:SetDescription("Cadastro de Grupo")
oBrowse:AddLegend( "ZAA_ATIVO=='1'", "GREEN" , "Ativo" )
oBrowse:AddLegend( "ZAA_ATIVO=='2'", "RED" , "Inativo" )
oBrowse:Activate()
Return( Nil )
7. Adicionando Filtro padrão no Browser
Vamos adicionar filtro no seu browser. Entrar com os dados filtrados.
EX: Apenas mostrar os ativos:
oBrowse:SetFilterDefault( "ZAA_ATIVO=='1'" )
Browser completo:
User Function UAMVC001()
Local oBrowse := Nil
oBrowse := FWMBrowse():New()
oBrowse:SetAlias("ZAA")
oBrowse:SetDescription("Cadastro de Grupo")
oBrowse:AddLegend( "ZAA_ATIVO=='1'", "GREEN" , "Ativo" )
oBrowse:AddLegend( "ZAA_ATIVO=='2'", "RED" , "Inativo" )
oBrowse:SetFilterDefault( "ZAA_ATIVO=='1'" )
oBrowse:Activate()
Return( Nil )
8. Ativando filtro e legenda com condição
Em alguns momentos pode ser que deseje usar o filtro padrão ou legenda, ou até mesmo remover campos da tela de acordo com uma condição.
Ex: Se não for administrador, executar filtro padrão.
OBS: Irei ensinar nos próximos capítulos como remover campo da tela.
If __cUserID <> "000000"
oBrowse:SetFilterDefault( "ZAA_ATIVO=='1'" )
Endif
Browser completo com filtro:
User Function UAMVC001()
Local oBrowse := Nil
oBrowse := FWMBrowse():New()
oBrowse:SetAlias("ZAA")
oBrowse:SetDescription("Cadastro de Grupo")
oBrowse:AddLegend( "ZAA_ATIVO=='1'", "GREEN" , "Ativo" )
oBrowse:AddLegend( "ZAA_ATIVO=='2'", "RED" , "Inativo" )
If __cUserID <> "000000"
oBrowse:SetFilterDefault( "ZAA_ATIVO=='1'" )
Endif
oBrowse:Activate()
Return( Nil )
9. Removendo campos da tela
Remoção de campos, são tratados na visão. ViewDef.
No exemplo, coloco condição para não mostrar determinados campos se não for usuário administrador:
If __cUserID <> "000000"
oStructZAA:RemoveField( "ZAA_IDUSR" )
oStructZAA:RemoveField( "ZAA_DATA" )
oStructZAA:RemoveField( "ZAA_HORA" )
Endif
Static Function ViewDef()
Local oModel := ModelDef()
Local oView := FWFormView():New() // Criacao da Interface
Local oStructZAA:= FWFormStruct(2, "ZAA")
oView:SetModel(oModel)
oView:AddField( 'VIEW_ZAA', oStructZAA, "MODEL_ZAA" )
If __cUserID <> "000000"
oStructZAA:RemoveField( "ZAA_IDUSR" )
oStructZAA:RemoveField( "ZAA_DATA" )
oStructZAA:RemoveField( "ZAA_HORA" )
Endif
oView:CreateHorizontalBox( "MASTER" , 100 )
oView:SetOwnerView( 'VIEW_ZAA', "MASTER" )
oView:EnableTitleView('VIEW_ZAA', 'Dados' )
Return( oView )
10. Adicionando botão na tela.
Agora vamos adicionar botão na tela, pode ser usado para executar alguma função.
Adicione a include abaixo no seu fonte, necessário para algumas execuções no MVC; como por exemplo:
MODEL_OPERATION_INSERT | MODEL_OPERATION_UPDATE
#INCLUDE 'FWMVCDEF.CH'
Para adicionar botão use:
oView:AddUserButton('NomeBotão','CLIPS',{||MsgAlert('Oieee')},'UniversoADVPL')
Para esse botão ser visualizado apenas quando for inserção ou alteração, faça como abaixo:
oView:AddUserButton('NomeBotão','CLIPS',{||MsgAlert('Oieee')},'UniversoADVPL',/*nShortCut*/,{MODEL_OPERATION_INSERT, MODEL_OPERATION_UPDATE})
Resultado:
Static Function ViewDef()
Local oModel := ModelDef()
Local oView := FWFormView():New() // Criacao da Interface
Local oStructZAA:= FWFormStruct(2, "ZAA")
oView:SetModel(oModel)
oView:AddUserButton('NomeBotão','CLIPS',{||MsgAlert('Oieee')},'UniversoADVPL')
oView:AddField( 'VIEW_ZAA', oStructZAA, "MODEL_ZAA" )
If __cUserID <> "000000"
oStructZAA:RemoveField( "ZAA_IDUSR" )
oStructZAA:RemoveField( "ZAA_DATA" )
oStructZAA:RemoveField( "ZAA_HORA" )
Endif
oView:CreateHorizontalBox( "MASTER" , 100 )
oView:SetOwnerView( 'VIEW_ZAA', "MASTER" )
oView:EnableTitleView('VIEW_ZAA', 'Dados' )
Return( oView )
11. Eventos View | FormField => Fechando a tela após confirmação
Caso tenha notado, quando confirma a gravação do registro; a tela não é fechada.
Caso queira fechar após confirmação, adicione a seguinte linha na View:
oView:SetCloseOnOk( {|| .T. } )
12. Eventos View | FormField => Clicando no OK
É executado quando clicar no botão confirmar:
oView:SetViewAction( 'BUTTONOK',{|| MsgInfo('Apertei OK') })
13. Eventos View | FormField => Clicando no Fechar
É executado quando clicar no botão cancelar:
oView:SetViewAction( 'BUTTONCANCEL',{|| MsgInfo('Apertei Cancelar') })
14. Eventos View | FormField => Clicando no OK. Após evento de OK
É executado após o evento de confirmar:
oView:SetAfterOkButton({|| MsgInfo('Apertei OK, Processamento!!!') })
15. Eventos View | FormField => Ao clicar nos botões
Defini se pode abrir a tela ou não. Executado no Botão -> INCLUIR / ALTERAR / EXCLUIR / VISUALIZAR / COPIAR:
oView:SetViewCanActivate({|| MsgInfo('Pode Ativar'), .F. })
16. Eventos View | FormField => Após clicar nos botões
Após passar pelo evento anterior “SetViewCanActive”, executa processamento:
oView:SetAfterViewActivate({|| MsgInfo('Depois de ativado') })
17. Eventos View | FormField => Validando se pode alterar folder
Caso tenha 2 ou mais folder/ABA na tela, é possível validar da seguinte forma.
oView:SetVldFolder({|cFolderID, nOldSheet, nSelSheet| VldFolder(cFolderID, nOldSheet, nSelSheet)})
Static Function VldFolder(cFolderID, nOldSheet, nSelSheet)
Local lRet := .T.
If nOldSheet == 1 .AND. nSelSheet == 2
Help( ,, 'Help',, 'Não é permitido selecionar a aba 2 se você estiver na aba 1.', 1, 0 )
lRet := .F.
EndIf
Return( lRet )
18. Eventos View | FormField => Setando um timer para execução
Setar tempo para executar uma função. Tempo é em milissegundos
oView:SetTimer(10000,{|| MsgInfo('10 Segundo') })
19. Modo de operação. Como utilizar o mesmo para validação
Quando necessário fazer validação, para inclusão alteração ou outro modo.
Podemos obter a operação, e validar se estamos INSERINDO | ATUALIZANDO | DELETANDO | VISUALIZANDO:
Local nOperation := oModel:GetOperation()
If nOperation == MODEL_OPERATION_INSERT
MsgInfo('Incluindo')
ElseIf nOperation == MODEL_OPERATION_UPDATE
MsgInfo('Atualizando')
ElseIf nOperation == MODEL_OPERATION_DELETE
MsgInfo('Deletando')
ElseIf nOperation == MODEL_OPERATION_VIEW
MsgInfo('Visualizando')
Endif
20. Eventos Model | Model => Executando função na entrada
Permite executar função na abertura de tela.
Possível criar função e validar o modo de operação.
oModel:SetActivate({|| MsgInfo(ZAA->ZAA_DESC) })
21. Eventos Model | Model => Fechando a tela
Permite executar função no encerramento da tela.
Possível criar função e validar o modo de operação.
oModel:SetDeActivate ({|| MsgInfo(ZAA->ZAA_DESC) })
22. Eventos Model | Model => Ao gravar ou cancelar os dados
Permite executar função na confirmação e cancelamento dos dados do model. bPre.
Possível criar função e validar o modo de operação.
Retorno True or False.
oModel := MPFormModel():New("MODELO",{|| MsgInfo('bPre'), .T. } )
23. Eventos Model | Model => Ao gravar os dados
Permite executar função na confirmação/gravação dos dados do model. bPost
Possível criar função e validar o modo de operação.
Retorno True or False.
oModel := MPFormModel():New("MODELO", ,{|| MsgInfo('bPos'), .T. } )
24. Eventos Model | Model => Ao gravar os dados
Permite executar função na confirmação/gravação dos dados do model. bCommit.
Possível criar função e validar o modo de operação.
Retorno True or False.
oModel := MPFormModel():New("MODELO",,,{ || MsgInfo(oModel:GetModel( 'MODEL_ZAA' ):GetValue('ZAA_DESC') ), .T. },)
25. Eventos Model | Model => Ao cancelar a gravação de dados
Permite executar função no cancelamento do model. bCancel.
Possível criar função e validar o modo de operação.
Retorno True or False.
oModel := MPFormModel():New("MODELO",,, ,{ || MsgInfo(oModel:GetModel( 'MODEL_ZAA' ):GetValue('ZAA_DESC') ), .T. })
26. Eventos Model | Model => Verificar se pode ativar o Model.
Antes de ativar o modo. É possível criar validação se pode ou não abrir a tela de acordo com uma função.
oModel:SetVldActivate ({ |oModel| fOnActivate(oModel) } )
Static Function fOnActivate( oModel )
Local lRet := .T.
If oModel:GetOperation() <> NIL
If oModel:GetOperation() == MODEL_OPERATION_UPDATE
If VALIDACAO()
Help( ,, 'HELP','Título', 'Descrição', 1, 0)
lRet := .F.
Endif
Endif
Endif
Return( lRet )
27. Mensagens na validação.
Nos eventos de validação, que possuem retorno True or False; necessário retornar a mensagem com a função HELP.
As funções MsgInfo, MsgAlert, MsgStop, Etc não funcionam de forma correta.
Help( ,, 'HELP','Título', 'Descrição', 1, 0)
28. Model | Grid => Criando um Grid.
Agora vamos ver como criar um grid e relacionar com o form.
Nesse caso serão 2 tabelas.
Uma utilizando o form e outra o Grid.
Não estarei tratando a criação da tabela no e-book. Apenas no curso em vídeo será tratado.
Crie a tabela de acordo com a necessidade e relacione
No Modelo, adicione:
oModel:AddGrid( 'MODEL_ZAB', 'MODEL_ZAA', oStructZAB )
oModel:SetRelation( 'MODEL_ZAB', { { 'ZAB_FILIAL', 'xFilial( "ZAB" )' }, { 'ZAB_ID', 'ZAA_ID' } }, ZAB->( IndexKey( 1 ) ) )
29. Model | Grid => Adicionando que uma linha é única.
No caso queria adicionar que uma linha é única, ou seja, o valor não pode se repetir; por exemplo:
Um campo SEQUENCIA ou ITEM de um GRID.
Adicione o valor abaixo no MODEL:
oModel:GetModel( 'MODEL_ZAB' ):SetUniqueLine( { 'ZAB_SEQ' } )
E podemos fazer chave composta, por exemplo:
oModel:GetModel( 'MODEL_ZAB' ):SetUniqueLine( { 'ZAB_SEQ', 'ZAB_DESC' } )
30. Model | Grid => Grid é Obrigatório.
No caso que você tenha 4 grid e 2 deles não são obrigado a ser preenchido; é opcional.
Para isso faça o seguinte.
oModel:getModel('MODEL_ZAC'):SetOptional(.T.)
31. View | Grid => Campo Sequencial
Para adicionar o campo como sequencial; ou seja, auto incremento. Por exemplo:
XX_ITEM == 0001 | 0002 e assim por diante.
Para isso faça, o seguinte na ViewDef.
oView:AddIncrementField( 'VIEW_ZAB', 'ZAB_SEQ' )
32. View | Configurando Layout.
Vou mostrar como criar Pasta, Folder e barras de separação.
Para isso, faça o seguinte na ViewDef.
oView:CreateFolder( 'PASTAS' )
oView:AddSheet( 'PASTAS', 'ABA01', 'Minha primeira ABA' )
oView:AddSheet( 'PASTAS', 'ABA02', 'Minha segunda ABA')
oView:CreateHorizontalBox( 'SUPERIOR', 20,,, 'PASTAS', 'ABA01' )
oView:CreateHorizontalBox( 'INFERIOR', 80,,, 'PASTAS', 'ABA01' )
oView:CreateVerticalBox( 'ESQUERDA', 50,,, 'PASTAS', 'ABA02' )
oView:CreateVerticalBox( 'DIREITA', 50,,, 'PASTAS', 'ABA02' )
oView:SetOwnerView( 'VIEW_ZAA', 'SUPERIOR' )
oView:SetOwnerView( 'VIEW_ZAB', 'INFERIOR' )
oView:SetOwnerView( 'VIEW_ZAC', 'ESQUERDA' )
oView:SetOwnerView( 'VIEW_ZAD', 'DIREITA' )
oView:EnableTitleView('VIEW_ZAA')
oView:EnableTitleView('VIEW_ZAB')
oView:EnableTitleView('VIEW_ZAC')
oView:EnableTitleView('VIEW_ZAD')
Nesse exemplo, é criado 2 ABA em uma pasta.
Dentro da primeira pasta, é adicionado 2 modelos de dados na horizontal.
Na segunda aba é adicionado 2 modelos de dados na vertical
33. Model | Grid – Validação de pré-edição dos dados.
Nessa validação, é possível validar se pode editar a coluna, deletar, ou se pode setar o valor. bLinePre.
Retorno é True or False.
Para isso, faça o seguinte no Modelo:
Local bLinPreZAB := {|oGridModel, nLine, cAction, cIDField, xValue, xCurrentValue| bLinPreZAB(oGridModel, nLine, cAction, cIDField, xValue, xCurrentValue)}
oModel:addGrid('MODEL_ZAB','MODEL_ZAA',oStructZAB,bLinPreZAB)
Função:
Static Function bLinPreZAB( oGridModel, nLine, cAction, cIDField, xValue, xCurrentValue )
Local lRet := .T.
Local oModel := oGridModel:GetModel()
Local nOperation := oModel:GetOperation()
If nOperation == MODEL_OPERATION_UPDATE
If cAction == "SETVALUE" //CANSETVALUE
If cIDField == 'ZAB_DESC'
Help( ,, 'HELP','UniversoADVPL', 'Não é possível alterar linha já inserida', 1, 0)
lRet := .F.
Endif
Endif
If cAction == "DELETE"
Help( ,, 'Help', 'UniversoADVPL', 'Não permitido apagar linhas na alteração', 1, 0)
lRet := .F.
Endif
Endif
Return( lRet )
Os valores da ação podem ser, SETVALUE | CANSETVALUE | DELETE | UNDELETE.
34. Model | Grid – Pós validação de Linha => LinhaOK
Esse evento refere-se a pós validação de linha. Equivale ao LinhaOK. bLinePost
Retorno é True or False
Para isso, faça o seguinte no Modelo:
Local bLinPosZAB := {|oGridModel, nLine | bLinPosZAB( oGridModel, nLine ) }
oModel:addGrid('MODEL_ZAB','MODEL_ZAA',oStructZAB,,bLinPosZAB)
Função:
Static Function bLinPosZAB( oGridModel, nLine )
Local lRet := .T.
Local oModel := oGridModel:GetModel()
If ! oGridModel:IsDeleted()
If AllTrim( oGridModel:GetValue("ZAB_DESC") ) == "VALIDA"
Help( ,, 'HELP','UniversoADVPL', 'Validação da Linha', 1, 0)
lRet := .F.
Endif
Endif
Return( lRet )
35. Model | Grid – Validação de pré-edição dos dados
Nessa validação, é possível validar se pode editar a coluna, deletar, ou se pode setar o valor. bPre.
Retorno é True or False.
Não vejo diferença entre bPre e o bLinePre. No caso do bLinePre, tem a ação ADDLINE; que por sinal não funciona até o momento.
Para isso, faça o seguinte no Modelo:
Local bPreLinZAB := {|oGridModel, nLine, cAction, cIDField, xValue, xCurrentValue| bPreLinZAB(oGridModel, nLine, cAction, cIDField, xValue, xCurrentValue)}
oModel:addGrid('MODEL_ZAB','MODEL_ZAA',oStructZAB,,,bPreLinZAB)
Função:
Static Function bLinPreZAB( oGridModel, nLine, cAction, cIDField, xValue, xCurrentValue )
Local lRet := .T.
Local oModel := oGridModel:GetModel()
Local nOperation := oModel:GetOperation()
If nOperation == MODEL_OPERATION_UPDATE
If cAction == "SETVALUE" //CANSETVALUE
If cIDField == 'ZAB_DESC'
Help( ,, 'HELP','UniversoADVPL', 'Não é possível alterar linha já inserida', 1, 0)
lRet := .F.
Endif
Endif
If cAction == "DELETE"
Help( ,, 'Help', 'UniversoADVPL', 'Não permitido apagar linhas na alteração', 1, 0)
lRet := .F.
Endif
Endif
Return( lRet )
Os valores da ação podem ser, SETVALUE | CANSETVALUE | DELETE | UNDELETE | ADDLINE.
OBS: ADDLINE, gera erro na validação.
36. Model | Grid – Pós validação de dados do Grid. Equivale ao TudoOK
Esse evento refere-se a validação do GRID. Equivale ao TudoOK. É executado na confirmação de dados. bLinePost.
Retorno é True or False.
Para isso, faça o seguinte no Modelo:
Local bPrePosZAB := {|oGridModel | bPrePosZAB( oGridModel ) }
oModel:addGrid('MODEL_ZAB','MODEL_ZAA',oStructZAB,,,,bPrePosZAB)
Função:
Static Function bPrePosZAB( oGridModel )
Local lRet := .T.
Local nI := 0
Local oModel := oGridModel:GetModel()
Local nOperation := oModel:GetOperation()
Local aSaveLines := FWSaveRows()
If nOperation == MODEL_OPERATION_INSERT .OR. nOperation == MODEL_OPERATION_UPDATE
For nI := 1 To oGridModel:Length()
oGridModel:GoLine( nI )
If !oGridModel:IsDeleted() // Verifica se não esta deletado
If AllTrim( oGridModel:GetValue("ZAB_DESC") ) == "VALIDA"
Help( ,, 'HELP','UniversoADVPL', 'Validação da Linha: ' + Str(nI), 1, 0)
lRet := .F.
Exit
Endif
EndIf
Next nI
Endif
FwRestRows( aSaveLines )
Return( lRet )
Os valores da ação podem ser, SETVALUE | CANSETVALUE | DELETE | UNDELETE | ADDLINE.
OBS: ADDLINE, gera erro na validação. Possível problema de LIB.
37. Model | Grid – Salvar e Restaurar posição da linha do GRID
Sempre que for validar todo grid e usar For, salve e restaure as posições das linhas do GRID.
Faça isso antes do For para salvar o valor:
Local aSaveLines := FWSaveRows()
Faça isso após o For, antes do Return para restaurar o valor:
FwRestRows( aSaveLines )
38. Model | Grid – Obter e Setar valor ao model.
Para obter valor do model, use:
AllTrim( oGridModel:GetValue("ZAB_DESC") )
Ou em casos que não tenha recuperado o modelo da tabela em uma variável:
AllTrim( oModel:GetModel( 'MODEL_ZAB' ):GetValue("ZAB_DESC") )
Para setar valor no campo, use:
If !oModelZQE:SetValue( 'ZAB_DESC', 'Minha Descrição' )
Help( ,, 'HELP','UniversoADVPL', 'Erro ao atualizar ZAB_DESC', 1, 0)
Endif
39. Eventos Model | Model => Ao gravar os dados
Esse evento foi tratado na página 20.
Irei demostrar como validar todos grids e informações apenas nesse evento.
oModel := MPFormModel():New("MODELO", , { |oModel| bPost(oModel) } )
Static Function bPost( oModel )
Local oModelZAA := oModel:GetModel( 'MODEL_ZAA' )
Local oModelZAB := oModel:GetModel( 'MODEL_ZAB' )
Local oModelZAC := oModel:GetModel( 'MODEL_ZAC' )
Local nOperation := oModel:GetOperation()
Local nI := 0
Local aSaveLines := FWSaveRows()
Local lRet := .T.
If nOperation == MODEL_OPERATION_INSERT .OR. nOperation == MODEL_OPERATION_UPDATE
For nI := 1 To oModelZAB:Length()
oModelZAB:GoLine( nI )
If ! oModelZAB:IsDeleted() // Verifica se não esta deletado
If AllTrim( oModelZAB:GetValue("ZAB_DESC") ) == "VALIDA"
Help( ,, 'HELP','UniversoADVPL', 'Validação da Linha: ' + Str(nI), 1, 0)
lRet := .F.
Exit
Endif
EndIf
Next nI
Endif
FwRestRows( aSaveLines )
Return( lRet )
No caso acima, apenas escrevi a validação da ZAB, porém recuperei todos os modelos das tabelas no início da função; com esses modelos podemos executar For nos outros grids ou pegar valor do FormField e validar os valores.
40. Criar campo na tela
Em alguns casos, podemos precisar criar um campo que não está na tabela.
Por Exemplo: Um campo observação, onde apenas será usado para enviar um e-mail e não será salvo no banco.
Precisamos criar no MODEL e na VIEW.
Código no ModelDef:
oStructZAA:AddField( ; // Ord. Tipo Desc.
"Descrição Customizada." , ;// [01] C Titulo do campo
"Descrição Customizada." , ;// [02] C ToolTip do campo
'ZAA_MEMO' , ;// [03] C Id do Field
'M' , ;// [04] C Tipo do campo
10 , ;// [05] N Tamanho do campo
0 , ;// [06] N Decimal do campo
NIL , ;// [07] B Code-block de validao do campo
NIL , ;// [08] B Code-block de validao When do campo
NIL , ;// [09] A Lista de valores permitido do campo
.T. , ;// [10] L Indica se o campo tem preenchimento obrigatorio
NIL , ;// [11] B Code-block de inicializacao do campo
NIL , ;// [12] L Indica se trata-se de um campo chave
NIL , ;// [13] L Indica se o campo pode receber valor em uma operao de update.
NIL ) // [14] L Indica se o campo virtual
Código no ViewDef:
oStructZAA:AddField( 'ZAA_MEMO' , ; // Nome do Campo
'07' , ; // Ordem
"Descrição Customizada." , ; // Titulo do campo ---- Selecionado
"Descrição Customizada." , ; // Descrição do campo ---- Selecionado
{"Descrição Customizada."} , ; // Array com Help ---- Selecionado
'M' , ; // Tipo do campo
'@!' , ; // Picture
NIL , ; // Bloco de Picture Var
'' , ; // Consulta F3
NIL , ; // Indica se o campo é evitável
NIL , ; // Pasta do campo
NIL , ; // Agrupamento do campo
{ } , ; // Lista de valores permitido do campo (Combo)
NIL , ; // Tamanho Maximo da maior opção do combo
NIL , ; // Inicializador de Browse
NIL , ; // Indica se o campo é virtual
NIL ) // Picture Variável
41. GRID - Contador de registro
Para adicionar contador de registro, adicione a seguinte linha no ModelDef:
oModel:AddCalc( 'COUNTZAB', 'MODEL_ZAA', 'MODEL_ZAB', 'ZAB_ID', 'Total', 'COUNT' )
Na ViewDef:
Local oCountZAB := FWCalcStruct( oModel:GetModel( 'COUNTZAB') )
oView:AddField( 'VCALC_ZAB', oCountZAB, 'COUNTZAB' )
oView:CreateHorizontalBox( 'COUNT_ZAB', 24)
oView:SetOwnerView('VCALC_ZAB',' COUNT_ZAB')
42. OtherObject
Para adicionar um outro Objeto, por exemplo um Botão ‘Tbutton’.
Adicione na ViewDef:
oView:AddOtherObject('VIEW_PANEL',{ |oPanel| CriaBTN( oPanel ) } )
Função:
Static Function CriaBTN( oPanel )
TButton():New( 020, 020, "TESTE", oPanel, {|| MsgInfo('TESTE') }, 030, 010, , , .F., .T., .F., , .F., , , .F. )
Return( Nil )
43. Limpar GRID
Limpar GRID (Somente Inclusão, na alteração irá dar erro):
Local oGridModel := oModel:getModel('MODEL_ZAB')
If FWAlertYesNo( 'Deseja limpar o GRID', 'uDesenv' )
oGridModel:ClearData()
Endif
44. Recuperar Linha
Recuperar a linha deletada do GRID:
Local oGridModel := oModel:getModel('MODEL_ZAB')
If oGridModel :IsDeleted()
oGridModel :UnDeleteLine()
EndIf
45. Deletar Linha
Deletar a linha deletada do GRID. No caso será deletado todas as linhas do grid:
Local oGridModel := oModel:getModel('MODEL_ZAB')
Local nI := 00
If FWAlertYesNo( 'Deseja limpar o GRID', 'uDesenv' )
For nI := 1 To oGridModel:Length()
oGridModel:GoLine( nI )
oGridModel:DeleteLine()
Next nI
Endif
46. Retornar valor do cabeçalho. Campo, field
FwFldGet("ZAA_STATU")
47. Salvar valor do cabeçalho. Campo, field
FwFldPut("ZAA_STATU")
48. Gatilho MVC. "SX7".
oStru:AddTrigger('XX_CAMPO' /*cIdField*/, 'XX_DESC' /*cTargetIdField*/, {||.T.} /*bPre*/,{|| FunctionValor() }/*bSetValue*/ )
49. MVC. Filtro Modeldef e ViewDef.
Corrigindo erro no filtro de campos no quais as iniciais são igual, exemplo tabela_COD:
De: FWFormStruct(2, cAliasMVC, {|cCampo| AllTrim(cCampo) $ "A3_COD"})
Para: FWFormStruct(2, cAliasMVC, {|cCampo| "|" + AllTrim(cCampo) + "|" $ "A3_COD"})
50. MVC. BMP.
oStr:SetProperty("XX_STATUS", MVC_VIEW_PICT ,"@BMP")
51. Deletar Linha All
Deletar todas as linhas:
oGridModel:DelAllLine()
52. Carregar modelo dinamicamente.
Exemplo, pode passar view ou outro já carregado:
FWExecView([ cTitulo ],
FWExecView( 'Inclusão' , 'UDCOMA01', 03 )
52. Carregar o model ativo. ModelActive.
oModel = FWModelActive()
53. Retornar linha posicionada no grid.
oModelGrid:GetLine()
#DEFINE FORM_STRUCT_TABLE_MODEL 1
#DEFINE FORM_STRUCT_TABLE_TRIGGER 2
#DEFINE FORM_STRUCT_TABLE_VIEW 3
#DEFINE FORM_STRUCT_TABLE_FOLDER 4
#DEFINE FORM_STRUCT_TABLE_GROUP 5
#DEFINE FORM_STRUCT_TABLE_ALIAS 6
#DEFINE FORM_STRUCT_TABLE_INDEX 7
#DEFINE FORM_STRUCT_TABLE_BROWSE 8
#DEFINE FORM_STRUCT_TABLE_ALIAS_ID 1
#DEFINE FORM_STRUCT_TABLE_ALIAS_PK 2
#DEFINE FORM_STRUCT_TABLE_ALIAS_DESCRIPTION 3
#DEFINE FORM_STRUCT_TABLE_INDEX_ORDEM 1
#DEFINE FORM_STRUCT_TABLE_INDEX_ID 2
#DEFINE FORM_STRUCT_TABLE_INDEX_KEY 3
#DEFINE FORM_STRUCT_TABLE_INDEX_DESCRIPTION 4
#DEFINE FORM_STRUCT_TABLE_INDEX_F3 5
#DEFINE FORM_STRUCT_TABLE_INDEX_NICKNAME 6
#DEFINE FORM_STRUCT_TABLE_INDEX_SHOWPESQ 7
#DEFINE FORM_STRUCT_TABLE_FOLDER_ID 1
#DEFINE FORM_STRUCT_TABLE_FOLDER_DESCRIPTION 2
#DEFINE FORM_STRUCT_TABLE_GROUP_ID 1
#DEFINE FORM_STRUCT_TABLE_GROUP_DESCRIPTION 2
//------------------------------------------------------------
#DEFINE MODELO_PK_OPERATION 1
#DEFINE MODELO_PK_KEYS 2
#DEFINE MODELO_PK_VALUE 1
#DEFINE MODELO_PK_IDFIELD 2
//------------------------------------------------------------
#DEFINE MODEL_TRIGGER_IDFIELD 1
#DEFINE MODEL_TRIGGER_TARGETIDFIELD 2
#DEFINE MODEL_TRIGGER_PRE 3
#DEFINE MODEL_TRIGGER_SETVALUE 4
//------------------------------------------------------------
#DEFINE MODEL_FIELD_TITULO 1
#DEFINE MODEL_FIELD_TOOLTIP 2
#DEFINE MODEL_FIELD_IDFIELD 3
#DEFINE MODEL_FIELD_TIPO 4
#DEFINE MODEL_FIELD_TAMANHO 5
#DEFINE MODEL_FIELD_DECIMAL 6
#DEFINE MODEL_FIELD_VALID 7
#DEFINE MODEL_FIELD_WHEN 8
#DEFINE MODEL_FIELD_VALUES 9
#DEFINE MODEL_FIELD_OBRIGAT 10
#DEFINE MODEL_FIELD_INIT 11
#DEFINE MODEL_FIELD_KEY 12
#DEFINE MODEL_FIELD_NOUPD 13
#DEFINE MODEL_FIELD_VIRTUAL 14
//------------------------------------------------------------
//Conjunto de especificacoes do FWFORMMODEL e derivacoes
//------------------------------------------------------------
#DEFINE MODEL_RELATION_RULES 1
#DEFINE MODEL_RELATION_KEY 2
#DEFINE MODEL_RELATION_RULES_ORIGEM 1
#DEFINE MODEL_RELATION_RULES_TARGET 2
//------------------------------------------------------------
#DEFINE MODEL_STRUCT_TYPE 1
#DEFINE MODEL_STRUCT_ID 2
#DEFINE MODEL_STRUCT_MODEL 3
#DEFINE MODEL_STRUCT_OWNER 4
//------------------------------------------------------------
#DEFINE MODEL_DATA_IDFIELD 1
#DEFINE MODEL_DATA_VALUE 2
#DEFINE MODEL_DATA_UPDATE 3
//------------------------------------------------------------
#DEFINE MODEL_GRID_DATA 1
#DEFINE MODEL_GRID_VALID 2
#DEFINE MODEL_GRID_DELETE 3
#DEFINE MODEL_GRID_ID 4
#DEFINE MODEL_GRID_CHILDREN 5
//------------------------------------------------------------
#DEFINE MODEL_GRID_CHILDREN_ID 1
#DEFINE MODEL_GRID_CHILDREN_DATA 2
#DEFINE MODEL_GRID_CHILDREN_COLS 3
#DEFINE MODEL_GRID_CHILDREN_CALC 4
//------------------------------------------------------------
#DEFINE MODEL_GRID_CALC_IDFIELD 1
#DEFINE MODEL_GRID_CALC_IDFORMCALC 2
#DEFINE MODEL_GRID_CALC_IDCALC 3
//------------------------------------------------------------
#DEFINE MODEL_GRIDLINE_VALUE 1
#DEFINE MODEL_GRIDLINE_UPDATE 2
//------------------------------------------------------------
#DEFINE MODEL_RULES_IDFIELD 1
#DEFINE MODEL_RULES_IDTARGET 2
#DEFINE MODEL_RULES_IDFIELDTARGET 3
#DEFINE MODEL_RULES_TYPE 4
//------------------------------------------------------------
#DEFINE MODEL_MSGERR_IDFORM 1
#DEFINE MODEL_MSGERR_IDFIELD 2
#DEFINE MODEL_MSGERR_IDFORMERR 3
#DEFINE MODEL_MSGERR_IDFIELDERR 4
#DEFINE MODEL_MSGERR_ID 5
#DEFINE MODEL_MSGERR_MESSAGE 6
#DEFINE MODEL_MSGERR_SOLUCTION 7
#DEFINE MODEL_MSGERR_VALUE 8
#DEFINE MODEL_MSGERR_OLDVALUE 9
//------------------------------------------------------------
#DEFINE MODEL_OPERATION_VIEW 1
#DEFINE MODEL_OPERATION_INSERT 3
#DEFINE MODEL_OPERATION_UPDATE 4
#DEFINE MODEL_OPERATION_DELETE 5
#DEFINE MODEL_OPERATION_ONLYUPDATE 6
//------------------------------------------------------------
//Conjunto de especificacoes do FWFORMVIEW e derivacoes
//------------------------------------------------------------
#DEFINE MVC_VIEW_IDFIELD 1
#DEFINE MVC_VIEW_ORDEM 2
#DEFINE MVC_VIEW_TITULO 3
#DEFINE MVC_VIEW_DESCR 4
#DEFINE MVC_VIEW_HELP 5
#DEFINE MVC_VIEW_PICT 7
#DEFINE MVC_VIEW_PVAR 8
#DEFINE MVC_VIEW_LOOKUP 9
#DEFINE MVC_VIEW_CANCHANGE 10
#DEFINE MVC_VIEW_FOLDER_NUMBER 11
#DEFINE MVC_VIEW_GROUP_NUMBER 12
#DEFINE MVC_VIEW_COMBOBOX 13
#DEFINE MVC_VIEW_MAXTAMCMB 14
#DEFINE MVC_VIEW_INIBROW 15
#DEFINE MVC_VIEW_VIRTUAL 16
#DEFINE MVC_VIEW_PICTVAR 17
#DEFINE MVC_MODEL_TITULO 1
#DEFINE MVC_MODEL_TOOLTIP 2
#DEFINE MVC_MODEL_IDFIELD 3
#DEFINE MVC_MODEL_TIPO 4
#DEFINE MVC_MODEL_TAMANHO 5
#DEFINE MVC_MODEL_DECIMAL 6
#DEFINE MVC_MODEL_VALID 7
#DEFINE MVC_MODEL_WHEN 8
#DEFINE MVC_MODEL_VALUES 9
#DEFINE MVC_MODEL_OBRIGAT 10
#DEFINE MVC_MODEL_INIT 11
#DEFINE FORMSTRUFIELD 1
#DEFINE FORMSTRUTRIGGER 2
#DEFINE VIEWSTRUFIELD 3
#DEFINE VIEWSTRUFOLDER 4
#DEFINE VIEWSTRUDOCKWINDOW 5
#DEFINE VIEWSTRUGROUP 6
// ------------------------------------------------------------
#DEFINE OP_PESQUISAR 1
#DEFINE OP_VISUALIZAR 2
#DEFINE OP_INCLUIR 3
#DEFINE OP_ALTERAR 4
#DEFINE OP_EXCLUIR 5
#DEFINE OP_IMPRIMIR 8
Gostou? Compartilhe com seus amigos e deixe um comentário! 😎
Um abraço, e até a próxima