Apostila MVC
Apostila MVC
Apostila MVC
sa separar a lgica de negcio da lgica de apresentao (a inte rface), permitindo o desenvolvimento, teste e manuteno isolada de ambos. Aqueles q ue j desenvolveram uma aplicao em AdvPL vo perceber, que justamente a diferena mais i mportante entre a forma de construir uma aplicao em MVC e a forma tradicional, ess a separao e que vai permitir o uso da regra de negcio em aplicaes que tenham ou no in erfaces, como Web Services e aplicao automtica, bem como seu reuso em outras aplicaes . AdvPl utilizando MVC 1
ndice AdvPl utilizando MVC ........................................................... .............................................................................. 1 ndice .......................................................................... ................................................................................ ........ 2 1.Arquitetura MVC ................................................... ................................................................................ .......... 6 2.Principais funes da aplicao em AdvPL utilizando o MVC ............... .......................................................... 7 2.1 O que a funo Mode lDef?........................................................................... ......................................... 7 2.2 O que a funo ViewDef? ............ ................................................................................ .......................... 8 2.3 O que a funo MenuDef?............................ ................................................................................ ......... 8 2.4 Novo comportamento na interface................................. ....................................................................... 10 3.Apl icaes com Browses (FWMBrowse) .................................................... ................................................... 10 3.1 Construo de um Browse . ................................................................................ .................................... 10 3.2 Construo bsica de um Browse ........... ................................................................................ ............... 10 3.3 Legendas de um Browse (AddLegend) ....................... ............................................................................ 11 3.4 Filtros de um Browse (SetFilterDefault) .................................... ............................................................. 12 3.5 Desabilitao d e detalhes do Browse (DisableDetails) .......................................... ................................ 12 3.6 Campos virtuais no Browse .............. ................................................................................ ...................... 12 3.7 Exemplo completo de Browse ....................... ................................................................................ ......... 13 4.Construo de aplicao AdvPL utilizando MVC ............................ ............................................................... 13 5.Construo de a plicao MVC com uma entidade ...................................................... ................................. 14 5.1 Construo de uma estrutura de dados (FWFor mStruct) ...................................................................... 14 5.2 Construo da funo ModelDef.................................................... ........................................................ 15 5.3 Criao de um compon ente de formulrios no modelo de dados (AddFields) ............................... ...... 16 5.4 Descrio dos componentes do modelo de dados (SetDescription) ........ ............................................. 16 5.5 Finalizao de ModelDef ....... ................................................................................ ................................. 16 5.6 Exemplo completo da ModelDef .......... ................................................................................ .................. 16 5.7 Construo da funo ViewDef ................................. ............................................................................. 17 5.8 Criao de um componente de formulrios na interface (AddField).................. ................................... 18 5.9 Exibio dos dados na interface (CreateHo rizontalBox / CreateVerticalBox) ........................................ 18 5.1 0 Relacionando o componente da interface (SetOwnerView)......................... ....................................... 18 5.11 Finalizao da ViewDef ............. ................................................................................ ............................ 19 5.12 Exemplo completo da ViewDef ............... ................................................................................ ............. 19 2 - AdvPl utilizando MVC
5.13 Finalizao da criao da aplicao com uma entidade ................................. .................................... 19 6.Construo de uma aplicao MVC com duas ou ma is entidades ................................................................ 20 6.1 Construo de estruturas para uma aplicao MVC com duas ou mais entidades ........ ....................... 20 6.2 Construo de uma funo ModelDef ....................... ............................................................................ 20 6.3 Criao de um componente de formulrios no modelo de dados (AddFields) ........... .......................... 21 6.4 Criao de um componente de grid no Modelo de dado s (AddGrid) .................................................... 21 6.5 Criao de r elao entre as entidades do modelo (SetRelation) .................................. ......................... 22 6.6 Definio da chave primria (SetPrimaryKey) ......... ............................................................................... 22 6.7 Descrevendo os componentes do modelo de dados (SetDescription) .......... ........................................ 22 6.8 Finalizao da ModelDef ............ ................................................................................ ............................ 23 6.9 Exemplo completo da ModelDef ............... ................................................................................ ............. 23 6.10 Construo da funo ViewDef ..................................... ....................................................................... 24 6.11 Criao de um componente de formulrios na interface (AddField)....................... ............................ 24 6.12 Criao de um componente de grid na interface ( AddGrid) ................................................................ 24 6.1 3 Exibio dos dados na interface (CreateHorizontalBox / CreateVerticalBox) ........ .............................. 25 6.14 Relacionando o componente da interface (S etOwnerView)................................................................ 26 6.15 Finalizao da ViewDef ........................................................ ................................................................. 26 6.16 Exempl o completo da ViewDef .......................................................... .................................................. 26 6.17 Finalizao da criao da apl icao com duas ou mais entidades .................................................. ..... 27 7.Tratamentos para o modelo de dados e para interface.................. .............................................................. 28 8.Tratamentos para o modelo de dados ......................................................... ................................................. 28 8.1 Mensagens exibidas na i nterface ....................................................................... .................................... 28 8.2 Obteno de componente do modelo de dado s (GetModel) ................................................................ 29 8.3 Validaes..................................................................... .......................................................................... 29 8. 3.3 Validao de linha duplicada (SetUniqueLine) ................................... ............................................. 30 8.3.5 Validao da ativao do modelo ( SetVldActive) .................................................................. .......... 32 8.4 Manipulao da componente de grid ................................ .................................................................... 32 8.4.1 Qu antidade de linhas do componente de grid (Length) .............................. ................................... 32 8.4.2 Ir para uma linha do componente de grid (GoLine) .................................................................. ...... 33 8.4.3 Status da linha de um componente de grid ....................... ............................................................. 33 8.4.4 Adio uma li nha a grid (AddLine)............................................................ ....................................... 34 8.4.5 Apagando e recuperando uma linh a da grid (DeleteLine e UnDeleteLine)..................................... 35 AdvPl utilizando MVC 3
8.4.6 Permisses para uma grid ................................................... ............................................................ 35 8.4.7 Permisso de grid sem dados (SetOptional) .................................................. ................................. 36 8.4.8 Guardando e restaurando o posicioname nto do grid (FWSaveRows / FWRestRows )................... 36 8.4.9 Definio da quan tidade mxima de linhas do grid (SetMaxLine) ..................................... ............. 37 8.5 Obteno e atribuio de valores ao modelo de dados................ ......................................................... 37 8.6 Comportamento . ................................................................................ .................................................... 39 8.6.1 Alterao de dados de um componente no modelo de dados (SetOnlyView) ............................... 3 9 8.6.2 No gravar dados de um componente do modelo de dados (SetOnlyQuery) ...... .......................... 39 8.6.3 Obteno da operao que est sendo realizada (GetOper ation) ................................................. 39 8.6.4 Gravao manual de dados (FWFormCommit) .......................................................... ..................... 40 8.7 Regras de preenchimento (AddRules) ................ ................................................................................ .... 41 9.Tratamentos de interface ............................................. ................................................................................ . 42 9.1 Campo Incremental (AddIncrementField) ................................. ............................................................. 42 9.2 Criao de botes na barra de botes (AddUserButton) .............................................. ......................... 43 9.3 Ttulo do componente (EnableTitleView)........... ................................................................................ .... 44 9.4 Edio de Campos no componente de grid (SetViewProperty) ............... .............................................. 45 9.5 Criao de pastas (CreateFolde r) ............................................................................. .............................. 46 9.6 Agrupamento de campos (AddGroup) ......... ................................................................................ .......... 48 9.7 Ao de interface (SetViewAction)................................. ........................................................................ 50 9.8 Ao de interface do campo (SetFieldAction) ........................................ ................................................ 51 9.9 Outros objetos (AddOther Objects) ....................................................................... ................................. 51 10.Tratamentos de estrutura de dados ...... ................................................................................ ..................... 55 10.1 Seleo de campos para a estrutura (FWFormStruct) .... ..................................................................... 55 10.2 Re moo de campos da estrutura (RemoveField) ......................................... ...................................... 56 10.3 Alterao de propriedades do campo (S etProperty) .................................................................... ....... 56 10.4 Criao de campos adicionais na estrutura (AddField) ............... ......................................................... 58 10.5 Formatao de bloc o de cdigo para a estrutura (FWBuildFeature) .................................... ............... 61 10.6 Campos do tipo MEMO virtuais (FWMemoVirtual) ........... .................................................................. 62 10.7 Criao m anual de gatilho (AddTrigger / FwStruTrigger)................................... .................................. 63 10.8 Retirando as pastas de uma estrutura (SetNoFolder) .................................................................. ........ 64 10. 9 Retirando os agrupamentos de campos de uma estrutura (SetNoGro ups) ........................................ 64 11.Criao de campos de total ou co ntadores (AddCalc) ............................................................. ................... 64 4 - AdvPl utilizando MVC
12.Outras funes para MVC ......................................................... .................................................................. 68 12.1 Execuo direta da interface (FWExecView) ............................................... ......................................... 68 12.2 Modelo de dados ativo (FWModel Active) ........................................................................ ................... 69 12.3 Interface ativa (FWViewActive) ..................... ................................................................................ ....... 69 12.4 Carregar o modelo de dados de uma aplicao j existente (FWLoadModel) .................................... 69 12.5 Carregar a interface de uma aplicao j existente (FWLoadView) .................................................... 70 12.6 Carregar a menu de uma aplicao j existente (FWLoadMenudef) ................... ................................ 70 12.7 Obteno de menu padro (FWMVCMenu) ......... ............................................................................... 70 13.Browse com coluna de marcao (FWMarkBrowse) ................................. ................................................. 71 14.Mltiplos Browses ........ ................................................................................ ............................................... 75 15.Rotina automtica .......... ................................................................................ ............................................. 82 16.Pontos de entrada no MVC ... ................................................................................ ...................................... 94 17.Web Services para MVC ............. ................................................................................ ............................... 101 17.1 Web Service para modelos de dados que p ossuem uma entidade ................................................... 101 17.2 Instnciamento do Client de Web Service ......................................... ................................................ 101 17.3 A estrutura do XML uti lizada ......................................................................... ..................................... 101 17.4 Obtendo a estrutura XML de um mod elo de dados (GetXMLData) ................................................... 10 3 17.5 Informando os dados XML ao Web Service .................................. ..................................................... 104 17.6 Validando os dado s (VldXMLData) ................................................................. .................................... 104 17.7 Validando e gravando os dados (Put XMLData) ....................................................................... ........... 105 17.8 Obtendo o esquema XSD de um modelo de dados (GetSchema) ... ................................................... 105 17.9 Exemplo completo de Web Service.................................................................... ................................ 106 17.10 Web Services para modelos de dados qu e possuem duas ou mais entidades ................................ 107 18.Uso do comando New Model .............................................................. ...................................................... 111 18.1 Sintaxe da New M odel ........................................................................... ............................................ 111 19.Reutilizando um modelo de da dos ou interface j existentes ................................................... ............... 124 19.1 Apenas reutilizando os componentes .................... ............................................................................ 124 19.2 Reutilizando e complementando os componentes.............................. .............................................. 125 19.3 Exemplo completo de uma aplicao que reutiliza componentes de modelo e interface ................ 129 Apndic e A ............................................................................ ......................................................................... 131 ndi ce Remissivo ................................................................... .......................................................................... 133 AdvPl utilizando MVC 5
1.Arquitetura MVC Primeiramente vamos entender o que a arquitetura MVC. A arquitetura Model-View-C ontroller ou MVC, como mais conhecida, um padro de arquitetura de software que vi sa separar a lgica de negcio da lgica de apresentao (a interface), permitindo o desen volvimento, teste e manuteno isolados de ambos. Aqueles que j desenvolveram uma apl icao em AdvPL vo perceber, que justamente a diferena mais importante entre a forma d e construir uma aplicao em MVC e a forma tradicional essa separao. E ela que vai pe mitir o uso da regra de negcio em aplicaes que tenham ou no interfaces, como Web Ser vices e aplicao automtica, bem como seu reuso em outras aplicaes. A arquitetura MVC p ossui trs componentes bsicos: Model ou modelo de dados: representa as informaes do domnio do aplicativo e fornece funes para operar os dados, isto , ele contm as funcionalidades do aplicativo. Nele definimos as regras de negcio: tabelas, campos, estruturas, relacionamentos etc. . O modelo de dados (Model) tambm responsvel por notificar a interface (View) quan do os dados forem alterados. View ou interface: responsvel por renderizar o model o de dados (Model) e possibilitar a interao do usurio, ou seja, o responsvel por exi bir os dados. Controller: responde s aes dos usurios, possibilita mudanas no Modelo d e dados (Model) e seleciona a View correspondente. Para facilitar e agilizar o d esenvolvimento, na implementao do MVC feita no AdvPL, o desenvolvedor trabalhar com as definies de Modelo de dados (Model) e View, a parte responsvel pelo Controller j esta intrnseca. Frisando bem, a grande mudana, o grande paradigma a ser quebrado na forma de pensar e se desenvolver uma aplicao em AdvPL utilizando MVC a separao da regra de negcio da interface. Para que isso fosse possvel foram desenvolvidas vria s novas classes e mtodos no AdvPL. 6 - AdvPl utilizando MVC
2.Principais funes da aplicao em AdvPL utilizando o MVC Apresentamos agora o modelo de construo de uma aplicao em AdvPL utilizando o MVC. Os desenvolvedores em suas aplicaes sero responsveis por definir as seguintes funes: Mo elDef: Contem a construo e a definio do Model, lembrando que o Modelo de dados (Mode l) contm as regras de negcio; ViewDef: Contem a construo e definio da View, ou seja, er a construo da interface; MenuDef: Contem a definio das operaes disponveis para o lo de dados (Model). Cada fonte em MVC (PRW) s pode conter uma de cada dessas funes . S pode ter uma ModelDef, uma ViewDef e uma MenuDef. Ao se fazer uma aplicao em Ad vPL utilizando MVC, automaticamente ao final, esta aplicao j ter disponvel: Pont Entradas j disponveis; Um Web Service para sua utilizao; Importao ou exportao mens XML. Poder ser utilizada, similarmente ao que a rotina automtica das aplicaes sem MVC. Um ponto importante na aplicao em MVC que ela no se baseia necessariamente em metadad os (dicionrios). Como veremos mais a frente, ela se baseia em estruturas e essas por sua vez que podem vir do metadados (dicionrios) ou serem construdas manualment e.
2.1 O que a funo ModelDef? A funo ModelDef define a regra de negcios propriamente dita onde so definidas: as entidades (tabelas) que faro parte do modelo de dados (Model); Regras de depe ndncia entre as entidades; Validaes (de campos e aplicao); Persistncia dos dados (gra ao). Para uma ModelDef no preciso necessariamente haver uma interface. Como a regra de negcios totalmente separada da interface no MVC, podemos utilizar a ModelDef em qualquer outra aplicao, ou at utilizarmos uma determinada ModelDef como base para o utra mais complexa. As entidades da ModelDef no se baseiam necessariamente em met adados (dicionrios). Como veremos mais a frente, ela se baseia em estruturas e es sas por sua vez que podem vir do metadados ou serem construdas manualmente. AdvPl utilizando MVC 7
2.2 O que a funo ViewDef? A funo ViewDef define como o ser a interface e portanto como o usurio interage com o modelo de dados (Model) recebendo os dados informados pelo usurio, fornecendo ao modelo de dados (definido na ModelDef) e apresentando o resultado. A interface pode ser baseada totalmente ou parcialmente em um metadado (dicionrio), permitind o: Reaproveitamento do cdigo da interface, pois uma interface bsica pode ser acres cida de novos componentes; Simplicidade no desenvolvimento de interfaces complex as. Um exemplo disso so aquelas aplicaes onde uma GRID depende de outra. No MVC a c onstruo de aplicaes que tem GRIDs dependentes extremamente fcil; Agilidade no desenv lvimento, a criao e a manuteno se tornam muito mais geis; Mais de uma interface por B ussiness Object. Poderemos ter interfaces diferentes para cada variao de um segmen to de mercado, como o varejo.
2.3 O que a funo MenuDef? Uma funo MenuDef define as operaes quer sero realizadas pela aplicao, tais como incl alterao, excluso, etc.. Deve retornar um array em um formato especfico com as segui ntes informaes: 1. Ttulo; 2. Nome da aplicao associada; 3. Reservado; 4. Tipo de Tran sao a ser efetuada. E que podem ser: - 1 para Pesquisar - 2 para Visualizar - 3 pa ra Incluir - 4 para Alterar - 5 para Excluir - 6 para Imprimir 8 - AdvPl utilizando MVC
- 7 para Copiar 5. Nvel de acesso; 6. Habilita Menu Funcional; Exemplo: Static Function MenuDef() Local aRotina := {} aAdd( aAdd( aAdd( aAdd( aAdd( aAdd ( aRotina, aRotina, aRotina, aRotina, aRotina, aRotina, { { { { { { 'Visualizar' , 'Incluir' , 'Alterar' , 'Excluir' , 'Imprimir' , 'Copiar' , 'VIEWDEF.COMP021_M VC', 'VIEWDEF.COMP021_MVC', 'VIEWDEF.COMP021_MVC', 'VIEWDEF.COMP021_MVC', 'VIEWD EF.COMP021_MVC', 'VIEWDEF.COMP021_MVC', 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 8, 9, 0, 0 , 0, 0, 0, 0, NIL NIL NIL NIL NIL NIL } } } } } } ) ) ) ) ) ) Return aRotina
Note que o 2 parmetro utiliza a chamada direta de uma aplicao, ela faz referncia a um a ViewDef de um determinado fonte (PRW). A estrutura deste 2 parmetro tem o format o: ViewDef.<nome do fonte> Sempre referenciaremos a ViewDef de um fonte, pois el a a funo responsvel pela a interface da aplicao. Para facilitar o desenvolvimento, n MVC a MenuDef escreva-a da seguinte forma: Static Function MenuDef() Local aRotina := {} ADD ADD ADD ADD ADD ADD OPTION OPT ION OPTION OPTION OPTION OPTION aRotina aRotina aRotina aRotina aRotina aRotina Title Title Title Title Title Title 'Visualizar' 'Incluir' 'Alterar' 'Excluir' ' Imprimir' 'Copiar' Action Action Action Action Action Action 'VIEWDEF.COMP021_MV C' 'VIEWDEF.COMP021_MVC' 'VIEWDEF.COMP021_MVC' 'VIEWDEF.COMP021_MVC' 'VIEWDEF.CO MP021_MVC' 'VIEWDEF.COMP021_MVC' OPERATION OPERATION OPERATION OPERATION OPERATI ON OPERATION 2 3 4 5 8 9 ACCESS ACCESS ACCESS ACCESS ACCESS ACCESS 0 0 0 0 0 0 Return aRotina
O resultado final o mesmo, o que difere apenas a forma de construo, mas recomendad o a 2 forma que utiliza o formato de comandos e no posies de um vetor, pois uma even tual manuteno se tornar mais fcil. A MenuDef deve ser uma Static Function dentro da aplicao. Utilizando-se a funo FWMVCMenu, obtm-se um menu padro com as opes: Visuali Incluir, Alterar, Excluir, Imprimir e Copiar. Deve ser passado como parmetro no n ome do fonte. AdvPl utilizando MVC 9
Por exemplo: Static Function MenuDef() Return FWMVCMenu( "COMP021_MVC" ) Isso criaria um Menudef exatamente como o exemplo anterior. Para mais detalhes v eja o captulo 12.7 Obter um menu padro (FWMVCMenu).
2.4 Novo comportamento na interface Nas aplicaes desenvolvidas em AdvPL tradicional, aps a concluso de uma operao de alte ao fecha-se a interface e retorna ao Browse. Nas aplicaes em MVC, aps as operaes de luso e alterao, a interface permanece ativa e no rodap exibe-se a mensagem de que a operao foi bem sucedida.
3.Aplicaes com Browses (FWMBrowse) Para a construo de uma aplicao que possui um Browse, o MVC utiliza a classe FWMBrows e. Esta classe exibe um objeto Browse que construdo a partir de metadados (dicionr ios). Esta classe no foi desenvolvida exclusivamente para o MVC, aplicaes que no so e m MVC tambm podem utiliz-la. No MVC a utilizaremos. Suas caractersticas so: Subst ir componentes de Browse; Reduzir o tempo de manuteno, em caso de adio de um novo re quisito; Ser independente do ambiente Microsiga Protheus.
E apresenta como principais melhorias: Padronizao de legenda de cores; Melhor u ilidade no tratamento de filtros; Padro de cores, fontes e legenda definidas pelo usurio Deficiente visual; Reduo do nmero de operaes no SGBD (no mnimo 3 vezes mai o); Novo padro visual. 3.1 Construo de um Browse Falaremos aqui de principais funes e caractersticas para uso em aplicaes com MVC. 3.2 Construo bsica de um Browse Iniciamos a construo bsica de um Browse. Primeiramente crie um objeto Browse da seg uinte forma: oBrowse := FWMBrowse():New() Definimos a tabela que ser exibida na Browse utilizando o mtodo SetAlias. As colun as, ordens, etc.. 10 - AdvPl utilizando MVC
A exibio obtidos pelo metadados (dicionrios). oBrowse:SetAlias('ZA0') Definimos o ttulo que ser exibido como mtodo SetDescription. oBrowse:SetDescription('Cadastro de Autor/Interprete') E ao final ativamos a classe. oBrowse:Activate()
Com esta estrutura bsica construmos uma aplicao com Browse. O Browse apresentado aut omaticamente j ter: Pesquisa de registro; Filtro configurvel; Configurao de co aparncia; Impresso. 3.3 Legendas de um Browse (AddLegend) Para o uso de legendas no Browse utilizamos o mtodo AddLegend, que possui a segui nte sintaxe: AddLegend( <cRegra>, <cCor>, <cDescrio> ) Exemplo: oBrowse:AddLegend( "ZA0_TIPO=='1'", "YELLOW", "Autor" oBrowse:AddLegend( "ZA0_TI PO=='2'", "BLUE" ) ) , "Interprete" cRegra cCor a expresso em AdvPL para definir a legenda. o parmetro que define a cor de cada it em da legenda. So possveis os seguintes valores: GREEN RED YELLOW ORANGE BLUE GRAY BROWN BLACK Pa ra a cor Verde Para a cor Vermelha Para a cor Amarela Para a cor Laranja Para a cor Azul Para a cor Cinza Para a cor Marrom Para a cor Preta AdvPl utilizando MVC 11
PINK WHITE cDescrio Para a cor Rosa Para a cor Branca a que ser exibida para cada item da legenda
Observao: Cada uma das legendas se tornar automaticamente uma opo de filtro. Cuida ao montar as regras da legenda. Se houverem regras conflitantes ser exibida a leg enda correspondente 1 regra que for satisfeita. 3.4 Filtros de um Browse (SetFilterDefault) Se quisermos definir um filtro para o Browse utilizamos o mtodo SetFilterDefault, que possui a seguinte sintaxe: SetFilterDefault ( <filtro> ) Exemplo: oBrowse:SetFilterDefault( "ZA0_TIPO=='1'" ) ou oBrowse:SetFilterDefault( "Empty(ZA0_DTAFAL)" )
A expresso de filtro em AdvPL. O filtro definido na aplicao no anula a possibilidade do usurio fazer seus prprios filtros. Os filtros feitos pelo usurio sero aplicados em conjunto com o definido na aplicao (condio de AND). Exemplo: Se na aplicao foi def nido que s sero exibidos clientes que so pessoas jurdicas, se usurio fizer um filtro para exibir apenas clientes do estado de So Paulo, sero exibidos os clientes pesso a jurdica do estado de So Paulo. Foi executado o filtro do usurio e ainda respeitad o o filtro original da aplicao. Observao: O filtro da aplicao no poder ser desabili pelo usurio. 3.5 Desabilitao de detalhes do Browse (DisableDetails) Automaticamente para o Browse so exibidos, em detalhes, os dados da linha posicio nada. Para desabilitar esta caracterstica utilizamos o mtodo DisableDetails. Exemp lo: oBrowse:DisableDetails() 3.6 Campos virtuais no Browse Normalmente, para se exibir campos virtuais nos Browses, fazemos uso da funo Posic ione. 12 - AdvPl utilizando MVC
No novo Browse esta prtica se torna ainda mais importante, pois, quando ele encon tra a funo Posicione na definio de um campo virtual e a base de dados um SGBD (usa o TOTVSDbAccess), o Browse acrescenta um INNER JOIN na query que ser enviada ao SG BD, melhorando assim o desempenho para a extrao dos dados. Portanto, sempre utiliz e a funo Posicione para exibir campos virtuais. 3.7 Exemplo completo de Browse User Function COMP011_MVC() Local oBrowse // Instanciamento da Classe de Browse oBrowse := FWMBrowse():New() // Definio da tabela do Browse oBrowse:SetAlias('ZA0' ) // Definio da legenda oBrowse:AddLegend( "ZA0_TIPO=='1'", "YELLOW", "Autor" ) oB rowse:AddLegend( "ZA0_TIPO=='2'", "BLUE" , "Interprete" // Definio de filtro oBrow se:SetFilterDefault( "ZA0_TIPO=='1'" ) // Titulo da Browse oBrowse:SetDescriptio n('Cadastro de Autor/Interprete') // Opcionalmente pode ser desligado a exibio dos detalhes //oBrowse:DisableDetails() // Ativao da Classe oBrowse:Activate() Return NIL )
4.Construo de aplicao AdvPL utilizando MVC Iniciamos agora a construo da parte em MVC da aplicao, que so as funes de ModeDef, q contem as regras de negcio e a ViewDef que contem a interface. Um ponto important e que deve ser observado que, assim como a MenuDef, s pode haver uma funo ModelDef e uma funo ViewDef em um fonte. Se para uma determinada situao for preciso trabalhar em mais de um modelo de dados (Model), a aplicao deve ser quebrada em vrios fontes (PRW) cada um com apenas uma ModelDef e uma ViewDef. AdvPl utilizando MVC 13
5.Construo de aplicao MVC com uma entidade Mostramos como criar uma aplicao em MVC com apenas uma entidade envolvida. 5.1 Construo de uma estrutura de dados (FWFormStruct) A primeira coisa que precisamos fazer criar a estrutura utilizada no modelo de d ados (Model). As estruturas so objetos que contm as definies dos dados necessrias par a uso da ModelDef ou para a ViewDef. Esses objetos contm: Estrutura dos Campos; ices; Gatilhos; Regras de preenchimento (veremos frente); Etc. Como dito anteriormente o MVC no trabalha vinculado aos metadados (dicionrios) do Microsiga Protheus, ele trabalha vinculado a estruturas. Essas estruturas, por s ua vez, que podem ser construdas a partir dos metadados. Com a funo FWFormStruct a estrutura ser criada a partir do metadado. Sua sintaxe : FWFormStruct( <nTipo>, <cAlias> ) Onde: nTipo cAlias Exemplo: Local oStruZA0 := FWFormStruct( 1, 'ZA0' ) Tipo da construo da estrutura: 1 para Modelo de dados (Model) e 2 para interface ( View); Alias da tabela no metadado; No exemplo, o objeto oStruZA0 ser uma estrutura para uso em um modelo de dados (M odel). O primeiro parmetro (1) indica que a estrutura para uso no modelo e o segu ndo parmetro indica qual a tabela dos metadados ser usada para a criao da estrutura (ZA0). Local oStruZA0 := FWFormStruct( 2, 'ZA0' ) No exemplo dado, o objeto oStruZA0 ser uma estrutura para uso em uma interface (V iew). O primeiro parmetro (2) indica que a estrutura para uso em uma interface e o segundo parmetro indica qual a tabela dos metadados ser usada para a criao da estr utura (ZA0). Mais adiante veremos como criar estruturas manualmente e como selec ionar os campos que 14 - AdvPl utilizando MVC
faro parte das estruturas e outros tratamentos especficos da estrutura. Importante : Para modelo de dados (Model), a funo FWFormStruct, traz para a estrutura todos o s campos que compem a tabela independentemente do nvel, uso ou mdulo. Considera tam bm os campos virtuais. Para a interface (View) a funo FWFormStruct, traz para a est rutura os campos conforme o nvel, uso ou mdulo.
5.2 Construo da funo ModelDef Como foi dito anteriormente, nesta funo so definidas as regras de negcio ou modelo d e dados (Model). Ela contm as definies de: Entidades envolvidas; Validaes; R entos; Persistncia de dados (gravao); Etc. Iniciamos a funo ModelDef: Static Function ModelDef() Local oStruZA0 := FWFormStruct( 1, 'ZA0' ) Local oMod el // Modelo de dados que ser construdo Construindo o Model oModel := MPFormModel():New( 'COMP011M' ) MPFormModel a classe utilizada para a construo de um objeto de modelo de dados (Mo del). Devemos dar um identificador (ID) para o modelo como um todo e tambm um par a cada componente. Essa uma caracterstica do MVC, todo componente do modelo ou da interface devem ter um ID, como formulrios, GRIDs, boxes, etc. COMP011M o identi ficador (ID) dado ao Model, importante ressaltar com relao ao identificador (ID) d o Model: Se a aplicao uma Function, o identificador (ID) do modelo de dados (Model ) pode ter o mesmo nome da funo principal e esta prtica recomendada para facilitar a codificao. Por exemplo, se estamos escrevendo a funo XPTO, o identificador (ID) do modelo de dados (Model) poder ser XPTO. Se a aplicao uma User Function o identific ador (ID) do modelo de dados (Model) NO pode ter o mesmo nome da funo principal, is so por causa dos pontos de AdvPl utilizando MVC 15
entrada que j so criados automaticamente quando desenvolvemos uma aplicao em MVC. Is so ser mais detalhado frente (ver captulo 16.Pontos de entrada no MVC ). 5.3 Criao de um componente de formulrios no modelo de dados (AddFields) O mtodo AddFields adiciona um componente de formulrio ao modelo. A estrutura do mo delo de dados (Model) deve iniciar, obrigatoriamente, com um componente de formu lrio. Exemplo: oModel:AddFields( 'ZA0MASTER', /*cOwner*/, oStruZA0 ) Devemos dar um identificador (ID) para cada componente do modelo. ZA0MASTER o id entificador (ID) dado ao componente de formulrio no modelo, oStruZA0 a estrutura que ser usada no formulrio e que foi construda anteriormente utilizando FWFormStruc t, note que o segundo parmetro (owner) no foi informado, isso porque este o 1 compo nente do modelo, o Pai do modelo de dados (Model) e portanto no tem um componente superior ou owner.
5.4 Descrio dos componentes do modelo de dados (SetDescription) Sempre definindo uma descrio para os componentes do modelo. Com o mtodo SetDescript ion adicionamos a descrio ao modelo de dados (Model), essa descrio ser usada em vrios lugares como em Web Services por exemplo. Adicionamos a descrio do modelo de dados : oModel:SetDescription( 'Modelo de dados de Autor/Interprete' ) Adicionamos a descrio dos componentes do modelo de dados: oModel:GetModel( 'ZA0MASTER' ):SetDescription( 'Dados de Autor/Interprete' ) Para um modelo que s contm um componente parece ser redundante darmos uma descrio pa ra o modelo de dados (Model) como um todo e uma para o componente, mas quando es tudarmos outros modelos onde haver mais de um componente esta ao ficar mais clara. 5.5 Finalizao de ModelDef Ao final da funo ModelDef, deve ser retornado o objeto de modelo de dados (Model) gerado na funo. Return oModel 5.6 Exemplo completo da ModelDef Static Function ModelDef() 16 - AdvPl utilizando MVC
// Cria a estrutura a ser usada no Modelo de Dados Local oStruZA0 := FWFormStruc t( 1, 'ZA0' ) Local oModel // Modelo de dados que ser construdo // Cria o objeto do Modelo de Dados oModel := MPFormModel():New('COMP011M' ) // Adiciona ao modelo um componente de formulrio oModel:AddFields( 'ZA0MASTER', / *cOwner*/, oStruZA0) // Adiciona a descrio do Modelo de Dados oModel:SetDescription( 'Modelo de dados d e Autor/Interprete' ) // Adiciona a descrio do Componente do Modelo de Dados oModel:GetModel( 'ZA0MASTER ' ):SetDescription( 'Dados de Autor/Interprete' ) // Retorna o Modelo de dados Return oModel
5.7 Construo da funo ViewDef A interface (View) responsvel por renderizar o modelo de dados (Model) e possibil itar a interao do usurio, ou seja, o responsvel por exibir os dados. O ViewDef contm a definio de toda a parte visual da aplicao. Iniciamos a funo: Static Function ViewDef() A interface (View) sempre trabalha baseada em um modelo de dados (Model). Criare mos um objeto de modelo de dados baseado no ModelDef que desejamos. Com a funo FWL oadModel obtemos o modelo de dados (Model) que est definido em um fonte, no nosso caso o prprio fonte, mas nada impediria que usssemos o modelo de qualquer outro f onte em MVC, com isso podemos reaproveitar um mesmo modelo de dados (Model) em m ais de uma interface (View). Local oModel := FWLoadModel( 'COMP011_MVC' ) COMP011_MVC nome do fonte de onde queremos obter o modelo de dados (Model). Inic iando a construo da interface (View) oView := FWFormView():New() FWFormView a classe que dever ser usada para a construo de um objeto de interface ( View). AdvPl utilizando MVC 17
Definimos qual o modelo de dados (Model) que ser utilizado na interface (View). oView:SetModel( oModel ) 5.8 Criao de um componente de formulrios na interface (AddField) Adicionamos no nosso interface (View) um controle do tipo formulrio (antiga Encho ice), para isso usamos o mtodo AddField A interface (View) deve iniciar, obrigato riamente, com um componente do tipo formulrio. oView:AddField( 'VIEW_ZA0', oStruZA0, 'ZA0MASTER' ) Devemos dar um identificador (ID) para cada componente do interface (View). VIEW _ZA0 o identificador (ID) dado ao componente da interface (View), oStruZA0 a est rutura que ser usada e ZA0MASTER identificador (ID) do componente do modelo de da dos (Model) vinculado a este componente da interface (View). Cada componente da interface (View) deve ter um componente do modelo de dados (Model) relacionado, isso equivale a dizer que os dados do ZA0MASTER sero exibidos na interface (View) no componente VIEW_ZA0 5.9 Exibio dos dados na interface (CreateHorizontalBox / CreateVerticalBox) Sempre precisamos criar um continer1, um objeto, para receber algum elemento da i nterface (View). Em MVC criaremos sempre box horizontal ou vertical para isso. O mtodo para criao de um box horizontal : oView:CreateHorizontalBox( 'TELA' , 100 ) Devemos dar um identificador (ID) para cada componente da interface (View). TELA o identificador (ID) dado ao box e o nmero 100 representa o percentual da tela q ue ser utilizado pelo Box. No MVC no h referncias a coordenadas absolutas de tela, o s componentes visuais so sempre All Client, ou seja, ocuparo todo o continer onde f or inserido 5.10 Relacionando o componente da interface (SetOwnerView) Precisamos relacionar o componente da interface (View) com um box para exibio, par a isso usamos o mtodo SetOwnerView. 1 Determinada rea definida pelo desenvolvedor para agrupar componentes visuais, por exemplo, Panel, Dialog, Window, etc 18 - AdvPl utilizando MVC
oView:SetOwnerView( 'VIEW_ZA0', 'TELA' ) Desta forma o componente VIEW_ZA0 ser exibido na tela utilizando o box TELA. 5.11 Finalizao da ViewDef Ao final da funo ViewDef, deve ser retornado o objeto de interface (View) gerado Return oView 5.12 Exemplo completo da ViewDef Static Function ViewDef() // Cria um objeto de Modelo de dados baseado no ModelD ef() do fonte informado Local oModel := FWLoadModel( 'COMP011_MVC' ) // Cria a estrutura a ser usada na View Local oStruZA0 := FWFormStruct( 2, 'ZA0' ) // Interface de visualizao construda Local oView // Cria o objeto de View oView := FWFormView():New() // Define qual o Modelo de dados ser utilizado na View oView:SetModel( oModel ) / / Adiciona no nosso View um controle do tipo formulrio // (antiga Enchoice) oView :AddField( 'VIEW_ZA0', oStruZA0, 'ZA0MASTER' ) // Criar um "box" horizontal para receber algum elemento da view oView:CreateHor izontalBox( 'TELA' , 100 ) // Relaciona o identificador (ID) da View com o "box" para exibio oView:SetOwnerVi ew( 'VIEW_ZA0', 'TELA' ) // Retorna o objeto de View criado Return oView 5.13 Finalizao da criao da aplicao com uma entidade Desta forma criamos uma aplicao de AdvPL utilizando MVC onde h apenas uma entidade envolvida. Construmos a ModelDef; AdvPl utilizando MVC 19
Construmos a ViewDef.
Esta aplicao seria o equivalente s aplicaes de tipo Modelo1 que normalmente so feitas Veremos a seguir a construo de aplicaes utilizando duas ou mais entidades.
6.Construo de uma aplicao MVC com duas ou mais entidades Vimos at agora a construo de uma aplicao onde era utilizada apenas uma entidade. Vere mos a construo onde duas ou mais entidades iro existir. A construo da aplicao seguir mesmos passos que vimos at agora: Construo da ModelDef e da ViewDef. A diferena bsica que agora cada uma delas possuir mais de um componente e eles se relacionaro. 6.1 Construo de estruturas para uma aplicao MVC com duas ou mais entidades Como descrevemos, a primeira coisa que precisamos fazer criar a estrutura utiliz ada no modelo de dados (Model). Temos que criar uma estrutura para cada entidade que participar do modelo. Se forem 2 entidades, 2 estruturas, se forem 3 entidad es, 3 estruturas e assim por diante. Mostraremos uma aplicao onde temos 2 entidade s em uma relao de dependncia de Master-Detail (Pai-Filho), como por exemplo um Pedi do de Venda, onde temos o cabealho do pedido seria o Master (Pai) e os itens seri am o Detail (Filho) A construo das estruturas seria: Local oStruZA1 := FWFormStruct( 1, 'ZA1' ) Local oStruZA2 := FWFormStruct( 1, 'Z A2' ) No exemplo anterior o objeto oStruZA1 ser uma estrutura para ser utilizada em um Modelo de dados (Model) para a entidade Master (Pai) e oStruZA2 para a entidade Detail (Filho). O primeiro parmetro (1) indica que a estrutura para ser utilizada em um modelo de dados (Model) e segundo indica qual a tabela ser usada para a cr iao da estrutura. Local oStruZA1 := FWFormStruct( 2, 'ZA1' ) Local oStruZA2 := FWFormStruct( 2, 'Z A2' ) No exemplo acima o objeto oStruZA1 ser uma estrutura para ser utilizada em uma in terface (View) para a entidade Master (Pai) e oStruZA2 para a entidade Detail (F ilho). O primeiro parmetro (2) indica que a estrutura para ser utilizada em uma i nterface (View) e o segundo indica qual tabela ser usada para a criao da estrutura. 6.2 Construo de uma funo ModelDef Iniciamos a funo ModelDef. Static Function ModelDef() 20 - AdvPl utilizando MVC
Local oStruZA1 := FWFormStruct( 1, 'ZA1' ) Local oStruZA2 := FWFormStruct( 1, 'Z A2' ) Local oModel // Modelo de dados que ser construdo Observe que no cdigo, houve a criao de 2 estruturas uma para cada entidade. Comeamos a construo do Model oModel := MPFormModel():New( 'COMP021M' ) Devemos dar um identificador (ID) para o Modelo de dados (Model) e para cada com ponente do Model. COMP021M o identificador (ID) dado ao Modelo de dados (Model). 6.3 Criao de um componente de formulrios no modelo de dados (AddFields) O mtodo AddFields adiciona ao modelo um componente de formulrio. A estrutura do mo delo deve iniciar, obrigatoriamente, com um componente de formulrio. oModel:AddFields( 'ZA1MASTER', /*cOwner*/, oStruZA1 ) Devemos dar um identificador (ID) para cada componente do Model. ZA1MASTER o ide ntificador (ID) dado ao formulrio no Model, oStruZA1 a estrutura que ser usada no formulrio e que foi construda anteriormente utilizando FWFormStruct; note que o se gundo parmetro (Owner) no foi informado, isso porque este o 1 componente do Model, o Pai do modelo de dados (Model) e, portanto no tem um componente superior ou own er.
6.4 Criao de um componente de grid no Modelo de dados (AddGrid) A relao de dependncia entre as entidades de Master-Detail, ou seja, h 1 ocorrncia do Pai para n ocorrncias do Filho (1-n) Quando uma entidade ocorrer n vezes no modelo em relao outra, devemos definir um componente de Grid para esta entidade. O mtodo AddGrid adiciona ao modelo um componente de grid. oModel:AddGrid( 'ZA2DETAIL', 'ZA1MASTER', oStruZA2 ) Devemos dar um identificador (ID) para cada componente do Model. ZA2DETAIL o ide ntificador (ID) dado ao componente no Model, oStruZA2 a estrutura que ser usada n o componente e que foi construda anteriormente utilizando FWFormStruct, note que o segundo parmetro (Owner) desta vez foi informado, isso porque esta entidade dep ende da 1 (Master), portanto ZA1MASTER o componente superior ou owner de ZA2DETAI L. AdvPl utilizando MVC 21
6.5 Criao de relao entre as entidades do modelo (SetRelation) Dentro do modelo devemos relacionar todas as entidades que participam dele. No n osso exemplo temos que relacionar a entidade Detail com a entidade Master. Uma r egrinha bem simples para entender isso : Toda entidade do modelo que possui um su perior (owner) dever ter seu relacionamento para ele definido. Em outras palavra s, preciso dizer quais as chaves de relacionamento do filho para o pai. O mtodo u tilizado para esta definio o SetRelation. Exemplo: oModel:SetRelation( 'ZA2DETAIL', { { 'ZA2_FILIAL', 'xFilial( "ZA2" )' }, { 'ZA2_ MUSICA', 'ZA1_MUSICA' } }, ZA2->( IndexKey( 1 ) ) ) O ZA2DETAIL o identificador (ID) da entidade Detail, o segundo parmetro um vetor bidimensional onde so definidos os relacionamentos entre cada campo da entidade f ilho para a entidade Pai. O terceiro parmetro a ordenao destes dados no componente. Estamos dizendo no exemplo acima que o relacionamento da entidade Detail ser por ZA2_FILIAL e ZA2_MUSICA, o valor de ZA2_FILIAL ser dado por xFilial() e o de ZA2 _MUSICA vir de ZA1_MUSICA. Observao: O relacionamento sempre definido do Detail (Fi lho) para o Master (Pai), tanto no identificador (ID) quanto na ordem do vetor b i-dimensional. 6.6 Definio da chave primria (SetPrimaryKey) O modelo de dados precisa que sempre se informe qual a chave primria para a entid ade principal do modelo de dados (Model). Se a estrutura da entidade foi construd a utilizando-se o FWFormStruct, a chave primria ser aquela que foi definida no met adados (dicionrios). Se a estrutura foi construda manualmente ou se a entidade no p ossui definio de chave nica no metadados, temos que definir qual ser essa chave com o mtodo S SetPrimaryKey. Exemplo: oModel: SetPrimaryKey( { "ZA1_FILIAL", "ZA1_MUSICA" } ) Onde o parmetro passado um vetor com os campos que compem a chave primria. Use este mtodo somente se for preciso. Sempre defina a chave primria para o modelo. Se rea lmente no for possvel criar uma chave primria para a entidade principal, informe-o no modelo de dados da seguinte forma: oModel: SetPrimaryKey( {} ) 6.7 Descrevendo os componentes do modelo de dados (SetDescription) Defina sempre uma descrio para os componentes do modelo. Com o mtodo SetDescription 22 - AdvPl utilizando MVC
adicionamos a descrio do Modelo de Dados, essa descrio ser usada em vrios lugares com em Web Services por exemplo. Adicionamos a descrio do modelo de dados. oModel:SetDescription( 'Modelo de Musicas' ) Adicionamos a descrio dos componentes do modelo de dados. oModel:GetModel( 'ZA1MASTER' ):SetDescription( 'Dados da Musica' ) oModel:GetMod el( 'ZA2DETAIL' ):SetDescription( 'Dados do Autor Da Musica' ) Note que desta vez definimos uma descrio para modelo e uma para cada componente do modelo. 6.8 Finalizao da ModelDef Ao final da funo ModelDef, deve ser retornado o objeto de Modelo de dados (Model) gerado na funo. Return oModel 6.9 Exemplo completo da ModelDef Static Function ModelDef() // Cria as estruturas a serem usadas no Modelo de Dados Local oStruZA1 := FWForm Struct( 1, 'ZA1' ) Local oStruZA2 := FWFormStruct( 1, 'ZA2' ) Local oModel // Mo delo de dados construdo // Cria o objeto do Modelo de Dados oModel := MPFormModel():New( 'COMP021M' ) // Adiciona ao modelo um componente de formulrio oModel:AddFields( 'ZA1MASTER', / *cOwner*/, oStruZA1 ) // Adiciona ao modelo uma componente de grid oModel:AddGrid( 'ZA2DETAIL', 'ZA1MA STER', oStruZA2 ) // Faz relacionamento entre os componentes do model oModel:SetRelation( 'ZA2DETA IL', { { 'ZA2_FILIAL', 'xFilial( "ZA2" )' }, { 'ZA2_MUSICA', 'ZA1_MUSICA' } }, Z A2->( IndexKey( 1 ) ) ) // Adiciona a descrio do Modelo de Dados oModel:SetDescription( 'Modelo de Musicas ' ) // Adiciona a descrio dos Componentes do Modelo de Dados oModel:GetModel( 'ZA1MAST ER' ):SetDescription( 'Dados da Musica' ) AdvPl utilizando MVC 23
oModel:GetModel( 'ZA2DETAIL' ):SetDescription( 'Dados do Autor Da Musica' ) // Retorna o Modelo de dados Return oModel 6.10 Construo da funo ViewDef Iniciamos a funo. Static Function ViewDef() A interface (View) sempre trabalhar baseada em um modelo de dados (Model). Criamo s um objeto de Modelo de dados baseado no ModelDef que desejamos. Com a funo FWLoa dModel obtemos o modelo de dados (Model) que est definido em um fonte, no nosso c aso, o prprio fonte, mas nada impede que usssemos o modelo de dados (Model) de qua lquer outro fonte em MVC, com isso podemos reaproveitar um mesmo Modelo de dados (Model) em mais de uma interface (View). Local oModel := FWLoadModel( 'COMP021_MVC' ) COMP021_MVC nome do fonte de onde queremos obter o model. Comeamos a construo da int erface (View) oView := FWFormView():New() FWFormView a classe que dever ser usada para a construo de um objeto de interface ( View). Definimos qual o Modelo de dados (Model) que ser utilizado na interface (V iew). oView:SetModel( oModel ) 6.11 Criao de um componente de formulrios na interface (AddField) Adicionamos na nossa interface (View) um controle do tipo formulrio (antiga Encho ice), para isso usamos o mtodo AddField. A interface (View) deve iniciar, obrigat oriamente, com um componente do tipo formulrio. oView:AddField( 'VIEW_ZA1', oStruZA1, 'ZA1MASTER' ) Devemos dar um identificador (ID) para cada componente do interface (View). VIEW _ZA1 o identificador (ID) dado ao componente da interface (View), oStruZA1 a est rutura que ser usada e ZA1MASTER identificador (ID) do componente do Modelo de da dos (Model) vinculado a este componente da interface (View). Cada componente da interface (View) deve ter um componente do Modelo de dados (Model) relacionado, isso equivale a dizer que os dados do ZA1MASTER sero exibidos na interface (View) no componente VIEW_ZA1. 6.12 Criao de um componente de grid na interface (AddGrid) 24 - AdvPl utilizando MVC
Adicionamos no nosso interface (View) um controle do tipo grid (antiga GetDados) , para isso usamos o mtodo AddGrid. oView:AddGrid( 'VIEW_ZA2', oStruZA2, 'ZA2DETAIL' ) Devemos dar um identificador (ID) para cada componente do interface (View). VIEW _ZA2 o identificador (ID) dado ao componente da interface (View), oStruZA2 a est rutura que ser usada e ZA2DETAIL identificador (ID) do componente do Modelo de da dos (Model) vinculado a este componente da interface (View). Cada componente da interface (View) deve ter um componente do Modelo de dados (Model) relacionado, isso equivale a dizer que os dados do ZA2DETAIL sero exibidos na interface (View) no componente VIEW_ZA2. Observao: Note que aqui no falamos que entidade superior a qual, isso porque esta funo do modelo de dados. A interface (View) s reflete os da dos do modelo. 6.13 Exibio dos dados na interface (CreateHorizontalBox / CreateVerticalBox) Sempre precisamos criar um continer, um objeto, para receber algum elemento da in terface (View). Em MVC criaremos sempre box horizontal ou vertical para isso. O mtodo para criao de um box horizontal : oView:CreateHorizontalBox( 'SUPERIOR', 15 ) Devemos dar um identificador (ID) para cada componente do interface (View). SUPE RIOR o identificador (ID) dado ao box e nmero 15 representa o percentual da tela que ser utilizado pelo box. Como teremos dois componentes precisamos definir mais um box para o segundo componente oView:CreateHorizontalBox( 'INFERIOR', 85 ) INFERIOR o identificador (ID) dado ao box e nmero 85 representa o percentual da t ela que ser utilizado por ele. Observao: A soma dos percentuais dos boxes de mesmo nvel dever ser sempre 100%. AdvPl utilizando MVC 25
6.14 Relacionando o componente da interface (SetOwnerView) Precisamos relacionar o componente da interface (View) com um box para exibio, par a isso usamos o mtodo SetOwnerView. oView:SetOwnerView( 'VIEW_ZA1', 'SUPERIOR' ) oView:SetOwnerView( 'VIEW_ZA2', 'IN FERIOR' ) Desta forma o componente VIEW_ZA1 ser exibido na tela pelo box SUPERIOR e o compo nente VIEW_ZA2 ser exibido na tela pelo box INFERIOR. Obs.: Note que os dados da entidade Pai ocuparo 15% da tela e da entidade Filho 85%, pois: Id do Model ZA1MA STER ZA2DETAIL Id da View VIEW_ZA1 VIEW_ZA2 Id do Box SUPERIOR (15%) INFERIOR (8 5%) 6.15 Finalizao da ViewDef Ao final da funo ViewDef, deve ser retornado o objeto de interface (View) gerado. Return oView 6.16 Exemplo completo da ViewDef Static Function ViewDef() // Cria um objeto de Modelo de dados baseado no ModelDef do fonte informado Loca l oModel := FWLoadModel( 'COMP021_MVC' ) // Cria as estruturas a serem usadas na View Local oStruZA1 := FWFormStruct( 2, 'ZA1' ) Local oStruZA2 := FWFormStruct( 2, 'ZA2' ) // Interface de visualizao construda Local oView // Cria o objeto de View oView := FWFormView():New() // Define qual Modelo de dados ser utilizado oView:SetModel( oModel ) // Adiciona no nosso View um controle do tipo formulrio (antiga Enchoice) 26 - AdvPl utilizando MVC
oView:AddField( 'VIEW_ZA1', oStruZA1, 'ZA1MASTER' ) //Adiciona no nosso View um controle do tipo Grid (antiga Getdados) oView:AddGri d( 'VIEW_ZA2', oStruZA2, 'ZA2DETAIL' ) // Cria um "box" horizontal para receber cada elemento da view oView:CreateHoriz ontalBox( 'SUPERIOR', 15 ) oView:CreateHorizontalBox( 'INFERIOR', 85 ) // Relaciona o identificador (ID) da View com o "box" para exibio oView:SetOwnerVi ew( 'VIEW_ZA1', 'SUPERIOR' ) oView:SetOwnerView( 'VIEW_ZA2', 'INFERIOR' ) // Retorna o objeto de View criado Return oView 6.17 Finalizao da criao da aplicao com duas ou mais entidades Desta forma criamos uma aplicao de AdvPL utilizando MVC onde h 2 entidades envolvid as. Construmos a ModelDef; Construmos a ViewDef.
Esta aplicao seria o equivalente s aplicaes de tipo Modelo3 que normalmente so feitas Se a necessidade for a construo de uma aplicao com mais de 2 entidades o processo s er o mesmo que o mostrado para 2. A diferena ser somente a quantidade de cada compo nente ou objeto que sero criados. Para o modelo de dados (Model) se a aplicao tem 3 entidades, sero precisos 3 estruturas, 3 componentes AddFields ou AddGrid e 2 re lacionamentos. Se a aplicao tem 4 entidades, sero precisos 4 estruturas, 4 componen tes AddFields ou AddGrid e 3 relacionamentos e assim por diante. Para a interfac e (View) se a aplicao tem 3 entidades, sero precisos 3 estruturas, 3 componentes Ad dField ou AddGrid e 3 boxes. Se a aplicao tem 4 entidades, sero precisos 4 estrutur as, 4 componentes AddField ou AddGrid e 4 boxes e assim por diante. O modelo de dados e a interface crescem na medida em que cresce a quantidade de entidades re lacionadas. Porm a forma bsica de construo sempre a mesma. AdvPl utilizando MVC 27
7.Tratamentos para o modelo de dados e para interface Agora que j sabemos como construir uma para aplicao em MVC utilizando n entidades, o que demonstraremos neste captulo so os tratamentos especficos para algumas necess idades na construo de uma aplicao para a regra de negcio e para interface, pois em te rmos de hierarquia a idia sempre a mesma. Exemplo: Validaes; Permisses; linhas; Obter e atribuir valores; Persistncia dos dados; Criar botes; Criar folder s; etc.
8.Tratamentos para o modelo de dados Veremos alguns tratamentos que podem ser feitos no modelo de dados (Model) confo rme a necessidade: Validaes; Comportamentos; Manipulao da Grid. Obter e atr ores ao modelo de dados (Model); Gravao dos dados manualmente; Regras de preenchim ento.
8.1 Mensagens exibidas na interface As mensagens so usadas principalmente durante as validaes feitas no modelo de dados . Vamos analisar: Um ponto bsico do MVC a separao da regra de negcio da interface. A validao um processo executado dentro da regra de negcio e uma eventual mensagem de erro que ser exibida ao usurio, um processo que deve ser executado na interface, ou seja, no pode ser executado na regra de negcios. Para trabalhar essa situao foi f eito um tratamento para a funo Help. A funo Help poder ser utilizada nas funes dentr o modelo de dados (Model), porm o MVC ira guardar essa mensagem e ela s ser exibida quando o controle voltar para a interface. 28 - AdvPl utilizando MVC
Por exemplo, uma determinada funo conter: If nPrcUnit == 0 // Preo unitrio Help( ,, 'Help',, 'Preo unitrio no informado.', 1, 0 ) EndIf
Supondo que a mensagem de erro foi acionada porque o preo unitrio 0 (zero), neste momento no ser exibido nada ao usurio, isso pode ser observado ao debugar o fonte. Voc ver que ao passar pela funo Help nada acontece, porm, quando o controle interno v olta para a interface, a mensagem exibida. Esse tratamento foi feito apenas para a funo Help, funes como MsgStop, MsgInfo, MsgYesNo, Alert, MostraErro, etc. no poder ser utilizadas. 8.2 Obteno de componente do modelo de dados (GetModel) Durante o desenvolvimento vrias vezes teremos que manipular o modelo de dados (Mo del), para facilitar essa manipulao podemos ao invs de trabalhar como o modelo todo , trabalhar com uma parte especfica (um componente) de cada vez. Para isso utiliz amos o mtodo GetModel. Local oModelZA2 := oModel:GetModel( 'ZA2DETAIL' ) oModelZA2 o objeto que contm um componente do modelo de dados (Model) e ZA2DETAIL o identificador (ID) do componente que queremos. Se tivermos uma parte do model o de dados (Model) e quisermos pegar o modelo completo tambm podemos usar o GetMo del. Local oModel := oModelZA2:GetModel() oModel o objeto que contm o modelo de dados (Model) completo. 8.3 Validaes Dentro do modelo de dados existentes vrios pontos onde podem ser inseridas as val idaes necessrias regra de negcio. O modelo de dados (Model) como um todo tem seus po ntos e cada componente do modelo tambm.
8.3.1 Ps-validao do modelo a validao realizada aps o preenchimento do modelo de dados (Model) e sua confirmao. eria o equivalente ao antigo processo de TudoOk. O modelo de dados (Model) j faz a validao se os campos obrigatrios de todos os componentes do modelo foram preenchi dos, essa validao executada aps isso. Definimos a pos-validao do modelo de dados (Mo el) como um bloco de cdigo no 3 parmetro da classe de construo do modelo MPFormModel. oModel := MPFormModel():New( 'COMP011M', ,{ oModel COMP011POS( oModel ) } ) AdvPl utilizando MVC 29
O bloco de cdigo recebe como parmetro um objeto que o modelo e que pode ser passad o funo que far a validao. Static Function COMP011POS( oModel ) Local lRet := .T. Local nOperation := oModel:GetOperation // Segue a funo ... Retu rn lRet A funo chamada pelo bloco de cdigo deve retornar um valor lgico, onde se .T. (verdad eiro) a operao realizada e .F. (falso) no realizada. 8.3.2 Ps-validao de linha Em um modelo de dados (Model) onde existam componentes de grid, pode ser definid a uma validao que ser executada na troca das linhas do grid. Seria o equivalente ao antigo processo de LinhaOk. Definimos a pos-validao de linha como um bloco de cdig o no 5 parmetros do mtodo AddGrid. oModel:AddGrid( 'ZA2DETAIL', 'ZA1MASTER', oStruZA2, , { oModelGrid COMP021LPOS (oModelGrid) }
O bloco de cdigo recebe como parmetro um objeto que a parte do modelo corresponden te apenas ao grid e que pode ser passado para a funo que far a validao. A funo chama pelo bloco de cdigo deve retornar um valor lgico, onde se .T. (verdadeiro) a troca de linha realizada e .F. (falso) no realizada. 8.3.3 Validao de linha duplicada (SetUniqueLine) Em um modelo de dados onde existam componentes de grid podem ser definidos quais os campos que no podem se repetir dentro deste grid. Por exemplo, imaginemos o P edido de Vendas e no podemos permitir que o cdigo do produto se repita, podemos de finir no modelo este comportamento, sem precisar escrever nenhuma funo especfica pa ra isso. O mtodo do modelo de dados (Model) que dever ser usado o SetUniqueLine. // Liga o controle de no repetio de linha oModel:GetModel( 'ZA2DETAIL' ):SetUniqueL ine( { 'ZA2_AUTOR' } ) No exemplo anterior o campo ZA2_AUTOR no poder ter seu contedo repetido na grid. Ta mbm pode ser informado mais de um campo, criando assim um controle com chave comp osta. oModel:GetModel( 'ZA2DETAIL' ):SetUniqueLine( { 'ZA2_AUTOR', 'ZA2_DATA' } ) No exemplo anterior a combinao do campo ZA2_AUTOR e ZA2_DATA no podem ter seu conted o repetido na grid. 30 - AdvPl utilizando MVC
Individualmente a repetio at poder ocorrer, mas em conjunto no. ZA2_AUTOR 001 001 002 001 ZA2_DATA 01/01/11 02/01/11 02/01/11 01/01/11 Ok Ok Ok No permitido 8.3.4 Pr-validao de linha Em um modelo de dados onde existam componentes de grid pode ser definida uma val idao que ser executada nas aes das linhas do grid. Podemos entender por essas aes a ibuio de valores, apagar ou recuperar uma linha. Definimos a pr-validao de linha como um bloco de cdigo no 4 parmetros do mtodo AddGrid. oModel:AddGrid( 'ZA2DETAIL', 'ZA1MASTER', oStruZA2, { cField COMP021LPRE(oModel Grid, nLine, cAction, cField) } oModelGrid, nLine, cAction,
O bloco de cdigo recebe como parmetro: Um objeto que a parte do modelo correspond nte apenas ao grid; O nmero da linha; A ao executada: o o SETVALUE Para a atribuio d valores; DELETE Para deleo e recuperao da linha.
Campo onde se esta atribundo o valor, para deleo e recuperao da linha no passado. E s parmetros podem ser passados para a funo que far a validao. A funo chamada pelo b de cdigo deve retornar um valor lgico, onde se .T. (verdadeiro) a troca de linha r ealizada e .F. (falso) no realizada. Um exemplo da utilizao da pr-validao de linha: Static Function COMP023LPRE( oModelGrid, nLinha, cAcao, cCampo ) Local lRet Local oModel := .T. := oModelGrid:GetModel() Local nOperation := oModel:GetOperation() AdvPl utilizando MVC 31
// Valida se pode ou no apagar uma linha do Grid If cAcao == 'DELETE' .AND. nOper ation == MODEL_OPERATION_UPDATE lRet := .F. Help( ,, 'Help',, 'No permitido apaga r linhas na alterao.' +; CRLF + 'Voc esta na linha ' + Alltrim( Str( nLinha ) ), 1, 0 ) EndIf Return lRet No exemplo anterior no ser permitida a deleo da linha na operao de alterao.
8.3.5 Validao da ativao do modelo (SetVldActivate) a validao realizada no momento da ativao do modelo, permitindo ou no a sua ativao. nimos a validao da ativao usando o mtodo SetVldActivate. oModel:SetVldActivate( { oModel COMP011ACT( oModel ) } ) O bloco de cdigo recebe como parmetro um objeto que rm, o modelo ainda no tem os dados carregados, pois a ua ativao. A funo chamada pelo bloco de cdigo deve . (verdadeiro) a ativao realizada e .F. (falso) no
o do modelo correspondente, po carga dos dados feita aps a s retornar um valor lgico, onde se . realizada.
8.4 Manipulao da componente de grid Veremos agora alguns tratamentos que podem ser feitos nos componentes de grid de um modelo de dados (Model) 8.4.1 Quantidade de linhas do componente de grid (Length) Para se obter a quantidade de linhas do grid devemos utilizar o mtodo Length. As linhas apagadas tambm so consideradas na contagem. Static Function COMP021POS( oModel ) Local lRet Local oModelZA2 Local nI := .T. := oModel:GetModel( 'ZA2DETAIL' ) := 0 For nI := 1 To oModelZA2:Length() // Segue a funcao ... Next nI Se for passado um parmetro no mtodo Length, o retorno ser apenas a quantidade de li nhas no apagadas da grid. nLinhas := oModelZA2:Length( .T. ) // Quantidade linhas no apagadas 32 - AdvPl utilizando MVC
8.4.2 Ir para uma linha do componente de grid (GoLine) Para movimentarmos o grid, ou seja, mudarmos a linha, onde o grid est posicionado , utilizamos o mtodo GoLine passando como parmetro o nmero da linha onde se deseja posicionar. Static Function COMP021POS( oModel ) Local lRet Local oModelZA2 Local nI := .T. := oModel:GetModel( 'ZA2DETAIL' ) := 0 For nI := 1 To oModelZA2:Length() oModelZA2:GoLine( nI ) // Segue a funo ... Next nI
8.4.3 Status da linha de um componente de grid Quando estamos falando do modelo de dados (Model) temos 3 operaes bsicas: Incluso, A lterao e Excluso. Quando a operao de incluso, todos os componentes do modelo de dad (Model) esto includos, esse raciocnio tambm se aplica excluso, se esta a operao, os componentes tero seus dados excludos. Porm, quando falamos da operao de alterao, em assim. Em um modelo de dados onde existam componentes do grid, na operao de alt erao o grid pode ter linhas includas, alteradas ou excludas, ou seja, o modelo de da dos (Model) esta em alterao mas um grid pode ter tido as 3 operaes em suas linhas. E m MVC possvel saber que operaes uma linha sofreu pelos seguintes mtodos de status: I sDeleted: Informa se uma linha foi apagada. Retornando .T. (verdadeiro) a linha foi apagada. IsUpdated: Informa se uma linha foi alterada. Retornando .T. (verdadeiro) a linh a foi alterada. IsInserted: Informa se uma linha foi inserida, ou seja, se uma l inha nova na grid. Retornando .T. (verdadeiro) a linha foi inserida. Exemplo: Static Function COMP23ACAO() Local oModel Local oModelZA2 Local nI := FWModelActive() := oModel:GetModel( 'ZA2DETAIL' ) := 0 AdvPl utilizando MVC 33
Local nCtInc Local nCtAlt Local nCtDel Local aSaveLines := 0 := 0 := 0 := FWSaveRows() For nI := 1 To oModelZA2:Length() oModelZA2:GoLine( nI ) If oModelZA2:IsDeleted() nCtDel++ ElseIf oModelZA2:IsInserted() nCtInc++ ElseIf oModelZA2:IsUpdated() nCtAlt++ End If Next Help( ,, 'HELP',, 'Existem na grid' + CRLF + ; Alltrim( Str( nCtInc ) ) + ' linh as includas' + CRLF + ; Alltrim( Str( nCtAlt ) ) + ' linhas alteradas' + CRLF + ; Alltrim( Str( nCtDel ) ) + ' linhas apagadas' , 1, 0) + CRLF ; Mas de um mtodo de status pode retornar .T. (verdadeiro) para a mesma linha. Se u ma linha foi includa, o IsInserted retornar .T. (verdadeiro), em seguida ela foi a lterada, o IsUpdated retornar .T. (verdadeiro) e em seguida a mesma linha foi apa gada, IsDeleted tambm retornar .T. (verdadeiro). 8.4.4 Adio uma linha a grid (AddLine) Para adicionarmos uma linha a um componente do grid do modelo de dados (Model) u tilizamos o mtodo AddLine. nLinha++ If oModelZA2:AddLine() == nLinha // Segue a funo EndIf
O mtodo AddLine retorna a quantidade total de linhas da grid. Se a grid j possui 2 linhas e tudo correu bem na adio da linha, o AddLine retornara 3, se ocorreu algu m problema retornar 2, pois a nova linha no foi inserida. Os motivos para a insero no ser bem sucedida poder ser algum campo obrigatrio no informado, a ps-validao da linh retornou .F. (falso), atingiu a quantidade mxima de linhas 34 - AdvPl utilizando MVC
para o grid, por exemplo. 8.4.5 Apagando e recuperando uma linha da grid (DeleteLine e UnDeleteLine) Para apagarmos uma linha de um componente de grid do modelo de dados (Model) uti lizamos o mtodo DeleteLine. Local oModel Local oModelZA2 Local nI := FWModelActive() := oModel:GetModel( 'ZA 2DETAIL' ) := 0 For nI := 1 To oModelZA2:Length() oModelZA2:GoLine( nI ) If !oModelZA2:IsDeleted() oModelZA2:DeleteLine() EndIf Next O mtodo DeleteLine retorna .T. (verdadeiro) se a deleo foi bem sucedida. Um motivo para que no seja a pr-validao da linha retornar .F. (falso). Se quisermos recuperar uma linha da grid que est apagada utilizamos o mtodo UnDeleteLine. Local oModel Local oModelZA2 Local nI := FWModelActive() := oModel:GetModel( 'ZA 2DETAIL' ) := 0 For nI := 1 To oModelZA2:Length() oModelZA2:GoLine( nI ) If oModelZA2:IsDeleted() oModelZA2:UnDeleteLine() EndIf Next O mtodo UnDeleteLine retorna .T. (verdadeiro) se a recuperao foi bem sucedida. Um m otivo para que no seja a pr-validao da linha retornar .F. (falso). 8.4.6 Permisses para uma grid Se quisermos limitar que uma linha da grid possa ser inserida, alterada ou apaga da, para fazermos uma consulta, por exemplo, utilizamos um dos mtodos abaixo: AdvPl utilizando MVC 35
SetNoInsertLine: No permitir serem inseridas linhas na grid. Exemplo: oModel:GetModel( 'ZA2DETAIL' ):SetNoInsertLine( .T. ) SetNoUpdateLine: No permite alterar as linhas do grid. Exemplo: oModel:GetModel( 'ZA2DETAIL' ):SetNoUpdateLine( .T. ) SetNoDeleteLine: No permite apagar linhas do grid. Exemplo: oModel:GetModel( 'ZA2DETAIL' ):SetNoDeleteLine( .T. ) Esses mtodos podem ser informados no momento da definio do modelo de dados (Model). 8.4.7 Permisso de grid sem dados (SetOptional) Por padro, quando temos um modelo de dados (Model) onde h um componente de grid, d eve ser informada pelo menos uma linha neste grid. Mas vamos imaginar um modelo onde tivssemos o cadastro de produtos e seus acessrios. um modelo Master-Detail, t eremos para cada produto n acessrios, mas tambm teremos produtos que no tm acessrio a lgum. Assim, esta regra de que deve haver pelo menos uma linha informada na grid no pode ser aplicada. Neste caso utilizamos o mtodo SetOptional para permitir que o grid tenha ou no pelo menos uma linha digitada, ou seja, para dizer que a digi tao de dados do grid opcional. Esse mtodo deve ser informado ao definir o modelo de dados (Model). Exemplo: oModel:GetModel( 'ZA2DETAIL' ):SetOptional( .T. ) Se um grid for opcional e na estrutura houver campos obrigatrios, s ser validado se estes campos foram informados e somente se a linha sofrer alguma alterao em qualq uer campo. O mtodo IsOptional pode ser utilizado para saber se o componente de gr id tem ou no esta caracterstica. Se retornar .T. (verdadeiro) o componente permite que no existam linhas digitadas. Este mtodo pode ser til em validaes. 8.4.8 Guardando e restaurando o posicionamento do grid (FWSaveRows / FWRestRows ) Um cuidado que devemos ter quando escrevemos uma funo, mesmo que no seja para uso e m MVC, restaurarmos as reas das tabelas que desposicionamos. Analogamente, devemo s ter o mesmo cuidado para os componentes desposicionamos em uma funo, com o uso d o mtodo GoLine, por exemplo. 36 - AdvPl utilizando MVC do grid que
Para isso utilizaremos as funes FWSaveRows para salvar o posicionamento das linhas dos grids do modelo de dados (Model) e o FWRestRows para restaurar esses posici onamentos. Exemplo: Static Function COMP23ACAO() Local oModel Local oModelZA2 Local nI Local aSaveLines := FWModelActive() := oModel:GetModel( 'ZA2DETAIL' ) := 0 := FWSaveRows() For nI := 1 To oModelZA2:Length() oModelZA2:GoLine( nI ) // Segue a funo Next FWRestRows( aSaveLine ) Obs.: O FWSaveRows guarda o posicionamento de todos os grids do modelo de dados (Model) e o FWSaveRows restaura o posicionamento de todos os grids do model. 8.4.9 Definio da quantidade mxima de linhas do grid (SetMaxLine) Por padro a quantidade mxima de linhas de um componente de grid 990. Se for necessr io alterar esta quantidade utiliza-se o mtodo SetMaxLine. Este mtodo deve ser usad o na definio do modelo de dados (Model), ou seja, na ModelDef. Importante: A quant idade se refere sempre ao total de linhas, independentemente se estas esto apagad as ou no. 8.5 Obteno e atribuio de valores ao modelo de dados As operaes mais comuns que faremos em um modelo de dados (Model) obter e atribuir valores. Para isso utilizamos um dos mtodos abaixo: GetValue: Obtm um dado do mode lo de dados (Model). Podemos obter o dado a partir do modelo completo ou a parti r de um componente dele. A partir do modelo de dados (Model) completo. Local cMusica := oModel:GetValue( 'ZA1MASTER', 'ZA1_MUSICA ) Onde ZA1MASTER o identificador (ID) do componente e ZA1_MUSICA o campo do qual s e deseja obter o dado. AdvPl utilizando MVC 37
Ou a partir de um componente do modelo de dados (Model). Local oModelZA2 := oModel:GetModel( 'ZA1MASTER' ) Local cMusica := oModelZA2:Get Value('ZA1_MUSICA ) SetValue: Atribui um dado ao modelo de dados (Model). Podemos atribuir o dado a partir do modelo completo ou a partir de uma parte dele. A partir do modelo de dados (Mode l) completo oModel:SetValue( 'ZA1MASTER', 'ZA1_MUSICA', '000001' ) Onde ZA1MASTER o identificador (ID) do componente e ZA1_MUSICA o campo no qual s e deseja atribuir o dado e 000001 o dado que se deseja atribuir. Ou a partir de um componente do modelo de dados (Model). Local oModelZA2 := oModel:GetModel( 'ZA1MASTER' ) oModelZA2:SetValue('ZA1_MUSICA ', '000001' )
Quando utilizamos o SetValue para atribuir um dado a um campo as validaes deste ca mpo so executadas e tambm so disparados os seus gatilhos. O SetValue retorna .T. (v erdadeiro) se a atribuio foi bem sucedida, os motivos para que no seja podem ser qu e o dado no satisfez a validao ou o modo de edio (WHEN) no foi satisfeito, etc. LoadV lue: Atribui um dado ao modelo de dados (Model). Podemos atribuir o dado a parti r do modelo completo ou a partir de uma parte dele. A partir do modelo de dados (Model) completo oModel:LoadValue( 'ZA1MASTER', 'ZA1_MUSICA', '000001' ) Onde ZA1MASTER o identificador (ID) do componente e ZA1_MUSICA o campo onde se d eseja atribuir o dado e 000001 o dado que se deseja atribuir. Ou a partir de um componente do modelo de dados (Model). Local oModelZA2 := oModel:GetModel( 'ZA1MASTER' ) ... oModelZA2:LoadValue('ZA1_M USICA', '000001' ) A diferena entre o LoadValue e o SetValue que o LoadValue no executa as validaes nem dispara os gatilhos do campo. Ele fora a atribuio de dado. Importante: Utilize sem pre o SetValue para atribuir um dado, evite o LoadValue. S o utilize quando for e xtremamente necessrio. 38 - AdvPl utilizando MVC
8.6 Comportamento Veremos como alterar alguns dos comportamentos padres do modelo de dados (Model). 8.6.1 Alterao de dados de um componente no modelo de dados (SetOnlyView) Se quisermos que um determinado componente do modelo de dados (Model) no permita alterao em seus dados, que seja apenas para visualizao, utilizamos o mtodo SetOnlyVie w. Esse mtodo deve ser informado no momento da definio do Model. Exemplo: oModel:GetModel( 'ZA2DETAIL' ):SetOnlyView ( .T. ) 8.6.2 No gravar dados de um componente do modelo de dados (SetOnlyQuery) A persistncia dos dados (gravao) feita automaticamente pelo modelo de dados (Model) . Se quisermos que um determinado componente do modelo de dados (Model) permita incluso e/ou alterao em seus dados, porm, que estes dados no sejam gravados, utilizam os o mtodo SetOnlyQuery. Esse mtodo deve ser informado no momento da definio do Mode l. Exemplo: oModel:GetModel( 'ZA2DETAIL' ):SetOnlyQuery ( .T. )
8.6.3 Obteno da operao que est sendo realizada (GetOperation) Para sabermos a operao com que um modelo de dados (Model) est trabalhando, usamos o mtodo GetOperation. Esse mtodo retorna: O valor 3 quando uma incluso; O valor 4 ando uma alterao; O valor 5 quando uma excluso. Static Function COMP023LPRE( oModelGrid, nLinha, cAcao, cCampo ) Local lRet := . T. Local oModel := oModelGrid:GetModel() Local nOperation := oModel:GetOperation () // Valida se pode ou no apagar uma linha do Grid If cAcao == 'DELETE' .AND. nO peration == 3 AdvPl utilizando MVC 39
lRet := .F. Help( ,, 'Help',, 'No permitido apagar linhas na alterao.' + CRLF + ; ' Voc esta na linha ' + Alltrim( Str( nLinha ) ), 1, 0 ) EndIf Return lRet No MVC foram criadas vrias diretivas de compilao desenvolvimento e tornar a leitura de uma aplicao mais fcil. #DEFINE para facilitar o Para utilizar este #DEFINE preciso incluir a seguinte diretiva no fonte: # INCLUDE 'FWMVCDEF.CH' Para as operaes do modelo de dados (Model) podem ser utilizados: MODEL_OPERATION_I NSERT para incluso; MODEL_OPERATION_UPDATE para alterao; MODEL_OPERATION_DELETE par a excluso. Assim no exemplo dado acima podemos escrever: If cAcao == 'DELETE' .AND. nOperation == MODEL_OPERATION_INSERT 8.6.4 Gravao manual de dados (FWFormCommit) A gravao dos dados do modelo de dados (Model) (persistncia) realizada pelo MVC onde so gravados todos os dados das entidades do model. Porm, pode haver a necessidade de se efetuar gravaes em outras entidades que no participam do modelo. Por exemplo , quando inclumos um Pedido de Vendas preciso atualizar o valor de pedidos em abe rto do Cadastro de Clientes. O cabealho e itens do pedido fazem parte do modelo e sero gravados, o cadastro de Cliente no faz parte, mas precisa ser atualizado tam bm. Para este tipo de situao possvel intervir no momento da gravao dos dados. Para o definimos um bloco de cdigo no 4. parmetro da classe de construo do modelo de dados (Model) MPFormModel. oModel := MPFormModel():New( 'COMP011M', , , { oModel COMP011GRV( oModel ) } )
O bloco de cdigo recebe como parmetro um objeto que o modelo e que pode ser passad o funo que far a gravao. Diferentemente dos blocos de cdigo definidos no modelo de os (Model) para validao que complementam a validaes feitas pelo MVC, o bloco de cdigo para gravao substitui a gravao dos dados. Ento ao ser definido um bloco de cdigo par gravao, passa ser responsabilidade da funo criada, a gravao de todos os dados inclus ve os dados do modelo de dados em uso. 40 - AdvPl utilizando MVC
Para facilitar o desenvolvimento foi criada a funo FWFormCommit que far a gravao dos dados do objeto de modelo de dados (Model) informado. Static Function COMP011GRV ( oModel ) FWFormCommit( oModel ) // Efetuar a gravao de outros dados em entidade que // no so do model Importante: No devem ser feitas atribuies de dados no modelo (Model) dentro da funo d e gravao. Conceitualmente ao se iniciar a gravao, o modelo de dados (Model) j passou por toda a validao, ao tentar atribuir um valor, esse valor pode no satisfazer a va lidao do campo tornando o modelo de dados (Model) invalidado novamente e o que oco rrer a gravao de dados inconsistentes.
8.7 Regras de preenchimento (AddRules) Uma nova caracterstica que foi implementada no MVC so as regras de preenchimento, onde o preenchimento de um campo depende do preenchimento de outro. Por exemplo, podemos definir que o campo Cdigo da Loja de uma entidade, s pode ser preenchido aps o preenchimento do campo Cdigo do Cliente. As regras de preenchimento podem se r de 3 tipos: Tipo 1 Pr-Validao Adiciona uma relao de dependncia entre campos do fo lrio, impedindo a atribuio de valor caso os campos de dependncia no tenham valor atri budo. Por exemplo, o preenchimento do campo Cdigo da Loja s pode ser preenchido aps o preenchimento do campo Cdigo do Cliente. Tipo 2 Pos-Validao Adiciona uma relao de ependncia entre a referncia de origem e destino, provocando uma reavaliao do destino em caso de atualizao da origem. Por exemplo, aps o preenchimento do campo Cdigo da Loja a validao reavaliado caso o Cdigo do Cliente. seja alterado. Tipo 3 Pr e Ps-V dao So os tipos 1 e 2 simultaneamente Exemplo: oModel:AddRules( 'ZA3MASTER', 'ZA3_LOJA', 'ZA3MASTER', 'ZA3_DATA', 1 ) O ZA3MASTER o identificador (ID) do componente do modelo de dados (Model) onde e sta o campo de destino, ZA3_LOJA o campo destino, o segundo ZA3MASTER do compone nte do modelo de dados (Model) onde est o campo de origem, ZA3_DATA o campo de or igem. AdvPl utilizando MVC 41
9.Tratamentos de interface Veremos alguns tratamentos que podem ser feitos na interface (View) conforme a n ecessidade. Criao de botes; Criao de pastas; Agrupamento de campos; Incremen pos; Etc. 9.1 Campo Incremental (AddIncrementField) Podemos fazer com que um campo do modelo de dados (Model) que faa parte de um com ponente de grid, possa ser incrementado unitariamente a cada nova linha inserida . Por exemplo, imaginemos o Pedido de Vendas, nos itens, o nmero do item pode ser um campo incremental. Para isso utilizamos o mtodo AddIncrementField. Exemplo: oView:AddIncrementField( 'VIEW_ZA2', 'ZA2_ITEM' ) Onde VIEW_ZA2 o identificador (ID) do componente da interface (View), onde se en contra o campo e ZA2_ITEM o nome do campo que ser incrementado. 42 - AdvPl utilizando MVC
Visualmente temos : Importante: Esse comportamento s acontece quando a aplicao est sendo usada por sua i nterface (View). Quando o modelo de dados usado diretamente (Web Services, rotin as automtica, etc.) o campo incremental tem que ser informado normalmente. 9.2 Criao de botes na barra de botes (AddUserButton) Para a criao de botes adicionais na barra de botes da interface utilizamos o mtodo Ad dUserButton. Exemplo: oView:AddUserButton( 'Inclui Autor', 'CLIPS', { oView COMP021BUT()} ) Onde o Inclui Autor, o texto que ser apresentado no boto, CLIPS o nome da imagem d o RPO2 que ser usada para o boto e o 3 parmetro o bloco de cdigo que ser executado acionar o boto. 2 RPO Repositrio do Microsiga Protheus para aplicaes e imagens AdvPl utilizando MVC 43
Visualmente temos: 9.3 Ttulo do componente (EnableTitleView) No MVC podemos atribuir um ttulo para identificar cada componente da interface, p ara isso usamos o mtodo EnableTitleView. Exemplo: oView:EnableTitleView('VIEW_ZA2','Musicas') Onde VIEW_ZA2 o identificador (ID) do componente da interface (View), e 'MUSICAS ' o titulo que deseja para o componente Podemos ainda usar: oView:EnableTitleView('VIEW_ZA2') Onde o titulo que ser exibido o que foi definido no mtodo SetDescription do modelo de dados (Model) para o componente. 44 - AdvPl utilizando MVC
Visualmente temos: 9.4 Edio de Campos no componente de grid (SetViewProperty) Uma nova caracterstica que o MVC possui no uso da interface, para um componente d e grid, fazer ao mesmo tempo a edio de dados diretamente na grid e/ou em uma tela no layout de formulrio. Para isso utilizamos o mtodo SetViewProperty. Esse mtodo ha bilita alguns comportamentos especficos ao componente da interface (View), confor me a diretiva recebida. Exemplo: oView:SetViewProperty( 'VIEW_ZA2', "ENABLEDGRIDDETAIL", { 60 } ) Onde VIEW_ZA2 o identificador (ID) do componente da interface (View), onde se en contra o campo e ENABLEDGRIDDETAIL a diretiva que habilita o comportamento. {60} o percentual que o formulrio de edio ocupar do tamanho que o componente de grid ocu pa atualmente. Exemplificando numericamente, se para o componente de grid foi de finido que ele utilizar 50% da tela, ao se colocar 60 (60%) no parmetro, quer se i ndicar que dos 50% destinados ao componente de grid, 60% sero usados para o formu lrio de edio. AdvPl utilizando MVC 45
Visualmente temos: 9.5 Criao de pastas (CreateFolder) Em MVC podemos criar pastas onde sero colocados os componentes da interface (View ). Para isso utilizamos o mtodo CreateFolder. Exemplo: oView:CreateFolder( 'PASTAS' ) Devemos dar um identificador (ID) para cada componente da interface (View). PAST AS o identificador (ID) dado s pastas. Aps a criao da pasta principal, precisamos cr iar as abas desta pasta. Para isso usado o mtodo AddSheet. Por exemplo, criaremos 2 abas: oView:AddSheet( 'PASTAS', 'ABA01', 'Cabealho' ) oView:AddSheet( 'PASTAS', 'ABA02' , 'Item' ) Onde PASTAS o identificador (ID) da pasta, e ABA01 e ABA02 so os IDs dados a cada aba e Cabealho e Item so os ttulos de cada aba. 46 - AdvPl utilizando MVC
Para que possamos colocar um componente em uma aba, precisamos criar um box, um objeto, para receber os elementos da interface (View). A forma para se criar um box em uma aba : oView:CreateHorizontalBox( 'SUPERIOR', 100,,, 'PASTAS', 'ABA01' ) oView:CreateHo rizontalBox( 'INFERIOR', 100,,, 'PASTAS', 'ABA02' ) Devemos dar um identificador (ID) para cada componente da interface (View). SUPE RIOR e INFERIOR so os IDs dados a cada box. 100 indica o percentual que o box ocu par da aba. PASTAS o identificador (ID) da pasta. ABA01 e ABA02 os IDs das abas. Precisamos relacionar o componente da interface (View) com um box para exibio, par a isso usamos o mtodo SetOwnerView. oView:SetOwnerView( 'VIEW_ZA1' , 'SUPERIOR' ) oView:SetOwnerView( 'VIEW_ZA2' , ' INFERIOR' ) Resumindo: // Cria Folder na view oView:CreateFolder( 'PASTAS' ) // Cria pastas nas folders oView:AddSheet( 'PASTAS', 'ABA01', 'Cabealho' ) oView: AddSheet( 'PASTAS', 'ABA02', 'Item' ) // Criar "box" horizontal para receber algum elemento da view oView:CreateHorizo ntalBox( 'GERAL' , 100,,, 'SUPERIOR', 'ABA01' ) oView:CreateHorizontalBox( 'CORP O' , 100,,, 'INFERIOR', 'ABA02' ) // Relaciona o identificador (ID) da View com o "box" para exibio oView:SetOwnerVi ew( 'VIEW_ZA1' , 'SUPERIOR') oView:SetOwnerView( 'VIEW_ZA2' , 'INFERIOR' ) Quando as pastas so definidas utilizando os metadados (dicionrios), automaticament e a AdvPl utilizando MVC 47
interface (View) cria estas pastas. Se o componente colocado em uma das abas pos sui pastas definidas no metadados, estas pastas sero criadas dentro da aba onde e le se encontra. Visualmente temos: 9.6 Agrupamento de campos (AddGroup) Uma nova caracterstica que o MVC possui para uso da interface para um componente de formulrio, fazer o agrupamento dos campos na tela. Por exemplo, em um cadastro de clientes podemos ter campos para o endereo de entrega, correspondncia e fatura mento. Para uma visualizao melhor poderamos agrupar os campos de cada endereo. Para isso usamos o mtodo AddGroup. Exemplo: oStruZA0:AddGroup( 'GRUPO01', 'Alguns Dados', '', 1 ) oStruZA0:AddGroup( 'GRUPO0 2', 'Outros Dados', '', 2 )
Devemos dar um identificador (ID) para cada componente da interface (View). GRUP O01 o identificador (ID) dado ao agrupamento, o 2 parmetro o ttulo que ser 48 - Adv l utilizando MVC
apresentado no agrupamento e 1 o tipo de agrupamento, podendo ser 1- Janela; 2 S eparador Com o agrupamento criado, precisamos dizer quais campos faro parte deste agrupamento. Para isso alteraremos uma propriedade da estrutura de alguns campo s. Usaremos o mtodo SetProperty, que pode ser visto mais detalhadamente no captulo Erro! Fonte de referncia no encontrada. Erro! Fonte de referncia no encontrada.. // Colocando todos os campos para um agrupamento' oStruZA0:SetProperty( '*' , MV C_VIEW_GROUP_NUMBER, 'GRUPO01' ) // Trocando o agrupamento de alguns campos oStruZA0:SetProperty( 'ZA0_QTDMUS', M VC_VIEW_GROUP_NUMBER, 'GRUPO02' ) oStruZA0:SetProperty( 'ZA0_TIPO' , MVC_VIEW_GR OUP_NUMBER, 'GRUPO02' ) Visualmente temos: Observao: Os agrupamentos sero exibidos na interface (View) na ordem de sua criao. AdvPl utilizando MVC 49
9.7 Ao de interface (SetViewAction) Existe no MVC a possibilidade de se executar uma funo em algumas aes da interface (V iew). Esse recurso pode ser usado quando queremos executar algo na interface e q ue no tem reflexo no modelo de dados (Model) como um Refresh de tela por exemplo. Isso possvel nas seguintes aes: Refresh da interface; Acionamento do boto da interface; Acionamento do boto cancelar da interface; Deleo da linha da grid; R estaurao da linha da grid; Para isso usamos o mtodo na SetViewAction A sua sintaxe : oView:SetViewAction( <cActionlID>, <bAction> ) Onde: cActionlID ID do ponto onde a ao ser executada que podem ser: Executa a ao no R efresh da View; Executa a ao no acionamento do boto confirmar da View; Executa a ao n o acionamento do boto cancelar da View; Executa a ao na deleo da linha da grid; Execu ta a ao na restaurao da linha da grid; REFRESH BUTTONOK BUTTONCANCEL DELETELINE UNDELETELINE bAction Bloco com a ao a ser executada. Recebe como parmetro: Recebe como parmetro o objeto de View; Recebe como parmetro o objeto de View; Recebe como parmetro o objeto de V iew; Recebe como parmetro o objeto de View, identificador (ID) da View e nmero da linha. Recebe como parmetro o objeto de View, identificador (ID) da View e nmero d a linha REFRESH BUTTONOK BUTTONCANCEL DELETELINE UNDELETELINE 50 - AdvPl utilizando MVC
Exemplo: oView:SetViewAction( 'BUTTONOK' ,{ oView SuaFuncao( oView ) } ) oView:SetViewAction( 'BUTTONCANCEL',{ oView OutraFuncao( oView ) } ) Importante: Essas aes so executadas apenas quando existe uma interface (View). O qu e no ocorre quando temos o instnciamento direto do modelo, rotina automtica ou Web Service. Deve-se evitar ento colocar nestas funes aes que possam influenciar a regra de negcio, pois na execuo da aplicao sem interface essas aes no sero executadas. 9.8 Ao de interface do campo (SetFieldAction) Existe no MVC a possibilidade de se executar uma funo aps a validao de campo de algum componente do modelo de dados (Model). Esse recurso pode ser usado quando quere mos executar algo na interface e que no tem reflexo no modelo, como um Refresh de tela ou abrir uma tela auxiliar, por exemplo. Para isso usamos o mtodo na SetFie ldAction. A sua sintaxe : oView:SetFieldAction( <cIDField>, <bAction> ) Onde: cIDField bAction ID do campo (nome): Bloco com a ao a ser executada, recebe como parmetro: Exemplo: oView:SetFieldAction( 'A1_COD', { oView, cIDView, cField, xValue SuaFuncao( oV iew, cIDView, cField, xValue ) } ) Objeto De View O identificador (ID) Da View O identificador (ID) Do Campo Contedo Do Campo
Importante: Essas aes so executadas aps a validao do campo. Essas aes so execu s quando existe uma interface (View). O que no ocorre quando temos o instnciamento direto do modelo, rotina automtica ou Web Service. Deve-se evitar ento colocar ne stas funes aes que possam influenciar a regra de negcio, pois na execuo da aplicao terface essas aes no sero executadas.
Na construo de algumas aplicaes pode ser que tenhamos que adicionar interface um com ponente que no faz parte da interface padro do MVC, como um grfico, um calendrio, et c. Para isso usaremos o mtodo AddOtherObject Sua sintaxe : AddOtherObject( <Id>, <Code Block a ser executado>) Onde o 1 parmetro o identificador (ID) do AddOtherOb jects e 2 parmetro o cdigo de bloco que ser executado para a criao dos outro objeto. MVC se limita a fazer a chamada da funo, a responsabilidade de construo e atualizao os dados cabe ao desenvolvedor em sua funo. Exemplo: AddOtherObject( "OTHER_PANEL", { oPanel COMP23BUT( oPanel ) } ) Note que o 2 parmetro recebe como parmetro um objeto que o container onde o desenvo lvedor deve colocar seus objetos. Abaixo segue um exemplo do uso do mtodo, onde c olocamos em pedao da interface (View) 2 botes. Observe os comentrios no fonte: oView := FWFormView():New() oView:SetModel( oModel ) oView:AddField( 'VIEW_ZA3', oStruZA3, 'ZA3MASTER' ) oView:AddGrid( oView:AddGrid ( 'VIEW_ZA4', oStruZA4, 'ZA4DETAIL' ) 'VIEW_ZA5', oStruZA5, 'ZA5DETAIL' ) // Criar "box" horizontal para receber algum elemento da view oView:CreateHorizo ntalBox( 'EMCIMA' , 20 ) oView:CreateHorizontalBox( 'MEIO' , 40 ) oView:CreateHorizontalBox( 'EMBAIXO', 40 ) // Quebra em 2 "box" vertical para receber algum elemento da view oView:CreateVe rticalBox( 'EMBAIXOESQ', 20, 'EMBAIXO' ) oView:CreateVerticalBox( 'EMBAIXODIR', 80, 'EMBAIXO' ) // Relaciona o identificador (ID) da View com o "box" para exibicao oView:SetOwn erView( 'VIEW_ZA3', 'EMCIMA' oView:SetOwnerView( 'VIEW_ZA4', 'MEIO' ) ) oView:SetOwnerView( 'VIEW_ZA5', 'EMBAIXOESQ') // Liga a identificacao do compone nte 52 - AdvPl utilizando MVC
oView:EnableTitleView( 'VIEW_ZA3' ) oView:EnableTitleView( 'VIEW_ZA4', "MSICAS DO LBUM" ) oView:EnableTitleView( 'VIEW_ZA5', "INTERPRETES DAS MSICAS" ) // Acrescenta um objeto externo ao View do MVC // AddOtherObject(cFormModelID,bB loco) // cIDObject - Id // bBloco ao MVC. - Bloco chamado devera ser usado para se criar os objetos de tela externos oView:AddOtherObject("OTHER_PANEL", { oPanel COMP23BUT(oPanel)}) // Associa ao box que ira exibir os outros objetos oView:SetOwnerView("OTHER_PAN EL",'EMBAIXODIR') Return oView //------------------------------------------------------------------Static Funct ion COMP23BUT( oPanel ) Local lOk := .F. // Ancoramos os objetos no oPanel passado @ 10, 10 Button 'Estatistica' Size 36, 13 Message 'Contagem da FormGrid' Pixel Action COMP23ACAO( 'ZA4DETAIL', 'Existe m na Grid de Musicas' ) of oPanel @ 30, 10 Button 'Autor/Inter.' Size 36, 13 Message 'Inclui Autor/Interprete' Pix el Action FWExecView('Inclusao por FWExecView','COMP011_MVC', MODEL_OPERATION_IN SERT, , { .T. } ) of oPanel Return NIL AdvPl utilizando MVC 53
10.Tratamentos de estrutura de dados Como dito anteriormente o MVC no trabalha vinculado aos metadados do Microsiga Pr otheus, ele trabalha vinculado a estruturas. Essas estruturas, por sua vez que p odem ser construdas a partir dos metadados (dicionrios). Veremos alguns tratamento s que podem ser feitos nas estruturas conforme a necessidade. 10.1 Seleo de campos para a estrutura (FWFormStruct) Ao criarmos uma estrutura baseada no metadados (dicionrios), utilizando a funo FWFo rmStruct, ela leva em considerao todos os campos da entidade, respeitando nvel, mdul o, uso , etc. Se quisermos selecionar quais os campos do metadados (dicionrios) q ue faro parte da estrutura, devemos utilizar o 3 parmetro da FWFormStruct, que um b loco de cdigo que ser executada para cada campo que a funo trouxer do metadados (dic ionrios) e que recebe como parmetro o nome do campo. O bloco de cdigo deve retornar um valor lgico, onde se .T. (verdadeiro) o campo far parte da estrutura, se .F. ( falso) no far. Exemplo: Local oStruZA0 := FWFormStruct( 2, 'ZA0', { cCampo COMP11STRU(cCampo) } ) Onde a funo pode ser: Static Function COMP11STRU( cCampo ) Local lRet := .T. If cCampo == 'ZA0_QTDMUS' lRet := .F. EndIf Return lRet No exemplo de funo dado o campo ZA0_QTDMUS no far parte da estrutura. O dicionrio de campos (SX3) do metadado posicionado para cada campo. Importante: Esse tratament o pode ser feito tanto para as estruturas que sero usadas no modelo de dados (Mod el) quanto na interface (View). Mas tome o seguinte cuidado: Se for removido da estrutura da interface (View) um campo obrigatrio, mesmo ele no sendo exibido para o usurio, o modelo de dados (Model) far a sua validao dizendo que um campo obrigatri o no foi preenchido. AdvPl utilizando MVC 55
10.2 Remoo de campos da estrutura (RemoveField) Uma forma para a retirada de um campo da estrutura o uso do mtodo RemoveField. Ex emplo: Local oStruZA0 := FWFormStruct( 2, 'ZA0') oStruZA0: RemoveField('ZA0_QTDMUS') No exemplo acima o campo ZA0_QTDMUS foi removido da estrutura. Importante: Esse tratamento pode ser feito tanto para as estruturas que sero usadas no modelo de d ados (Model) quanto na interface (View). Mas tome o seguinte cuidado: Se for rem ovido da estrutura da interface (View) um campo obrigatrio, mesmo ele no sendo exi bido para o usurio, o modelo de dados (Model) far a sua validao dizendo que um campo obrigatrio no foi preenchido. 10.3 Alterao de propriedades do campo (SetProperty) Ao criarmos uma estrutura baseada no metadados (dicionrios), utilizando a funo FWFo rmStruct, so respeitadas as propriedades que o campo tem como validao, inicializado r padro e modo de edio, etc. Se houver a necessidade de mudar alguma propriedade do campo na estrutura, usaremos o mtodo SetProperty para isso. oStruZA0:SetProperty( 'ZA0_QTDMUS' , MODEL_FIELD_WHEN,'INCLUI') Onde o 1 parmetro o nome do campo que se deseja mudar ou atribuir a propriedade o 2 a propriedade que esta sendo tratada e o 3 o valor para a propriedade. No exempl o anterior o campo ZA0_QTDMUS s poder ser editado na operao de incluso. 56 - AdvPl utilizando MVC
As propriedades para os campos da estrutura do modelo de dados (Model) so: Propri edade para campos da estrutura do modelo de dados (Model) MODEL_FIELD_TITULO MOD EL_FIELD_TOOLTIP MODEL_FIELD_IDFIELD MODEL_FIELD_TIPO MODEL_FIELD_TAMANHO MODEL_ FIELD_DECIMAL MODEL_FIELD_VALID MODEL_FIELD_WHEN MODEL_FIELD_VALUES MODEL_FIELD_ OBRIGAT MODEL_FIELD_INIT MODEL_FIELD_KEY MODEL_FIELD_NOUPD MODEL_FIELD_VIRTUAL Tipo Descrio C C C C N N b B A L B L L L
Titulo Descrio completa do campo Nome (ID) Tipo Tamanho Decimais Validao Modo de edio Lista de valores permitido do campo (combo) Indica se o campo tem preenchimento obrigatrio Inicializador padro Indica se o campo chave Indica se o campo pode rece ber valor em uma operao de update. Indica se o campo virtual AdvPl utilizando MVC 57
As propriedades para os campos da estrutura da interface (View) so: Propriedade p ara campos da estrutura da interface (View) MVC_VIEW_IDFIELD MVC_VIEW_ORDEM MVC_ VIEW_TITULO MVC_VIEW_DESCR MVC_VIEW_HELP MVC_VIEW_PICT MVC_VIEW_PVAR MVC_VIEW_LO OKUP MVC_VIEW_CANCHANGE MVC_VIEW_FOLDER_NUMBER MVC_VIEW_GROUP_NUMBER MVC_VIEW_CO MBOBOX MVC_VIEW_MAXTAMCMB MVC_VIEW_INIBROW MVC_VIEW_VIRTUAL MVC_VIEW_PICTVAR Tip o C C C C A C B C L C C A N C L C Descrio Nome do Campo Ordem Titulo do campo Desc rio do campo Array com Help Picture Bloco de Picture Var Consulta F3 Indica se o c ampo editvel Pasta do campo Agrupamento do campo Lista de valores permitido do ca mpo (Combo) Tamanho Maximo da maior opo do combo Inicializador de Browse Indica se o campo virtual Picture Varivel Os nomes de propriedades citados nas tabelas dadas so na verdade diretivas de com pilao do tipo #DEFINE. Para utilizar este #DEFINE preciso incluir a seguinte diret iva no fonte: #INCLUDE 'FWMVCDEF.CH' Tambm possvel atribuirmos uma propriedade para todos os campos da estrutura de s ve z utilizando no nome do campo o asterisco "*" oStruZA0:SetProperty( '*' , MODEL_FIELD_WHEN,'INCLUI') 10.4 Criao de campos adicionais na estrutura (AddField) 58 - AdvPl utilizando MVC
Se quisermos criar um campo em uma estrutura j existente, utilizamos o mtodo Addfi eld. H diferenas na seqncia de parmetros deste mtodo para adicionar campos para a est utura do modelo de dados (Model) ou da interface (View). Sua sintaxe para o mode lo de dados (Model) : AddField Onde: cTitulo cTooltip cIdField cTipo nTamanho nDe cimal bValid bWhen aValues lObrigat bInit lKey lNoUpd lVirtual Ttulo do campo; To oltip do campo; Id do Field; Tipo do campo; Tamanho do campo; Decimal do campo; Code-block de validao do campo; Code-block de validao do modo de edio do campo; Lista de valores permitido do campo; Indica se o campo tem preenchimento obrigatrio; Co de-block de inicializao do campo; Indica se trata de um campo chave; Indica se o c ampo no pode receber valor em uma operao de update; Indica se o campo virtual; ( cT itulo, cTooltip, cIdField, cTipo, nTamanho, nDecimal, bValid, bWhen, aValues, lO brigat, bInit, lKey, lNoUpd, lVirtual, cValid) AdvPl utilizando MVC 59
A seguir exemplificamos o seu uso: Local oStruZA0 := FWFormStruct( 1, 'ZA0' ) oStruZA0:AddField( ; AllTrim( 'Exemplo 1' ) , ; , ; , ; , ; , ; , ; // Ord. Tipo Desc. // [01] // [02] // [03] // [04] // [05] // [06] C C C C N N T itulo do campo ToolTip do campo identificador (ID) do Field Tipo do campo Tamanh o do campo Decimal do campo // [07] B Code-block de AllTrim( 'Campo Exemplo 1' ) 'ZA0_XEXEM1' 'C' 1 0 FwBuildFeature( STRUCT_FEATURE_VALID,"Pertence('12')"), ; validao do campo NIL cam po {'1=Sim','2=No'} campo NIL preenchimento obrigatrio , ; , ; , ; // [08] // [09] // [10] B A L Code-block de validao When do Lista de valores permitido do Indica se o campo tem , ; // [11] B Code-block de FwBuildFeature( STRUCT_FEATURE_INIPAD, "'2'" ) inicializacao do campo NIL , ; // [12] // [13] // [14] L L L Indica se trata de um campo chave Indica se o campo pode receber Indica se o cam po virtual NIL , ; valor em uma operao de update. .T. ) Sua sintaxe para a interface (View) : AddField( cIdField, cOrdem, cTitulo, cDescr ic, aHelp, cType, cPicture, bPictVar, cLookUp, lCanChange, cFolder, cGroup, aCom boValues, nMaxLenCombo, cIniBrow, lVirtual, cPictVar, lInsertLine ) Onde: cIdFie ld cOrdem cTitulo cDescric aHelp cType cPicture bPictVar cLookUp lCanChange Nome do Campo; Ordem; Ttulo do campo; Descrio completa do campo; Array com Help; Tipo d o campo; Picture; Bloco de PictureVar; Consulta F3; Indica se o campo editvel; 60 - AdvPl utilizando MVC
cFolder cGroup aComboValues nMaxLenCombo cIniBrow lVirtual cPictVar Pasta do campo; Agrupamento do campo; Lista de valores permitido do campo (combo ); Tamanho mximo da maior opo do combo; Inicializador de Browse; Indica se o campo virtual; Picture Varivel; Abaixo exemplificamos os seu uso:: Local oStruZA0 := FWFormStruct( 2, 'ZA0' ) oStruZA0:AddField( ; 'ZA0_XEXEM1' '50' AllTrim( 'Exemplo 1' ) , ; , ; , ; , ; // Ord. Tipo Desc. // [01] // [02] // [03] // [04] // [05] 8] // [09] // [10] // [11] // [12] // [13] C C C C A C C B po Ordem Titulo do campo Descrio do campo Array com Help co de Picture Var Consulta F3 Indica se o campo evitvel o do campo Lista de valores permitido do campo AllTrim( 'Campo Exemplo 1' ) { 'Exemplo de Campo de Manual 1' } , ; 'C' '@!' NIL '' .T. NIL NIL {'1=Sim','2=No '} (Combo) NIL combo NIL .T. NIL , ; , ; ) , ; , ; , ; , ; , ; , ; , ; , ; , ; // [14] C L C N Tamanho Maximo da maior opo do // [15] // [16] // [17] Inicializador de Browse Indica se o campo virtual Picture Varivel Obs.: Os campos do tipo lgico sero exibidos como um checkbox na interface (View) 10.5 Formatao de bloco de cdigo para a estrutura (FWBuildFeature) Algumas propriedades dos campos da estrutura pedem uma construo especfica de bloco de cdigo. Ao se atribuir ou manipular essas propriedades elas devem ser informada s no padro que o MVC espera. Ao se tratar essas propriedade para FWBuildFeature p ara constru-la. o uso em aplicaes deve-se usar a funo AdvPl utilizando MVC 61 // [06] // [07] // [0 C L C C A Nome do Cam Tipo do campo Picture Blo Pasta do campo Agrupament
Exemplo: FwBuildFeature( STRUCT_FEATURE_VALID,"Pertence('12')" ) Onde o 1 parmetro indica qual a propriedade a ser construda e o 2 o contedo a ser atr ibudo. O 2 parmetro deve sempre ser ou retornar um dado do tipo caracter. As propri edades que precisam ser tratadas com esta funo so: STRUCT_FEATURE_VALID STRUCT_FEAT URE_WHEN STRUCT_FEATURE_INIPAD STRUCT_FEATURE_PICTVAR Para a validao Para o modo d e edio Para o inicializador padro Para PictureVar Os nomes de propriedades citados acima so na verdade #DEFINE. Para utilizar este #DEFINE preciso incluir a seguinte diretiva no fonte: #INCLUDE 'FWMVCDEF.CH'
Obs.: Utlize sempre esta a funo FWBuildFeature para a construo das propriedades do c ontrrio podero ocorrer erros na aplicao, tal como a no atualizao das variveis de me ara os componentes de formulrio. 10.6 Campos do tipo MEMO virtuais (FWMemoVirtual) Alguns campos do tipo MEMO utilizam-se de tabelas para a gravao de seus valores (S YP 3), esses campos devem ser informados na estrutura para que o MVC consiga faz er seu tratamento corretamente. Usamos para isso a funo FWMemoVirtual. Exemplo: FWMemoVirtual( oStruZA1,{ { 'ZA0_CDSYP1' , 'ZA0_MMSYP1' } , { 'ZA0_CDSYP2' , 'ZA 0_MMSYP2' }}) Para estes campos MEMO sempre deve haver outro campo que conter o cdigo com qu e o campo MEMO foi armazenado na tabela auxiliar No exemplo, oStruZA1 a estrutur a que contm os campos MEMO e o segundo parmetro um vetor bi-dimensional onde cada par relaciona o campo da estrutura que contm o cdigo do campo MEMO com o campo MEM O propriamente dito. 3 SYP Tabela do Microsiga Protheus que armazena os dados dos campos do tipo MEMO v irtuais 62 - AdvPl utilizando MVC
Se a tabela auxiliar a ser utilizada no for a SYP, um 3 parmetro dever ser passado no vetor bi-dimensional, como o alias da tabela auxiliar. FWMemoVirtual( oStruZA1, { { 'ZA0_CDSYP1' , 'ZA0_MMSYP1', 'ZZ1' } , { 'ZA0_CDSYP 2' , 'ZA0_MMSYP2' , 'ZZ1'} } ) Observao: Tanto o campo MEMO quanto o campo que armazenar seu cdigo devem fazer part e da estrutura. 10.7 Criao manual de gatilho (AddTrigger / FwStruTrigger) Se quisermos adicionar um gatilho a uma estrutura j existente, utilizamos o mtodo AddTrigger Sua sintaxe : AddTrigger( cIdField, cTargetIdField, bPre, bSetValue )
Onde: cIdField cTargetIdField bPre bSetValue Nome (ID) do campo de origem; Nome (ID) do campo de destino; Bloco de cdigo de validao da execuo do gatilho; Bloco de cd go de execuo do gatilho; Os blocos de cdigo deste mtodo pendem uma construo especfica. Ao se atribuir ou manip ular essas propriedades devem ser informadas no padro que o MVC espera. Para faci litar a construo do gatilho foi criada a funo FwStruTrigger, ela retorna um array co m 4 elementos j formatados para uso no AddTrigger. Sua sintaxe : FwStruTrigger Ond e: cDom cCDom cRegra lSeek cAlias nOrdem cChave Campo Domnio; Campo de Contradomni o; Regra de Preenchimento; Se posicionara ou no antes da execuo do gatilhos; Alias da tabela a ser posicionada; Ordem da tabela a ser posicionada; Chave de busca d a tabela a ser posicionada; ( cDom, cCDom, cRegra, lSeek, cAlias, nOrdem, cChave , cCondic ) AdvPl utilizando MVC 63
cCondic Exemplificando: Local oStruZA2 Local aAux Condio para execuo do gatilho ; := FWFormStruct( 2, 'ZA2' ) := {} aAux := FwStruTrigger(; 'ZA2_AUTOR' 'ZA2_NOME' ,; ,; 'ZA0->ZA0_NOME'..,; .T...............,; 'ZA0'........ 1............ ,; ,; 'xFilial("ZA0")+M->ZA2_AUTOR')
oStruct:AddTrigger( ; aAux[1] aAux[2] aAux[3] aAux[4] , ; , ; , ; ) // [01] iden tificador (ID) do campo de origem // [02] identificador (ID) do campo de destino // [03] Bloco de cdigo de validao da execuo do gatilho // [04] Bloco de cdigo de exe uo do gatilho 10.8 Retirando as pastas de uma estrutura (SetNoFolder) Se quisermos retirar as pastas que esto configuradas em uma estrutura, por exempl o, pelo uso da funo FWFormStruct, usamos o mtodo SetNoFolder. Da seguinte forma: Local oStruZA0 := FWFormStruct( 2, 'ZA0' ) // Retira as pastas da estrutura oStruZA0:SetNoFolder() 10. 9 Retirando os agrupamentos de campos de uma estrutura (SetNoGroups) Se quisermos retirar os agrupamentos de campos que esto configuradas em uma estru tura, por exemplo, quando usamos a funo FWFormStruct, usamos o mtodo SetNoGroups. D a seguinte forma: Local oStruZA0 := FWFormStruct( 2, 'ZA0' ) // Retira os agrupamentos de campos d a estrutura oStruZA0:SetNoGroups() 11.Criao de campos de total ou contadores (AddCalc) 64 - AdvPl utilizando MVC
Em MVC possvel criar automaticamente um novo componente composto de campos totali zadores ou contadores, um componente de clculos. Os campos do componente de clculo s so baseados em componentes de grid do modelo. Atualizando o componente de grid automaticamente os campos do componente de clculos sero atualizados. O Addcalc o c omponente de modelo de dados (Model) responsvel por isso Sua sintaxe : AddCalc Ond e: cId cOwner Identificador do componente de clculos; Identificador do componente superior (owner). No necessariamente o componente de grid de onde viro os dados. Normalmente o superior AddField principal do modelo de dados (Model); Cdigo do co mponente de grid que contm o campo, a que se refere o campo calculado; Nome do ca mpo do componente de grid a que se refere o campo calculado; Identificador (nome ) para o campo calculado; (cId, cOwner, cIdForm, cIdField, cIdCalc, cOperation, bCond, bInitValue, cTitle, bFormula, nTamanho, nDecimal) cIdForm cIdField cIdCalc cOperation Identificador da operao a ser realizada. As operaes podem ser: SUM COUNT AVG FORMULA bCond Faz a soma do campo do componente de grid; Faz a contagem do c ampo do componente de grid; Faz a mdia do campo do componente de grid; Executa um a frmula para o campo do componente de grid; Condio para avaliao do campo calculado. Recebe como parmetro o objeto do modelo. Reto rnando .T. (verdadeiro) executa a operao do campo calculado; Exemplo: { oModel te ste (oModel)}; bInitValue Bloco de cdigo para o valor inicial para o campo calculado. Recebe como parmetro o objeto do modelo; Exemplo: { oModel teste (oModel)}; cTitle bFormula Ttulo para o campo calculado; Frmula a ser utilizada quando o parmetro cOperation d o tipo FORMULA. AdvPl utilizando MVC 65
Recebe como parmetros: o objeto do modelo, o valor da atual do campo frmula, o con tedo do campo do componente de grid, campo lgico indicando se uma execuo de soma (.T . (verdadeiro)) ou subtrao (.F. (falso)); O valor retornado ser atribudo ao campo ca lculado; Exemplo: { oModel, nTotalAtual, xValor, lSomando Calculo( oModel, nTo talAtual, xValor, lSomando ) }; nTamanho SUM Tamanho do campo calculado (Se no fo r informado usa o tamanho padro). Os tamanhos padres para as operaes so: Ser o tamanh do campo do componente de grid + 3; Se o campo do componente de grid tiver o ta manho de 9, o campo calculado ter 12. COUNT AVG FORMULA nDecimal Ser o tamanho ser fixo em 6; Ser o tamanho do campo do componente de grid. Se o campo do componente de grid tiver o tamanho de 9, o campo calculado ter 9; Ser o tamanho do campo do componente de grid + 3. Se o campo do componente de grid tiver o tamanho de 9, o campo calculado ter 12; Nmero de casas decimais do campo calculado; Observao: Para as operaes de SUM e AVG o campo do componente de grid tem de ser do t ipo numrico. Exemplo: Static Function ModelDef() ... oModel:AddCalc( 'COMP022CALC1', 'ZA1MASTER', 'ZA2 DETAIL', 'ZA2_AUTOR', 'COUNT', { oFW COMP022CAL( oFW, .T. ) },,'Total Pares' ) oModel:AddCalc( 'COMP022CALC1', 'ZA1MASTER', 'ZA2DETAIL', 'ZA2_AUTOR', 'COUNT ', { oFW COMP022CAL( oFW, .F. ) },,'Total Impares' ) ... 'ZA2__TOT01', 'ZA2__TOT02', Onde: COMP022CALC1 ZA1MASTER ZA2DETAIL ZA2_AUTOR ZA2__TOT01 o identificador do c omponente de clculos; o identificador do componente superior (owner); o cdigo do c omponente de grid de onde viro os dados; o nome do campo do componente de grid a que se refere o campo calculado; o Identificador (nome) para o campo calculado; 66 - AdvPl utilizando MVC
COUNT o Identificador da operao a ser realizada; { oFW COMP022CAL( oFW, .T. ) } a condio para avaliao do campo calculado; 'Total Pares' o ttulo para o campo calculado; Na ViewDef tambm temos que fazer a definio do componente de clculo. Os dados usados em um componente de clculo so baseados em um componente de grid, porm, a sua exibio s e d da mesma forma que um componente de formulrio, por utilizarmos para o componen te de clculo o AddField e para obtermos a estrutura que foi criada na ModelDef us amos FWCalcStruct. Exemplo: Static Funcion View ... // Cria o objeto de Estrutura oCalc1 := FWCalcStruct( oM odel:GetModel( 'COMP022CALC1') ) //Adiciona no nosso View um controle do tipo Fo rmGrid(antiga newgetdados) oView:AddField( 'VIEW_CALC', oCalc1, 'COMP022CALC1' ) ... AdvPl utilizando MVC 67
12.Outras funes para MVC Algumas funes podem ser especialmente teis durante o desenvolvimento de uma aplicao.
12.1 Execuo direta da interface (FWExecView) Faz a execuo da interface (View) com uma determinada operao. Esta funo instancia a in erface (View) e conseqentemente o modelo de dados (Model) com as operaes de visuali zar, incluir, alterar ou excluir. A inteno dela fazer similarmente o que faziam as funes AXVISUAL, AXINCLI, AXALTERA e AXDELETA. Sua sintaxe : FWExecView (cTitulo, c Programa, nOperation, oDlg, bCloseOnOk, bOk, nPercReducao, aEnableButtons, bCanc el ) Onde: cTitulo cPrograma nOperation oDlg bCloseOnOK bOk Ttulo da janela; Nome do programa-fonte; Indica o cdigo de operao (incluso, alterao ou excluso); Objeto d anela em que o View deve ser colocado. Se no informado, uma nova janela ser criada ; Indica se a janela deve ser fechada ao final da operao. Se ele retornar .T. (ver dadeiro) fecha a janela; Bloco executado no acionamento do boto confirmar que ret ornando .F. (falso) impedir o fechamento da janela; nPercReducao Se informado reduz a janela em percentualmente; aEnableButtons Indi ca os botes da barra de botes que estaro habilitados; bCancel Bloco executado no ac ionamento do boto cancelar que retornando .F. (falso) impedir o fechamento da jane la;
O retorno desta funo ser: 0 1 Se o usurio finalizar a operao com o boto confirmar; S usurio finalizar a operao com o boto cancelar; 68 - AdvPl utilizando MVC
Exemplo: lOk := ( FWExecView('Incluso por FWExecView','COMP011_MVC', MODEL_OPERATION_INSER T,, { .T. } ) == 0 ) If lOk Help( ,, 'Help',, 'Foi confirmada a operao, 1, 0 ) Else Help( ,, 'Help',, ' Foi cancelada a operao, 1, 0 ) EndIf 12.2 Modelo de dados ativo (FWModelActive) Em uma aplicao podemos trabalhar com mais de um modelo de dados (Model). A funo FWMo delActive retorna o modelo de dados (Model) que est ativo no momento. Exemplo: Static Function COMP021BUT() Local oModel := FWModelActive() Local nOperation := oModel:GetOperation() Para definir qual o modelo de dados (Model) ativo: Local oModelBkp ... FWModelActive( oModelBkp ) := FWModelActive() 12.3 Interface ativa (FWViewActive) Em uma aplicao podemos trabalhar com mais de uma interface (View). A funo FWViewActi ve retorna a interface (View) que est ativa no momento. Exemplo: Static Function COMP021BUT() Local oView oView:Refresh() := FWViewActive() Para definir qual a interface (View): Local oViewBkp ... FWViewActive(oViewBkp) := FWViewActive() 12.4 Carregar o modelo de dados de uma aplicao j existente (FWLoadModel) AdvPl utilizando MVC 69
Para criarmos um objeto com o modelo de dados de uma aplicao, utilizamos o funo FWLo adModel. Sua sintaxe : FWLoadModel( <nome do fonte> ) Exemplo: Static Function ModelDef() // Utilizando um model que ja existe em outra aplicac ao Return FWLoadModel( 'COMP011_MVC' ) 12.5 Carregar a interface de uma aplicao j existente (FWLoadView) Para criarmos um objeto com o modelo de dados de uma aplicao, utilizamos o funo FWLo adView. Sua sintaxe : FWLoadView ( <nome do fonte> ) Exemplo: Static Function ViewDef() // Utilizando uma view que ja existe em outra aplicaca o Return FWLoadView( 'COMP011_MVC' )
12.6 Carregar a menu de uma aplicao j existente (FWLoadMenudef) Para criarmos um vetor com as opes de menu de uma aplicao, utilizamos a funo FWLoadMe udef. Sua sintaxe : FWLoadMenudef ( <nome do fonte> ) Exemplo: Static Function MenuDef() // Utilizando um menu que ja existe em outra aplicacao Return FWLoadMenuDef( 'COMP011_MVC' ) 12.7 Obteno de menu padro (FWMVCMenu) Podemos criar um menu com opes padro para o MVC utilizando a funo FWMVCMENU. Sua sint axe : FWMVCMENU ( <nome do fonte> ) 70 - AdvPl utilizando MVC
Exemplo: //---------------------------------------Static Function MenuDef() Return FWMVCM enu( 'COMP011_MVC' )) Ser criado um menu padro com as opes: Visualizar, Incluir, Alterar, Excluir, Imprimi r e Copiar. 13.Browse com coluna de marcao (FWMarkBrowse) Se quisermos construir uma aplicao com um Browse que utilize uma coluna para marcao, similarmente a funo MarkBrowse no AdvPL tradicional, utilizaremos a classe FWMark Browse. Assim como a FWmBrowse (ver cap. 0 3.Aplicaes com Browses (FWMBrowse), a F WMarkBrowse no exclusivamente do MVC pode ser utilizada tambm por aplicaes que no o tilizam. Neste contedo no nos aprofundaremos nos recursos da FWMarkBrowse, falarem os aqui de suas principais funes e caractersticas para uso em aplicaes com MVC. Como premissa, preciso que haja um campo na tabela do tipo caracter com o tamanho de 2 e que receber fisicamente a marca. Ser gerada uma marca diferente cada vez que a FWMarkBrowse for executada. Iniciaremos a construo bsica de um FWMarkBrowse. Prime iramente deve-se criar um objeto Browse da seguinte forma: oMark := FWMarkBrowse():New() Definimos a tabela que ser exibida na Browse pelo mtodo SetAlias. As colunas, orde ns, etc. para a exibio sero obtidos atravs do metadados (dicionrios) oMark:SetAlias('ZA0') Definimos o ttulo que ser exibido como mtodo SetDescription. oMark:SetDescription('Seleo do Cadastro de Autor/Interprete') Definimos qual ser o campo da tabela que receber a marca fsica. oMark:SetFieldMark( 'ZA0_OK' ) E ao final ativamos a classe oMark:Activate() Com esta estrutura bsica construmos uma aplicao com Browse. Mas por enquanto temos a penas o Browse com coluna de marcao, precisamos definir uma AdvPl utilizando MVC 71
ao para os itens marcados. Para isso, podemos colocar no MenuDef da aplicao a funo qu tratar os marcados. ADD OPTION aRotina TITLE 'Processar' ACTION 'U_COMP25PROC()' OPERATION 2 ACCESS 0 Na funo que tratar os marcados ser preciso identificar se um registro esta ou no marc ado. Para sabermos a marca que esta sendo utilizado no momento usamos o mtodo Mar k. Local cMarca := oMark:Mark() E para saber se o registro est marcado usamos o mtodo IsMark passando como parmetro a marca. If oMark:IsMark(cMarca)
possvel tambm colocar outras opes como visualizar ou alterar no menu de opes (MenuD , mas ser preciso criar tambm o modelo de dados (Model) e a interface (View). Toda s as outras caractersticas da FWMBrowse tambm se aplicam a FWMarkBrowse como legen das, filtros, detalhes, etc. Um recurso que a FWMarkBrowse tem o controle de mar cao exclusiva do registro pelo usurio. Onde se 2 usurios abrirem o mesmo FWMarkBrows e e tentarem marcar o mesmo registro o prprio FWMarkBrowse permitir que apenas um deles execute a marcao. Para habilitar esta caracterstica usamos o mtodo SetSemaphor e. Abaixo, segue um exemplo da utilizao do FWMarkBrowse User Function COMP025_MVC() Private oMark // Instanciamento do classe oMark := FWMarkBrowse():New() // Definio da tabela a ser utilizada oMark:SetAlias('ZA0') // Define se utiliza controle de marcao exclusiva do oMark:SetSemaphore(.T.) // Define a titulo do browse de marcacao oMark:SetDescription('Seleo do Cadastro d e Autor/Interprete') // Define o campo que sera utilizado para a marcao oMark:SetFieldMark( 'ZA0_OK' ) // Define a legenda 72 - AdvPl utilizando MVC
oMark:AddLegend( "ZA0_TIPO=='1'", "YELLOW", "Autor" oMark:AddLegend( "ZA0_TIPO== '2'", "BLUE" , "Interprete" ) ) // Definio do filtro de aplicacao oMark:SetFilterDefault( "ZA0_TIPO=='1'" ) // Ativacao da classe oMark:Activate() Return NIL //------------------------------------------------------------------Static Funct ion MenuDef() Local aRotina := {} ADD OPTION aRotina TITLE 'Visualizar' ACTION 'VIEWDEF.COMP025_MVC' OPERATION 2 A CCESS 0 ADD OPTION aRotina TITLE 'Processar' ACTION 'U_COMP25PROC()' OPERATION 2 ACCESS 0 Return aRotina //------------------------------------------------------------------Static Funct ion ModelDef() // Utilizando um model que ja existe em outra aplicacao Return FW LoadModel( 'COMP011_MVC' ) //------------------------------------------------------------------Static Funct ion ViewDef() // Utilizando uma View que ja existe em outra aplicacao Return FWL oadView( 'COMP011_MVC' ) //------------------------------------------------------------------User Functio n COMP25PROC() Local aArea Local cMarca Local nCt := GetArea() := oMark:Mark() : = 0 ZA0->( dbGoTop() ) While !ZA0->( EOF() ) If oMark:IsMark(cMarca) nCt++ EndIf AdvPl utilizando MVC 73
ZA0->( dbSkip() ) End ApMsgInfo( 'Foram marcados ' + AllTrim( Str( nCt ) ) + ' registros.' ) RestArea( aArea ) Return NIL Visualmente teremos: 74 - AdvPl utilizando MVC
14.Mltiplos Browses Com a utilizao da classe FWmBrowse podemos escrever aplicaes com mais de um objeto d esta classe, ou seja, podemos escrever aplicaes que trabalharo com mltiplas Browses. Podemos por exemplo desenvolver uma aplicao para os pedidos de venda, onde teremo s uma Browse com os cabealhos dos itens e outra com os itens na mesma tela e conf orme formos navegando pelos registros da Browse de cabealho, automaticamente o it ens so atualizados na outra Browse. Para isso, basta criarmos na nossa aplicao 2 ob jetos da FWMBrowse e relacion-los entre si. Abaixo descreveremos como fazer isso. Criaremos uma aplicao com 3 Browses. Primeiro criamos uma tela Dialog comum, cada um dos Browses deve estar ancorado em um objeto container, para isso usaremos o FWLayer com 2 linhas e em uma dessas linhas colocaremos 2 colunas. Para mais de talhes do FWLayer consulte a documentao especfica no TDN4. User Function COMP024_MVC() Local aCoors := FWGetDialogSize( oMainWnd ) Local oP anelUp, oFWLayer, oPanelLeft, oPanelRight, oBrowseUp, oBrowseLeft, oBrowseRight, oRelacZA4, oRelacZA5 Define MsDialog oDlgPrinc Title 'Multiplos FWmBrowse' From aCoors[1], aCoors[2] To aCoors[3], aCoors[4] Pixel // // Cria o conteiner onde sero colocados os browses // oFWLayer := FWLayer():Ne w() oFWLayer:Init( oDlgPrinc, .F., .T. ) // // Define Painel Superior // oFWLayer:AddLine( 'UP', 50, .F. ) oFWLayer:AddCo llumn( 'ALL', 100, .T., 'UP' ) coluna com 100% da tamanho dela oPanelUp := oFWLa yer:GetColPanel( 'ALL', 'UP' ) container // Cria uma "linha" com 50% da tela // Na "linha" criada eu crio uma // Pego o objeto desse pedao do 4 TDN TOTVS Developer Network portal voltado a desenvolvedores do Microsiga Prothe us AdvPl utilizando MVC 75
// // Painel Inferior // oFWLayer:AddLine( 'DOWN', 50, .F. ) oFWLayer:AddCollumn ( 'LEFT' , 50, .T., 'DOWN' ) coluna com 50% da tamanho dela oFWLayer:AddCollumn( 'RIGHT', 50, .T., 'DOWN' ) coluna com 50% da tamanho dela oPanelLeft := oFWLaye r:GetColPanel( 'LEFT' , 'DOWN' ) // Cria uma "linha" com 50% da tela // Na "linh a" criada eu crio uma // Na "linha" criada eu crio uma // Pego o objeto do pedao esquerdo // Pego o objeto do pedao direito oPanelRight := oFWLayer:GetColPanel( 'RIGHT', 'DOWN' ) Feito isso criamos as 3 Browses conforme o descrito no captulo 0 3.Aplicaes com Bro wses (FWMBrowse). Este o 1 Browse. // // FWmBrowse Superior Albuns // oBrowseUp:= FWmBrowse():New() oBrowseUp:SetOw ner( oPanelUp ) // Aqui se associa o browse ao //componente de tela oBrowseUp:Se tDescription( "Albuns" ) oBrowseUp:SetAlias( 'ZA3' ) oBrowseUp:SetMenuDef( 'COMP 024_MVC' ) // Define de onde virao os // botoes deste browse oBrowseUp:SetProfil eID( '1' ) oBrowseUp:ForceQuitButton() // identificador (ID) para o Browse // Fo ra exibio do boto // Sair oBrowseUp:Activate()
Note 2 mtodos definidos neste Browse: SetProfileID e ForceQuitButton O mtodo SetPr ofileID define um identificador (ID) para o Browse, isso necessrio j que teremos m ais de um Browse na aplicao. O mtodo ForceQuitButton faz com que o boto Sair seja ex ibido nas opes deste Browse. Como haver mais de um Browse o boto Sair no ser colocado automaticamente em nenhum deles, este mtodo faz com que ele aparea no Browse. Note tambm que utilizamos o mtodo SetMenuDef para definir de qual fonte dever ser utili zado para a obter o MenuDef. Quando no utilizamos o SetMenuDef automaticamente o Browse busca no prprio fonte onde ele se encontra o Menudef a ser usado. 76 - AdvPl utilizando MVC
Estes so o 2 e 3 Browses: oBrowseLeft:= FWMBrowse():New() oBrowseLeft:SetOwner( oPanelLeft ) oBrowseLeft:S etDescription( 'Musicas' ) oBrowseLeft:SetMenuDef( '' ) // Referencia vazia para que nao // exiba nenhum boto oBrowseLeft:DisableDetails() oBrowseLeft:SetAlias( 'ZA4' ) oBrowseLeft:SetProfileID( '2' ) oBrowseLeft:Activate() oBrowseRight:= FWMBrowse():New() oBrowseRight:SetOwner( oPanelRight ) oBrowseRig ht:SetDescription( 'Autores/Interpretes' ) oBrowseRight:SetMenuDef( '' ) // Refe rencia vazia para que nao funcao // exiba nenhum botao oBrowseRight:DisableDetai ls() oBrowseRight:SetAlias( 'ZA5' ) oBrowseRight:SetProfileID( '3' ) oBrowseRigh t:Activate() Note que nestes Browses utilizamos o mtodo SetMenuDef com uma referncia vazia, com o queremos que apenas o Browse principal tenha botes de ao, se no definimos o SetMen uDef, automaticamente, o Browse busca no prprio fonte onde ele se encontra e com a referncia vazia no so exibidos botes. Agora que definimos os Browses precisamos fa zer o relacionamento entre eles, para que ao efetuar o movimento em um, automati camente os outros sejam atualizados. Para criar o relacionamento utilizaremos a classe FWBrwRelation. Similarmente ao que relacionamento entre entidades feito n o modelo de dados (Model) preciso dizer quais as chaves de relacionamento do fil ho para o pai. Instanciaremos o FWBrwRelation e usaremos seu mtodo AddRelation. A sintaxe deste mtodo do FWBrwRelation : AddRelation( <oBrowsePai>, <oBrowseFilho>, <Vetor com os campos de relacionamento> ) Como temos 3 Browses teremos 2 relaci onamentos: oRelacZA4:= FWBrwRelation():New() oRelacZA4:AddRelation( oBrowseUp 'ZA4_ALBUM' , 'ZA3_ALBUM' } } ) oRelacZA4:Activate() , oBrowseLeft , { { 'ZA4_FILIAL', 'xFili al( "ZA4" )' }, { AdvPl utilizando MVC 77
oRelacZA5:= FWBrwRelation():New() oRelacZA5:AddRelation( oBrowseLeft, oBrowseRig ht, { { 'ZA5_FILIAL', 'xFilial( "ZA5" )' }, { 'ZA5_ALBUM' , 'ZA4_ALBUM' }, { 'ZA 5_MUSICA', 'ZA4_MUSICA' } } ) oRelacZA5:Activate() Segue um exemplo completo da aplicao com mltiplas Browses: User Function COMP024_MVC() Local aCoors := FWGetDialogSize( oMainWnd ) Local oPanelUp, oFWLayer, oPanelLeft, oPanelRight, oBrowseUp, oBrowseLeft, oBrow seRight, oRelacZA4, oRelacZA5 Private oDlgPrinc Define MsDialog oDlgPrinc Title 'Multiplos FWmBrowse' From aCoors[1], aCoors[2] To aCoors[3], aCoors[4] Pixel // // Cria o conteiner onde sero colocados os browses // oFWLayer := FWLayer():New() oFWLayer:Init( oDlgPrinc, .F., .T. ) // // Define Painel Superior // oFWLayer:AddLine( 'UP', 50, .F. ) // Cria uma "l inha" com 50% da tela oFWLayer:AddCollumn( 'ALL', 100, .T., 'UP' ) // Na "linha" criada eu crio uma coluna com 100% da tamanho dela oPanelUp := oFWLayer:GetColP anel( 'ALL', 'UP' ) // Pego o objeto desse pedao do container // // Painel Inferior // oFWLayer:AddLine( 'DOWN', 50, .F. ) // Cria uma "linha" com 50% da tela oFWLayer:AddCollumn( 'LEFT' , 50, .T., 'DOWN' ) // Na "linha" criada eu crio uma coluna com 50% da tamanho dela oFWLayer:AddColl umn( 'RIGHT', 50, .T., 'DOWN' ) // Na "linha" criada eu crio uma coluna com 50% da tamanho dela 78 - AdvPl utilizando MVC
oPanelLeft := oFWLayer:GetColPanel( 'LEFT' , 'DOWN' ) // Pego o objeto do pedao esquerdo // Pego o objeto do pedao direito oPanelRight := oFWLayer:GetColPanel( 'RIGHT', 'DOWN' ) // // FWmBrowse Superior Albuns // oBrowseUp:= FWmBrowse():New() oBrowseUp:SetOw ner( oPanelUp ) // Aqui se associa o browse ao componente de tela oBrowseUp:SetD escription( "Albuns" ) oBrowseUp:SetAlias( 'ZA3' ) oBrowseUp:SetMenuDef( 'COMP02 4_MVC' ) // Define de onde virao os botoes deste browse oBrowseUp:SetProfileID( '1' ) oBrowseUp:ForceQuitButton() oBrowseUp:Activate() // // Lado Esquerdo Musicas // oBrowseLeft:= FWMBrowse():New() oBrowseLeft:SetOw ner( oPanelLeft ) oBrowseLeft:SetDescription( 'Musicas' ) oBrowseLeft:SetMenuDef ( '' ) // Referencia vazia para que nao exiba nenhum botao oBrowseLeft:DisableDe tails() oBrowseLeft:SetAlias( 'ZA4' ) oBrowseLeft:SetProfileID( '2' ) oBrowseLef t:Activate() // // Lado Direito Autores/Interpretes // oBrowseRight:= FWMBrowse():New() oBrow seRight:SetOwner( oPanelRight ) oBrowseRight:SetDescription( 'Autores/Interprete s' ) oBrowseRight:SetMenuDef( '' ) // Referencia vazia para que nao exiba nenhum botao oBrowseRight:DisableDetails() oBrowseRight:SetAlias( 'ZA5' ) AdvPl utilizando MVC 79
oBrowseRight:SetProfileID( '3' ) oBrowseRight:Activate() // // Relacionamento entre os Paineis / oRelacZA4:= FWBrwRelation():New() oRelac ZA4:AddRelation( oBrowseUp 'ZA4_ALBUM' , 'ZA3_ALBUM' } } ) oRelacZA4:Activate() , oBrowseLeft , { { 'ZA4_FILIAL', 'xFilial( "ZA4" )' }, { oRelacZA5:= FWBrwRelation():New() oRelacZA5:AddRelation( oBrowseLeft, oBrowseRig ht, { { 'ZA5_FILIAL', 'xFilial( "ZA5" )' }, { 'ZA5_ALBUM' , 'ZA4_ALBUM' }, { 'ZA 5_MUSICA', 'ZA4_MUSICA' } } ) oRelacZA5:Activate() Activate MsDialog oDlgPrinc Center Return NIL //------------------------------------------------------------------Static Funct ion MenuDef() Return FWLoadMenuDef( 'COMP023_MVC' ) //------------------------------------------------------------------Static Funct ion ModelDef() // Utilizamos um model que ja existe Return FWLoadModel( 'COMP023 _MVC' ) //------------------------------------------------------------------Static Funct ion ViewDef() // Utilizamos uma View que ja existe Return FWLoadView( 'COMP023_M VC' ) 80 - AdvPl utilizando MVC
15.Rotina automtica Quando uma aplicao desenvolvida utilizando-se o conceito de MVC e suas classes, po de-se fazer uso de seu modelo de dados em outras aplicaes, similarmente ao que ser ia uma rotina automtica no desenvolvimento tradicional. No existe mais o uso da fu no MSExecAuto. A idia bsica instanciar o modelo de dados (Model) que se deseja, atri buir os valores a ele e fazer a validao. Para melhor entendimento, usaremos de exe mplo o fonte abaixo, onde se faz em MVC o que seria uma rotina automtica para imp ortao de um cadastro simples. Observe os comentrios. //------------------------------------------------------------------// Rotina pr incipal de Importao //-----------------------------------------------------------------User Function COMP031_MVC() Local Local Local Local Local Local Local Loca l aSay aButton nOpc Titulo cDesc1 cDesc2 cDesc3 lOk := {} := {} := 0 := 'IMPORTA CAO DE COMPOSITORES' := 'Esta rotina far a importao de compositores/interpretes' := 'conforme layout.' := '' := .T. aAdd( aSay, cDesc1 ) aAdd( aSay, cDesc2 ) aAdd( aSay, cDesc3 ) aAdd( aButton, { 1, .T., { nOpc := 1, FechaBatch() } } ) aAdd( aButton, { 2, .T., { FechaBatch() FormBatch( Titulo, aSay, aButton ) } } ) If nOpc == 1 Processa( { lOk := Runproc() },'Aguarde','Processando...',.F.)
If lOk ApMsgInfo( 'Processamento terminado com sucesso.', 'ATENO' ) Else ApMsgStop ( 'Processamento realizado com problemas.', 'ATENO' ) EndIf 82 - AdvPl utilizando MVC
EndIf Return NIL //------------------------------------------------------------------/ / Rotina Auxiliar de Importao //-----------------------------------------------------------------Static Function Runproc() Local lRet := .T. Local aCampos := {} // Criamos um vetor com os dados para facilitar o manuseio dos dados aCampos := {} aAdd( aCampos, { 'ZA0_CODIGO', '000100' aAdd( aCampos, { 'ZA0_NOME' , 'Vila L obos' } ) } ) aAdd( aCampos, { 'ZA0_NOTAS' , 'Observaes...' } ) aAdd( aCampos, { 'ZA0_TIPO' , 'C ' } ) If !Import( 'ZA0', aCampos ) lRet := .F. EndIf // Importamos outro registro aCampos := {} aAdd( aCampos, { 'ZA0_CODIGO', '00010 2' aAdd( aCampos, { 'ZA0_NOME' } ) , 'Tom Jobim' } ) aAdd( aCampos, { 'ZA0_NOTAS' , 'Observaes...' } ) aAdd( aCampos, { 'ZA0_TIPO' , 'C ' } ) If !Import( 'ZA0', aCampos ) lRet := .F. EndIf // Importamos outro registro aCampos := {} aAdd( aCampos, { 'ZA0_CODIGO', '00010 4' } ) aAdd( aCampos, { 'ZA0_NOME' , 'Emilio Santiago' } ) aAdd( aCampos, { 'ZA0_NOTAS' , 'Observaes...' } ) aAdd( aCampos, { 'ZA0_TIPO' , 'I' } ) If !Import( 'ZA0', aCampos ) AdvPl utilizando MVC 83
lRet := .F. EndIf Return lRet //------------------------------------------------------------------// Importao do s dados //------------------------------------------------------------------Stat ic Function Import( cAlias, aCampos ) Local Local Local Local Local oModel, oAux , oStruct nI nPos lRet aAux := 0 := 0 := .T. := {} dbSelectArea( cAlias ) dbSetOrder( 1 ) // Aqui ocorre o instnciamento do modelo de dados (Model) // Neste exemplo instan ciamos o modelo de dados do fonte COMP011_MVC // que a rotina de manuteno de compo sitores/interpretes oModel := FWLoadModel( 'COMP011_MVC' )
// Temos que definir qual a operao deseja: 3 Incluso / 4 Alterao / 5 - Excluso oM SetOperation( 3 ) // Antes de atribuirmos os valores dos campos temos que ativar o modelo oModel:A ctivate() // Instanciamos apenas referentes s dados oAux := oModel:GetModel( cAlias + 'MAST ER' ) // Obtemos a estrutura de dados oStruct := oAux:GetStruct() aAux := oStruct:GetF ields() For nI := 1 To Len( aCampos ) // Verifica se os campos passados existem na estru tura do modelo If ( nPos := aScan(aAux,{ x AllTrim( x[3] )== AllTrim(aCampos[nI ][1]) } ) ) > 0 // feita a atribuio do dado ao campo do Model If !( lAux := oModel :SetValue( cAlias + 'MASTER', aCampos[nI][1], aCampos[nI][2] ) ) // Caso a atrib uio no possa ser feita, por algum motivo (validao, por 84 - AdvPl utilizando MVC
exemplo) // o mtodo SetValue retorna .F. lRet Exit EndIf EndIf Next nI := .F. If lRet // Faz-se a validao dos dados, note que diferentemente das tradicionais // "rotinas automticas" // neste momento os dados no so gravados, so somente validados . If ( lRet := oModel:VldData() ) // Se o dados foram validados faz-se a gravao ef etiva dos dados (commit) oModel:CommitData() EndIf EndIf If !lRet // Se os dados no foram validados obtemos a descrio do erro para gerar LOG ou mensagem de aviso a Erro := oModel:GetErrorMessage() // A estrutura do vetor com erro : // // // // // // // // // [1] identificador ( ID) do formulrio de origem [2] identificador (ID) do campo de origem [3] identifi cador (ID) do formulrio de erro [4] identificador (ID) do campo de erro [5] ident ificador (ID) do erro [6] mensagem do erro [7] mensagem da soluo [8] Valor atribudo [9] Valor anterior AutoGrLog( "Id do formulrio de origem:" + ' [' + AllToChar( aErro[1] AutoGrLog( " Id do campo de origem: AutoGrLog( "Id do formulrio de erro: AutoGrLog( "Id do cam po de erro: AutoGrLog( "Id do erro: AutoGrLog( "Mensagem do erro: AutoGrLog( "Me nsagem da soluo: AutoGrLog( "Valor atribudo: AutoGrLog( "Valor anterior: " + ' [' + AllToChar( aErro[2] " + ' [' + AllToChar( aErro[3] " + ' [' + AllToChar( aErro[ 4] " + ' [' + AllToChar( aErro[5] " + ' [' + AllToChar( aErro[6] " + ' [' + AllT oChar( aErro[7] " + ' [' + AllToChar( aErro[8] " + ' [' + AllToChar( aErro[9] ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) AdvPl utilizando MVC 85
MostraErro() EndIf // Desativamos o Model oModel:DeActivate() Return lRet Neste outro exemplo, temos a importao para um modelo de dados onde h uma estrutura de Master-Detail (Pai-Filho). Tambm o que faremos instanciar o modelo de dados (M odel) que desejamos, atribuir os valores ele e fazer a validao, s que faremos isso para as duas entidades. Observe os comentrios: //------------------------------------------------------------------// Rotina pr incipal de Importao //-----------------------------------------------------------------User Function COMP032_MVC() Local Local Local Local Local Local Local Loca l aSay aButton nOpc Titulo cDesc1 cDesc2 cDesc3 lOk := {} := {} := 0 := 'IMPORTA CAO DE MUSICAS' := 'Esta rotina far a importao de musicas' := 'conforme layout.' := '' := .T. aAdd( aSay, cDesc1 ) aAdd( aSay, cDesc2 ) aAdd( aSay, cDesc3 ) aAdd( aButton, { 1, .T., { nOpc := 1, FechaBatch() } } ) aAdd( aButton, { 2, .T., { FechaBatch() } } ) FormBatch( Titulo, aSay, aButton ) If nOpc == 1 Processa( { lOk := Runproc() },'Aguarde','Processando...',.F.) If lOk ApMsgInfo( 'Processamento terminado com sucesso.', 'ATENO' ) Else ApMsgStop( 'Processamento realizado com problemas.', 'A TENO' ) EndIf 86 - AdvPl utilizando MVC
EndIf Return NIL //------------------------------------------------------------------// Rotina au xiliar de Importao //-----------------------------------------------------------------Static Function Runproc() Local lRet := .T. Local aCposCab := {} Local aCposDet := {} Local aAux := {} // Criamos um vetor com os dados de cabealho e outro para itens para facilitar o manuseio dos dados aCposCab := {} aCposDet := {} aAdd( aCposCab, { 'ZA1_TITULO' , 'LA, LA, LA,' } ) aAdd( aCposCab, { 'ZA1_DATA', Date() } ) aAux := {} aAdd( aAux, { 'ZA2_ITEM' , '01' aAdd( aAux, { 'ZA2_AUTOR', '000100' a Add( aCposDet, aAux ) } ) } ) aAux := {} aAdd( aAux, { 'ZA2_ITEM' , '02' aAdd( aAux, { 'ZA2_AUTOR', '000104' a Add( aCposDet, aAux ) If !Import( 'ZA1', 'ZA2', aCposCab, aCposDet ) lRet := .F. EndIf } ) } ) // Importamos outro conjunto de dados aCposCab := {} aCposDet := {} aAdd( aCposC ab, { 'ZA1_TITULO' , 'BLA, BLA, BLA' } ) aAdd( aCposCab, { 'ZA1_DATA', Date() } ) aAux := {} aAdd( aAux, { 'ZA2_ITEM' , '01' } ) AdvPl utilizando MVC 87
aAdd( aAux, { 'ZA2_AUTOR', '000102' aAdd( aCposDet, aAux ) aAux := {} aAdd( aAux , { 'ZA2_ITEM' , '02' aAdd( aAux, { 'ZA2_AUTOR', '000104' aAdd( aCposDet, aAux ) } ) } ) } ) If !Import( 'ZA1', 'ZA2', aCposCab, aCposDet ) lRet := .F. EndIf // Importamos outro conjunto de dados aCposCab := {} aCposDet := {} aAdd( aCposC ab, { 'ZA1_TITULO' , 'ZAP, ZAP, ZAP' } ) aAdd( aCposCab, { 'ZA1_DATA', Date() } ) aAux := {} aAdd( aAux, { 'ZA2_ITEM' , '01' aAdd( aAux, { 'ZA2_AUTOR', '000100' a Add( aCposDet, aAux ) } ) } ) aAux := {} aAdd( aAux, { 'ZA2_ITEM' , '02' aAdd( aAux, { 'ZA2_AUTOR', '000102' a Add( aCposDet, aAux ) } ) } ) If !Import( 'ZA1', 'ZA2', aCposCab, aCposDet ) lRet := .F. EndIf Return lRet //------------------------------------------------------------------// Importaca o dos dados //-----------------------------------------------------------------Static Function Import( Local Local Local cMaster, cDetail, aCpoMaster, aCpoDeta il ) oModel, oAux, oStruct nI nJ := 0 := 0 88 - AdvPl utilizando MVC
Local Local Local Local Local Local Local nPos lRet aAux aC aH nItErro lAux := 0 := .T. := {} := {} := {} := 0 := .T. dbSelectArea( cDetail ) dbSetOrder( 1 ) dbSelectArea( cMaster ) dbSetOrder( 1 ) // Aqui ocorre o instnciamento do modelo de dados (Model) // Neste exemplo instan ciamos o modelo de dados do fonte COMP022_MVC // que a rotina de manuteno de music as oModel := FWLoadModel( 'COMP022_MVC' )
// Temos que definir qual a operao deseja: 3 Incluso / 4 Alterao / 5 - Excluso oM SetOperation( 3 ) // Antes de atribuirmos os valores dos campos temos que ativar o modelo oModel:A ctivate() // Instanciamos apenas a parte do modelo referente aos dados de cabealho oAux := oModel:GetModel( cMaster + 'MASTER' ) // Obtemos a estrutura de dados do cabealho oStruct := oAux:GetStruct() aAux := o Struct:GetFields() If lRet For nI := 1 To Len( aCpoMaster ) // Verifica se os campos passados exist em na estrutura do cabealho If ( nPos := aCpoMaster[nI][1] ) } ) ) > 0 aScan( aAu x, { x AllTrim( x[3] ) == AllTrim( // feita a atribuio do dado aos campo do Model do cabealho If !( lAux := oModel:Set Value( cMaster + 'MASTER', aCpoMaster[nI][1], AdvPl utilizando MVC 89
aCpoMaster[nI][2] ) ) // Caso (validao, por exemplo) a atribuio no possa ser feita, p or algum motivo // o mtodo SetValue retorna .F. lRet Exit EndIf EndIf Next EndIf If lRet // Insta nciamos apenas a parte do modelo referente aos dados do item oAux := oModel:GetM odel( cDetail + 'DETAIL' ) := .F. // Obtemos a estrutura de dados do item oStruct aAux nItErro := 0 := oAux:GetStr uct() := oStruct:GetFields() For nI := 1 To Len( aCpoDetail ) // Inclumos uma linha nova // ATENO: O itens so por tanto j criada uma primeira linha criados em uma estrutura de grid (FORMGRID), //branco automaticamente, desta forma comeamos a inserir novas linhas a partir da 2 vez If nI > 1 // Inclumos uma nova linha de item If ( nItErro := oAux:AddLine() ) <> nI // Se por algum motivo o mtodo AddLine() no consegue incluir a linha, // ele retor na a quantidade de linhas j // existem no grid. Se conseguir retorna a quantidade mais 1 lRet Exit EndIf EndIf := .F. For nJ := 1 To Len( aCpoDetail[nI] ) // Verifica se os campos passados existem n a estrutura de item If ( nPos := aScan( aAux, { x AllTrim( x[3] ) == aCpoDetai l[nI][nJ][1] ) } ) ) > 0 AllTrim( If !( lAux := oModel:SetValue( cDetail + 'DETAIL', aCpoDetail[nI][nJ][1], aCpoDe tail[nI][nJ][2] ) ) 90 - AdvPl utilizando MVC
// Caso a atribuio no possa ser feita, por algum motivo (validao, por exemplo) // o m odo SetValue retorna .F. lRet := .F. nItErro := nI Exit EndIf EndIf Next If !lRet Exit EndIf Next EndIf If lRet // Faz-se a validao dos dados, note que diferentemente das tradicionais "r otinas automticas" // neste momento os dados no so gravados, so somente validados. I f ( lRet := oModel:VldData() ) // Se o dados foram validados faz-se a gravao efeti va dos // dados (commit) oModel:CommitData() EndIf EndIf If !lRet // Se os dados no foram validados obtemos a descrio do erro para gerar // LOG ou mensagem de aviso aErro := oModel:GetErrorMessage() // A estrutura do vetor com erro : // [1] identificador (ID) do formulrio de orige m // [2] identificador (ID) do campo de origem // [3] identificador (ID) do form ulrio de erro // [4] identificador (ID) do campo de erro // [5] identificador (ID ) do erro // [6] mensagem do erro // [7] mensagem da soluo // [8] Valor atribudo // [9] Valor anterior AdvPl utilizando MVC 91
AutoGrLog( "Id do formulrio de origem:" + ' [' + AllToChar( aErro[1] AutoGrLog( " Id do campo de origem: AutoGrLog( "Id do formulrio de erro: AutoGrLog( "Id do cam po de erro: AutoGrLog( "Id do erro: AutoGrLog( "Mensagem do erro: AutoGrLog( "Me nsagem da soluo: AutoGrLog( "Valor atribudo: AutoGrLog( "Valor anterior: If nItErro > 0 AutoGrLog( "Erro no Item: ) ) + ']' ) " + ' [' + AllToChar( aErro[2] " + ' [' + AllToChar( aErro[3] " + ' [' + AllToChar( aErro[4] " + ' [' + AllToChar( aE rro[5] " + ' [' + AllToChar( aErro[6] " + ' [' + AllToChar( aErro[7] " + ' [' + AllToChar( aErro[8] " + ' [' + AllToChar( aErro[9] ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) ) + ']' ) " + ' [' + AllTrim( AllToChar( nItErro EndIf MostraErro() EndIf // Desativamos o Model oModel:DeActivate() Return lRet
Uma situao que poder ser encontrada, nos casos em que se est convertendo uma aplicao existente para a estrutura de MVC, o fato da aplicao j estar preparada para trabalh ar com rotina automtica e conseqentemente pode haver vrias outras aplicaes que j util zam essa rotina automtica. A funo FWMVCRotAuto foi criada para que no seja necessrio que estas aplicaes, que hoje usam a chamada da rotina padro, mudem sua forma de tra balhar, j a aplicao foi convertida para MVC. A funo utiliza os parmetros passados no ormato anterior de rotina automtica (MSEXECAUTO) e faz o instanciamento do model, atribuio de valores e validao no formato MVC, garantindo os programas legados. Sua sintaxe : FWMVCRotAuto( oModel, cAlias, nOpcAuto, aAuto, lSeek, lPos ) Onde: oModel Objeto com o modelo do formulrio de dados; 92 - AdvPl utilizando MVC
cAlias nOpcAuto Alias do Browse principal; Cdigo de identificao do tipo de processamento da rotina automtica; [3] [4] [5] Incluso Alterao Excluso aAuto Array com os dados da rotina automtica na seguinte estrutura; [n][1] Cdigo do form ulrio do Modelo que ter uma atribuio; [n][2] Array padro dos dados da EnchAuto e GetD Auto, conforme documentao anterior; lSeek lPos Indica se o arquivo principal deve ser posicionado com base nos dados fornecidos ; Indica se o nOpc no deve ser calculado com base no aRotina; Assim a aplicao em MVC que foi convertida poder trabalhar das duas formas: automtica e o Instnciamento do model. A rotina
No exemplo a seguir temos uma rotina de cadastro onde h o tratamento para isso, s e os dados xRotAuto, nOpcAuto forem passados, indica que a aplicao foi chamada por rotina automtica e assim usamos a FWMVCRotAuto. E essa construo no impede que em ou tras aplicaes tambm se instancie o modelo de dados (Model) diretamente. Function MATA030_MVC(xRotAuto,nOpcAuto) Local oMBrowse If xRotAuto == NIL oBrowse := FWMBrowse():New() oBrowse:SetAlias('SA1') oBrowse: SetDescription("Cadastro de Clientes") oBrowse:Activate() Else aRotina := MenuDe f() FWMVCRotAuto(ModelDef(),"SA1",nOpcAuto,{{"MATA030_SA1",xRotAuto}}) Endif Ret urn NIL AdvPl utilizando MVC 93
16.Pontos de entrada no MVC Pontos de entrada so desvios controlados executados no decorrer das aplicaes. Ao se escrever uma aplicao utilizando o MVC, automaticamente j estaro disponveis pontos de entrada pr-definidos. A idia de ponto de entrada, para fontes desenvolvidos utili zando-se o conceito de MVC e suas classes, um pouco diferente das aplicaes desenvo lvidas de maneira convencional. Nos fontes convencionais temos um nome para cada ponto de entrada criado, por exemplo, na rotina MATA010 Cadastro de Produtos, t emos os pontos de entrada: MT010BRW, MTA010OK, MT010CAN, etc. Em MVC, no desta fo rma. Em MVC criamos um nico ponto de entrada e este chamado em vrios momentos dent ro da aplicao desenvolvida. Este ponto de entrada nico deve ser uma User Function e ter como nome o identificador (ID) do modelo de dados (Model) do fonte. Peguemo s de exemplo um fonte do Modulo Jurdico: JURA001. Neste fonte o identificador (ID ) do modelo de dados (definido na funo ModelDef) tambm JURA001, portanto ao se escr ever o ponto de entrada desta aplicao, faramos: User Function JURA001() Local aParam := PARAMIXB Local xRet ... Return xRet := . T.
O ponto de entrada criado recebe via parmetro (PARAMIXB) um vetor com informaes ref erentes aplicao. Estes parmetros variam para cada situao, em comum todos eles tem os 3 primeiros elementos que so listados abaixo, no quadro seguinte existe a relao de parmetros para cada ID: Posies do array de parmetros comuns a todos os IDs: POS. 1 2 3 TIPO O C C DESCRIO Objeto do formulrio ou do modelo, conforme o caso ID do local de execuo do ponto de entrada ID do formulrio 94 - AdvPl utilizando MVC
Como j foi dito, o ponto de entrada chamado em vrios momentos dentro da aplicao, na 2 posio da estrutura do vetor passado um identificador (ID) que identifica qual ess e momento. Ela pode ter como contedo: ID DO PONTO DE ENTRADA MOMENTO DE EXECUO DO P ONTO DE ENTRADA Antes da alterao de qualquer campo do modelo. Parmetros Recebidos: 1 MODELPRE 2 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do loc al de execuo do ponto de entrada. ID do formulrio. Retorno: Requer um retorno lgico. Na validao total do modelo. Parmetros Recebidos: 1 MODELPOS 2 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do loca l de execuo do ponto de entrada. ID do formulrio. Retorno: Requer um retorno lgico. Antes da alterao de qualquer campo do formulrio. P armetros Recebidos: 1 FORMPRE 2 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio. Retorno: Requer um retorno lgico. Na validao total do formulrio. Parmetros Recebidos: 1 FORMPOS 2 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do loc al de execuo do ponto de entrada. ID do formulrio. Retorno: Requer um retorno lgico. AdvPl utilizando MVC 95
Antes da alterao da linha do formulrio FWFORMGRID. Parmetros Recebidos: 1 2 FORMLINE PRE 3 4 5 6 O C C N C C Objeto do formulrio ou do modelo, conforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio. Nmero da Linha da FWFORMGRID. Ao da FWFORMGRID. Id do campo. Retorno: Requer um retorno lgico. Na validao total da linha do formulrio FWFORMGRID. Parmetros Recebidos: 1 2 FORMLINEPOS 3 4 O C C N Objeto do formulrio ou do modelo , conforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio. Nmero da Linha da FWFORMGRID.
Retorno: Requer um retorno lgico. Aps a gravao total do modelo e dentro da transao. P rmetros Recebidos: 1 MODELCOMMITTT S 2 3 O C C Objeto do formulrio ou do modelo, c onforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio.
Retorno: No espera retorno. Aps a gravao total do modelo e fora da transao. Parmetro ecebidos: 1 MODELCOMMITNT TS 2 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio. Retorno: No espera retorno. 96 - AdvPl utilizando MVC
Antes da gravao da tabela do formulrio. Parmetros Recebidos: 1 2 FORMCOMMITTTS PRE 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio.
4 L Se .T. (verdadeiro) indica novo registro (Incluso) se .F. (falso) registro j e xistente (Alterao / Excluso) . Retorno: No espera retorno. Aps a gravao da tabela do rmulrio. Parmetros Recebidos: 1 2 FORMCOMMITTTS POS 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do local de execuo do ponto de entrada. ID do formu lrio. 4 L Se .T. (verdadeiro) indica novo registro (Incluso) se .F. (falso) registro j e xistente (Alterao / Excluso). Retorno: No espera retorno. No cancelamento do boto. Pa rmetros Recebidos: 1 FORMCANCEL 2 3 O C C Objeto do formulrio ou do modelo, confor me o caso. ID do local de execuo do ponto de entrada. ID do formulrio. Retorno: Requer um retorno lgico. Na ativao do modelo Parmetros Recebidos: 1 MODELVL DACTIVE 2 3 O C C Objeto do formulrio ou do modelo, conforme o caso. ID do local de execuo do ponto de entrada. ID do formulrio. Retorno: Requer um retorno lgico. AdvPl utilizando MVC 97
Para a incluso de botes na ControlBar. Para criar os botes deve-se retornar um arra y bi-dimensional com a seguinte estrutura de cada item: 1 2 3 BUTTONBAR 4 1 2 3 C C B C O C C Titulo para o boto. Nome do Bitmap para exibio. CodeBlock a ser execu tado. ToolTip (Opcional). Objeto do formulrio ou do modelo, conforme o caso. ID d o local de execuo do ponto de entrada. ID do formulrio. Parmetros Recebidos: Retorno: Requer um array de retorno com estrutura pr definida. Observaes: Quando o modelo de dados possui vrios componentes (por exemplo, de grid), a 3 posio do vetor trar o identificador (ID) deste componente; Quando o tipo de retorno de um determ inado momento de execuo no for passado ou for passado com o tipo errado ser exibida uma mensagem no console avisando sobre isso. Todos IDs que esperam retorno devem ser tratados no ponto de entrada. Importante: Ao se escrever um fonte em MVC que ser uma User Function, cuidado ao se atribuir o identificador (ID) do modelo de dados (Model), pois ele no poder ter o mesmo nome do fonte (PRW). Se o fonte tiver o nome FONT001, o identificador ( ID) do modelo de dados (Model) no poder ser tambm FONT001, pois no ser possvel criar utra User Function com o nome de FONT001 (ID do modelo de dados) para os pontos de entrada. Exemplo: User Function JURA001() Local aParam Local xRet Local oObj Local cIdPonto Local cIdModel Local lIsGrid Local nLinha := PARAMIXB := .T. := '' := '' := '' := .F. := 0 Local nQtdLinhas := 0 98 - AdvPl utilizando MVC
Local cMsg If aParam <> NIL oObj cIdPonto cIdModel lIsGrid := '' := aParam[1] := aParam[2] := aParam[3] := ( Len( aParam ) > 3 ) If lIsGrid nQtdLinhas := oObj:GetQtdLine() nLinha EndIf If cIdPonto == 'MODELPOS ' := oObj:nLine cMsg := 'Chamada na validao total do modelo (MODELPOS).' + CRLF cMsg += 'ID ' + cI dModel + CRLF If !( xRet := ApMsgYesNo( cMsg + 'Continua ?' ) ) Help( ,, 'Help',, 'O MODELPOS retornou .F.', 1, 0 ) EndIf ElseIf cIdPonto == 'FORMPOS' cMsg := 'Chamada na validao total do formulrio (FORMPOS).' + CRLF cMsg += 'ID ' If + cIdModel + CRLF cClasse == 'FWFORMGRID' cMsg += ' um FORMGRID com ' + Alltrim( Str( nQtdLinhas ) ) + ; ' linha(s).' + CRLF ) ) + CRLF cMsg += 'Posicionado na linha ' + Alltrim( Str( nLinha ElseIf cClasse == 'FWFORM FIELD' cMsg += ' um FORMFIELD' + CRLF EndIf If !( xRet := ApMsgYesNo( cMsg + 'Continua ?' ) ) Help( ,, 'Help',, 'O FORMPOS r etornou .F.', 1, 0 ) EndIf ElseIf cIdPonto == 'FORMLINEPRE' If aParam[5] == 'DELETE' INEPRE).' + CRLF cMsg += = ' um FORMGRID com ' + += 'Posicionado na linha F ) ) +; CRLF cMsg := 'Chamada na pr validao da linha do formulrio (FORML 'Onde esta se tentando deletar uma linha' + CRLF cMsg + Alltrim( Str( nQtdLinhas ) ) +; ' linha(s).' + CRLF cMsg ' + Alltrim( Str( nLinha cMsg += 'ID ' + cIdModel + CRL
If !( xRet := ApMsgYesNo( cMsg + 'Continua ?' ) ) Help( ,, 'Help',, 'O FORMLINEP RE retornou .F.', 1, 0 ) EndIf AdvPl utilizando MVC 99
EndIf ElseIf cIdPonto == 'FORMLINEPOS' cMsg := 'Chamada na validao da linha do formulrio (FORMLINEPOS).' +; CRLF cMsg += ' ID ' + cIdModel + CRLF cMsg += ' um FORMGRID com ' + Alltrim( Str( nQtdLinhas ) ) + ; ' linha(s).' + CRL F cMsg += 'Posicionado na linha ' + Alltrim( Str( nLinha If !( xRet := ApMsgYesN o( cMsg + 'Continua ?' ) ) Help( ,, 'Help',, 'O FORMLINEPOS retornou .F.', 1, 0 ) EndIf ElseIf cIdPonto == 'MODELCOMMITTTS' ) ) + CRLF ApMsgInfo('Chamada apos a gravao total do modelo e dentro da transao (MODELCOMMITTTS ).' + CRLF + 'ID ' + cIdModel ) ElseIf cIdPonto == 'MODELCOMMITNTTS' ApMsgInfo('Chamada apos a gravao total do modelo e fora da transao (MODELCOMMITNTTS) .' + CRLF + 'ID ' + cIdModel) //ElseIf cIdPonto == ElseIf cIdPonto == 'FORMCOMMI TTTSPRE' 'FORMCOMMITTTSPOS' + CRLF + ApMsgInfo('Chamada apos a gravao da tabela do formulrio (FORMCOMMITTTSPOS).' 'ID ' + cIdModel) ElseIf cIdPonto == 'MODELCANCEL' cMsg := 'Chamada no Boto Cancelar (MODELCANCEL).' + CRLF + 'Deseja Realmente Sair ?' If !( xRet := ApMsgYesNo( cMsg ) ) Help( ,, 'Help',, 'O MODELCANCEL retornou .F. ', 1, 0 ) EndIf ElseIf cIdPonto == 'MODELVLDACTIVE' cMsg := 'Chamada na validao da ativao do Model.' + CRLF + ; 'Continua ?' If !( xRet := ApMsgYesNo( cMsg ) ) Help( ,, 'Help',, 'O MODELVLDACTIVE retornou .F.', 1, 0 ) EndIf ElseIf cIdPonto == 'BUTTONBAR' + cIdModel ) ApMsgInfo('Adicionando Boto na Barra de Botes (BUTTONBAR).' + CRLF + 'ID ' xRet := { {'Salvar', 'SALVAR', { dIf EndIf Return xRet 100 - AdvPl utilizando MVC Alert( 'Salvou' ) }, 'Este boto Salva' } } En
17.Web Services para MVC Ao se desenvolver uma aplicao utilizando MVC, j estar disponvel um Web Service para s er utilizado para o recebimento de dados. Todas as aplicaes em MVC utilizaro o mesm o Web Service, independentemente de sua estrutura ou de quantas entidades ele po ssua. O Web Service que est disponvel para o MVC o FWWSMODEL . A idia bsica que ire os instanciar o Web Service, informar qual a aplicao que ser utilizada e informar o s dados em um formato XML. 17.1 Web Service para modelos de dados que possuem uma entidade Veremos como construir uma aplicao que utilize o Web Service FWWSMODEL com um mode lo de dados (Model) que possui apenas uma entidade. 17.2 Instnciamento do Client de Web Service O instnciamento se d seguinte forma: Instnciamento do Client do Web Service propria mente dito. oMVCWS := WsFwWsModel():New() Definio da URL do FWWSMODEL no servidor de Web Services. oMVCWS:_URL := http://127.0.0.1:8080/ws/FWWSMODEL.apw
Definio da aplicao que ser usada. Definimos aqui o nome do fonte que contm a ModelDef que queremos utilizar. oMVCWS:cModelId := 'COMP011_MVC' 17.3 A estrutura do XML utilizada Como dito anteriormente os dados sero informados em um XML. A estrutura desse XML segue a seguinte hierarquia bsica: <ID do Model> <ID de Componente> <ID de Campo> Contedo... </ID de Campo </ID de C omponente > </ID do Model> A tag <ID do Model> o que identificador (ID) foi definido no modelo de dados (Mo del) da aplicao MVC. Exemplo: AdvPl utilizando MVC 101
Na aplicao temos definido: oModel := MPFormModel():New('COMP011M' ) No XML a tags <ID do Model> sero: <COMP011M> ... </COMP011M> A operao que ser realizada incluso (3), alterao (4) ou excluso (5) tambm dever ser mada nesta tag, no atributo Operation. Assim se quisermos fazer uma operao de incl uso teremos: <COMP011M Operation="3"> As tags <ID de Componente> so IDs dos componentes de formulrios ou componente de g ris que foram definidos no modelo de dados (Model) da aplicao. Exemplo: Se na apli cao temos: oModel:AddFields( 'ZA0MASTER' ) No XML as tags <ID de Componente> sero: <ZA0MASTER> ... </ZA0MASTER> O tipo do componente (de formulrio ou de grid) tambm deve ser informados nesta tag no atributo modeltype. Informe FIELDS para componentes de formulrios e GRID para componentes de grid. Teramos ento: <ZA0MASTER modeltype="FIELDS"> As tags <ID de Campo> sero os nomes dos campos da estrutura do componente, seja f ormulrio ou grid. Assim se na estrutura tivermos os campos ZA0_FILIAL, ZA0_ CODIG O e ZA0_NOME, por exemplo, teremos: <ZA0_FILIAL> ... </ZA0_FILIAL> <ZA0_CODIGO> ... </ZA0_CODIGO> 102 - AdvPl utilizando MVC
<ZA0_NOME> ... </ZA0_NOME> A ordem dos campos tambm deve ser informada nestas tags, no atributo order. <ZA0_FILIAL order="1"> ... </ZA0_FILIAL> <ZA0_CODIGO order="2"> ... </ZA0_CODIGO > <ZA0_NOME ... </ZA0_NOME> order="3"> Quando o componente um formulrio (FIELDS), os dados propriamente ditos devem ser informados em uma tag value. <ZA0_FILIAL order="1"> <value>01</value> </ZA0_FILIAL> <ZA0_CODIGO order="2"> <v alue>001000</value> </ZA0_CODIGO > <ZA0_NOME order="3"> <value>Tom Jobim</value> </ZA0_NOME> Ento a estrutura completa ser: <COMP011M Oper ation="1"> <ZA0MASTER modeltype="FIELDS" > <ZA0_FILIAL order="1"> <value>01</val ue> </ZA0_FILIAL> <ZA0_CODIGO order="2"> <value>01000</value> </ZA0_CODIGO> <ZA0 _NOME order="3"> <value>Tom Jobim</value> </ZA0_NOME> </ZA0MASTER> </COMP011M> 17.4 Obtendo a estrutura XML de um modelo de dados AdvPl utilizando MVC 103
(GetXMLData) Podemos obter a estrutura XML que uma aplicao em MVC espera, para isso utilizando o mtodo GetXMLData do Web Service. Exemplo: oMVCWS:GetXMLData() O XML esperado ser informado no atributo cGetXMLDataResult do WS. cXMLEstrut := oMVCWS:cGetXMLDataResult Utilizando ainda o exemplo acima, teramos: <?xml version="1.0" encoding="UTF-8"?> <COMP011M Operation="1" <ZA0MASTER modelt ype="FIELDS" > <ZA0_FILIAL order="1"><value></value></ZA0_FILIAL> <ZA0_CODIGO or der="2"><value></value></ZA0_CODIGO> <ZA0_NOME </ZA0MASTER> </COMP011M> order="3 "><value></value></ZA0_NOME> 17.5 Informando os dados XML ao Web Service O XML contendo os dados dever ser atribudo ao atributo cXML do objeto de Web Serv ice. Exemplo: oMVCWS:cXML := cXML // varivel que contem o XML com os dados 17.6 Validando os dados (VldXMLData) Para submetermos esses dados ao modelo de dados (Model) para que sejam validados utilizamos o mtodo VldXMLData. If !oMVCWS:VldXMLData() MsgStop( 'Problemas na validao dos dados' + CRLF + WSError () ) EndIf Neste momento os dados so validados, mas no so gravados. O VldXMLData apenas valida . Este um recurso interessante se quisermos fazer uma simulao, por exemplo. 104 - AdvPl utilizando MVC
17.7 Validando e gravando os dados (PutXMLData) A diferena entre o mtodo VldXMLData e o mtodo PutXMLData, que o PutXMLData alm de su bmeter os dados do XML ao modelo de dados para validao, tambm far a gravao destes dad s se a validao foi bem sucedida. O resultado informado no atributo lPutXMLDataResu lt e caso haja algum problema, ser descrito no atributo cVldXMLDataResult do obje to de Web Service. If oMVCWS:PutXMLData() If oMVCWS:lPutXMLDataResult MsgInfo( 'Informao gravada com sucesso.' ) Else MsgStop( 'Informao no gravada ' + CRLF + WSError() ) EndIf Else Ms gStop( AllTrim(oMVCWS:cVldXMLDataResult) + CRLF + WSError() ) EndIf
17.8 Obtendo o esquema XSD de um modelo de dados (GetSchema) O XML informado antes da validao das informaes pelo modelo de dados (Model) ser valid ado pelo schema XSD referente ao modelo. Essa validao feita automaticamente e o XS D baseado na estrutura do modelo de dados (Model). Esta validao se refere estrutur ao do XML (tags, nveis, ordens, etc.) e no aos dados dos XML, a validao dos dados f a regra de negcios. Se o desenvolvedor quiser obter o schema XSD que ser usado, po der usar o mtodo GetSchema. Exemplo: If oMVCWS:GetSchema() cXMLEsquema := oMVCWS:cGetSchemaResult EndIf O schema XSD retornado no atributo cGetSchemaResult do objeto de Web Service. AdvPl utilizando MVC 105
17.9 Exemplo completo de Web Service User Function COMPW011() Local oMVCWS // Instancia o WebService Genrico para Roti nas em MVC oMVCWS := WsFwWsModel():New() // URL onde esta o WebService FWWSModel do Protheus oMVCWS:_URL := http://127.0.0.1:8080/ws/FWWSMODEL.apw // Seta Atributos do WebService oMVCWS:cModelId := 'COMP011_MVC' // Fonte de ond e se usara o Model // Exemplo de como pegar a descrio do Modelo de Dados //If oMVCWS:GetDescription() // //Else // MsgStop( 'Problemas em obter descrio do Model' + CRLF + WSError() ) MsgInfo( oMVCWS:cGetDescriptionResult ) //EndIf // Obtm a estrutura dos dados do Model If oMVCWS:GetXMLData() // Retorno da GetXMLData cXMLEstrut := oMVCWS:cGetXMLDataResult // Retorna //<?x ml version="1.0" encoding="UTF-8"?> //<COMP011M Operation="1" version="1.01"> // // // // // <ZA0MASTER modeltype="FIELDS" > <ZA0_FILIAL order="1"><value></valu e></ZA0_FILIAL> <ZA0_CODIGO order="2"><value></value></ZA0_CODIGO> <ZA0_NOME </Z A0MASTER> order="3"><value></value></ZA0_NOME> //</COMP011M> // Obtm o esquema de dados XML (XSD) If oMVCWS:GetSchema() cXMLEsquema := oMVCWS: cGetSchemaResult EndIf // Cria o XML cXML := '<?xml version="1.0" encoding="UTF-8"?>' cXML += '<COMP011 M Operation="1" version="1.01">' cXML += ' cXML += ' <ZA0MASTER modeltype="FIELD S" >' <ZA0_FILIAL order="1"><value>01</value></ZA0_FILIAL>' 106 - AdvPl utilizando MVC
cXML += ' cXML += ' cXML += ' <ZA0_CODIGO order="2"><value>000100</value></ZA0_CODIGO>' <ZA0_NOME </ZA0MASTER> ' order="3"><value>Tom Jobim</value></ZA0_NOME>' cXML += '</COMP011M>' // Joga o XML para o atributo do WebService oMVCWS:cModelXML := cXML // Valida e Grava os dados If oMVCWS:PutXMLData() If oMVCWS:lPutXMLDataResult Ms gInfo( 'Informao Importada com sucesso.' ) Else MsgStop( 'No importado' + CRLF + WS Error() ) EndIf Else MsgStop( AllTrim( oMVCWS:cVldXMLDataResult ) + CRLF + WSErr or() ) EndIf 17.10 Web Services para modelos de dados que possuem duas ou mais entidades Para a construo de Web Services que possuam duas ou mais entidades o que ser difere nte apenas o XML recebido que ter mais nveis. Observe o fonte exemplo: #INCLUDE 'PROTHEUS.CH' #INCLUDE 'XMLXFUN.CH' #INCLUDE 'FWMVCDEF.CH' //------------------------------------------------------------------/*/{Protheus .doc} COMPW021 Exemplo de utilizacao do WebService generico para rotinas em MVC para uma estrutura de pai/filho @author Ernani Forastieri e Rodrigo Antonio Godi nho @since 05/10/2009 @version P10 /*/ //-----------------------------------------------------------------User Function COMPW021() Local oMVCWS AdvPl utilizando MVC 107
Local cXMLEstrut := '' Local cXMLEsquema := '' Local cXMLFile := '\XML\WSMVCTST.XML' RpcSetType( 3 ) RpcSetEnv( '99', '01' ) // Instancia o WebService Generico para Rotinas em MVC oMVCWS := WsFwWsModel():N ew() oMVCWS:_URL := "http://127.0.0.1:8080/ws/FWWSMODEL.apw" oMVCWS:cUserLogin := 'admin' oMVCWS:cUserToken := 'admin' oMVCWS:cPassword oMVCW S:cModelId := '' := 'COMP021_MVC' // Fonte de onde se usara o Model // Obtem a estutura dos dados do Model If oMVCWS:GetXMLData() If oMVCWS:GetSchem a() cXMLEsquema := oMVCWS:cGetSchemaResult EndIf cXMLEstrut := oMVCWS:cGetXMLDataResult //<?xml version="1.0" encoding="UTF-8"?> //<COMP021MODEL Operation="1" version=" 1.01"> //<ZA1MASTER modeltype="FIELDS" > //<ZA1_FILIAL order="1"><value></value> </ZA1_FILIAL> //<ZA1_MUSICA order="2"><value></value></ZA1_MUSICA> //<ZA1_TITULO order="3"><value></value></ZA1_TITULO> //<ZA1_DATA // // // // // // // // // / / order="4"><value></value></ZA1_DATA> <ZA2DETAIL modeltype="GRID" > <struct> <ZA2_FILIAL order="1"></ZA2_FILIAL> <ZA2_ MUSICA order="2"></ZA2_MUSICA> <ZA2_ITEM <ZA2_AUTOR </struct> <items> <item id=" 1" deleted="0" > <ZA2_FILIAL></ZA2_FILIAL> order="3"></ZA2_ITEM> order="4"></ZA2 _AUTOR> 108 - AdvPl utilizando MVC
// // // // // // <ZA2_MUSICA></ZA2_MUSICA> <ZA2_ITEM></ZA2_ITEM> <ZA2_AUTOR></ZA2_AUTOR> </item> </items> </ZA2DETAIL> //</ZA1MASTER> //</COMP021MODEL> // Obtem o esquema de dados XML (XSD) If oMVCWS :GetSchema() cXMLEsquema := oMVCWS:cGetSchemaResult EndIf cXML := '' cXML += '<?xml version="1.0" encoding="UTF-8"?>' cXML += '<COMP021MOD EL Operation="1" version="1.01">' cXML += '<ZA1MASTER modeltype="FIELDS">' cXML += '<ZA1_FILIAL order="1"><value>01</value></ZA1_FILIAL>' cXML += '<ZA1_MUSICA o rder="2"><value>000001</value></ZA1_MUSICA>' cXML += '<ZA1_TITULO order="3"><val ue>AQUARELA</value></ZA1_TITULO>' cXML += '<ZA1_DATA cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' cXML += ' order="4"><value></value></ZA1_DATA>' <ZA2DETAIL modeltype="GRID" >' <struct>' <ZA2_FILIAL order="1"></ZA2_FILIAL>' <Z A2_MUSICA order="2"></ZA2_MUSICA>' <ZA2_ITEM <ZA2_AUTOR </struct>' <items>' <ite m id="1" deleted="0" >' <ZA2_FILIAL>01</ZA2_FILIAL>' <ZA2_MUSICA>000001</ZA2_MUS ICA>' <ZA2_ITEM>01</ZA2_ITEM>' <ZA2_AUTOR>000001</ZA2_AUTOR>' </item>' <item id= "2" deleted="0" >' <ZA2_FILIAL>01</ZA2_FILIAL>' <ZA2_MUSICA>000002</ZA2_MUSICA>' <ZA2_ITEM>02</ZA2_ITEM>' <ZA2_AUTOR>000002</ZA2_AUTOR>' order="3"></ZA2_ITEM>' order="4"></ZA2_AUTOR>' AdvPl utilizando MVC 109
cXML += ' cXML += ' cXML += </item>' </items>' </ZA2DETAIL>' cXML += '</ZA1MASTER>' cXML += '</COMP021MODEL>' // Joga o XML para o atributo do WebService oMVCWS:cModelXML := cXML // Valida e Grava os dados If oMVCWS:PutXMLData() If oMVCWS:lPutXMLDataResult Ms gInfo( 'Informao importada com sucesso.' ) Else MsgStop( 'No importado' + CRLF + WS Error() ) EndIf Else MsgStop( AllTrim( oMVCWS:cVldXMLDataResult ) + CRLF + WSErr or() ) EndIf Else MsgStop( 'Problemas em obter Folha de Dados do Model' EndIf Rp cClearEnv() + CRLF + WSError() ) Return NIL //------------------------------------Static Function WSError() Return IIf( Empty( GetWscError(3) ), GetWscError(1), GetWscError(3) ) 110 - AdvPl utilizando MVC
18.Uso do comando New Model Para facilitar o desenvolvimento foram criados comandos que podem gerar mais sim ples e rapidamente uma aplicao em MVC. o comando New Model. Este comando indicado para aquelas aplicaes onde se tem o uso de uma tabela (antiga Modelo1) ou uma tabe la no normalizada (cabealho e item no mesmo registro), mas com a necessidade de tr abalhar em uma estrutura master-detail (antiga Modelo2) ou onde se tem o uso de duas tabelas em uma estrutura master-detail (antiga Modelo3). Utilizando o coman do New Model no necessrio se escrever todas as funes e classes normalmente utilizada s em uma rotina MVC. Durante o processo de pr-compilao o New Model e suas diretivas so transformados em um fonte MVC que utiliza FWmBrowse, ModelDef, ViewDef e even tualmente MenuDef. A premissa para se utilizar este comando que se tenha uma das construes citadas acima e as estruturas das tabelas estejam definidas no dicionrio SX3. No podero ser construdas estruturas manualmente ou se adicionar ou retirar ca mpos das estruturas. Como este comando uma diretiva de compilao do tipo #COMMAND, para utilizar este comando preciso incluir a seguinte diretiva no fonte: #INCLUDE 'FWMVCDEF.CH' seguir h a sintaxe do comando e exemplos de uso. 18.1 Sintaxe da New Model Esta sintaxe do comando New Model: NEW MODEL TYPE DESCRIPTION BROWSE SOURCE MODE LID FILTER <nType> ; <cDescription> ; <oBrowse> ; <cSource> ; <cModelID> ; <cFil ter> ; CANACTIVE <bSetVldActive> ; PRIMARYKEY <aPrimaryKey> ; MASTER <cMasterAli as> ; HEADER <aHeader,...> ; BEFORE <bBeforeModel> ; AdvPl utilizando MVC 111
AFTER <bAfterModel> ; COMMIT <bCommit> ; CANCEL <bCancel> ; BEFOREFIELD <bBefore Field> ; AFTERFIELD <bAfterField> ; LOAD <bFieldLoad> ; DETAIL <cDetailAlias> ; BEFORELINE <bBeforeLine> ; AFTERLINE <bAfterLine> ; BEFOREGRID <bBeforeGrid> ; A FTERGRID <bAfterGrid> ; LOADGRID <bGridLoad> ; RELATION <aRelation> ; ORDERKEY < cOrder> ; UNIQUELINE <aUniqueLine> ; AUTOINCREMENT <cFieldInc> ; OPTIONAL Onde: TYPE <nType> Tipo Numrico - Obrigatrio Tipo de Estrutura 1 = 1 Tabela 2 = 1 Tabela Master/Detail 3 = 2 Tabelas Master/Detail 112 - AdvPl utilizando MVC
DESCRIPTION <cDescription> Tipo Caracter - Obrigatrio Descrio da Rotina BROWSE <oBr owse> Tipo Objeto - Obrigatrio Objeto de Browse que ser utilizado SOURCE <cSource> Tipo Caracter - Obrigatrio Nome do Fonte MODELID <cModelID> Tipo Caracter - Obri gatrio identificador (ID) do Model FILTER <cFilter> Tipo Caracter - Opcional Filt ro para Browse CANACTIVE <bSetVldActive> Tipo Bloco - Opcional Bloco para validao da ativao do Model. Recebe como parmetro o Model Ex. { oModel COMP011ACT( oModel ) } PRIMARYKEY <aPrimaryKey> Tipo Array - Opcional Array com as Chaves primrias do Br owse, se no for informado ira buscar o X2_UNICO da tabela. MASTER <cMasterAlias> Tipo Caracter - Obrigatrio Tabela Principal (Master) HEADER <aHeader> AdvPl utilizando MVC 113
Tipo Array - Obrigatrio para TYPE = 2 Array com campos que sero considerados no "C abealho" BEFORE <bBeforeModel> Tipo Bloco - Opcional Bloco de Pr Validao do Model. Recebe co mo parmetro o Model. Ex. { oModel COMP011PRE( oModel ) } AFTER <bAfterModel> Tipo Bloco - Opcional Bloco de Ps Validao do Model Recebe como parmetro o Model. Ex. { oModel COMP011POS( oModel ) } COMMIT <bCommit> Tipo Bloco - Opcional Bloco de persistncia dos dados (Commit) do Model. Recebe como parmetro o Model. Ex. { oModel COMP022CM( oModel ) } CANCEL <bCancel> Tipo Bloco - Opcional Bloco acionado no boto de cancelar. Recebe como parmetro o Model. Ex. { oModel COMP011CAN( oModel ) } BEFOREFIELD <bBeforeField> Tipo Bloco - Opcional Bloco de Pr Validao da FORMFIELD d a tabela Master. Recebe como parmetro o ModelField, identificador (ID) do local d e execuo e identificador (ID) do Formulrio Ex. { oMdlF,cId ,cidForm COMP023FPRE( oMdlF,cId ,cidForm) } AFTERFIELD <bAfterField> Tipo Bloco - Opcional Bloco de Ps Validao da FORMFIELD da tabela Master. . Recebe como parmetro o ModelField, identificador (ID) do local d e execuo e identificador (ID) do Formulrio 114 - AdvPl utilizando MVC
Ex. { oMdlF,cId ,cidForm COMP023FPOS( oMdlF,cId ,cidForm) } LOAD <bFieldLoad> Tipo Bloco - Opcional Bloco de Carga dos dados da FORMFIELD da tabela Master DETAIL <cDetailAlias> Tipo Caracter - Obrigatrio para TYPE = 2 ou 3 Tabela Detail BEFORELINE <bBeforeLine> Tipo Bloco - Opcional Bloco de Pr Validao da linha da FOR MGRID da tabela Detail. Recebe como parmetro o ModelGrid, o numero da linha do FO RMGRID, a ao e o campo da FORMGRID. Ex. { oMdlG,nLine,cAcao,cCampo COMP023LPRE( oMdlG, nLine, cAcao, cCampo ) } Usado apenas para TYPE = 2 ou 3 AFTERLINE <bAfterLine> Tipo Bloco - Opcional Blo co de Ps Validao da linha da FORMGRID da tabela Detail. Recebe como parmetro o Model Grid e o numero da linha do FORMGRID. Ex. { oModelGrid, nLine COMP022LPOS( oMo delGrid, nLine ) } Usado apenas para TYPE = 2 ou 3 BEFOREGRID <bBeforeGrid> Tipo Bloco - Opcional B loco de Pr Validao da FORMGRID da tabela Detail. Recebe como parmetro o ModelGrid Us ado apenas para TYPE = 2 ou 3 AFTERGRID <bAfterGrid> Tipo Bloco - Opcional Bloco de Pr Validao da FORMGRID da tabela Detail. Recebe como parmetro o ModelGrid AdvPl utilizando MVC 115
Usado apenas para TYPE = 2 ou 3 LOADGRID <bGridLoad> Tipo Bloco - Opcional Bloco de Carga dos dados da FORMGRID da tabela Detail Usado apenas para TYPE = 2 ou 3 RELATION <aRelation> Tipo Array - Obrigatrio para TYPE = 2 ou 3 Array bidimensional para relacionamento das tabe las Master/Detail Usado apenas para TYPE = 2 ou 3 ORDERKEY <cOrder> Tipo Caracte r - Opcional Ordenao da FORMGRID da tabela Detail Usado apenas para TYPE = 2 ou 3 UNIQUELINE <aUniqueLine> Tipo Array - Opcional Array com campos para que podero s er duplicados na FORMGRID da tabela Detail Usado apenas para TYPE = 2 ou 3 AUTOI NCREMENT <cFieldInc> Tipo Array - Opcional Campos auto incremental para FORMGRID da tabela Detail Usado apenas para TYPE = 2 ou 3 OPTIONAL Indica se o preenchim ento da FORMGRID da tabela Detail ser opcional Usado apenas para TYPE = 2 ou 3 116 - AdvPl utilizando MVC
Exemplo: // // Construcao para uma tabela // #INCLUDE "PROTHEUS.CH" #INCLUDE "FWMVCDEF.CH " User Function COMP041_MVC() Local oBrowse NEW MODEL ; TYPE 1 ; DESCRIPTION "Cadastro de Autor/Interprete" ; BROWSE SOURCE MODELID FILTER MASTER AFTER COMMIT Return NIL oBrowse "COMP041_MVC" "MDCOMP041" ; ; ; "ZA0_TIPO=='1'" ; "ZA0" ; { oMdl COMP041POS( oMdl ) } ; { oMdl COMP041CMM( oMdl ) } Static Function COMP041POS( oModel ) Help( ,, 'Help',, 'Acionou a COMP041POS', 1 , 0 ) Return .T. Static Function COMP041CMM( oModel ) FWFormCommit( oModel ) Return NIL AdvPl utilizando MVC 117
Visualmente teremos: // // Construcao para uma tabela Master/Detail // #INCLUDE "PROTHEUS.CH" #INCLUD E "FWMVCDEF.CH" User Function COMP042_MVC() Local oBrowse NEW MODEL ; TYPE DESCRIPTION BROWSE SOURCE MODELID MASTER HEADER 2 ; "Tabela Nao Normalizada" ; oBrowse "COMP042_MVC" "MDCOMP042" "ZA2" ; ; ; ; { 'ZA2_MUSICA', 'ZA2_ITEM' } ; 118 - AdvPl utilizando MVC
RELATION { { 'ZA2_FILIAL', 'xFilial( "ZA2" )' }, ; { 'ZA2_MUSICA', 'ZA2_MUSICA' } } ; UNIQUELINE ORDERKEY AUTOINCREMENT Return NIL { 'ZA2_AUTOR' } ; ZA2->( IndexKey( 1 ) ) ; 'ZA2_ITEM' O Resultado : AdvPl utilizando MVC 119
// // Construcao para duas tabelas Master/Detail // #INCLUDE "PROTHEUS.CH" #INCL UDE "FWMVCDEF.CH" User Function COMP043_MVC() Local oBrowse NEW MODEL ; TYPE DESCRIPTION BROWSE SOURCE MODELID MASTER DETAIL RELATION 3 ; "M usicas" oBrowse "COMP043_MVC" "MDCOMP043" "ZA1" "ZA2" ; ; ; ; ; ; { { 'ZA2_FILIAL', 'xFilial( "ZA2" )' }, ; { 'ZA2_MUSICA', 'ZA1_MUSICA' } } ; UNIQUELINE { 'ZA2_AUTOR' } ; 120 - AdvPl utilizando MVC
ORDERKEY AUTOINCREMENT ZA2->( IndexKey( 1 ) ) ; 'ZA2_ITEM' Return NIL O Resultado : AdvPl utilizando MVC 121
// // Construcao para uma tabela com menudef diferenciado // #INCLUDE "PROTHEUS. CH" #INCLUDE "FWMVCDEF.CH" User Function COMP044_MVC() Local oBrowse NEW MODEL ; TYPE 1 ; DESCRIPTION "Cadastro de Autor/Interprete" ; BROWSE SOURCE MENUDEF MODELID FILTE R MASTER oBrowse "COMP044_MVC" "COMP044_MVC" "MDCOMP044" ; ; ; ; "ZA0_TIPO=='1'" ; "ZA0" 122 - AdvPl utilizando MVC
Return NIL //------------------------------------------------------------------S tatic Function MenuDef() Local aRotina := {} ADD OPTION aRotina TITLE 'Pesquisar ' ACTION 'PesqBrw' OPERATION 1 ACCESS 0 ADD OPTION aRotina TITLE 'Visualizar' ACTION 'VIEWDEF.COMP044_MVC' OPERATION 2 A CCESS 0 Return aRotina O Resultado : AdvPl utilizando MVC 123
19.Reutilizando um modelo de dados ou interface j existentes Uma das grandes vantagens na construo de aplicaes em MVC a possibilidade de reutiliz ao do modelo de dados (Model) ou da interface (View) em outras aplicaes, utilizando o conceito de herana. Tanto podemos reutilizar os componentes como esto definidos, como tambm podemos acrescentar novas entidades aos mesmos. Para fazer isso preci samos dentro da nova aplicao instanciar o modelo de dados (Model) ou a interface ( View). A seguir exemplificamos esse uso. 19.1 Apenas reutilizando os componentes Neste exemplo realizaremos o modelo de dados (Model) e a interface (View) j exist entes em uma aplicao, para a construo de uma nova sem alteraes. Usaremos as funes: dModel, ver cap. 0 12.4 Carregar o modelo de dados de uma aplicao j existente (FWLo adModel) ) e; FWLoadView, ver cap. 0 12.5 Carregar a interface de uma aplicao j exi stente (FWLoadView). Na ModelDef da nova aplicao instanciamos o modelo de dados (M odel) da aplicao j existente: Static Function ModelDef() Local oModel := FWLoadModel( "COMP011_MVC" ) Return oModel Na MenuDef da aplicao instanciamos a interface (View) de outra aplicao: Static Function ModelDef() Local oModel := FWViewModel( "COMP011_MVC" ) Return o Model Nos exemplos acima a nova aplicao usar os mesmos componentes da aplicao j existente, o caso, o que est definido na ModelDef do fonte COMP011_MVC. Exemplo: #INCLUDE 'PROTHEUS.CH' #INCLUDE 'FWMVCDEF.CH' 124 - AdvPl utilizando MVC
//------------------------------------------------------------------User Functio n COMP015_MVC() Local oBrowse oBrowse := FWMBrowse():New() oBrowse:SetAlias('ZA0') oBrowse:SetDescription('Cad astro de Autor/Interprete') oBrowse:DisableDetails() oBrowse:Activate() Return NIL //------------------------------------------------------------------Static Funct ion MenuDef() Return FWLoadMenuDef( "COMP011_MVC") //------------------------------------------------------------------Static Funct ion ModelDef() // Criamos o modelo de dados desta aplicacao com o modelo existen te em // outra aplicacao, no caso COMP011_MVC Local oModel := FWLoadModel( "COMP 011_MVC" ) Return oModel //------------------------------------------------------------------Static Funct ion ViewDef() // Criamos o modelo de dados desta aplicacao com a interface exist ente em // outra aplicacao, no caso COMP011_MVC Local oView := FWLoadView( "COMP 011_MVC" ) Return oView 19.2 Reutilizando e complementando os componentes Mostraremos agora como reutilizar um componente de MVC onde acrescentaremos nova s entidades ao mesmo. S possvel acrescentar novas e no retirar entidades, pois se r etirssemos alguma entidade estaramos quebrando a regra de negcios criada no modelo original. O ideal para este tipo de uso criarmos um modelo bsico e o incrementarm os conforme a necessidade. Analisemos primeiro o modelo de dados (Model). No exe mplo a partir do modelo de dados j existente acrescentaremos uma nova entidade. A dvPl utilizando MVC 125
O primeiro passo criar a estrutura da nova entidade, ver cap. 0 5.1 Construo de um a estrutura de dados (FWFormStruct) para detalhes. // Cria a estrutura a ser acrescentada no Modelo de Dados Local oStruZA6 := FWFo rmStruct( 1, 'ZA6', /*bAvalCampo*/, /*lViewUsado*/ ) Instanciamos o modelo j existente. // Inicia o Model com um Model j existente Local oModel := FWLoadModel( 'COMP011_ MVC' ) No nosso exemplo, acrescentaremos um novo formulrio, ver cap. 0 5.3 Criao de um com ponente de formulrios no modelo de dados (AddFields) para detalhes. Note que em n ossa nova aplicao no usamos o MPFormModel, pois estamos apenas acrescentando entida de. O MPFormModel foi usado na aplicao original. // Adiciona a nova FORMFIELD oModel:AddFields( 'ZA6MASTER', 'ZA0MASTER', oStruZA 6 ) Fazemos o relacionamento do novo formulrio, ver cap. 0 126 - AdvPl utilizando MVC
6.5 Criao de relao entre as entidades do modelo (SetRelation). // Faz relacionamento entre os compomentes do model oModel:SetRelation( 'ZA6MAST ER', { { 'ZA6_FILIAL', 'xFilial( "ZA6" )' }, { 'ZA6_CODIGO', 'ZA0_CODIGO' } }, Z A6->( IndexKey( 1 ) ) ) Acionamos a descrio do novo formulrio. // Adiciona a descricao do novo componente oModel:GetModel( 'ZA6MASTER' ):SetDes cription( 'Complemento dos Dados de Autor/Interprete' ) E ao final retornamos o novo modelo. Return oModel Com isso criamos um modelo a partir de outro e de formulrio. Veremos agora como reutilizar a o um novo componente. O primeiro passo criar ap. 0 5.1 Construo de uma estrutura de dados // Cria a estrutura a ser acrescentada na View , 'ZA6' ) acrescentamos um novo componente interface (View), tambm acrescentand a estrutura da nova entidade ,ver c (FWFormStruct) . Local oStruZA6 := FWFormStruct( 2
Instanciaremos o modelo utilizado pela interface, note que no instanciaremos o mo delo original e sim o modelo da nova aplicao que j tem o novo componente acrescido em seu modelo de dados. // Cria um objeto de Modelo de Dados baseado no ModelDef do fonte informado Loca l oModel := FWLoadModel( 'COMP015_MVC' ) Instanciamos a interface original // Inicia a View com uma View ja existente Local oView := FWLoadView( 'COMP011_M VC' ) Adicionamos o novo componente da view e associamos ao criado no modelo, ver cap. 0 5.8 Criao de um componente de formulrios na interface (AddField) para detalhes. // Adiciona no nosso View um controle do tipo FormFields(antiga enchoice) oView: AddField( 'VIEW_ZA6', oStruZA6, 'ZA6MASTER' ) Temos que criar um box para o novo componente. preciso criar sempre um box verti cal dentro de um horizontal e vice-versa como na COMP011_MVC o box j existente ho rizontal, cria-se um vertical primeiro, para detalhes ver cap. 0 6.13 Exibio dos d ados na interface (CreateHorizontalBox / CreateVerticalBox). // 'TELANOVA' o box existente na interface original oView:CreateVerticallBox( 'T ELANOVA' , 100, 'TELA' ) AdvPl utilizando MVC 127
// Novos Boxes oView:CreateHorizontalBox( 'SUPERIOR' , 50, 'TELANOVA' ) oView:Cr eateHorizontalBox( 'INFERIOR' , 50, 'TELANOVA' ) Relacionado os componente com os box de exibio, ver cap. 0 5.10 Relacionando o com ponente da interface (SetOwnerView). oView:SetOwnerView( 'VIEW_ZA0', 'SUPERIOR' ) oView:SetOwnerView( 'VIEW_ZA6', 'IN FERIOR' ) E ao final retornamos o novo objeto de interface. Return oView Com isso criamos uma interface a partir de outra e acrescentamos um novo compone nte. Um exemplo de aplicao para este conceito seria a internacionalizaco, onde pode ramos ter um modelo bsico e o incrementaramos conforme a localizao. Para entender mel hor a internacionalizao, veja o Apndice A. Abaixo temos o exemplo completo da aplic ao que reutiliza componentes. 128 - AdvPl utilizando MVC
19.3 Exemplo completo de uma aplicao que reutiliza componentes de modelo e interfa ce #INCLUDE 'PROTHEUS.CH' #INCLUDE 'FWMVCDEF.CH' //------------------------------------------------------------------User Functio n COMP015_MVC() Local oBrowse oBrowse := FWMBrowse():New() oBrowse:SetAlias('ZA0') oBrowse:SetDescription( 'Ca dastro de Autor/Interprete' ) oBrowse:AddLegend( "ZA0_TIPO=='1'", "YELLOW", "Aut or" oBrowse:AddLegend( "ZA0_TIPO=='2'", "BLUE" oBrowse:Activate() , "Interprete" ) ) Return NIL //------------------------------------------------------------------Static Funct ion MenuDef() Local aRotina := {} ADD OPTION aRotina TITLE 'Visualizar' ACTION ' VIEWDEF.COMP015_MVC' OPERATION 2 ACCESS 0 ADD OPTION aRotina TITLE 'Incluir' ADD OPTION aRotina TITLE 'Alterar' ADD OPTION aRotina TITLE 'Excluir' ADD OPTION aR otina TITLE 'Imprimir' ADD OPTION aRotina TITLE 'Copiar' Return aRotina ACTION ' VIEWDEF.COMP015_MVC' OPERATION 3 ACCESS 0 ACTION 'VIEWDEF.COMP015_MVC' OPERATION 4 ACCESS 0 ACTION 'VIEWDEF.COMP015_MVC' OPERATION 5 ACCESS 0 ACTION 'VIEWDEF.CO MP015_MVC' OPERATION 8 ACCESS 0 ACTION 'VIEWDEF.COMP015_MVC' OPERATION 9 ACCESS 0 //------------------------------------------------------------------Static Funct ion ModelDef() // Cria a estrutura a ser acrescentada no Modelo de Dados Local o StruZA6 := FWFormStruct( 1, 'ZA6', /*bAvalCampo*/,/*lViewUsado*/ ) // Inicia o Model com um Model ja existente Local oModel := FWLoadModel( 'COMP01 1_MVC' ) // Adiciona a nova FORMFIELD oModel:AddFields( 'ZA6MASTER', 'ZA0MASTER', oStruZA 6 ) AdvPl utilizando MVC 129
// Faz relacionamento entre os compomentes do model oModel:SetRelation( 'ZA6MAST ER', { { 'ZA6_FILIAL', 'xFilial( "ZA6" )' }, { 'ZA6_CODIGO', 'ZA0_CODIGO' } }, Z A6->( IndexKey( 1 ) ) ) // Adiciona a descricao do novo componente oModel:GetModel( 'ZA6MASTER' ):SetDes cription( 'Complemento dos Dados de Autor/Interprete' ) Return oModel //------------------------------------------------------------------Static Funct ion ViewDef() // Cria um objeto de Modelo de Dados baseado no ModelDef do fonte informado Local oModel := FWLoadModel( 'COMP015_MVC' ) // Cria a estrutura a ser acrescentada na View Local oStruZA6 := FWFormStruct( 2 , 'ZA6' ) // Inicia a View com uma View ja existente Local oView := FWLoadView( 'COMP011_MVC' ) // Altera o Modelo de dados quer ser utilizado oView:SetModel( oModel ) // Adicio na no nosso View um controle do tipo FormFields(antiga enchoice) oView:AddField( 'VIEW_ZA6', oStruZA6, 'ZA6MASTER' ) // preciso criar sempre um box vertical dentro de um horizontal e vice-versa // como na COMP011_MVC o box horizontal, cria-se um vertical primeiro // Box existe nte na interface original oView:CreateVerticallBox( 'TELANOVA' , 100, 'TELA' ) // Novos Boxes oView:CreateHorizontalBox( 'SUPERIOR' , 50, 'TELANOVA' ) oView:Cr eateHorizontalBox( 'INFERIOR' , 50, 'TELANOVA' ) // Relaciona o identificador (ID) da View com o "box" para exibicao oView:SetOwn erView( 'VIEW_ZA0', 'SUPERIOR' ) oView:SetOwnerView( 'VIEW_ZA6', 'INFERIOR' ) Return oView 130 - AdvPl utilizando MVC
Apndice A O Framework MVC do Microsiga Protheus e a internacionalizao. Internacionalizao (I18N ) e localizao (L10N) so processos de desenvolvimento e/ou adaptao de softwares, para uma lngua e/ou cultura de um pas. A internacionalizao de um software no fornece um no vo Sistema, somente adapta as mensagens do Sistema lngua e cultura locais. A loca lizao por sua vez, adiciona novos elementos do pas ao Sistema, como processos, aspe ctos legais, entre outros. O Framework MVC auxilia a localizao do Sistema, compone ntizando o software de forma que a parte comum a todos os pases seja desagregada da parte no-comum, incluindo-se interface e regra de negcio. Por exemplo, tome com o base o formulrio Nota Fiscal/Invoice. Este formulrio tem como caracterstica comum em todos os pases os elementos: Origem, Destino, Lista de produtos, Transporte e Faturas. Em certos pases como o Brasil, necessrio registrar elementos legais, com o impostos, escriturao, cdigos de classificao, entre outros. A alternativa que se tem duplicar o cdigo ou alterar o cdigo inserindo linhas de cdigo dos elementos locali zados. Apesar de esta alternativa funcionar bem no inicio, ao longo do tempo mos tra-se impraticvel devido ao volume de implementaes diferentes para cada pas, causan do grandes transtornos e um alto custo para a sustentao do Sistema. O Framework MV C traz uma luz racional e simples para este problema. A herana de formulrios. possv el construir um formulrio comum para a Nota Fiscal/Invoice que no tenha nenhum ele mento de localizao e utiliz-lo pela herana, como base para os formulrios localizados. Neste modelo, garante-se a evoluo da localizao e da parte comum do formulrio sem que uma implementao afete a outra reduzindo o custo de sustentao do produto. AdvPl utilizando MVC 131
A herana do framework MVC pode ocorrer no Model e View ou somente no View. Neste momento vocs devem estar se perguntado como isto pode ser feito. A resposta esta no par de funes FWLoadModel e FWLoadView, como poder ser visto no cdigo abaixo: #INCLUDE MATA103BRA.CH Static Function ModelDef() Local oModel := FWLoadModel(MATA103) oModel:AddField(.. ..) oModel:AddGrid(....) Return(oModel) Static Function ViewDef() Local oView := FWLoadView(MATA103) oView:AddField() oView :AddGrid() Return (oView) H inmeras vantagens neste modelo de desenvolvimento que gostaria de destacar alm da componentizao, que o isolamento do cdigo fonte. O isolamento permite que os dois cd igos fontes evoluam separadamente, porm pela herana o cdigo localizado sempre ir her dar os benefcios da parte comum, inclusive possibilitando que duas pessoas intera jam simultaneamente no mesmo processo sem que um prejudique o trabalho do outro. 132 - AdvPl utilizando MVC
ndice Remissivo AddCalc ........................................................................ ........ 64 AddField ........................................................... 18, 24, 58, 127 AddFields ..................................................... ........... 16, 21, 126 AddGrid ................................................ .............. 21, 24, 30, 31 AddGroup ......................................... .................................... 48 AddIncrementField ...................... ......................................... 42 AddLegend ......................... .................................................. 11 AddLine .................. .............................................................. 34 AddOtherObject s.................................................................. 51 AddRules .............................................................................. 4 1 AddTrigger ................................................................... ......... 63 AddUserButton...................................................... ............... 43 AVG ......................................................... ............................. 65 AXALTERA ...................................... ....................................... 68 AXDELETA ............................ ................................................. 68 AXINCLI ................... .............................................................. 68 AXVISUAL...... ........................................................................ 68 Camp os de Total................................................................... 6 4 CommitData ................................................................... 85, 91 Contadores ............................................................. .............. 64 COUNT ........................................................ .......................... 65 CreateFolder...................................... ................................... 46 CreateHorizontalBox ..................... ......................... 18, 25, 127 CreateVerticalBox......................... .......................... 18, 25, 127 DeleteLine .............................. .............................................. 35 DisableDetails ............... ........................................................ 12 EnableTitleView .... ................................................................ 44 ForceQuitBut ton................................................................... 76 Frmula ................................................................................ 65 FWBrwRelation .............................................................. ...... 77 FWBuildFeature........................................................ ............ 61 FWCalcStruct ................................................... ..................... 67 FWExecView ............................................ ............................. 68 FWFormCommit .................................. ................................. 40 FWFormStruct .............................. ...... 14, 15, 16, 55, 126, 127 FWLoadMenudef .................................. ................................ 70 FWLoadModel ................................ ............ 17, 19, 24, 69, 124 FWLoadView .................................... ............................ 70, 124 FWMarkBrowse .............................. ...................................... 71 FWMemoVirtual ........................ ........................................... 62 FWModelActive ................... ................................................. 69 FWMVCMenu ................. .................................................. 9, 70 FWMVCRotAuto .......... ......................................................... 92 FWRestRows......... ................................................................ 36 FWSaveRows . ....................................................................... 36 FwStr uTrigger ....................................................................... 63 FWViewActive ............................................................... ....... 69 FwWsModel ........................................................... ............ 101 Gatilhos ...................................................... .......................... 63 GetErrorMessage .................................. ......................... 85, 91 GetModel ...................................... ....................................... 29 GetOperation ........................ ............................................... 39 GetSchema ................... ...................................................... 105 GetValue............. .................................................................. 37 GetXMLData
....................................................................... 104 GoL ine ............................................................................ ...... 33 Help ................................................................. ..................... 28 Internacionalizao ....................................... ..................... 131 IsDeleted ............................................ .................................. 33 IsInserted ............................... .............................................. 33 IsMark ....................... ........................................................... 72 IsOptional ...... ....................................................................... 36 IsUpd ated ........................................................................... .. 33 Length ................................................................... ............... 32 LinhaOk ..................................................... ........................... 30 LoadValue........................................ ..................................... 38 Mark .................................. ................................................... 72 MarkBrowse .............. ........................................................... 71 Master-Detail ... .................................................................... 20 Mensagen s ........................................................................... 28 MenuDef ...................................................................... 7, 8, 13 MODEL_OPERATION_DELETE .............................................. 4 0 MODEL_OPERATION_INSERT ............................................... 40 MODE L_OPERATION_UPDATE ............................................. 40 ModelDef ... .........................................7, 13, 15, 16, 20, 23, 27 Modelo1 ..... .................................................................. 20, 111 Model o2 ............................................................................. 111 Modelo3 ................................................................... .... 27, 111 MPFormModel ....................................................... ........ 15, 29 MSExecAuto ..................................................... .................... 92 New Model .............................................. ........................... 111 PARAMIXB ....................................... ..................................... 94 Pastas ................................ ................................................... 46 Pontos De Entrada ....... .................................................. 16, 94 PutXMLData ........... ............................................................ 105 RemoveField.... ..................................................................... 56 Rotina Automtica ............................................................... 82 SetD escription ................................................................ 16, 22 SetFieldAction .............................................................. ........ 51 SetFilterDefault ................................................... ................. 12 SetNoDeleteLine ........................................... ....................... 36 SetNoFolder ......................................... ................................ 64 SetNoGroups ................................ ........................................ 64 SetNoInsertLine .................... ................................................ 36 SetNoUpdateLine ............ ..................................................... 36 SetOnlyQuery .......... ............................................................. 39 SetOnlyView ... ...................................................................... 39 SetOpe ration .................................................................. 84, 89 SetOptional ................................................................... ....... 36 SetOwnerView ....................................................... 18, 26, 128 SetPrimaryKey ...................................................... ................ 22 SetProfileID ............................................... ........................... 76 SetProperty ..................................... ..................................... 56 SetRelation ........................... ........................................ 22, 127 SetSemaphore .................. .................................................... 72 SetUniqueLine .......... ............................................................ 30 SetValue ....... ........................................................................ 38 SetV iewAction ...................................................................... 50 SetViewProperty ............................................................
...... 45 SetVldActive ......................................................... ................ 32 STRUCT_FEATURE_INIPAD ...................................... ............. 62 STRUCT_FEATURE_PICTVAR ........................................ ......... 62 AdvPl utilizando MVC 133
STRUCT_FEATURE_VALID ..................................................... 62 ST RUCT_FEATURE_WHEN .................................................... 62 SUM .. ................................................................................ .... 65 TudoOk ................................................................. ................ 29 UnDeleteLine ............................................... ......................... 35 Validaes ............................................ ................................ 29 ViewDef .................................................7, 8, 17, 19, 24, 26, 2 7 VldData....................................................................... .... 85, 91 VldXMLData ......................................................... .............. 104 WebServices ................................................. ...................... 101 WsFwWsModel ......................................... ......................... 101 134 - AdvPl utilizando MVC