AdvPL Utilizando MVC v1 0 - ESP PDF
AdvPL Utilizando MVC v1 0 - ESP PDF
AdvPL Utilizando MVC v1 0 - ESP PDF
6.1 Construccin de estructuras para una aplicacin MVC con dos ms entidades ............. 2322
6.2 Construccin de la funcin ModelDef ............................................................... 2423
6.3 Creacin de un componente de formularios en modelo de dados (AddFields) .............. 2423
6.4 Creacin de un componente de grid en un Modelo de dados (AddGrid) .......................... 24
6.5 Creacin de relacin entre las entidades del modelo (SetRelation) ........................... 2524
6.6 Definicin de llave primaria (SetPrimaryKey) .................................................... 2625
6.7 Descripcin de los componentes del modelo de datos (SetDescription)...................... 2625
6.8 Finalizacin del ModelDef ............................................................................ 2726
6.9 Ejemplo completo del ModelDef .................................................................... 2726
6.10 Construccin de la funcin ViewDef .............................................................. 2726
6.11 Creacin de un componente de formularios en la interface (AddField) .................... 2827
6.12 Creacin de un componente de grid en la interfaz (AddGrid) ................................ 2827
6.13 Mostrar los datos en la interfaz (CreateHorizontalBox / CreateVerticalBox) ............. 2928
6.14 Relacionar el componente de la interfaz (SetOwnerView) .................................... 3028
6.15 Finalizacin del ViewDef............................................................................ 3029
6.16 Ejemplo completo de la ViewDef .................................................................. 3029
6.17 Finalizacin de la construccin de la aplicacin con dos ms entidades .................. 3130
17.1 Web Service para modelos de datos que tienen una entidad .............................. 107104
17.2 Instanciar el Client de Web Service ........................................................... 107104
17.3 La estructura del XML utilizada ................................................................ 107104
17.4 Obtener la estructura XML de un modelo de datos(GetXMLData) ........................ 110107
17.5 Informando los datos XML al Web Service ................................................... 110107
17.6 Validando los datos (VldXMLData) ............................................................ 110107
17.7 Validando la grabacin de los datos (PutXMLData) ......................................... 111108
17.8 Obteniendo el esquema XSD de un modelo de datos (GetSchema) ....................... 111108
17.9 Ejemplo completo de Web Service ............................................................. 112109
17.10 Web Services para modelos de datos que tienen dos ms entidades ................ 113110
18.Uso del comando New Model ......................................................................115112
Apndice A ...............................................................................................134131
Aquellos que ya han desarrollado una aplicacin en ADVPL podrn percibir que
justamente la diferencia ms importante entre la forma de construir una aplicacin en
MVC y la forma tradicional, es esa separacin.
Los desarrolladores en sus aplicaciones sern los responsables por definir las siguientes
funciones:
Cada fuente en MVC (PRW) slo puede contener uno de estos de cada uno una de estas
funciones. Solo Slo puede tener una ModelDef, una ViewDef y una MenuDef.
Podr ser utilizada,Se podr utilizar de la misma forma que la rutina automtica de
aplicaciones sin MVC.
Todos los entes Todas las entidades (Tablas) que sern formarn parte del
modelo de dados (Model);).
La funcin ViewDef define como ser la interfaz y, por tantopor lo tanto, como el
usuario interacta con el Modelo modelo de datos (Model) recibiendo los datos
informados por el usuario, proveyendo suministrando al el modelo de datos (definido
en ModelDef)y presentando los resultados.
Una funcin MenuDef define las operaciones que sern realizadas por la
aplicacin, tales como incluirIncluir, alterarModificar, excluirBorrar, etc.
1. Ttulo;.
3. Reservado;.
- 2 para Visualizar
- 3 para Incluir
- 6 para Imprimir
- 7 para Copiar
5. Nivel de acceso;.
Local aRotina := {}
Return aRotina
Return aRotina
Por ejemplo:
Esto creara un Menudef igual que el ejemplo anterior. Para ms detalles vase
el captulo 12.7 Creacin de un men estndar (FWMVCMenu).
Esta clase muestra un objeto Browse que es construido a partir dese crea utilizando
metadatos (diccionarios).
oBrowse := FWMBrowse():New()
oBrowse:SetAlias('ZA0')
oBrowse:SetDescription('Cadastro de Autor/Interprete')
oBrowse:Activate()
Bsqueda de Registro; .
Filtro configurable; .
Configuracin de columnas y apariencia;.
Impresin.
3.3 Leyendas de un Browse (AddLegend)
Ejemplo:
Observaciones:
SetFilterDefault ( <filtro> )
Ejemplo:
oBrowse:SetFilterDefault( "ZA0_TIPO=='1'" )
o
oBrowse:SetFilterDefault( "Empty(ZA0_DTAFAL)" )
Ejemplo:
Si en la aplicacin fue definido que solo muestre los clientes que sonse defini que se
mostrarn slo las personas jurdicas, y si el usuario hace un filtro para que le
muestremostrar solamente los clientes del estado de So Paulo, entonces se mostrar
mostrarn los clientes jurdicos del estado de So Paulo. Fue ejecutado el filtro del
usuario y sigue siendo respetadoSe ejecut el filtro del usuario pero respetando el
filtro original de la aplicacin.
Ejemplo:
oBrowse:DisableDetails()
Por tantoPor lo tanto, siempre utilice la funcin POSICIONE para mostrar campos
virtuales.
// Definio da legenda
oBrowse:AddLegend( "ZA0_TIPO=='1'", "YELLOW", "Autor" )
oBrowse:AddLegend( "ZA0_TIPO=='2'", "BLUE" , "Interprete" )
// Definio de filtro
oBrowse:SetFilterDefault( "ZA0_TIPO=='1'" )
// Titulo da Browse
oBrowse:SetDescription('Cadastro de Autor/Interprete')
// Ativao da Classe
oBrowse:Activate()
Return NIL
Las estructuras son objetos que contienen las definiciones de los datos necesarios para
utilizar el ModelDef o para el ViewDef.
Donde:
Ejemplo:
En el ejemplo, el objeto oStruZA0 ser una estructura para usoque se utilizar en una
interfaz (View). El primer parmetro (2) indica que la estructura es para definir
una interfaz y el segundo parmetro indica la tabla de los metadatos que ser
utilizada para la definicin dese utilizar para definir la estructura (ZA0).
Ms adelante veremos cmo definir estructuras manualmente y como seleccionar los
campos que formarn parte de las estructuras y otros tratamientos especficos de la
estructura.
Debemos dar un identificador (ID) para el modelo como un todo y tambin uno
para cada componente.
Ejemplo:
Al final de una funcin de ModelDef, debe ser retornadose debe devolver el objeto de
modelo de datos (Model) generado en la funcin.
Return oModel
oView:SetModel( oModel )
Debemos dar un identificador (ID) para cada componente de interface interfaz (View).
Debemos dar un identificador (ID) para cada componente de interface interfaz (View).
1
Determinada rea definida por el desarrollador para agrupar
componentes visuales, por ejemplo, Panel, Dialog, Window, etc etc.
Return oView
// Interfaz de visualizacin
Local oView
// Crea el objeto del View
oView := FWFormView():New()
oView:SetModel( oModel )
// Adiciona en nuestra View un control de tipo formulrio
// (antigua Enchoice)
Return oView
De esta forma crearemos una aplicacin de AdvPL utilizando + donde solo slo hay
una entidad involucrada.
Construimos el ModelDef;
Construimos el ViewDef.
Esta aplicacin sera el equivalente a las aplicaciones de del tipo Modelo1 que
normalmente son realizadas.
Ms adelante veremos la construccin de aplicaciones utilizando dos o ms
entidadesentes.
La construccin creacin de las aplicaciones, seguirn los mismos pasos que vimos
con anterioridad: Construccin Creacin del ModelDef y de la ViewDef. La
diferencia bsica que hay ahora es que cada una de ellas podr tener ms de un
componente y estarn relacionados.
En el ejemplo anterior el objeto oStruZA1, ser una estructura para ser utilizadaque
se utilizar en un Modelo de datos (Model) para la entidadel ente Master
(PadrePrincipal) y oStruZA2 para la entidadel ente Detalle (HijoSecundario).
Observe que en el dicho cdigo, se crearon 2 estructuras, una para cada entidadente.
Debemos dar un identificador (ID) para el Modelo de datos (Model) y para cada
componente del Model.
Debemos dar un identificador (ID) para cada componente del Model. Formatado: Fonte: Itlico
ZA1MASTER es un identificador (ID) del formulario en el Model, oStruZA1 es la Formatado: Fonte: Itlico
estructura que ser utilizadase utilizar en el formulario y que fue construida
anteriormente utilizando FWFormStruct, note que el segundo parmetro (Owner) no
fue informado, esto porque este es el 1er componente del Model, es el componente Formatado: Fonte: Itlico
padre principal del modelo de datos (Model) y, por tantopor lo tanto no tiene un Formatado: Fonte: Itlico
componente superior u owner.
Cuando una entidadun ente ocurra n veces en el modelo en con relacin a otraal
otro, debemos definir un componente de Grid para esta entidaddicho ente.
Dentro del modelo debemos relacionar todas las entidadesa todos los entes que
participan de len el mismo. En nuestro ejemplo tenemos que relacionar la entidadel
ente Detail con la entidadel ente Master.
Una regla de oro simplemuy sencilla para entender esto es: Toda entidadTodo ente
de del modelo que tiene un superior (owner) debe tener su relacin para el
hijodefinida para ste. En otras palabras, es necesario decir cules son las llaves claves
de relacin del hijo para el padrede la relacin que existe entre los detalles y el
principal.
Ejemplo:
oModel:SetRelation( 'ZA2DETAIL', { { 'ZA2_FILIAL',
'xFilial( "ZA2" )' }, { 'ZA2_MUSICA', 'ZA1_MUSICA' } },
ZA2->( IndexKey( 1 ) ) )
El modelo de datos necesita que siempre se informe cual es la llave clave primaria
para la entidadel ente principal del modelo de datos (Model).
Ejemplo:
oModel: SetPrimaryKey( { "ZA1_FILIAL", "ZA1_MUSICA" } )
Donde Aqu, el parmetro pasado que se pas es un vector con los campos que
componen la llave clave primaria. Use este mtodo solo slo si es necesario.
Siempre defina la llave clave primaria para el modelo. Si realmente no fue posible
crear una llave clave primaria para la entidadel ente principal, informe el modelo de
datos de la siguiente forma:
oModel: SetPrimaryKey( {} )
Defina siempre una descripcin para los componentes del modelo. Con el mtodo
SetDescription agregamos la descripcin del Modelo de DadosDatos, esa
descripcin ser utilizadase utilizar en varios lugares como en Web Services por
ejemplo.
Note que de esta manera definimos una descripcin para el modelo y una para cada
componente del modelo.
6.8 Finalizacin del ModelDef
Al final de la funcin ModelDef, debe ser retornadose debe devolver el objeto del
Modelo de datos (Model) generado en la funcin.
Return oModel
COMP021_MVC es el nombre del fuente de donde queremos obtener el model. Formatado: Fonte: Itlico
Definimos cual es el Modelo de datos (Model) que ser utilizadose utilizar en la interfaz
(View).
oView:SetModel( oModel )
Observacin: Note que aqu no hablamos comentamos sobre que entidad ente
es superior a cualotro, esto es porque esta dicha funcin es del modelo de datos. La
interfaz (View) solo slo refleja los datos del modelo.
En MVC crearemos siempre un box horizontal o vertical para esto. El mtodo para la
construccin decrear un box horizontal es:
oView:CreateHorizontalBox( 'SUPERIOR', 15 )
oView:CreateHorizontalBox( 'INFERIOR', 85 )
Observacin: La suma de los porcentajes de los dos boxes del mismo nivel deber ser
siempre 100%.
Obs.: Note que los datos de entidad padredel ente principal ocuparn el 15% de la
pantalla y la entidad hijoel ente secundario el 85%, porque:
Return oView
// Interfaz de visualizacin
Local oView
// Crea un objeto de View
oView := FWFormView():New()
oView:SetModel( oModel )
oView:CreateHorizontalBox( 'SUPERIOR', 15 )
oView:CreateHorizontalBox( 'INFERIOR', 85 )
De esta forma manera construimos una aplicacin de AdvPL utilizando MVC donde hay
2 entidades involucradasentes involucrados.
Construimos la el ModelDef;
Construimos la el ViewDef.
Esta aplicacin ser el equivalente a las aplicaciones de del tipo Modelo3 que
normalmente son construidaspor lo general se crean.
El modelo de datos y la interfaz crece crecen en la medida en que crecen crece las la
cantidades cantidad de entidades relacionadasentes relacionados. Pero la forma bsica
de construccin es siempre la misma.
Ejemplo:
Validaciones;,
Permisos;,
Movimientos en Lneas;,
Obtener y atribuir valores;,
Persistencia de los datos;,
Crear botones;,
Crear folders; , etc.
Validaciones; .
Comportamientos; .
Manipulacin del Grid.
Obtener y atribuir valores en el modelo de dados (Model); ).
Grabacin de los datos manualmente; .
Reglas de llenado.
Los mensajes son usadosse utilizan principalmente durante las validaciones realizadas
en el modelo de datos.
Vamos a analizarAnalisemos: Un ponto punto bsico de MVC es la separacin de la
regla de negocio de la interfaz de usuario.
La validacin es un proceso ejecutado dentro de la regla de negocio en un eventual
mensaje de error que ser mostradose mostrar a los usuarios, es un proceso que
debe ser ejecutadose debe ejecutar en la interfaz, es decir, no puede ser ejecutado en
la regla de negocios.
Para trabajar esamanejar esta situacin fue realizadose hizo un tratamiento para la
funcin Help.
La funcin Help podr ser utilizadase utilizar en las funciones dentro del modelo de
datos (Model), pero el MVC ir a guardarguardar ese este mensaje y esta sta solo
slo ser mostradose mostrar cuando el control vuelva para a la interfaz.
Este tratamiento fue realizado solo slo se realiza para la funcin Help, funciones
como MsgStop, MsgInfo, MsgYesNo, Alert, MostraErro, etc. No podrn ser
utilizadasse utilizarn.
8.3 Validaciones
Dentro del modelo de datos existentes hay varios puntos donde pueden ser
insertadas las validaciones necesariasexisten varios puntos que permiten insertar las
validaciones necesarias para a la regla del negocio. El modelo de datos (Model) como
un todo tiene sus propios puntos y cada componente de del modelo, tambin sus
puntostambin los tiene.
La funcin llamada por el bloque de cdigo debe retornar un valor lgico, donde si es
.T. (verdadero) la operacin es realizadase realiza, si es .F. (falso) la operacin no se
realiza.
El bloque de cdigo recibe como parmetro un objeto que es la parte del modelo
correspondiente al grid y que puede ser pasado parase puede pasar a la funcin que
har la validacin.
La funcin llamada por el bloque de cdigo debe retornar un valor lgico, donde si .T.
(verdadero) cambia de lnea y significa que es realizadase realiza la operacin y si es .F.
(falso) no se realiza el cambio de lnea.
El mtodo del modelo de datos (Model) que debe ser utilizadose debe utilizar es
SetUniqueLine.
001 01/01/11 Ok
001 02/01/11 Ok
002 02/01/11 Ok
En un modelo de datos donde existen componentes de grid puede ser definidase puede
definir una validacin que ser ejecutadase ejecutar en mas las acciones
actividades de las lneas del grid. Podemos entender por estas acciones
actividades la asignacin atribucin de valores, apagar borrar o recuperar una lnea.
El campo donde se est asignandoal que se est atribuyendo el valor, para declaracin y
recuperacin deborrar y recuperar la lnea no es pasadose transfiere.
Esos Dichos parmetros pueden ser pasados parase deben pasar a la funcin que har
lase encargar de la validacin.
La funcin llamada por el bloque de cdigo debe retornar un valor lgico, donde si es .T.
(verdadero) cambia de lnea y si es .F. (falso) no la cambia.
Return lRet
La funcin llamada por el bloque de cdigo debe retornar un valor lgico, donde si es
.T. (verdadero) la activacin es realizadase realiza y si es .F. (falso) no es realizadase
realiza.
Veremos ahora algunos tratamientos que pueden ser realizadosse pueden realizar
en los componentes de grid de un modelo de datos (Model).
Para obtener el nmero de lneas del grid debemos utilizar el mtodo Length. Las
lneas apagadas borradas tambin son consideradas en el conteose consideran en el
cmputo.
Static Function COMP021POS( oModel )
Local lRet := .T.
Local oModelZA2 := oModel:GetModel( 'ZA2DETAIL' )
Local nI := 0
For nI := 1 To oModelZA2:Length()
// Sigue la Funcin ...
Next nI
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
// Sigue la funcin ...
Next nI
Cuando estamos hablandohablamos del modelo de datos (Model) tenemos 3 Formatado: Fonte: Itlico
operaciones bsicas: Incluir, Modificar y Borrar.
En MVC es posible saber que operaciones de ha sufrido una lnea han sufrido por en los
siguientes mtodos de statusestatus:
Local nI := 0
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
If oModelZA2:IsDeleted()
nCtDel++
ElseIf oModelZA2:IsInserted()
nCtInc++
ElseIf oModelZA2:IsUpdated()
nCtAlt++
EndIf
Next
Para agregar una lnea a un componente de grid del modelo de datos (Model) Formatado: Fonte: Itlico
utilizamos el mtodo AddLine.
nLinha++
If oModelZA2:AddLine() == nLinha
// Segue a funo
EndIf
El mtodo AddLine retorna devuelve la cantidad de total de lneas del grid. Si el grid
ya tiene 2 lneas y todo lo dems ha ido resultado bien en la adicin deal agregar la
lnea, el AddLine devolver 3, si ha ocurrido un problema devolver 2, ya que la
nueva fila lnea no se ha insertado.
Los motivos para que la inclusin no sea correcta podrn ser quehaya tenido xito,
debe ser por que algn campo obligatorio no se ha informado, la pos-
validacinpostvalidacin de la lnea retorno volvi .F. (falso), alcanzo alcanz la
cantidad mxima de lneas para el grid, por mencionar algunasejemplo.
Para apagar borrar una lnea de un componente de grid del modelo de datos (Model) Formatado: Fonte: Itlico
utilizamos el mtodo DeleteLine.
If !oModelZA2:IsDeleted()
oModelZA2:DeleteLine()
EndIf
Next
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
If oModelZA2:IsDeleted()
oModelZA2:UnDeleteLine()
EndIf
Next
El mtodo UnDeleteLine retorna .T. (verdadero) si la recuperacin fue realizada
con xito. Un motivo para que no lo sea es que la pre-validacinprevalidacin de la
lnea retorne .F. (falso).
Si quisiramos limitar para que una lnea de un grid se pueda ser insertadaincluir,
modificada apagadamodificar o borrar, para hacer una consulta, por ejemplo,
utilizamos uno de los mtodos abajo:
Ejemplo:
oModel:GetModel( 'ZA2DETAIL' ):SetNoInsertLine( .T. )
Ejemplo:
oModel:GetModel( 'ZA2DETAIL' ):SetNoUpdateLine( .T. )
Ejemplo:
oModel:GetModel( 'ZA2DETAIL' ):SetNoDeleteLine( .T. )
Por estndar, cuando tenemos un modelo de datos (Model) donde hay un componente
de grid, debe ser informadase debe informar por lo menos una lnea en este grid.
En este caso utilizamos el mtodo SetOptional para permitir que el grid tenga
o no por lo menos una lnea digitada, es decir, para decir considerar que la
introduccin digitacin de datos del grid es opcional.
Este mtodo debe ser informadose debe informar al definir el modelo de datos (Model).
Ejemplo:
oModel:GetModel( 'ZA2DETAIL' ):SetOptional( .T. )
Un cuidado que debemos tener cuando escribimos una funcin, mismo queaunque no
sea para uso en MVC, es restaurar las reas de las tablas que des
posicionamosdescolocamos.
Del mismo modo, debemos tener el mismo cuidado para los componentes
del grid que des posicionamosdescolocamos en una funcin, como el uso del mtodo
GoLine, por ejemplo.
Ejemplo:
Static Function COMP23ACAO()
For nI := 1 To oModelZA2:Length()
oModelZA2:GoLine( nI )
// Sigue la Funcin.
Next
FWRestRows( aSaveLine )
GetValue: Obtiene un dato del modelo de datos (Model). Podemos obtener el dato a
partir del modelo completo o a partir de su componente.
SetValue: Asignar Atribuir un dato del modelo de dados (Model). Podemos asignar
atribuir un dato a partir del modelo completo o a partir de algn componente.
LoadValue: Cargar un dato del modelo de dados (Model). Podemos asignar atribuir
el dato a partir del modelo completo o a partir de una parte de leste.
oModelZA2:LoadValue('ZA1_MUSICA', '000001' )
Ejemplo:
oModel:GetModel( 'ZA2DETAIL' ):SetOnlyView ( .T. )
Ejemplo:
Para saber la operacin con que un modelo de datos (Model) est trabajando,
utilizamos el mtodo GetOperation.
Return lRet
# INCLUDE 'FWMVCDEF.CH'
Para las operaciones del modelo de datos (Model) pueden ser utilizados:
La grabacin de los datos del modelo de datos (Model) es realizada por MVC donde son
grabados todos los datos de las entidadeslos entes del model.
Para este tipo de situacin es posible intervenir el momento de la grabacin de los datos.
El bloque de cdigo recibe como parmetro un objeto que es el modelo y que puede
ser pasado a la funcin que har la grabacin.
A diferencia de los bloques de cdigo definidos en el modelo de datos (Model) para
validacin, que complementan las validaciones hechas por el MVC, el bloque de
cdigo para grabacin reemplaza la grabacin de los dados. Entonces al ser
definido un bloque de cdigo para grabacin, pasa ser responsabilidad de la funcin
creada, la grabacin de todos los datos inclusive incluso los dados del modelo de datos
en uso.
FWFormCommit( oModel )
Una nueva caracterstica que fue implementadase implement en MVC son las reglas
de llenadopara completar, donde el llenado de un campo depende del llenadocompletar
um campo depende de cmo se complete de el otro.
Por ejemplo, podemos definir que en el campo Cdigo de Loja de una entidadesun
ente, solo puede ser informado despus del llenado delde completar el campo Cdigo
de del Cliente.
Tipo 1 Pre-ValidacinPrevalidacin
Tipo 2 Pos-Validacin
Ejemplo:
oModel:AddRules( 'ZA3MASTER', 'ZA3_LOJA', 'ZA3MASTER', 'ZA3_DATA', 1 )
Donde elEl ZA3MASTER es el identificador (ID) del componente del modelo de datos
(Model) donde est el campo de destino, el ZA3_LOJA es el campo destino, el
segundo ZA3MASTER es del componente del modelo de datos (Model) donde est
el campo de origen, y ZA3_DATA es el campo de origen.
9. Tratamientos de la interfaz
Veremos algunos tratamientos que pueden ser realizados en la interfaz (View)
conforme asegn las necesidades.
Creacin de botones;
Creacin de folders;
Agrupamiento Agrupacin de campos;
Incremento de campos;
Etc.
Visualmente tenemos:
Importante: Este comportamiento solo acontecesolamente ocurre cuando la
aplicacin est siendo utilizada por la interfaz (View). Cuando el modelo de datos es
usadose utiliza directamente (Web Services, rutinas automticas, etc.) el campo
incremental tiene que ser informado normalmente.
Ejemplo:
oView:AddUserButton( 'Inclui Autor', 'CLIPS', {|oView| COMP021BUT()} )
2
RPO - Repositorio do del Microsiga Protheus para aplicaciones e imgenes.
Ejemplo:
oView:EnableTitleView('VIEW_ZA2','Musicas')
oView:EnableTitleView('VIEW_ZA2')
Donde el titulo que ser mostradose mostrar es el que fue definidose defini en el
mtodo SetDescription del modelo de datos (Model) para el componente.
Visualmente tenemos:
Una nueva caracterstica que el MVC tiene, en el uso de la interfaz, es para que un
componente de grid, hacer haga lo mismo durante laal mismo tiempo la edicin de
datos directamente en el grid y/ en una pantalla del layout de formulario.
Ejemplo:
Ejemplo:
oView:CreateFolder( 'PASTAS' )
Debemos dar un identificador (ID) para cada componente de la interfaz (View).
PASTAS CARPETAS es un identificador (ID) dado que se da al foldera la carpeta.
Resumiendo:
oView:CreateFolder( 'PASTAS' )
Cuando los folderlas carpetas son definidosse definen utilizando los metadados
metadatos (diccionarios), automticamente la interfaz (View) crea estos foldersestas
carpetas. Si el componente colocado en una de las pestaas solapas tiene folders
carpetas definidos definidas en los metadadosmetadatos, estos foldersdichas carpetas
sern creadosse crearn dentro de la pestaa solapa donde l ste se encuentra.
Visualmente tenemos:
9.6 Agrupamiento Agrupacin de campos
(AddGroup)
Una nueva caracterstica que el MVC tiene para el uso de la interfaz, para un
componente de formulario, es hacer un agrupamientouna agrupacin de los campos en
la pantalla.
Por ejemplo, en un cadastro archivo de clientes podemos tener los campos para la
direccin de entrega, correspondencia y facturacin. Para una visualizacinvisualizar
mejor podramos agrupar los campos de cada direccin.
Ejemplo:
oStruZA0:AddGroup( 'GRUPO01', 'Alguns Dados', '', 1 )
oStruZA0:AddGroup( 'GRUPO02', 'Outros Dados', '', 2 )
Visualmente tenemos:
Donde:
Ejemplo:
Importante: Estas acciones son ejecutadas cuando existe una interfaz (View). Lo
que no ocurre cuando tenemos la instancia directa del modelo, rutina automtica
o Web Service. Se debe evitar entonces colocar en estas funciones acciones que
Existe en MVC la posibilidad de ejecutar una funcin desde la validacin del campo de
algn componente del modelo de datos (Model).
Este recurso puede ser utilizado cuando queremos ejecutar algo en la interfaz y
que no tiene reflejo en el modelo, como un Refresh de la pantalla abrir una pantalla
auxiliar, por ejemplo.
Sintaxis:
Donde:
Objeto de la View
El identificador (ID) de la View
El identificador (ID) del Campo
Contenido del Campo
Ejemplo:
Importante:
Estas acciones son ejecutadas solo cuando existe una interfaz (View). Lo que
no ocurre cuando tenemos la instancia directa del modelo, rutina automtica
Web Service.
Ejemplo:
A continuacin sigue un ejemplo del uso del mtodo, donde colocamos en una seccin
de la interfaz (View) 2 botones. Observe los comentarios en el fuente:
oView := FWFormView():New()
oView:SetModel( oModel )
// bBloco - Bloco llamado, deber ser utilizado para crear los objetos de la
pantalla externa MVC.
Return oView
//-------------------------------------------------------------------
Static Function COMP23BUT( oPanel )
Local lOk := .F.
Return NIL
Visualmente tenemos:
10. Tratamientos de estructuras de datos
Como se dijo anteriormente, en MVC no se trabaja vinculado a los metadatos de
Microsiga Protheus, el este trabaja vinculado a estructuras. Estas estructuras, a su vez
pueden ser construidas a partir de metadados metadatos (diccionarios).
Veremos algunos tratamientos que pueden ser realizados en las estructuras conforme
a las necesidades.
El bloque de cdigo debe retornar un valor lgico, donde si es .T. (verdadero) el campo
ser parte de la estructura, si es .F. (falso) el campo no ser parte de la estructura.
Ejemplo:
If cCampo == 'ZA0_QTDMUS'
lRet := .F.
EndIf
Importante: Este tratamiento puede ser realizado tanto para las estructuras que
sern utilizadas en el modelo de datos (Model) como tanto para enpara la interfaz
(View).
Ejemplo:
Local oStruZA0 := FWFormStruct( 2, 'ZA0')
oStruZA0: RemoveField('ZA0_QTDMUS')
Importante: Este tratamiento puede ser realizado tanto para las estructuras que
sern utilizadas en el modelo de datos (Model) tanto como en la interfaz (View).
Donde, el 1er parmetro es el nombre del campo que se desea modificar o asignar
atribuir una propiedad el 2do es la propiedad que es modificada o asignada y el 3ero
es el valor para la propiedad.
Las propiedades para los campos de la estructura del modelo de datos (Model) son:
MODEL_FIELD_TITULO C Titulo
MODEL_FIELD_TOOLTIP C Descripcin completa del campo
MODEL_FIELD_IDFIELD C Nombre (ID)
MODEL_FIELD_TIPO C Tipo
MODEL_FIELD_TAMANHO N Tamao
MODEL_FIELD_DECIMAL N Decimales
MODEL_FIELD_VALID b Validacin
MODEL_FIELD_WHEN B Modo de edicin
Lista de valores permitido del campo
MODEL_FIELD_VALUES A
(combo)
MODEL_FIELD_OBRIGAT L Indica si el campo es obligatorio
MODEL_FIELD_INIT B Inicializador estndar
MODEL_FIELD_KEY L Indica si el campo es llave
Indica si el campo puede recibir valor en
MODEL_FIELD_NOUPD L
una operacin de Update.
MODEL_FIELD_VIRTUAL L Indica si el campo es virtual
#INCLUDE 'FWMVCDEF.CH'
Tambin es posible asignar atribuir una propiedad para a todos los campos de una
estructura utilizando en el nombre del campo un asterisco "*"
Donde:
Donde:
cOrdem Orden;
cPicture Picture;
Ejemplo de su uso:
Obs.: Los campos de tipo lgico sern mostrados como un checkbox en la interfaz
(View)
Ejemplo:
FwBuildFeature( STRUCT_FEATURE_VALID,"Pertence('12')" )
Las propiedades que necesitan ser tratadas con esta funcin son:
#INCLUDE 'FWMVCDEF.CH'
Algunos campos de tipo MEMO utilizan tablas para la grabacin de sus valores
(SYP3), esos campos deben ser informados en la estructura para que en MVC
se pueda hacer su tratamiento correctamente.
Ejemplo:
FWMemoVirtual( oStruZA1,{ { 'ZA0_CDSYP1' , 'ZA0_MMSYP1' } , {
'ZA0_CDSYP2' , 'ZA0_MMSYP2' } } )
3
SYP - Tabla de Microsiga Protheus que almacena los datos de los campos de tipo MEMO virtuales
Para estos campos MEMO siempre debe hacer haber otro campo que contenga el
cdigo con que el campo MEMO fue almacenado en la tabla auxiliar.
La sintaxis es:
Donde:
La sintaxis es:
Donde:
aAux := FwStruTrigger(;
'ZA2_AUTOR' ,;
'ZA2_NOME' ,;
'ZA0->ZA0_NOME'..,;
.T... ..................... ...,;
'ZA0'... ............... .. ,; Formatado: Portugus (Brasil)
1... ......................... ,;
'xFilial("ZA0")+M->ZA2_AUTOR')
Se quisiramos retirar las carpetas que estn configuradas en una estructura, por
ejemplo, por el uso de la funcin FWFormStruct, usamos el mtodo SetNoFolder.
De la siguiente forma:
La sintaxis es:
Donde:
Ejemplo:
Ejemplo:
Donde:
Ejemplo:
Esta funcin instancia crea la interface interfaz (View) y por consiguiente el modelo de
datos (Model) con las operaciones de visualizar, incluir, alterar modificar o
excluirborrar. La intencin es hacer similarmente de manera similar lo que
hacan las funciones AXVISUAL, AXINCLI, AXALTERA y AXDELETA.
Sintaxis:
Donde:
Ejemplo:
FWModelActive( oModelBkp )
Formatado: Espanhol (Espanha -
12.3 Interface Interfaz activa (FWViewActive) tradicional)
Formatado: Espanhol (Espanha -
tradicional)
Formatado: Espanhol (Espanha -
En una aplicacin podemos trabajar con ms de una interfaz (View). La funcin tradicional)
FWViewActive retorna la interfaz (View) que est activa en el momento.
Formatado: Espanhol (Espanha -
tradicional)
Ejemplo:
FWViewActive(oViewBkp)
FWLoadModel( 'COMP011_MVC' )
Sintaxis:
Ejemplo:
Static Function ViewDef()
// Utilizando una view que ya existe en otra aplicacin
Return FWLoadView( 'COMP011_MVC' )
Sintaxis:
Ejemplo:
Static Function MenuDef()
// Utilizando un men que ya existe en otra aplicacin
Return FWLoadMenuDef( 'COMP011_MVC' )
Sintaxis:
Ejemplo:
//--------------------------------------
--
oMark := FWMarkBrowse():New()
Se define la tabla que aparece en Browse con el mtodo SetAlias. Las columnas,
rdenes, etc., para mostrarlos, sern obtenidas a travs de los metadatos
(diccionarios)).
oMark:SetAlias('ZA0')
oMark:SetFieldMark( 'ZA0_OK' )
oMark:Activate()
Por el momento solo se tiene una columna de marcado, ahora se tiene que definir una
accin para los tems marcados. Para esto, podemos colocar un MenuDef de la
aplicacin a la funcin que tratar a los tems marcados.
Y para saber si el registro est marcado usamos el mtodo IsMark pasando como
parmetro la marca.
If oMark:IsMark(cMarca)
// Instanciamiento de la clase
oMark := FWMarkBrowse():New()
// Define a leyenda
// Activacin de la clase
oMark:Activate()
Return NIL
//-------------------------------------------------------------------
Static Function MenuDef()
Local aRotina := {}
Return aRotina
//-------------------------------------------------------------------
Static Function ModelDef()
// Utilizando um model que ja existe Formatado: Portugus (Brasil)
//---------------------- ---------------------------------------------
Static Function ViewDef()
// Utilizando uma View que ja existe
//-------------------------------------------------------------------
User Function COMP25PROC()
Local aArea := GetArea()
Local cMarca := oMark:Mark()
Local nCt := 0
ZA0->( dbGoTop() )
While !ZA0->( EOF() )
If oMark:IsMark(cMarca)
nCt++
EndIf
ZA0->( dbSkip() ) Formatado: Portugus (Brasil)
End
Return NIL
Visualmente tenemos:
14. Mltiples Browses
Como en el uso de la clase FWmBrowse podemos escribir aplicaciones con ms de un
objeto de esta clase, es decir, podemos escribir aplicaciones que trabajarn con
mltiples Browses.
Podemos por ejemplo desarrollar una aplicacin para los pedidos de venta, donde
tendremos un Browse con los encabezados de los tems, otra con los tems en la
misma pantalla y conforme vamos navegando por los registros del Browse de
encabezado, automticamente los tems son actualizados en el otro Browse.
Primero creamos una pantalla Dialog comn, cada uno de los Browses deben
estar anclados fijados en un objeto contenedor, para esto usaremos la funcin
FWLayer con 2 lneas y en una de esas lneas colocaremos 2 columnas.
//
// Crea contenerdor donde sern colocados los browses
//
oFWLayer := FWLayer():New()
oFWLayer:Init( oDlgPrinc, .F., .T. )
oFWLayer:AddLine( 'DOWN', 50, .F. )// Crea una "linha" con 50% de la pantalla
oFWLayer:AddCollumn( 'LEFT' , 50, .T., 'DOWN' )// En la "linha" creada ,se crea una
columna con el 50% de su tamao
oFWLayer:AddCollumn( 'RIGHT', 50, .T., 'DOWN' ) // En la "linha" creada, se crea
una columna con el 50% de su tamao
oPanelLeft := oFWLayer:GetColPanel( 'LEFT' , 'DOWN' ) // Pego el objeto del lado
izquierdo
oPanelRight := oFWLayer:GetColPanel( 'RIGHT', 'DOWN' ) // Pego el objeto den el
pedazo derecho
//
// FWmBrowse Superior Albuns
//
oBrowseUp:= FWmBrowse():New()
oBrowseUp:SetOwner( oPanelUp ) // Aqui se associa o browse ao
//componente de tela Formatado: Portugus (Brasil)
El mtodo ForceQuitButton hace que el botn Salir se muestre en las opciones del
Browse. Como habr ms de un Browse el botn Salir no ser colocado
automticamente en ninguno de ellos, este mtodo hace que aparezca en el
Browse.
Note tambin, que utilizamos el mtodo SetMenuDef para definir de cual fuente
deber ser utilizado para ael fuente que se utilizar para obtener el MenuDef.
Cuando no utilizamos el SetMenuDef automticamente el Browse busca el propio
fuente donde se encuentra el Menudef a ser usadoque se utilizar.
oBrowseLeft:= FWMBrowse():New()
oBrowseLeft:SetOwner( oPanelLeft )
oBrowseLeft:SetDescription( 'Musicas' )
oBrowseLeft:SetMenuDef( '' ) // Referencia vazia para que nao
// exiba nenhum boto
oBrowseLeft:DisableDetails()
oBrowseLeft:SetAlias( 'ZA4' )
oBrowseLeft:SetProfileID( '2' )
oBrowseRight:= FWMBrowse():New()
oBrowseRight:SetOwner( oPanelRight )
Formatado: Ingls (Estados Unidos)
oBrowseRight:SetDescription( 'Autores/Interpretes' )
Formatado: Ingls (Estados Unidos)
oBrowseRight:SetMenuDef( '' ) // Referencia vazia para que nao funcao
Formatado: Ingls (Estados Unidos)
// exiba nenhum botao
Formatado: Portugus (Brasil)
oBrowseRight:DisableDetails()
Formatado: Ingls (Estados Unidos)
oBrowseRight:SetAlias( 'ZA5' )
oBrowseRight:SetProfileID( '3' )
oBrowseRight:Activate()
Note que en estoy estos Browses utilizamos el mtodo SetMenuDef con una
referencia vaca, como queremos que el Browse principal tenga botones de
accin, si no definimos el SetMenuDef, automticamente, el Browse busca el
propio fuente donde se encuentra y con la referencia vaca no son mostrados los
botoneslos botones no aparecen.
Ahora que definimos los Browses necesitamos relacionarlos entre ellos, para que al
efectuar el movimiento en uno, automticamente, los otros sean actualizados.
oRelacZA5:= FWBrwRelation():New()
oRelacZA5:AddRelation( oBrowseLeft, oBrowseRight, { { 'ZA5_FILIAL',
'xFilial( "ZA5" )' }, { 'ZA5_ALBUM' , 'ZA4_ALBUM' }, { 'ZA5_MUSICA',
'ZA4_MUSICA' } } )
oRelacZA5:Activate()
Private oDlgPrinc
//
// Crear el contenedor donde sern colocados los browses
//
oFWLayer := FWLayer():New()
oFWLayer:Init( oDlgPrinc, .F., .T. )
//
// Define Panel Superior
//
oFWLayer:AddLine( 'UP', 50, .F. )
// Cria uma "linha" com 50% da tela Formatado: Portugus (Brasil)
//
// Panel Inferior
//
oFWLayer:AddLine( 'DOWN', 50, .F. )
// Cria uma "linha" com 50% da tela Formatado: Portugus (Brasil)
//
// FWmBrowse Superior Albuns
//
oBrowseUp:= FWmBrowse():New()
oBrowseUp:SetOwner( oPanelUp ) Formatado: Ingls (Estados Unidos)
//
// Lado Esquerdo Musicas
//
oBrowseLeft:= FWMBrowse():New()
oBrowseLeft:SetOwner( oPanelLeft )
oBrowseLeft:SetDescription( 'Musicas' )
oBrowseLeft:SetMenuDef( '' )
// Referencia vazia para que nao exiba nenhum botao oBrowseLeft:DisableDetails() Formatado: Portugus (Brasil)
Formatado: Portugus (Brasil)
oBrowseLeft:SetAlias( 'ZA4' )
Formatado: Portugus (Brasil)
oBrowseLeft:SetProfileID( '2' )
oBrowseLeft:Activate() Formatado: Portugus (Brasil)
//
// Lado Direcho Autores/Interpretes
//
oBrowseRight:= FWMBrowse():New()
oBrowseRight:SetOwner( oPanelRight )
oBrowseRight:SetDescription( 'Autores/Interpretes' ) oBrowseRight:SetMenuDef( '' )
// Referencia vazia para que nao exiba nenhum botao Formatado: Portugus (Brasil)
oRelacZA4:Activate()
oRelacZA5:= FWBrwRelation():New()
oRelacZA5:AddRelation( oBrowseLeft, oBrowseRight, { { 'ZA5_FILIAL','xFilial( "ZA5"
)' }, { 'ZA5_ALBUM' , 'ZA4_ALBUM' }, { 'ZA5_MUSICA', 'ZA4_MUSICA' } } )
oRelacZA5:Activate()
Return NIL
//-----------------------------------------------------------------
Static Function MenuDef()
Return FWLoadMenuDef( 'COMP023_MVC' )
//-------------------------------------------------------------------
Static Function ModelDef()
// Utilizamos um model que ja existe Formatado: Portugus (Brasil)
//-------------------------------------------------------------------
Static Function ViewDef()
// Utilizamos uma View que ja existe
Return FWLoadView( 'COMP023_MVC' )
Para entenderlo mejor, usaremos de como ejemplo del el fuente que se muestra a
continuacin, donde se hace en MVC lo que sera una rutina automtica para
importacin de un cadastro simple.
If nOpc == 1
Processa( { || lOk := Runproc() },'Aguarde','Processando...',.F.)
If lOk
ApMsgInfo( 'Processamento terminado com sucesso.', 'ATENO' )
Else
ApMsgStop( 'Processamento realizado com problemas.', 'ATENO' ) Formatado: Portugus (Brasil)
EndIf
EndIf
Return NIL
//-------------------------------------------------------------------
// Rotina Auxiliar de Importao
//-------------------------------------------------------------------
Static Function Runproc()
Local lRet := .T. Formatado: Ingls (Estados Unidos)
Local aCampos := {}
// Creamos un vector con los datos para facilitar la manupulacin de los datos
aCampos := {} Formatado: Portugus (Brasil)
aAdd( aCampos, { 'ZA0_CODIGO', '000100' } )
aAdd( aCampos, { 'ZA0_NOME' , 'Vila Lobos' } )
aAdd( aCampos, { 'ZA0_NOTAS' , 'Observaes...' } )
aAdd( aCampos, { 'ZA0_TIPO' , 'C' } )
If !Import( 'ZA0', aCampos )
lRet := .F. Formatado: Espanhol (Espanha -
EndIf tradicional)
dbSelectArea( cAlias )
dbSetOrder( 1 )
oModel:SetOperation( 3 )
// Antes de asignar los valores de los campos tenemos que activar el modelo
oModel:Activate()
oStruct := oAux:GetStruct()
aAux := oStruct:GetFields()
lRet := .F.
Exit
EndIf
EndIf
Next nI
If ( lRet := oModel:VldData() )
// Si los datos fueran validados hace la grabacin efectiva de los datos (commit)
oModel:CommitData()
EndIf
EndIf
If !lRet
//Si los datos no fueran validos obtenemos la descripcin del error para genear LOG
//o mensaje de aviso
aErro := oModel:GetErrorMessage()
Return lRet
En este otro ejemplo, temos la importacin para a un modelo de datos donde hay una
estructura de Master-Detail (Padre-HijoPrincipal-Secundario). Tambin lo que
haremos es instanciar el modelo de datos (Model) que deseamos, asignar atribuir
los valores a elal mismo y hacer la validacin, solo slo que haremos esto para las dos
entidadeslos dos entes.
EndIf
Return NIL
//-------------------------------------------------------------------
// Rutina auxiliar de Importacin
//-------------------------------------------------------------------
Static Function Runproc()
Local lRet := .T.
Local aCposCab := {}
Local aCposDet := {}
Local aAux := {}
//Creamos un vector con los datos del encabezado y otro para los tems,
//para facilitar el mantenimiento de los datos
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' } )
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. Formatado: Portugus (Brasil)
EndIf
// Importamos otro conjunto de datos
aCposCab := {}
aCposDet := {}
aAdd( aCposCab, { 'ZA1_TITULO' , 'BLA, BLA, BLA' } ) aAdd( aCposCab, { 'ZA1_DATA',
Date() } )
aAux := {}
aAdd( aAux, { 'ZA2_ITEM' , '01' } )
aAux := {}
aAdd( aAux, { 'ZA2_ITEM' , '01' } )
aAdd( aAux, { 'ZA2_AUTOR', '000100' } )
aAdd( aCposDet, aAux )
aAux := {}
aAdd( aAux, { 'ZA2_ITEM' , '02' } )
aAdd( aAux, { 'ZA2_AUTOR', '000102' } )
aAdd( aCposDet, aAux )
If !Import( 'ZA1', 'ZA2', aCposCab, aCposDet )
lRet := .F.
EndIf Formatado: Espanhol (Espanha -
tradicional)
Return lRet
//-------------------------------------------------------------------
// Importaciacn de los datos
//------------------------------------------------------------------- Formatado: Espanhol (Espanha -
Static Function Import( cMaster, cDetail, aCpoMaster, aCpoDetail ) tradicional)
Local oModel, oAux, oStruct Formatado: Espanhol (Espanha -
Local nI := 0 tradicional)
Local nJ := 0
Local nPos := 0
Local lRet := .T.
Local aAux := {}
Local aC := {}
Local aH := {}
Local nItErro := 0
Local lAux := .T.
dbSelectArea( cDetail )
dbSetOrder( 1 )
dbSelectArea( cMaster )
dbSetOrder( 1 )
// Aqu ocurre el instanciamiento del modelo de datos (Model)
// En este ejemplo instanciamos el modelo de datos del fuente COMP022_MVC
// que es a rutina de mantenimiento de msica
oModel := FWLoadModel( 'COMP022_MVC' )
// Tenemos que definir cul es la operacin : 3 - Incluir / 4 - Alterar / 5 -
Excluir
oModel:SetOperation( 3 )
// Antes de asignar los valores de los campos tenemos que activar el modelo
oModel:Activate()
// Instanciamos solo la parte del modelo referente a los dados de encabezado
oAux := oModel:GetModel( cMaster + 'MASTER' )
// Obtenemos la estructura de dados del encabezado
oStruct := oAux:GetStruct()
aAux := oStruct:GetFields()
If lRet
For nI := 1 To Len( aCpoMaster )
// Verifica si los campos pasados existen en la estructura del encabezado
If ( nPos := aScan( aAux, { |x| AllTrim( x[3] ) == AllTrim(
aCpoMaster[nI][1] ) } ) ) > 0
//hace la asignacin del dato a los campos del Model del encabezado
If !( lAux := oModel:SetValue( cMaster + 'MASTER', aCpoMaster[nI][1],
aCpoMaster[nI][2] ) )
// En caso de que la asignacin no pueda ser realizada,por algn
motivo(validacin, por ejemplo)
// el mtodo SetValue retorna .F. Formatado: Portugus (Brasil)
lRet := .F.
Exit
EndIf
EndIf
Next
EndIf Formatado: Portugus (Brasil)
If lRet
// Instanciamos solo la parte del modelo referente a los dados de tem
oAux := oModel:GetModel( cDetail + 'DETAIL' )
// Obtenemos la estructura de dados del tem
oStruct := oAux:GetStruct()
aAux := oStruct:GetFields()
nItErro := 0
For nI := 1 To Len( aCpoDetail )
// Incluimos una lnea nueva
// ATENCIN: Loas tems son creados en una estructura de grid(FORMGRID),
//por tanto ya fue creado una primera lnea
//en blanco automticamente, de esta forma comenzamos a insertar nuevas
lneas a partir de 2 vez
If nI > 1
// Incluimos una nueva lnea de tem
If ( nItErro := oAux:AddLine() ) <> nI
// Se por algn motivo el mtodo AddLine() no incluye la lnea,
// este retornara la cantidad de lneas que ya
// existen en el grid. y si la incluye, retornara la cantidad ms 1
lRet := .F.
Exit
EndIf
EndIf
If lRet
// Se realiza la validacin de los datos, note que a diferencia de las
tradicionales "rutinas automticas"
// en este momento los datos no son grabados, son solamente validados.
If ( lRet := oModel:VldData() )
// Si los datos fueran validos se realiza la grabacin de los datos (Commit)
oModel:CommitData()
EndIf
EndIf
If !lRet
// Si los datos no fueran validos obtenemos la descripcin de error para generar
// LOG o mensaje de aviso
aErro := oModel:GetErrorMessage()
// La estructura del vector con los errores es:
// [1] identificador (ID) del formulario de origen
// [2] identificador (ID) del campo de origen
// [3] identificador (ID del formulario de error
// [4] identificador (ID) del campo de error
// [5] identificador (ID) del error
// [6] mensaje de error
// [7] mensaje de solucin
// [8] Valor atribuido
// [9] Valor anterior
AutoGrLog( "Id do formulrio de origem:" + ' [' + AllToChar( aErro[1] ) + ']' ) Formatado: Portugus (Brasil)
AutoGrLog( "Id do campo de origem: " + ' [' + AllToChar( aErro[2] ) + ']' )
AutoGrLog( "Id do formulrio de erro: " + ' [' + AllToChar( aErro[3] ) + ']' )
AutoGrLog( "Id do campo de erro: " + ' [' + AllToChar( aErro[4] ) + ']' )
AutoGrLog( "Id do erro: " + ' [' + AllToChar( aErro[5] ) + ']' )
AutoGrLog( "Mensagem do erro: " + ' [' + AllToChar( aErro[6] ) + ']' )
AutoGrLog( "Mensagem da soluo: " + ' [' + AllToChar( aErro[7] ) + ']' )
AutoGrLog( "Valor atribudo: " + ' [' + AllToChar( aErro[8] ) + ']' )
AutoGrLog( "Valor anterior: " + ' [' + AllToChar( aErro[9] ) + ']' )
If nItErro > 0
AutoGrLog( "Erro no Item: " + ' [' + AllTrim( AllToChar(nItErro ) ) + ']' )
EndIf
MostraErro()
EndIf
// Desactivamos o Model
oModel:DeActivate()
Return lRet
Una situacin que podr ser encontrada, en los casos en que se est
convirtiendo una aplicacin que ya existe para la estructura de MVC, es el hecho de
que la aplicacin ya puede estar preparada para trabajar como rutina automtica y por
consecuencia pueden existir otras aplicaciones que ya utilicen esa rutina automtica.
La funcin FWMVCRotAuto fue creada para que no sea necesario que estas
aplicaciones, que hoy se usan en la llamada de la rutina estndar, cambien su
forma de trabajar, ya que la aplicacin fue convertida para a MVC.
Sintaxis:
Donde:
[3] Inclusin
[4] AlteracinModificacin
[5] ExclusinBorrado
lSeek Indica si el archivo principal debe ser posicionado con base en los datos
proporcionados;
Function MATA030_MVC(xRotAuto,nOpcAuto)
Return NIL
Pontos de entrada son desvos controlados que se ejecutan durante las aplicaciones.
La ida idea del punto de entrada, para fuentes desarrollados que utilizan el concepto
de MVC y sus clases, es un poco diferente a de las aplicaciones desarrolladas de forma
manera convencional.
En los fuentes convencionales tenemos un nombre para cada punto de entrada , por
ejemplo, en la rutina MATA010 - Cadastro Archivo de Productos, tenemos los
puntos de entrada: MT010BRW, MTA010OK, MT010CAN, etc. En MVC, no es de
esta formamanera.
Este punto de entrada nico debe ser una User Function y debe tener como nombre
el identificador (ID) del modelo de datos (Model) del fuente. Tomemos por ejemplo
un fuente del Modulo Jurdico: JURA001. En este dicho fuente el identificador (ID)
del modelo de datos (definido en la funcin ModelDef) es tambin JURA001, por lo
tanto si se escribe un punto de entrada de esta aplicacin, haramos:
ID DEL PUNTODE
ENTRADA MOMENTO DE EJECUCIN DEL PUNTO DE ENTRADA
3 C ID del formulario.
Retorno:
3 C ID del formulario.
Retorno:
3 C ID del formulario.
Retorno:
3 C ID del formulario.
Retorno:
3 C ID del formulario.
5 C Accin de la FWFORMGRID.
6 C Id del campo.
Retorno:
3 C ID del formulario.
Retorno:
3 C ID del formulario.
Retorno:
3 C ID del formulario.
Retorno:
No espera retorno.
3 C ID del formulario.
Retorno:
No espera retorno.
3 C ID del formulario.
Retorno:
No espera retorno.
3 C ID del formulario.
Retorno:
MODELVLDACTIVE
Activacin del modelo
Parmetros Recibidos:
3 C ID del formulario.
Retorno:
4 C ToolTip (Opcional).
Parmetros Recibidos:
3 C ID del formulario.
Retorno:
Array con la estructura pre-definidapredefinida.
Observaciones:
Importante:
oObj := aParam[1]
cIdPonto := aParam[2]
cIdModel := aParam[3]
lIsGrid := ( Len( aParam ) > 3 )
If lIsGrid
nQtdLinhas := oObj:GetQtdLine()
nLinha := oObj:nLine
EndIf
If cIdPonto == 'MODELPOS'
EndIf
ElseIf cIdPonto == 'FORMPOS'
cMsg := 'Chamada na validao total do formulrio (FORMPOS).' + CRLF Formatado: Portugus (Brasil)
cMsg += 'ID ' + cIdModel + CRLF
If cClasse == 'FWFORMGRID'
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
Return xRet
oMVCWS := WsFwWsModel():New()
oMVCWS:_URL := http://127.0.0.1:8080/ws/FWWSMODEL.apw
Definimos aqu el nombre del fuente que contiene el ModelDef que queremos utilizar.
oMVCWS:cModelId := 'COMP011_MVC'
El tag <ID del Model> es el identificador (ID) que est definido en el modelo de
datos (Model) da la aplicacin MVC.
oModel := MPFormModel():New('COMP011M' )
<COMP011M>
</COMP011M>
<COMP011M Operation="3">
Ejemplo:
Si en la aplicacin tenemos:
oModel:AddFields( 'ZA0MASTER' )
<ZA0MASTER>
</ZA0MASTER>
El tipo de componente (del formulario o del grid) tambin debe ser informado en
este tag en el atributo modeltype. Informe FIELDS para componentes de
formularios y GRID para componentes de grid.
Tendremos esto:
<ZA0MASTER modeltype="FIELDS">
Los tags <ID de Campo> sern los nombres de los campos de la estructura del
componente, sea formulario grid.
De esta misma forma, si en la estructura tuviramos los campos ZA0_FILIAL,
ZA0_ CODIGO y ZA0_NOME, por ejemplo, tendramos:
<ZA0_FILIAL>
</ZA0_FILIAL>
<ZA0_CODIGO>
</ZA0_NOME>
El orden de los campos tambin deben ser informados en los tags, con el atributo
order.
</ZA0_FILIAL>
<ZA0_CODIGO order="2"> Formatado: Portugus (Brasil)
</ZA0_CODIGO >
<ZA0_NOME order="3">
</ZA0_NOME>
<ZA0_CODIGO order="2">
<value>001000</value>
</ZA0_CODIGO >
<ZA0_NOME order="3">
<value>Tom Jobim</value>
</ZA0_NOME>
Estrutura completa:
<COMP011M Operation="1">
<ZA0MASTER modeltype="FIELDS" >
<ZA0_FILIAL order="1">
<value>01</value>
</ZA0_FILIAL> Formatado: Ingls (Estados Unidos)
<ZA0_CODIGO order="2">
Podemos obtener la estructura XML que una aplicacin en MVC espera, para esto
se utilizar el mtodo GetXMLData del Web Service.
Ejemplo:
oMVCWS:GetXMLData()
If !oMVCWS:VldXMLData()
MsgStop( 'Problemas na validao dos dados' + CRLF + WSError() Formatado: Portugus (Brasil)
)
EndIf
En este momento los datos son validados por VldXMLData , mas no son grabados.
Este es un recurso interesante si quisiramos hacer una simulacin, por ejemplo.
Esta validacin se refiere a la estructura del XML (tags, nivel, orden, etc.) y no a los
datos del XML, la validacin de los datos es funcin de la regla de negocio.
Si el desarrollador quiere obtener el esquema XSD que ser utilizado, podr usar
el mtodo GetSchema.
Ejemplo:
If oMVCWS:GetSchema()
cXMLEsquema := oMVCWS:cGetSchemaResult
EndIf
Local oMVCWS
// Retorna
//<?xml version="1.0" encoding="UTF-8"?>
//<COMP011M Operation="1" version="1.01">
// <ZA0MASTER modeltype="FIELDS" >+ CRLF + WSError() )
// <ZA0_FILIAL order="1"><value></value></ZA0_FILIAL>
// <ZA0_CODIGO order="2"><value></value></ZA0_CODIGO>
// <ZA0_NOME order="3"><value></value></ZA0_NOME>
// </ZA0MASTER> Formatado: Portugus (Brasil)
//</COMP011M>
If oMVCWS:GetSchema()
cXMLEsquema := oMVCWS:cGetSchemaResult
EndIf
// Crea el XML
cXML += '</COMP011M>'
Para la construccin de Web Services que tienen dos o ms entidades lo que ser
diferente en el XML es que tendr ms niveles. Observe el fuente, ejemplo:
#INCLUDE 'PROTHEUS.CH'
#INCLUDE 'XMLXFUN.CH'
#INCLUDE 'FWMVCDEF.CH'
//-------------------------------------------------------------------
/*/{Protheus.doc} COMPW021
Ejemplo para utilizar un WebService generico para rutinas en MVC para una
estructura de padre/hijo
@author Ernani Forastieri e Rodrigo Antonio Godinho @since 05/10/2009 Formatado: Portugus (Brasil)
@version P10
/*/
//-------------------------------------------------------------------
If oMVCWS:lPutXMLDataResult
Else
Else
MsgStop( AllTrim( oMVCWS:cVldXMLDataResult ) + CRLF + WSError() )
EndIf
Else
EndIf
RpcClearEnv()
Return NIL
//-------------------------------------
Static Function WSError()
Return IIf( Empty( GetWscError(3) ), GetWscError(1), GetWscError(3) )
Lo que se necesita para utilizar este comando es que se tenga una uno de los modelos
mencionados y que las estructuras de las tablas estn definidas en el diccionario
SX3. No podrn ser construidas estructuras manualmente o agregar, quitar
retirar campos de las estructuras.
Como este comando es una directiva de compilacin del tipo #COMMAND, para
utilizar este comando es necesario incluir la siguiente directiva en el fuente:
#INCLUDE 'FWMVCDEF.CH'
NEW MODEL
TYPE <nType> ;
DESCRIPTION <cDescription> ;
BROWSE <oBrowse> ;
SOURCE <cSource> ;
MODELID <cModelID> ;
FILTER <cFilter> ;
CANACTIVE <bSetVldActive> ;
PRIMARYKEY <aPrimaryKey> ;
MASTER <cMasterAlias> ;
HEADER <aHeader,...> ;
BEFORE <bBeforeModel> ;
AFTER <bAfterModel> ;
COMMIT <bCommit> ;
CANCEL <bCancel> ;
BEFOREFIELD <bBeforeField> ;
AFTERFIELD <bAfterField> ;
LOAD <bFieldLoad> ;
DETAIL <cDetailAlias> ;
BEFORELINE <bBeforeLine> ;
AFTERLINE <bAfterLine> ;
BEFOREGRID <bBeforeGrid> ;
AFTERGRID <bAfterGrid> ;
LOADGRID <bGridLoad> ;
RELATION <aRelation> ;
ORDERKEY <cOrder> ;
UNIQUELINE <aUniqueLine> ;
AUTOINCREMENT <cFieldInc> ;
OPTIONAL
Donde:
TYPE <nType>
DESCRIPTION <cDescription>
Tipo Carcter - Obligatorio
Descripcin de la Rutina
BROWSE <oBrowse>
SOURCE <cSource>
FILTER <cFilter>
Tipo Carcter - Opcional
CANACTIVE<bSetVldActive>
PRIMARYKEY <aPrimaryKey>
Tipo Array - Opcional
Array con las llaves primarias del Browse, si no es informado
buscar X2_UNICO de la tabla.
MASTER <cMasterAlias>
Tipo Carcter - Obligatorio
HEADER <aHeader>
BEFORE <bBeforeModel>
AFTER <bAfterModel>
COMMIT <bCommit>
Tipo Bloque - Opcional
Bloque de Commit de los datos del Model. Recibe como parmetro el
Model.
Ejemplo. { |oModel| COMP022CM( oModel ) }
CANCEL <bCancel>
BEFOREFIELD <bBeforeField>
Ejemplo.
{ |oMdlF,cId ,cidForm| COMP023FPRE( oMdlF,cId ,cidForm) }
AFTERFIELD <bAfterField>
LOAD <bFieldLoad>
DETAIL <cDetailAlias>
BEFORELINE <bBeforeLine>
AFTERLINE <bAfterLine>
BEFOREGRID <bBeforeGrid>
AFTERGRID <bAfterGrid>
LOADGRID <bGridLoad>
RELATION <aRelation>
ORDERKEY <cOrder>
UNIQUELINE <aUniqueLine>
AUTOINCREMENT <cFieldInc>
OPTIONAL
Indica si el llenado de FORMGRID de la tabla Detalle ser opcional
Utilizado solo slo para el TYPE = 2 o 3
FILTER "ZA0_TIPO=='1'" ;
MASTER "ZA0" ;
AFTER { |oMdl| COMP041POS( oMdl ) } ;
COMMIT { |oMdl| COMP041CMM( oMdl ) }
Return NIL
NEW MODEL ;
TYPE 2 ;
BROWSE oBrowse ;
SOURCE "COMP042_MVC" ;
MODELID "MDCOMP042" ;
MASTER "ZA2" ;
{ 'ZA2_MUSICA', 'ZA2_MUSICA' } } ;
AUTOINCREMENT 'ZA2_ITEM'
Local oBrowse
NEW MODEL ;
TYPE 3 ;
DESCRIPTION "Musicas";
BROWSE oBrowse ;
SOURCE "COMP043_MVC" ;
MODELID "MDCOMP043" ;
MASTER "ZA1" ;
DETAIL "ZA2" ;
UNIQUELINE{ 'ZA2_AUTOR' } ;
AUTOINCREMENT 'ZA2_ITEM'
Return NIL Formatado: Espanhol (Espanha -
tradicional)
El Resultado es:
Local oBrowse
TYPE 1 ;
BROWSE oBrowse;
SOURCE "COMP044_MVC" ;
MENUDEF "COMP044_MVC" ;
MODELID "MDCOMP044" ;
MASTER "ZA0"
Return NIL
//-------------------------------------------------------------------
Static Function MenuDef()
Local aRotina := {}
Return aRotina
El Resultado es:
Return oModel
Ejemplo:
#INCLUDE 'PROTHEUS.CH'
#INCLUDE 'FWMVCDEF.CH'
//-------------------------------------------------------------------
User Function COMP015_MVC()
Formatado: Portugus (Brasil)
Local oBrowse
Formatado: Ingls (Estados Unidos)
Formatado: Ingls (Estados Unidos)
oBrowse := FWMBrowse():New()
Formatado: Ingls (Estados Unidos)
oBrowse:SetAlias('ZA0')
Formatado: Ingls (Estados Unidos)
oBrowse:SetDescription('Cadastro de Autor/Interprete') oBrowse:DisableDetails()
Formatado: Ingls (Estados Unidos)
oBrowse:Activate()
Return NIL
//-------------------------------------------------------------------
Static Function MenuDef()
Return FWLoadMenuDef( "COMP011_MVC")
//-------------------------------------------------------------------
Static Function ModelDef()
// Creamos el modelo de dados de esta aplicacin con un modelo existente en
// otra aplicacin, en caso COMP011_MVC
Local oModel := FWLoadModel( "COMP011_MVC" ) Return oModel
//-------------------------------------------------------------------
Static Function ViewDef()
// Creamos el modelo de datos de esta aplicacin con una interfaz existente en
// otra aplicacin, en caso COMP011_MVC
Local oView := FWLoadView( "COMP011_MVC" )
Return oView
Lo ideal para este tipo de uso es construir un modelo bsico e incrementarlo conforme
a las necesidades.
El primer paso es crear la estructura de la nueva entidaddel nuevo ente, ver cap. 0 5.1
Construccin de una estructura de datos (FWFormStruct), para detalles.
Return oModel
El primer paso es crear la estructura de la nueva entidad, ver cap. 0 5.1 Construccin
de una estructura de datos (FWFormStruct).
Tenemos que crear un box para el nuevo componente. Es necesario crear siempre un
box vertical dentro de un horizontal y vice-versa como en COMP011_MVC el box que
ya existe es horizontal, primero crearemos un vertical, para ms detalles ver cap. 0
6.13 Mostrar los dados en la interfaz (CreateHorizontalBox / CreateVerticalBox).
// Nuevos Boxes
oView:CreateHorizontalBox( 'SUPERIOR' , 50, 'TELANOVA' )
oView:CreateHorizontalBox( 'INFERIOR' , 50, 'TELANOVA' )
Relacionar los componentes con lo box, ver cap. 0 5.10 Relacionando el componente
de la interfaz (SetOwnerView).
Return oView
Con esto creamos una interfaz a partir de otra y agregamos un nuevo componente.
//-------------------------------------------------------------------
User Function COMP015_MVC()
Local oBrowse
//-------------------------------------------------------------------
Static Function MenuDef()
Local aRotina := {}
ADD OPTION aRotina TITLE 'Visualizar' ACTION 'VIEWDEF.COMP015_MVC' OPERATION 2
ACCESS 0
ADD OPTION aRotina TITLE 'Incluir' ACTION 'VIEWDEF.COMP015_MVC' OPERATION 3
ACCESS 0
ADD OPTION aRotina TITLE 'Alterar' ACTION 'VIEWDEF.COMP015_MVC' OPERATION 4
ACCESS 0
ADD OPTION aRotina TITLE 'Excluir' ACTION 'VIEWDEF.COMP015_MVC' OPERATION 5
ACCESS 0
ADD OPTION aRotina TITLE 'Imprimir' ACTION 'VIEWDEF.COMP015_MVC' OPERATION 8
ACCESS 0
ADD OPTION aRotina TITLE 'Copiar' ACTION 'VIEWDEF.COMP015_MVC' OPERATION 9
ACCESS 0
Return aRotina
//-------------------------------------------------------------------
Static Function ModelDef()
// Crea la estructura a ser acrecentada en el Modelo de Datos
Local oStruZA6 := FWFormStruct( 1, 'ZA6', /*bAvalCampo*/,/*lViewUsado*/ )
// Nuevos Boxes
oView:CreateHorizontalBox( 'SUPERIOR' , 50, 'TELANOVA' )
oView:CreateHorizontalBox( 'INFERIOR' , 50, 'TELANOVA' )
Return oView
Por ejemplo, tome como base el formulario Nota Fiscal/Invoice. Este formulario
tiene como caracterstica comn en todos los pases los elementos: Origen,
Destino, Lista de productos, Transporte y Facturas.
El Framework MVC trae una luz racional y simple para este problema. La
herencia de formularios. Es posible construir un formulario comn para la Nota
FiscalFactura/Invoice que no tenga ningn elemento de localizacin y utilizarlo por
herencia, como base para los formularios localizados.
#INCLUDE MATA103BRA.CH
Entre las innumeradas innumerables ventajas que tiene este modelo de desarrollo
nos gustara destacar la creacin de componentes, y el aislamiento de del cdigo
fuente. El aislamiento permite que los dos cdigos fuentes evolucionen por
separado, sin embargo por la herenciaherencia el cdigo localizado siempre ir
heredarheredar los beneficios de la parte comn, incluso posibilitara apermite
que las dos personas interacten simultneamente en el mismo proceso sin que una
perjudique el trabajo de la otra.
GetModel, 2, 19, 20, 26, 27, 28, 34, 36, 37, 38,
39, 41, 42, 43, 44, 45, 46, 75, 93, 97, 130, 132
Addcalc, 72 GetOperation, 2, 35, 37, 46, 77
AddField, 1, 2, 3, 21, 22, 28, 32, 33, 60, 66, 67, GetSchema, 4, 114, 115, 116, 117
68, 73, 75, 130, 132, 135
AddFields, 1, 18, 19, 20, 24, 25, 27, 32, 110, 129,
132
AddGrid, 1, 2, 25, 27, 29, 32, 33, 35, 36, 60, 135
AddGroup, 3, 55, 56 GetValue, 44
AddIncrementField, 2, 49 GetXMLData, 3, 112, 115, 116
AddLegend, 1, 13, 15, 81, 131 GoLine, 2, 38, 39, 41, 43
AddLine, 2, 40, 84, 87, 98 Help, 34, 37, 40, 46, 64, 68, 76, 107, 108, 123
AddOtherObjects, 3, 59 IsDeleted, 39, 40, 41
AddRules, 2, 48 IsInserted, 39, 40
AddTrigger, 3, 70, 71 IsMark, 80, 82
AddUserButton, 2, 50 IsOptional, 43
AVG, 73, 74 IsUpdated, 39, 40
AXALTERA, 75 LinhaOk, 35
AXDELETA, 75 LoadValue, 45
AXINCLI, 75 Master-Detail, 23, 25, 42, 94
AXVISUAL, 75 MODEL_OPERATION_DELETE, 47
CommitData, 94, 98 MODEL_OPERATION_INSERT, 47, 61, 76
contadores, 3, 72 MODEL_OPERATION_UPDATE, 37, 47
COUNT, 73, 74 ModelDef, 1, 2, 8, 9, 16, 17, 18, 19, 20, 22, 23,
CreateFolder, 3, 53, 54 24, 27, 28, 30, 32, 44, 74, 75, 77, 81, 90, 100,
CreateHorizontalBox, 1, 2, 21, 23, 29, 30, 32, 54, 101, 109, 118, 128, 130, 132, 135
60, 130, 131, 132 Modelo1, 23, 118
CreateVerticalBox, 1, 2, 21, 29, 60, 130 Modelo2, 118
DeleteLine, 2, 41 Modelo3, 32, 118
DisableDetails, 1, 15, 16, 86, 89, 128 MPFormModel, 18, 20, 24, 27, 35, 47, 110, 129
EnableTitleView, 2, 51, 60 MSExecAuto, 91
ForceQuitButton, 85, 89 New Model, 4, 118
Framework, 134, 135 PARAMIXB, 101, 107
FWBrwRelation, 86, 87, 90 PutXMLData, 3, 113, 115, 117
FwBuildFeature, 67, 69 RemoveField, 3, 62, 63
FWCalcStruct, 75 SetDescription, 1, 13, 15, 19, 20, 26, 27, 28, 52,
FWExecView, 3, 61, 75, 76 79, 80, 85, 86, 89, 100, 128, 130, 131, 132
FWFormCommit, 2, 47, 123 SetFieldAction, 3, 58, 59
FWFormStruct, 1, 3, 16, 17, 18, 19, 20, 22, 24, SetFilterDefault, 1, 14, 15, 81
25, 26, 27, 31, 61, 62, 63, 67, 68, 71, 72, 129, SetNoDeleteLine, 42
130, 132 SetNoFolder, 3, 72
FWLoadMenudef, 3, 78 SetNoGroups, 3, 72
FWLoadModel, 3, 20, 22, 28, 31, 77, 81, 90, 93, SetNoInsertLine, 42
97, 128, 129, 130, 132, 135 SetNoUpdateLine, 42
FWLoadView, 3, 78, 81, 90, 128, 129, 130, 132, SetOnlyQuery, 2, 46
135 SetOnlyView, 2, 45
FWMarkBrowse, 3, 79, 80 SetOperation, 93, 97
FWMemoVirtual, 3, 69, 70 SetOptional, 2, 42, 43
FWModelActive, 3, 39, 41, 43, 76, 77 SetOwnerView, 1, 2, 22, 23, 30, 32, 54, 55, 60,
FWMVCMenu, 3, 11, 12, 78 131, 133
FWMVCRotAuto, 99, 100 SetPrimaryKey, 1, 26
FWRestRows, 2, 43 SetProfileID, 85, 86, 89, 90
FWSaveRows, 2, 39, 43 SetProperty, 3, 56, 63, 66
FwStruTrigger, 3, 70, 71 SetRelation, 1, 25, 27, 129, 132
FWViewActive, 3, 77 SetSemaphore, 80
FWWSMODEL, 109, 114, 116 SetUniqueLine, 2, 35, 36
Gatillos, 16 SETVALUE, 37
GetErrorMessage, 94, 99 SetViewAction, 3, 57, 58
SetViewProperty, 3, 52
STRUCT_FEATURE_INIPAD, 67, 69
STRUCT_FEATURE_PICTVAR, 69
STRUCT_FEATURE_VALID, 67, 69 ViewDef, 1, 2, 8, 9, 10, 16, 20, 22, 23, 28, 30, 32,
STRUCT_FEATURE_WHEN, 69 75, 78, 81, 90, 118, 129, 132, 135
SUM, 73, 74 VldData, 94, 98
TudoOk, 35 VldXMLData, 3, 113
UnDeleteLine, 2, 41, 42 WsFwWsModel, 109, 114, 116