Você está na página 1de 38

Apostila de MVC

MVC na Prática

Autor: Eurai Rapelli

WWW.UNIVERSOADVPL.COM
WWW.UNIVERSOADVPL.COM Versão 1.00

Apresentação

Meu nome é Eurai Rapelli, tenho 25 anos e sou formado em Ciências da Computação.

Criador do BLOG www.universoadvpl.com

Atuo na área de desenvolvimento ADVPL com conhecimentos em outras tecnologias; MSSQL,


HTML, PHP, Delphi, Etc.
Sempre procurando melhorar e aprofundar na tecnologia Protheus/ADVPL.
Resolvi criar esse E-book para auxiliar no curso de MVC e além de ser um resumo do MVC;
breve e prático.

WWW.UNIVERSOADVPL.COM Página 2
WWW.UNIVERSOADVPL.COM Versão 1.00

SUMÁRIO

1. Plugin => Desenhador MVC................................................................................................... 5


2. Browser ................................................................................................................................. 6
3. Menu - MenuDef ................................................................................................................... 7
4. Modelo – ModelDef .............................................................................................................. 8
5. Visão – ViewDef..................................................................................................................... 9
6. Seu primeiro Fonte MVC - Completo .................................................................................. 10
7. Adicionando Legenda no Browser ...................................................................................... 12
8. Adicionando Filtro padrão no Browser ............................................................................... 13
9. Ativando filtro e legenda com condição ............................................................................. 14
10. Removendo campos da tela ............................................................................................ 15
11. Adicionando botão na tela. ............................................................................................. 16
12. Eventos View | FormField => Fechando a tela após confirmação .................................. 17
13. Eventos View | FormField => Clicando no OK ................................................................. 17
14. Eventos View | FormField => Clicando no Fechar........................................................... 17
15. Eventos View | FormField => Clicando no OK. Após evento de OK ................................ 17
16. Eventos View | FormField => Ao clicar nos botões ......................................................... 17
17. Eventos View | FormField => Após clicar nos botões .................................................... 17
18. Eventos View | FormField => Validando se pode alterar folder ..................................... 18
19. Eventos View | FormField => Setando um timer para execução .................................... 18
20. Modo de operação. Como utilizar o mesmo para validação .......................................... 19
21. Eventos Model | Model => Executando função na entrada ........................................... 20
22. Eventos Model | Model => Fechando a tela ................................................................... 20
23. Eventos Model | Model => Ao gravar ou cancelar os dados .......................................... 20
24. Eventos Model | Model => Ao gravar os dados .............................................................. 20
25. Eventos Model | Model => Ao gravar os dados .............................................................. 21
26. Eventos Model | Model => Ao cancelar a gravação de dados ........................................ 21
27. Eventos Model | Model => Verificar se pode ativar o Model. ........................................ 21
28. Mensagens na validação. ................................................................................................ 22
29. Model | Grid => Criando um Grid. .................................................................................. 23
30. Model | Grid => Adicionando que uma linha é única. .................................................... 23
31. Model | Grid => Grid é Obrigatório................................................................................. 24

WWW.UNIVERSOADVPL.COM Página 3
WWW.UNIVERSOADVPL.COM Versão 1.00

32. View | Grid => Campo Sequencial................................................................................... 24


33. View | Configurando Layout. .......................................................................................... 25
34. Model | Grid – Validação de pré-edição dos dados........................................................ 26
35. Model | Grid – Pós validação de Linha => LinhaOK ........................................................ 27
36. Model | Grid – Validação de pré-edição dos dados........................................................ 28
37. Model | Grid – Pós validação de dados do Grid. Equivale ao TudoOK ........................... 29
38. Model | Grid – Salvar e Restaurar posição da linha do GRID ......................................... 30
39. Model | Grid – Obter e Setar valor ao model. ................................................................ 30
40. Eventos Model | Model => Ao gravar os dados .............................................................. 31
41. Criar campo na tela ......................................................................................................... 33
42. GRID - Contador de registro ............................................................................................ 35
43. OtherObject..................................................................................................................... 36

WWW.UNIVERSOADVPL.COM Página 4
WWW.UNIVERSOADVPL.COM Versão 1.00

MVC na Prática

1. Plugin => Desenhador MVC

Para instalar o plugin desenhador, no TDS, vá até ajuda -> Instalador novo programa.

Acione o link => http://ds.totvs.com/updates/desenhador/

Lembre de desmarcar a opção ‘Agrupar itens por categoria’.

WWW.UNIVERSOADVPL.COM Página 5
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 6
WWW.UNIVERSOADVPL.COM Versão 1.00

3. 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" )

WWW.UNIVERSOADVPL.COM Página 7
WWW.UNIVERSOADVPL.COM Versão 1.00

4. 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({ })

WWW.UNIVERSOADVPL.COM Página 8
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 9
WWW.UNIVERSOADVPL.COM Versão 1.00

6. 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' })

WWW.UNIVERSOADVPL.COM Página 10
WWW.UNIVERSOADVPL.COM Versão 1.00

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

Return( oView )

WWW.UNIVERSOADVPL.COM Página 11
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 12
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 13
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 14
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 15
WWW.UNIVERSOADVPL.COM Versão 1.00

11. 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*/,{MOD
EL_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 )

WWW.UNIVERSOADVPL.COM Página 16
WWW.UNIVERSOADVPL.COM Versão 1.00

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

13. Eventos View | FormField => Clicando no OK

É executado quando clicar no botão confirmar:

oView:SetViewAction( 'BUTTONOK',{|| MsgInfo('Apertei OK') })

14. Eventos View | FormField => Clicando no Fechar

É executado quando clicar no botão cancelar:

oView:SetViewAction( 'BUTTONCANCEL',{|| MsgInfo('Apertei Cancelar') })

15. Eventos View | FormField => Clicando no OK. Após evento de OK

É executado após o evento de confirmar:

oView:SetAfterOkButton({|| MsgInfo('Apertei OK, Processamento!!!') })

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

17. Eventos View | FormField => Após clicar nos botões

Após passar pelo evento anterior “SetViewCanActive”, executa processamento:

oView:SetAfterViewActivate({|| MsgInfo('Depois de ativado') })

WWW.UNIVERSOADVPL.COM Página 17
WWW.UNIVERSOADVPL.COM Versão 1.00

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

19. 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') })

WWW.UNIVERSOADVPL.COM Página 18
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 19
WWW.UNIVERSOADVPL.COM Versão 1.00

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

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

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

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

WWW.UNIVERSOADVPL.COM Página 20
WWW.UNIVERSOADVPL.COM Versão 1.00

25. 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. },)

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

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

WWW.UNIVERSOADVPL.COM Página 21
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 22
WWW.UNIVERSOADVPL.COM Versão 1.00

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

30. 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' } )

WWW.UNIVERSOADVPL.COM Página 23
WWW.UNIVERSOADVPL.COM Versão 1.00

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

32. 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' )

WWW.UNIVERSOADVPL.COM Página 24
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 25
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 26
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 27
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 28
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 29
WWW.UNIVERSOADVPL.COM Versão 1.00

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

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

WWW.UNIVERSOADVPL.COM Página 30
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 31
WWW.UNIVERSOADVPL.COM Versão 1.00

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.

WWW.UNIVERSOADVPL.COM Página 32
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 33
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 34
WWW.UNIVERSOADVPL.COM Versão 1.00

42. 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')

WWW.UNIVERSOADVPL.COM Página 35
WWW.UNIVERSOADVPL.COM Versão 1.00

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

WWW.UNIVERSOADVPL.COM Página 36
WWW.UNIVERSOADVPL.COM Versão 1.00

Conclusão

Nesse e-book / Curso foram abordados uma grande parte do MVC.


Conhecimento suficiente para desenvolver em MVC no dia a dia sem problema.
Não foi abordado no e-book, por exemplo:
FwLayer / Múltiplos Browsers.
ExecAuto em MVC / Rotinas Automáticas
Ponto de Entrada em MVC.
WebService para MVC.

WWW.UNIVERSOADVPL.COM Página 37
WWW.UNIVERSOADVPL.COM Versão 1.00

Obrigado!!!

www.universoadvpl.com

https://www.facebook.com/UniversoADVPL?ref=hl

https://www.youtube.com/user/UniversoADVPL/

https://plus.google.com/u/0/+UniversoADVPL

universoadvpl@universoadvpl.com

WWW.UNIVERSOADVPL.COM Página 38

Você também pode gostar