Descarga la aplicación para disfrutar aún más
Vista previa del material en texto
ADVPL Básico 1 Educación Corporativa – TOTVS Protheus 10 1 de 51 ADVPL Básico ADVPL Básico.......................................................................................................................1 Antecedentes ......................................................................................................................3 Pre requisitos.......................................................................................................................3 Objetivos .............................................................................................................................3 Parte I. Revisión de Tecnología Protheus e implicaciones de configuración para desarrollos 3 Preparación de ambiente de Trabajo..............................................................................3 Ejercicio 1. Inicialización del servicio Protheus y primer acceso. ...............................4 Componentes Físicos.......................................................................................................4 Protheus Remote.........................................................................................................4 Protheus Server Maestro ............................................................................................5 Protheus Servers Esclavos e independientes..............................................................5 CTreeServer .................................................................................................................6 TopConnect .................................................................................................................6 Componentes Lógicos (Definición de ambiente) ............................................................7 Archivos Sxs .................................................................................................................8 Ejercicio 2, Identificación del contenido de los archivos SXs y mapeo entre el configurador y el contenido de las tablas........................................................................................8 Parte II. Conceptos genéricos de lenguaje ADVPL .............................................................8 Origen del Lenguaje y evolución .....................................................................................8 La herramienta de desarrollo mp8ide (IDE)....................................................................9 Configuraciones y preferencias...................................................................................9 Ejercicio 3. Cambiar las preferencias del IDE ..........................................................9 Ejercicio 4. Configurar ambiente de Trabajo.........................................................10 Concepto de Proyecto y Programas..........................................................................10 Ejercicio 5. Generando un Proyecto de Trabajo. ..................................................10 Ejercicio 6 Eliminar un archivo del proyecto y funciones del RPO........................10 Revisión de las principales opciones del IDE.............................................................10 Ciclo de vida del RPO (ptm,pak, upd)....................................................................11 Ejercicio 7. Ejecutar un mantenimiento al RPO desde el IDE. ..............................11 Variables y Tipos de datos.............................................................................................11 Tipos de datos ...........................................................................................................11 Declaración de variables y asignación de valores .................................................12 Ejercicio 8. Declaración de variables y usos típicos. .........................................12 Alcance (Scope de las variables) ...........................................................................12 Tipos estructurados...................................................................................................13 Declaración de variables arrays y asignación de valores ......................................13 Funciones para el manejo de arrays .....................................................................13 Ejercicio 10. Declaración y manejo de arreglos ....................................................14 Operadores y precedencia de ejecución.......................................................................15 ADVPL Básico 2 Educación Corporativa – TOTVS Protheus 10 2 de 51 Operadores básicos...................................................................................................15 Operadores matemáticos......................................................................................15 Operadores strings ................................................................................................15 Operadores de comparación.................................................................................16 Operadores Lógicos...............................................................................................16 Ejercicio 11. Uso de operadores básicos...............................................................16 Operadores de asignación.........................................................................................17 Operadores especiales ..............................................................................................18 Elementos de programación estructurada ...................................................................18 Tipos de funciones.....................................................................................................18 Ejercicio 12 Entendimiento del alcance de variables y funciones ........................19 Funciones de uso común...........................................................................................20 Ejercicio 13. Uso de funciones ..............................................................................21 Paso de parámetros ..................................................................................................21 Ejercicio 14. Funciones con parámetros ...............................................................21 Macro Substitución ...................................................................................................22 Ejercicio 15. Ejemplo de Macro substitución ........................................................22 Bloques de código .....................................................................................................23 Ejercicio 16. de Bloques de código........................................................................24 Estructuras de control de flujo......................................................................................24 Condicionales ............................................................................................................24 De ciclo ......................................................................................................................26 Funciones Protheus para interacción con usuarios ......................................................28 Ejercicio 15. Interacción con el usuario ....................................................................28 Parte III. Funciones básicas de acceso a datos..................................................................30 Consideraciones de filial y archivos compartidos .........................................................30 Ejercicio 16. Interactuando con Protheus.................................................................31 Funciones básicas de manejo de tablas ........................................................................33 Lectura y actualización de archivos...............................................................................34 Índices........................................................................................................................34 Estatutos SQL.................................................................................................................35Control de transacciones...............................................................................................39 Parte IV ADVPL y Protheus ................................................................................................40 Gatillos...........................................................................................................................40 Funciones para registro de datos..................................................................................42 XCadastro ..................................................................................................................42 Modelo 2 ...................................................................................................................43 Modelo 3 ...................................................................................................................47 Validaciones de Campo .................................................................................................50 Regla de avance.............................................................................................................50 ADVPL Básico 3 Educación Corporativa – TOTVS Protheus 10 3 de 51 Antecedentes Pre requisitos Objetivos Parte I. Revisión de Tecnología Protheus e implicaciones de configuración para desarrollos El contenido de esta sección es un extracto de los documentos: Generalidades de la Tecnología Protheus y Administración de un Protheus Balanceado. \ Preparación de ambiente de Trabajo. Como primera actividad debemos de preparar el ambiente de trabajo del curso. El instructor les entregará un archivo .zip que contiene una instalación válida de Protheus8 que descompactaremos dentro de un directorio c:\microsiga\ creado para tal efecto en el disco duro de cada uno de los asistentes. La instalación Protheus tiene dos ambientes definidos, uno para uso 100% local (tablas de datos DBF) y otro preparado para acceso a un DBMS a través del topconnect. Una vez descompactado es necesario que generen un shortcut en el escritorio hacia los siguientes programas: mp8rmt.exe, del directorio ...protheus8\bin\remote, modificar el shorcut adicionando un -m a la linea de ejecución. mp8ide.exe, del directorio ...protheus8\bin\remote mp8monitor.exe, del directorio ...protheus8\bin\remote ADVPL Básico 4 Educación Corporativa – TOTVS Protheus 10 4 de 51 mp8srv.exe, del directorio ...protheus8\bin\remote, modificar el shorcut adicionando un - console a la linea de ejecución. Ejercicio 1. Inicialización del servicio Protheus y primer acceso. Ejecuta el shortcut al servicio Protheus Server. Ejecuta el shortcut al servicio Protheus Remote. Ejecuta el shorcut al mp8ide. Componentes Físicos Vamos a revisar los conceptos principales de la instalación que acaban de hacer. El contenido de esta sección es un extracto de los documentos: Generalidades de la Tecnología Protheus y Administración de un Protheus Balanceado. \ Protheus Remote Solo revisaremos algunas características básicas Cliente delgado Corre en Windows y Linux (verificar distribuciones) Puede correr en IE sobre Windows (ActiveX) mp8monitor mp8ide mp8wizard ADVPL Básico 5 Educación Corporativa – TOTVS Protheus 10 5 de 51 Protheus Server Maestro Ubicación estándar: En el servidor principal de la solución. Orden de Arranque: El Protheus Master debe ser iniciado después de que todos los Protheus esclavos hayan sido levantados. Dependencias: CTree Server. (Si el ambiente está configurado para usar CTreeServer). La inexistencia de CTreeServer no evita la ejecución del Protheus Master, sin embargo ninguna sesión podrá establecerse hasta que este componente esté levantado Validación de Funcionamiento: Para validar su funcionamiento de bajo nivel se recomienda ejecutar un telnet IP_SERVER PUERTO_ESCUCHA para validar que el puerto esté abierto y aceptando requisiciones. Implicaciones de caídas completas: En el caso de que un servidor Maestro sufra un error fatal que lo obligue a cerrarse, todos los Protheus Esclavos y todos los Protheus Independientes cerraran las sesiones abiertas con un error de Lock Server, provocando que todos los usuarios se queden sin servicio. En este caso el procedimiento de recuperación consiste en reiniciar el servicio del Protheus Master. Si el Protheus levanta adecuadamente el Servida Maestro lo detectará nuevamente y le empezará a asignar sesiones. Protheus Servers Esclavos e independientes Ubicación estándar: En todos los servidores de aplicación de la solución. Orden de Arranque: Todas las instancias de Servidores Esclavos deben ser arrancadas inmediatamente después del CTreeServer y antes del arranque del Protheus Master. Dependencias: NFSServer: En caso de ambientes balanceados bajo Linux, con dos o más equipos usados para ejecutar servidores Protheus esclavos es necesario que el servidor donde se ejecuta el servidor esclavo accese al directorio publicado vía NFS en el servidor principal. CTree Server. La inexistencia de CTreeServer no evita la ejecución del Protheus esclavo, sin embargo ninguna sesión podrá establecerse hasta que este componente esté levantado. Validación de Funcionamiento: Para validar su funcionamiento de bajo nivel se recomienda ejecutar un telnet IP_SERVER PUERTO_ESCUCHA para validar que el puerto esté abierto y aceptando requisiciones. De igual manera se puede generar la conexión directa de un remote siempre y cuando se indiquen los parámetros adecuados en el archivo mp8rmt.ini. Implicaciones de caídas completas: En el caso de que un servidor esclavo sufra un error fatal que lo obligue a cerrarse todas las sesiones conectadas a el marcaran un error de conexión. ADVPL Básico 6 Educación Corporativa – TOTVS Protheus 10 6 de 51 En este caso el procedimiento de recuperación consiste en reiniciar el servicio del Protheus esclavo. Si el Protheus levanta adecuadamente el Servidor Maestro lo detectará nuevamente y le empezará a asignar sesiones. CTreeServer Ubicación estándar: Servidor principal del ambiente balanceado Orden de Arranque: Primer componente que debe ser iniciado. Dependencias: NFSServer: En caso de ambientes balanceados bajo Linux, con dos o más equipos usados para ejecutar servidores Protheus esclavos es necesario que el servidor donde se ejecuta el CtreeServer comparta el directorio protheus_data a través de NFS. Validación de Funcionamiento: Para validar su funcionamiento es necesario conectarse a través del cliente ctadm. Tal como se describe en la sección correspondiente. Implicaciones de caídas parciales: Definamos una caída parcial de CTreeServer cuando por alguna razón un usuario obtiene un error de Protheus donde le indica que la sesión de CtreeServer ya no está disponible. Este tipo de errores son poco frecuentes y generalmente están asociados a caídas de conexión y solo afectan a un usuario. En este caso el procedimiento solo implica que el usuario reingrese al sistema. Implicaciones de caídas completas: En el caso de que el CTreeServer tenga un error fatal y se cierre sin previa notificación generará que TODAS LAS SESIONES DE PROTHEUS MARQUEN ERROR. El error se genera a nivel de sesión, la caída de CTreeServer no implica de ningún otro componente En este caso el procedimiento de recuperación implica la revisión de los logs del CTreeServer para determinar la causa y el intento de reinicial el servicio. Si el CTreeServer se levanta sin problemas los usuarios pueden volver a abrir la sesión. TopConnect Ubicación estándar: En todos los servidores de aplicación de la solución. Orden de Arranque: El componente topConnect debe ser arrancado después del Protheus Master. Dependencias: DBMS: Aunque la no disponibilidad del DBMS no evita la ejecución del TopConnect es indispensable que el DBMS esté levantado para poder ejecutar cualquier sesión de Protheus. Validación de Funcionamiento: Para validar su funcionamiento de bajo nivel se recomienda ejecutar un telnet IP_SERVER PUERTO_ESCUCHA para validarque el puerto esté abierto y aceptando requisiciones. Además la herramienta de diagnóstico y monitoreo de esta herramienta es el TopMonitor que puede ser ejecutado desde cualquier PC. ADVPL Básico 7 Educación Corporativa – TOTVS Protheus 10 7 de 51 El topmonitor solicita la IP y el puerto de escucha del topconnect Server y permite el monitoreo de diversas variables de este componente. Para más detalle referirse a la ayuda de topmonitor. Implicaciones de caídas completas: En el caso de que el TopConnect sufra de un error fatal todas las sesiones Protheus se cerraran. Los servicios Protheus Servers se mantienen ejecutando aunque en este caso se recomienda el reinicio de todos los componentes. El único procedimiento de respuesta implica el intento de levantar nuevamente el servicio. Componentes Lógicos (Definición de ambiente) Un ambiente Protheus se configura en el mp8srv.ini y está definido principalmente por 3 elementos: La funcionalidad del ambiente, es decir el archivo RPO representado por la variable SOURCEPATH que le indica al Protheus Server la ubicación del archvo RPO. Nota:Estrictamente hablando las variables RpoLanguage, RpoDB y RPOVersion también son indispensables para ubicar el RPO ya que en base a ellos define el nombre del archivo. La configuración almacenada en los archivos SXs (Diccionario de Datos).Las variables ROOTPATH y SOURCEPATH le indican al Protheus Server la ubicación del directorio system que contiene tanto los archivos SXs como otros archivos básicos de Protheus, por ejemplo: Los archivos de ayuda contextual. (SIGAHL*.HL*) El archivo de control de usuarios, el sigapss.spf El archivo de empresas existentes, el sigamat.emp Los datos necesarios para establecer la conexión con TopConnect. Representados por las variables TopServer, TopDatabase, TopAlias. [ambiente] SourcePath=/microsiga/mp8root/protheus8/apo/server/ambiente/ RootPath=/microsiga/mp8root/protheus_data/ CTreeRootPath=/microsiga/mp8root/protheus_data/ StartPath=/system RpoDb=top RpoLanguage=Spanish RpoVersion=811 LocalFiles=CTREE Pictformat=AMERICAN DateFormat=STANDARD TopDatabase=ORACLE TopAlias=DADOSADV TopServer=192.168.1.1 TOPPORT=6789 helpserver=lnx01/protheus8_help ADVPL Básico 8 Educación Corporativa – TOTVS Protheus 10 8 de 51 theme=flat Archivos Sxs Los archivos Sxs almacenan una parte vital de la configuración de Protheus. Estos archivos se almacenan en el servidor de aplicación maestro y son altamente usados durante la operación de Protheus. Entre otras cosas en estos archivos se guardan: La lista de preguntas. La lista de tablas de datos de usuario en la DB. La lista de los campos de usuario. Los índices definidos para cada tabla Los gatillos a ejecutar Los parámetros generales del sistema. Las relaciones entre campos Las consultas estandard. Tipos de archivo para el diccionario de datos (dtc vs dbf) Originalmente Protheus utilizó estos archivos en formato tipo dbf, por lo que su uso se ha convertido en el estándar en la plataforma Windows. Sin embargo para instalaciones mayores a los 40 usuarios en plataformas Windows y para las plataformas basadas en Linux el formato estandar de estos archivos es el dtc. Ejercicio 2, Identificación del contenido de los archivos SXs y mapeo entre el configurador y el contenido de las tablas. Abre una sesión de configurador y una de APSDU para identificar las características principales de los archivos SXs. Abre los archivos SX2, SX3 y SIXS en APSDU y despliega la opción de Base de Datos en configurador y revisa el contenido. Abre el archivo de parámetros y gatillos en el APSDU y las opciones correspondientes en el configurador y revisa el contenido. Parte II. Conceptos genéricos de lenguaje ADVPL Origen del Lenguaje y evolución El lenguaje de programación ADVPL, tiene el objetivo de permitir al usuario de Advance Protheus, construir sus propios programas, agregarlos a los Menús de los módulos y ejecutarlos de una forma transparente al operador,. De forma análoga, las rutinas escritas por el usuario también pueden ser ejecutadas por medio de la función ExecBlock() o U_<Funcion>, donde el Advance Protheus acepta una expresión que es ejecutada en tiempo real. ADVPL Básico 9 Educación Corporativa – TOTVS Protheus 10 9 de 51 El lenguaje ADVPL tiene su inicio en 1994, siendo en verdad una evolución en el uso de lenguajes en el estándar xBase por Microsiga Software, S.A. (Clipper, Visual Objects y después FireWin). Con la creación de la tecnología Protheus, era necesario crea un lenguaje que soportara el estandard de funcione s de xBase para el mantenimiento de todo el código existente de el sistema ERP SIGA Advanced. Fue entonces creado el lenguaje llamado Advanced Prothues Lenguage. El ADVPL, es una extensión del estándar xBase de comandos y funciones, operadores, estructuras de control de flujo y palabras reservadas, contando también con comando y funciones disponible por Microsiga que lo transforma en un lenguaje completo para la creación de aplicaciones ERP listas para Internet. También es un lenguaje orientado a objetos y eventos, permitiendo al programador desarrollar aplicaciones visuales y crear sus propias clases y objetos. Cuando son compilados todos los archivos del código son transformados en unidades de inteligencia básicas, llamados APO’s (advanced Protheus Objects). Tales APO’s son mantenidos en un repositorio y cargados dinámicamente por el Advanced Prothues Server para la ejecución. Como no existen encadenamientos (Links), o union física del código compilado a un determinado modulo o aplicación, funciones creadas en ADVPL puede ser ejecutada en cualquier punto de ambiente Advanced Protheus. El compilador y el interpretador de el lenguaje ADVPL es el propio servidor Advanced Protheus y existe un ambiente visual para el desarrollo (IDE), donde el código puede se creado, compilado y depurado. La herramienta de desarrollo mp8ide (IDE) El MP8IDE es un ambiente integrado de desarrollo diseñado por Microsiga que permite la codificación y compilación de programas ADVPL dentro de ambientes Protheus. Además de ser un editor de programas el ADVPL cuenta herramientas para administrar el proyecto de adecuaciones, para interactuar con el repositorio de funcionalidad (RPO) y con su bitácora de actualizaciones, para depurar programas en un ambiente Protheus en ejecución y hasta para generar código de uso común. Configuraciones y preferencias Para lograr que el IDE pueda ser utilizado para compilar nuevas funcionalidades en un ambiente Protheus es necesario configurar dicho ambiente de trabajo en el IDE. Antes de configurar el ambiente de trabajo iniciemos con la configuración del idioma por default de la aplicación: en la opción de menú Archivo-Preferencias se puede seleccionar entre otras cosas el idioma deseado de la interface y las informaciones que influyen en el comportamiento de Advance Protheus IDE, o sea, el Perfil de teclas utilizado, Colores de los Fuentes, Tabuladores, etc.el estilo de IDE con el que se desea trabajar. Después de la definición de las Preferencias que serán utilizadas, se debe configurar el Ambiente de Trabajo que será utilizado por el compilador, o sea, cual camino deberá ser usado por la herramienta IDE, para actualizar un determinado RPO, durante la compilación de los fuentes. Esta definición se hace desde el menú Archivos- Configuraciones. Ejercicio 3. Cambiar las preferencias del IDE Cargue el “Advance Protheus Server”, a través del atajo en Desktop. Entre a la Herramienta IDE, de la misma manera. Selecciona las opciones “Arquivo” + “Preferencias” En la pasta “General”, en “Estándar de Teclas Utilizadas”, seleccione la opción “Visual C++”. En Configuraciones del Editor selecciones “Idioma “, “Español” Marque la opción “Ignorar todos los fuentes no encontrados”, que esta localizado en la parte inferior En la pasta de “Código”, verifique los colores que serán utilizados durante la “digitación del Fuente”. ADVPLBásico 10 Educación Corporativa – TOTVS Protheus 10 10 de 51 En la pasta “Control de Versión”, informe el “camino del Software” utilizado para realizar el “Control de Versión de los Fuentes”, en caso de que sea utilizado alguno. Ejercicio 4. Configurar ambiente de Trabajo Selecciona “Archivos” + “Configuraciones” Clic en la opción “Adicionar” En el campo “Descripción”, informe el nombre del ambiente a ser utilizado, puede ser “Environment”, o un nombre relacionado al curso , como “Curso ADVPL”. En la pasta “Compilación”, informe en el campo “Ambiente” el “Nombre del Ambiente” a se utilizado por el compilador. Deberá ser un ambiente valido que se encuentre dentro del “Advance Protheus Server MP8SRV.INI”, que en este caso seria Environment. En el campo “Conexión” informe el protocolo valido, para la conexión con al Advance Protheus Server, que deberá ser TCP. Por ultimo, en el campo Directorio de Incluyes, informe el camino de los directorios donde se encuentran la bibliotecas de los programas (*.CH), ese camino deberá ser “C:\mp8\include”, después confirme la “Configuración de Ambientes” Concepto de Proyecto y Programas El IDE asume la existencia de un proyecto de trabajo que integra todos los archivos fuente de las adecuaciones de una implantación. Un proyecto es un archivo de texto con extensión .prj que es creado por el IDE a través de la opción de menú Proyectos-Nuevo. Para compilar un programa es necesario adicionar de manera explicita el archivo fuente al projecto . De lo contrario las opciones de compilación no son activadas en el IDE. Ejercicio 5. Generando un Proyecto de Trabajo. Seleccione “Proyectos” +”Nuevo”, coloque un nombre al proyecto por ejemplo, “Curso” Adicione del programa performance.prw al proyecto en uso. 1. Clique con el botón derecho del Mouse sobre la pasta de “Fontes” del mismo. 2. Deleccione la opción “Adicionar Archivos”, posicionando el cursor sobre el programa y confirmar. Compile clicando con el botón derecho del Mouse sobre el programa en cuestión y seleccione la opción compilar archivo. Será solicitado el “Usuario”, en este caso admin. Con Password en blanco. Ejercicio 6 Eliminar un archivo del proyecto y funciones del RPO Revisión de las principales opciones del IDE Menu Funciones relacionadas con Archivo Apertura, cierre y guardado de archivos de programas. Configuracion del IDE. Editar Funciones de búsqueda y edición de texto en el archivo en proceso de edición y en ADVPL Básico 11 Educación Corporativa – TOTVS Protheus 10 11 de 51 los archivos existentes Insertar Acciones para insertar textos predefinidos al archivo en edición Visualizar Accesos a ventanas de información del RPO, ventanas de depuración y otras Proyectos Creación, apertura, y guardado de archivos de proyecto. Opciones de adición de programas a proyectos. Ejecución Opciones para interactuar con el depurador de programas. Herramientas Herramientas de interacción con el RPO para su actualización, compactación y verificación. Ciclo de vida del RPO (ptm,pak, upd) Ejercicio 7. Ejecutar un mantenimiento al RPO desde el IDE. Aplica un archivo upd al RPO en uso. Verifica el log de repositorio del RPO Compacta el RPO. Variables y Tipos de datos Tipos de datos ADVPL ofrece los tipos de datos típicos de un lenguaje de 3a generación y además ofrece tipos de datos avanzados, dado que el lenguaje no requiere de una tipificación explícita para las variables, existe un estándar de nomenclatura que se maneja en Microsiga para que el nombre de la variable defina su tipo tal como se describe en la tabla siguiente : Nomenclatura sugerida Tipo cVar Carácter nVar Numérico dVar Fecha lVar Lógico mVar Memo aVar Array uVar Sin definición oVar Objeto http://www.clicketyclick.dk/databases/xbase/format/data_types.html ADVPL Básico 12 Educación Corporativa – TOTVS Protheus 10 12 de 51 Declaración de variables y asignación de valores La declaración de las variables puede hacerse en cualquier punto de una rutina, sin embargo se recomienda que sean hechas siempre en el inicio de la rutina que la utilizara. Cuando no atribuimos ningún valor a una variable en el momento de su declaración, corremos el riesgo de utilizarla con el valor NIL y causar errores fatales. Por eso, la inicialización de una variable es de extrema importancia.por ejemplo: Static Function a910VerCod() Local cCod910 := ”001” Return Ejercicio 8. Declaración de variables y usos típicos. Crea un archivo nuevo en el IDE, guardalo como ejercicioX.prw Codifica el siguiente programa que utilizaremos como base para algunas pruebas de tipos de datos. user function DeclaracionVariables1 Local cVar1 := 'Hola Mundo' Local nVar2 := 9.99 Local dVar3 := CtoD('01/01/2007') Local lVar4 := .T. Conout('') Conout('') Conout('') Conout('Los valores asignados son: Fecha: ') Conout('') Conout(DtoC(dVar3) + ', Valor numerico' + Str(nVar2) + ', String ' + cVar1 )) Conout('') Conout('') Conout('') return user function DeclaracionVariables1 Local cVar1 := 'Hola Mundo' Local nVar2 := 9.99 Local dVar3 := CtoD('01/01/2007') Local lVar4 := .T. Conout('') Conout('') Conout('') Conout('Los valores asignados son: Fecha: ') Conout('') nVar := nVar2 + cVar1 Conout('') Conout('') Conout('') return Alcance (Scope de las variables) Una característica importante del ADVPL es el alcance de las variables y las funciones que definimos. Los alcances posibles de las variables en ADVPL se describen a continuación: 1. PUBLIC: Esta variable será inicializada en un valor lógico falso (.F.), hasta que sea atribuido un valor especifico. Esta variable permanece definida por toda la duración de la aplicación y puede ser vista por cualquier función. Esta variable genera un token en la tabla de símbolos, esto significa que el modulo principal contendrá símbolos para esta clase de variables, lo que a su vez, ocupa mas espacio de memoria, debe evitar el uso de este tipo, use solo en casos extremos. http://www.clicketyclick.dk/databases/xbase/format/data_types.html ADVPL Básico 13 Educación Corporativa – TOTVS Protheus 10 13 de 51 2. PRIVATE: Esta variable será inicializada en valor nulo (NIL) y una vez declarada, permanecerá así durante toda la duración de el flujo de la función, hasta que este regrese al procedimiento inicial que la llamo. En esencia, una variable de memoria Private inicializada después en el inicio del Protheus, actuara como variable Public. 3. LOCAL: Esta variable será inicializada con valor nulo (NIL) y solo es visible dentro de la función que la inicializa. 4. STATIC: Es idéntica a la Local, con una excepción. Una variable Static, es retenida dentro de su subrutina, después que el flujo de la función es liberado. Tipos estructurados Conjunto de variables de memoria con un mismo nombre, que tienen un índice para diferencia un elemento del otro. Algunas veces el tamaño de la matriz es conocido previamente. Otras veces el tamaño de la matriz solo será conocido en tiempo de ejecución. Declaración de variables arrays y asignación de valores Si el tamaño de la matriz es conocido, puede ser declara de las formas siguientes: Local aX[10] Local aZ:={0,0,0,0,0,0} Local aB:= Array(10) Si el tamaño de la matriz NO es conocido, puede ser declarado de las formas siguientes: Local aX[0] Local aZ:={} Local aB:= Array(0) Funciones para el manejo de arrays Existen diferentes funciones relacionadas con las matrices. Una descripción breve de la finalidad de cada una de esas funciones se muestra a continuación. Además de esas funciones especificas para el manejo de matrices, pueden usarse otras funciones sobre una matriz, tales como LEN(), para verificar el tamaño o numero de elementos, TYPE() o VALTYPE(), para verificar el tipo de elemento de la matriz. AADD() Agrega, un elemento al final de la matriz especificada. ACLONE() Duplica es decir, crea una nueva matriz que es idéntica, en tamaño y contenido, a la matriz fuente. ACOPY() Copia los elementos de una matriz a otraADEL Borra un elemento de la matriz ADIR() Llena una o mas matrices con los datos de un directorio. AEVAL() Evalúa un bloque de código para cada elemento de la matriz. AFIELDS() Llena una o mas matrices con el nombre y la descripción de los campos de un archivo AFILL() Llena una matriz con un valor determinado. AINS() Inserta, un elemento en una posición determinada de la matriz. ASCAN() Busca, un determinado valor dentro de la matriz. ADVPL Básico 14 Educación Corporativa – TOTVS Protheus 10 14 de 51 ASIZE() Redimensiona, el tamaño de una matriz. ASORT() Coloca en orden creciente o decreciente los elementos de una matriz. Ejercicio 10. Declaración y manejo de arreglos Crea un nuevo archivo de programa llamado Arreglos1, dentro de este programa codifica la siguiente función user function Arreglos1 Local acX[10] Local anZ:={1,2,3,4,5.5,1000} Local aB:= Array(10) Local nSuma:=0.0 Local acX[1]:='Hola' Local acX[2]:='Mundo' Conout(acX[1] + ' ' + acX[2]) nSuma := anZ[1] + anZ[2] + anZ[3]+ anZ[4] + anZ[5] + anZ[6] Conout(Str(nSuma)) Return User Function VarArray Local aX[0] Local aZ:={} Local aB:= Array(0) Conout(Str(Len(Ax))) AADD(aX,'ZZZZZ ') Conout(Str(Len(Ax))) AADD(aX,'AAAAA') Conout(aX[1] + ' ' + aX[2]) AADD(aX,25) Conout(aX[1] + ' ' + aX[2] + ' ' + Str(aX[3])) ConOut(str(ASCAN(aX,25))) /* ASORT(aX) Conout(aX[1] + ' ' + aX[2] + ' ' + Str(aX[3])) */ return User Function VarArray Local aX[0] Local aZ:={} Local aB:= Array(0) Conout(Str(Len(Ax))) AADD(aX,'ZZZZZ ') Conout(Str(Len(Ax))) AADD(aX,'AAAAA') Conout(aX[1] + ' ' + aX[2]) AADD(aX,'CCCCCC') Conout(aX[1] + ' ' + aX[2] + ' ' + aX[3]) ConOut(str(ASCAN(aX,25))) ASORT(aX) Conout(aX[1] + ' ' + aX[2] + ' ' + aX[3]) return ADVPL Básico 15 Educación Corporativa – TOTVS Protheus 10 15 de 51 Operadores y precedencia de ejecución 1. Operadores de Incremento/Decremento 2. Operadores de String 3. Operadores Matemáticos 4. Operadores Relacionales 5. Operadores Lógicos 6. Operadores de Asignación 7. Operadores de Incremento/Decremento En expresiones complejas: Exponenciacion Multiplicación y división. Adición y substracción. Considere o ejemplo: Local nResultado := 2+10/2+5*3+2^3 El resultado de esta expresión es 30, pues primeramente es calculada la exponenciacion 2^3(=8), entonces son calculadas las multiplicaciones y divisiones 10/2(=5) e 5*3(=15), y finalmente las adiciones resultando en 2+5+15+8(=30). Operadores básicos Operadores matemáticos + Adición - Resta * Multiplicación / División ** o ^ Exponenciacion % Módulo o Residuo de la división Operadores strings + Concatenación de strings - Concatenación de strings con eliminación de los blancos finales de los strings intermediarios $ Comparación de Substrings (contenido en) ADVPL Básico 16 Educación Corporativa – TOTVS Protheus 10 16 de 51 Operadores de comparación < Menor que > Mayor que = Igual == Exactamente Igual (para caracteres) <= Menor o Igual >= Mayor o Igual <> ó # ó != Diferente Operadores Lógicos .And. Y .Or. O .Not. ó ! Negación Ejercicio 11. Uso de operadores básicos user function operator local nA:=0 local nB:=0 local c1:= 'HOLA ' local c2:= ' MUNDO' local c3:= 'UN' local c4:= '' local lresultado := .T. // .F. c4 := c1 + c2 conout(c4) c4:= c1 - c2 conout(c4) c4 := Trim(c1) + ' ' + LTrim(c2) conout(c4) lresultado:= c3 $ c1 if lresultado conout('"' + c3 + '" SI ESTA CONTENIDO EN "' + c1 + '"') ADVPL Básico 17 Educación Corporativa – TOTVS Protheus 10 17 de 51 else conout('"' + c3 + '" NO ESTA CONTENIDO EN "' + c1 +'"') endif lresultado:= c3 $ c2 if lresultado conout('"' + c3 + '" SI ESTA CONTENIDO EN "' + c2 + '"') else conout('"' + c3 + '" NO ESTA CONTENIDO EN "' + c2 +'"') endif return Operadores de asignación = Asignación simple := Asignación en línea += Adición de asignación en línea -= Sustracción de asignación en línea *= Multiplicación de asignación en línea /= División de asignación en línea **= ó ^= Exponenciacion y de asignación en línea %= Módulo (residuo) de asignación en línea Asignación simple El signo de igual es utilizado para asignar valor a una variable de memoria. nVariavel := 10 Asignación en Línea El operador de asignación es caracterizado por 2 puntos y el signo de igual. Tiene la misma función del signo de igualdad solito, sin embargo aplica la asignación a varias. Con el se puede se puede asignara a mas de una variable al mismo tiempo. nVar1 := nVar2 := nVar3 := 0 ó Local nVar1 := 0, nVar2 := 0, nVar3 := 0 por Local nVar1 := nVar2 := nVar3 := 0 Asignación Compuesta Son una facilidad del lenguaje ADVPL para expresiones de calculo y atributos. Con ello se puede economizar la digitación. Operador Exemplo Equivalente a ADVPL Básico 18 Educación Corporativa – TOTVS Protheus 10 18 de 51 += X += Y X = X + Y -= X -= Y X = X - Y *= X *= Y X = X * Y /= X /= Y X = X / Y **= o ^= X **= Y X = X ** Y %= X %= Y X = X % Y Operadores de Incremento y Decremento ++ Incremento -- Decremento Ejemplos: Local nA := 10 Local nB := nA++ + nA Operadores especiales Además de los operadores comunes, el AdvPl posee algunos otros operadores o identificadores. () Agrupamiento o Funcion [] Elemento de Matriz {} Definición de Matriz, Constante o Bloque de Código -> Identificador & Macro substitución @ Paso de parámetros por referencia Elementos de programación estructurada Tipos de funciones Durante el desarrollo de los programas ADVPL, se debe considerar que existen dos tipos de Funciones User Function y Static Function. Cuando una función es declarada tipo User, esta deberá ser llamada de la forma: U_NomFunc() Y podrá ser usada en cualquier programa o modulo del Protheus, entonces cuando declaramos una función como User, la estamos declarando tipo Publica. Si fuese Static, esta deberá ser llamada de la forma: NomFuncSta() ADVPL Básico 19 Educación Corporativa – TOTVS Protheus 10 19 de 51 Al ser declarada como Static solo podrá ser usada dentro del miso programa en donde fue desarrollada, pudiese decirse que entonces actúa de forma local. Ejercicio 12 Entendimiento del alcance de variables y funciones user function alc1 local nA:=0 Private nB:=5 u_alc2() u_alc3() conout('') conout('') conout (str(nB)) conout('') conout('') return user function alc2 local nC:=2 nB:=nB + 3 return user function alc3 local nC :=3 nB := nB * nC return user function alc1 local nA:=0 Private nB:=5 u_alc2() u_alc3() // u_alc4() alc4() conout('') conout('') conout (str(nB)) conout('') conout('') return user function alc2 local nC:=2 nB:=nB + 3 return user function alc3 local nC :=3 nB := nB * nC return static function alc4 conout('') conout('Desde una funcion estatica') conout (str(nB)) conout('') conout('') return ADVPL Básico 20 Educación Corporativa – TOTVS Protheus 10 20 de 51 Funciones de uso común Funciones para interactuar con fechas CDOW() Retorna el nombre del día de la semana. CMONTH() Retorna el nombre del mes. CTOD() Convierte una cadena en fecha DATE() Retorna fecha del sistema DAY() Retorna el día del mes. DOW() Retorna el día del sistema. DTOC() Transforma la fecha en cadena. DTOS() Transforma la fecha en formato cadena para índices AAAAMMDD DMY() Transforma la fecha en formato DD/MM/AA MDY() Transforma la fecha en formato MM/DD/AA MONTH() Retorna el numero de mes. TIME() Retorna la hora del sistema. YEAR() Retorna el año. Por ejemplo: Para inicializar una variable que será de tipo fecha se hace: Local dFecNew := CTOD(“ / / “) Funciones para manejo de cadenas de caracteres: AT() Búsqueda de Cadena LEFT() Retorna una subcadena de la parte izquierda del texto LEN() Retorna el numero de caracteres en el texto LOWER() Transforma el texto en minúscula LTRIM() Remueve espacios iniciales en blanco PADC) Centra la variable dentro de un espacio PADL() Ajusta la variable a la izquierda dentro de un espacio PADR() Ajusta la variable a la derecha dentro deun espacio REPLICATE() Repite un texto un numero determinado de veces RIGHT() Retorna una subcadena de la parte derecha del texto RTRIM() Remueve espacio finales en blanco SPACE() Genera una cadena de espacios en blanco ADVPL Básico 21 Educación Corporativa – TOTVS Protheus 10 21 de 51 STUFF() Sustituye una parte de la cadena SUBSTR() Extrae una subcadena TRANSFORM() Retorna el argumento en un formato especificado TRIM Remueve espacio en blanco finales e iniciales. UPPER() Transforma el texto en mayúsculas Ejercicio 13. Uso de funciones user function datefunc local ndia:=0 local ndiasem:=0 local nmes:=0 local nanio:=0 local dFecha:= Date() ndia:=Day(dFecha) ndiasem:=DoW(dFecha) nmes:=Month(dFecha) nanio:=Year(dFecha) Conout ('Hoy es el dia ' + str(ndia,4) + 'del mes ' + str(nmes,4) + ' del año' + str(nanio,6) + 'Dia de semana ' + Str(ndiasem,4) + ' Fecha completa' + DtoC (dFecha)) return Paso de parámetros Ejercicio 14. Funciones con parámetros user function func1 local cmsg := 'HOLA MUNDO' local nValor:=1 mensaje(cmsg) Conout('Antes de pasar' + nValor) Func2(@nValor) Conout('Despues de pasar' + nValor) Conout(nValor) return static function func2( npar1) nPar1:=25 mailto:@nValor ADVPL Básico 22 Educación Corporativa – TOTVS Protheus 10 22 de 51 return user function mensaje ( cpar1) conout('') conout('') Conout(cpar1) conout('') conout('') return Macro Substitución El operador de macro substitucion simbolizado por (&), es utilizado para la aplicación de expresiones en tiempo de ejecución. Funciona como si una expresión almacenada fuese compilada en tiempo de ejecución, antes de ser de hecho, ejecutada. Por ejemplo: 01 X := 10 02 Y := "X + 1" 03 B := &Y //El contenido de B será 11 La variable X es asignada con el valor 10, en tanto la variable Y es asignada con el string de caracteres conteniendo "X + 1". La tercera línea utiliza el operador de macro. Esta línea hace que el número 11 sea asignado a la variable B. Se puede ver que ese es el valor resultante de la expresión en formato caracter contenida en la variable Y. Utilizando una técnica matemática elemental, la substitución, tenemos que en la segunda línea, Y es definido como "X + 1", entonces se puede sustituir Y en la tercera línea: 03 B := &"X + 1" El operador de macro cancela las dobles comillas: 03 B := X + 1 El operador macro tiene una limitación: variables referenciadas dentro de el string de caracteres (X en los ejemplos anteriores) no pueden ser locales. Ejercicio 15. Ejemplo de Macro substitución user function macro1 private nA:=1 u_macro2() return user function macro2 local nB:=0 local cC:='' ADVPL Básico 23 Educación Corporativa – TOTVS Protheus 10 23 de 51 cC:= 'nA * 25' nB:= &cC conout('') conout('') Conout(Str(nB)) conout('') conout('') return Bloques de código Los bloques de código se parecen a una macro, solo que con algunas importantes diferencias. En una macro una expresión es un valor literal que solo se conoce durante la ejecución del programa, cuando el macro se procesa. Si existiera un error de sintaxis, o cualquier otro tipo, este error ocurrirá en el proceso de runtime. El compilador por otra parte, compila el bloque de código. Cualquier error se identifica a nivel de compilación. Además de eso el bloque de código solo se compilara la primera vez. Si usted utiliza una macro, cada vez que tenga necesidad de utilizar la expresión, la macro tendrá que compilarse, lo que demuestra que la macro será mas lenta en un proceso intenso. Una lista de expresiones es como un pequeño programa o función. Con pocos cambios, una lista de expresiones se pueden transformar en un bloque de código. ( X := 10 , Y := 20 ) // Lista de Expresiones {|| X := 10 , Y := 20 } // Bloque de Código Note las llaves {} utilizadas en el bloque de código. O sea, un bloque de código es una matriz. Sin embargo no lo es, y si una lista de comandos, una lista de código. // Esto es una matriz de datos A := {10, 20, 30} // Esto es un bloque de código, sin embargo funciona como //si fuese una matriz de comandos. B := {|| x := 10, y := 20} Ejecución de un Bloque de Código nRes := Eval(B) ==> 20 La función Eval recibe como parámetro un bloque de código y ejecuta todas las expresiones contenidas, retornando el resultado de la última expresión ejecutada. Pasando Parámetros Como el bloque de código son como pequeñas funciones, también es posible el pase parámetros. Los parámetros deben ser informados entre las barras verticales (||) separados por comas, igual que una función. B := {| N | X := 10, Y := 20 + N} En l siguiente expresión se muestra el pase del parámetro, donde envía un 1 a N, y entonces ejecuta el bloque B. C := Eval(B, 1) ==> 21 Utilizando Bloques de Código Los bloques de código pueden ser usados en diversas situaciones. Generalmente son utilizados para ejecutar tareas en los cuando eventos de objetos accionados o para modificar el comportamiento estándar de algunas funciones. ADVPL Básico 24 Educación Corporativa – TOTVS Protheus 10 24 de 51 Por ejemplo, considere la matriz: A := {"GARY HALL", "FRED SMITH", "TIM JONES"} Esta matriz puede ser ordenada por el primer nombre, utilizando la función asort(A), resultado la matriz de la forma: {"FRED SMITH", "GARY HALL", "TIM JONES"} El orden por default en la función asort ascendente. Este comportamiento puede ser modificado a través de un bloque de código que ordena la matriz en forma descendente: B := { |X, Y| X > Y } aSort(A, B) El bloque de código (de acuerdo con la documentación de la función asort) debe ser escrito para aceptar 2 parámetros que son los dos elementos de la matriz para comparación. Note que el bloque de código no conoce que elementos se están comparando. Entonces si la comparación X > Y es verdadera los elementos están en orden descendente, lo que significa que el primer valor es mayor que el segundo. Para ordenar la misma matriz por el último nombre, también en orden descendente, se puede utilizar el siguiente bloque de código: B := { |X, Y| Substr(X,At(" ",X)+1) > Substr(Y,At(" ",Y)+1) } Note que este bloque de código busca y compara las partes de los caracteres inmediatamente después de un espacio en blanco. Despues de utilizar ese bloque para la función asort, la matriz contendrá: {"GARY HALL", "TIM JONES", "FRED SMITH"} Finalmente, para ordenar un sub-elemento (columna) de una matriz por ejemplo, se puede usar el siguiente bloque de código: B := { |X, Y| X[1] > Y[1] } Ejercicio 16. de Bloques de código user function bloques local oB := {|| x := 10, y := 20} local nRes:=50 nRes := Eval(oB) u_Mensaje(Str(nRes)) oB:={|N| x := 10, y := 20, y:=N+x+y} nRes := Eval(oB,5) u_Mensaje(Str(nRes)) return Estructuras de control de flujo Condicionales Desvio condicional La estructura se representa por el comando IF..ENDIF Sintaxis ADVPL Básico 25 Educación Corporativa – TOTVS Protheus 10 25 de 51 IF lExpresion //Comandos &&Si es verdadera ELSE //Comandos &&Si es falsa ENDIF Formas mas simples: IF <condicion> //Comandos &&Si es verdadera ENDIF Parametros lExpresion Especifica una expresión lógica que es valida. Si lExpresion resulta verdadera (.T.), cualquier comando que sigue al IF y antecede al ELSE o IF (o lo que ocurra primero) será ejecutado. Si lExpresion resulta falso (.F.) y la cláusula ELSE fue definida, cualquier comando después de esa cláusula y antes del ENDIF sera ejecutada. Comandos Conjunto de comando ADVPL que serán ejecutados dependiendo del resultado en lExpresion. Do Case Ejecuta el primer conjunto de comandos cuya expresión condicional resulta en verdadero (.T.). Sintaxis DO CASE CASE lExpresion1 [CASE lExpresion2] //Comandos … [CASE lExpresionN] //Comandos … [OTHERWISE] //Comandos … ENDCASE Parametros CASE lExpresion1 Comandos.. Cuando la primer expresión CASE resulta verdadera (.T.) el conjunto de comandos siguiente es ejecutado. La ejecución del conjunto de comandos continua hasta que la próxima cláusula CASE, OTHERWISEo ENDCASE sea encontrada. Al terminar de ejecutar ese conjunto de comandos, la ejecución continua con el primer comando siguiente al ENDCASE. OTHERWISE Comandos Si todas las expresiones CASE fueron ejecutadas como falso (.F.), la cláusula OTHERWISE determina si un conjunto adicional de comandos debe ser ejecutado. Si esa cláusula fue incluida, los comandos siguientes serán ejecutados y entonces el programa continuara con el primer comando siguiente al ENDCASE.. si la cláusula OTHERWISE fue emitida, la ejecución continuara normalmente después de la cláusula ENDCASE. ADVPL Básico 26 Educación Corporativa – TOTVS Protheus 10 26 de 51 El comando DO CASE..ENDCASE es utilizado en logar del comando IF..ENDIF cuando un numero mayor de una expresión debe ser validada, sustituyendo la necesidad de mas de un comando IF..ENDIF anidados. De ciclo Do While La estructura de control WHILE..ENDDO, repite una sección de código en tanto una determinada expresión resulta en verdadero (.T.). Sintaxis WHILE lExpresion1 //Comandos [EXIT] [LOOP] ENDDO Parametros lExpresion Especifica una expresión lógica cuyo valor determina cuando los comandos entre el WHILE y el ENDDO son ejecutados. Mientras el resultado de lExpresion sea verdadero (.T.) el conjunto de comandos será ejecutado. Comandos Una o mas instrucciones en ADVPL . EXIT Sale de ciclo While. LOOP Retorna el control directamente a la cláusula WHILE. For La estructura de control FOR..NEXT, o simplemente el loop FOR, repite una sección de código en un numero determinado de veces. Sintaxis FOR Variable:=nValorInicial TO nValorFinal [STEP nIncremento] //Comandos [EXIT] [LOOP] NEXT Parametros Variable Especifica una variable o un elemento de una matriz para actuar como contador. nValorInicial TO nValorFinal nValorinicial es un valor inicial para el contador; nValorFinal es el valor final para el contador. Es posible usar valores numéricos literalmente, variable o expresiones, teniendo en cuenta que el ADVPL Básico 27 Educación Corporativa – TOTVS Protheus 10 27 de 51 resultado del tipo de dato sea numérico . STEP nIncremente Será la cantidad que será incrementada o decrementada en el contador después de cada ejecución . si el valor de nIncemento fuera negativo, el contador será decrementado.Si la cláusula STEP fuese omitida, el contador será incrementado en 1.El tipo de datos aquí debe ser numérico. LOOP Retorna el control directamente a la cláusula FOR EXIT Sale del ciclo FOR. ADVPL Básico 28 Educación Corporativa – TOTVS Protheus 10 28 de 51 Funciones Protheus para interacción con usuarios Existen una gran cantidad de comandos y funciones que permiten generar interfaces de usuario utilizando el ambiente típico Protheus. Una revisión detallada de estas funciones es parte del curso avanzado de ADVPL, sin embargo mostraremos con un ejemplo el uso de algunas de ellas para generar un mensaje de notificación y un cuadro de dialogo con botones que detonan acciones. Ejercicio 15. Interacción con el usuario #include "Rwmake.ch" User function msg1() cNome:= 'Microsiga' msgAlert('Hola Mundo') Return cNome User Function Cuadro1() Local cTit := OemtoAnsi("Ventana de Interaccion avanzada") Local cMsj1 := "De esta manera podemos generar cuadros de dialogo" Local cMsj2 := "para interactuar con el cliente" Local cOCIn := " " Local cOCFn := "ZZZZZZ" Local cFini := "" Local cFfin := "" Local cFac1:= 0.00 Local cFac2:= 0.00 Local cFac3:= 0.00 Local cFac4:= 0.00 Local cFac5:= 0.00 Local cFac6:= 0.00 Local cFac7:= 0.00 Local cFac8:= 0.00 Local cFac9:= 0.00 Local cLinea:= "ACA" _clave:="" @ 0,0 TO 250,359 DIALOG oDlg TITLE cTit @ 01,02 TO 107,179 @ 03,04 TO 105,177 @ 08,12 Say cMsj1 @ 16,12 Say cMsj2 @ 28,12 Say "L I N E A" @ 28,47 Get cLinea size 40,10 When .F. Picture "@!" //F3 "SMB" //Valid (cOCIn<=cOCFn) @ 28,95 Say "1 - Precio 0" @ 28,130 Get cFac1 size 40,10 Picture "@E 999.99" // F3 "SZ1"// Valid (cOCFn>=cOCIn) mailto:@! ADVPL Básico 29 Educación Corporativa – TOTVS Protheus 10 29 de 51 @ 43,12 Say "2 - Costo " @ 43,47 Get cFac2 size 40,10 Picture "@E 999.99" //Valid (cFini<=cFfin) @ 43,95 Say "3 - Precio 1" @ 43,130 Get cFac3 size 40,10 Picture "@E 999.99" //Valid (cFfin>=cFini) @ 58,12 Say "4 - Precio 2" @ 58,47 Get cFac4 size 40,10 Picture "@E 999.99" //Valid (cFini<=cFfin) @ 58,95 Say "5 - Precio 3" @ 58,130 Get cFac5 size 40,10 Picture "@E 999.99" //Valid (cFfin>=cFini) @ 73,12 Say "6 - P. Venta" @ 73,47 Get cFac6 size 40,10 Picture "@E 999.99" //Valid (cFini<=cFfin) @ 73,95 Say "7 - Pr. 3+5%" @ 73,130 Get cFac7 size 40,10 Picture "@E 999.99" //Valid (cFfin>=cFini) @ 88,12 Say "8 - Pr.3+10%" @ 88,47 Get cFac8 size 40,10 Picture "@E 999.99" //Valid (cFini<=cFfin) @ 88,95 Say "9 - Pr.3+15%" @ 88,130 Get cFac9 size 40,10 Picture "@E 999.99" //Valid (cFfin>=cFini) @ 110,118 BMPBUTTON TYPE 1 ACTION u_msg1() @ 110,150 BMPBUTTON TYPE 2 ACTION oDlg:End() ACTIVATE DIALOG oDlg CENTERED Return mailto:@E mailto:@E mailto:@E mailto:@E mailto:@E mailto:@E mailto:@E mailto:@E mailto:@E ADVPL Básico 30 Educación Corporativa – TOTVS Protheus 10 30 de 51 Parte III. Funciones básicas de acceso a datos. Consideraciones de filial y archivos compartidos El sistema permite la creación de varias filiales para una misma empresa registrada, de modo que las filiales de la misma empresa comparten o no los mismos datos como Catalogo de Productos, clientes, etc. Este tratamiento es hecho internamente a través de los campos XX_FILIAL obedeciendo a la siguiente regla: Archivos Compartidos Cuando el archivo esta configurado para trabajar en modo compartido (X2_MODO = ‘C’), este campo será guardado con “ ” (espacios). De este modo el registro quedara disponible para todas las filiales. Archivos exclusivos Cuando el archivo esta configurado para modo exclusivo (X2_MOD = ‘E’), este campo será guardado con el código de la filial actual. De este modo el registro quedara disponible solamente para la filial que lo registro. Para que el registro realmente quede disponible o no para sus respectivas filiales, todas las rutinas que manipulan registros directamente en la base de datos deberá verificar la filial a través de la función XFILIAL(), además de esto la mayoría de los índices poseen el campo FILIAL en la llave. Sintaxisi: XFILIAL(EXPEC1) donde, Expec1=Alias del archivo. La función XFILIAL() verifica si el archivo es exclusivo o compartido y entonces retornara “ “ si el archivo fue compartido y el código de Filial su el archivo es exclusivo. Por ejemplo: Para ejecutar un dbseek en los archivos de clientes: DbSelectaArea(“SA1”) Dbseek(XFILIAL(“SA1”)+cCodCli+CLoja) Índice de la SA1: A1_FILIAL+A1_COD+A1_LOJA Jamás utilice el campo Filial de una tabla para ejecutar un dbseek() en otra tabla. Pues una tabla podría ser compartida (campo filial en blanco), en tanto que la otra podría ser exclusiva (campo filial llenado). La variable CFILANT contiene la filial que el usuario esta operando, y la variable CEMPANT contiene la empresa y la filial. ADVPL Básico 31 Educación Corporativa – TOTVS Protheus 10 31 de 51 Ejercicio 16. Interactuando con Protheus user function funcion5 rpcsetenv("99","01") // "Define la empresa y filial en la que queremos trabajar" Conout('La filial es ' + CFILANT) Conout('La empresa es ' + CEMPANT) IF XFILIAL('SA1') ==' ' Conout('La tabla SA1 es compartida') else Conout('La tabla SA1 es exclusiva, y estoy en la filial ' + XFILIAL('SA1') ) endif IF XFILIAL('SB1') ==' ' Conout('La tabla SB1 es compartida') else Conout('La tabla es SB1 exclusiva, y estoy en la filial ' + XFILIAL('SB1') ) endif return user Function Funcion1() Local n rpcsetenv("99","01") FOR n:= 1 to 10 Funcion2(n) Conout( ' ' ) sleep( 1000 ) Next Return Static function Funcion2(_n) Local nIni, nIni2,nAnt,nAct,nRecords,nTotRecords,i local c_variable:= "" dDatabase= Date() Conout( DToc(dDatabase) + ' ' +Time() + '|' +Str(_n) + ' | ' +'Inicia Rutina usuarios-> ' + ' | ' + LTrim( Str(Len(GetUserInfoArray())) ) ) SX5->( dbGoTop() ) nIni := Seconds() nAnt:= nIni nRecords:=0 nTotRecords:=0 While ! SX5->( Eof() ) SX5->( dbSkip() ) nRecords:=nRecords + 1 if nRecords >= 600 ADVPL Básico 32 Educación Corporativa – TOTVS Protheus 10 32 de 51 nTotRecords:=nTotRecords+nRecords nRecords=0 nAct = Seconds() Conout(DToc(dDatabase) + ' ' + Time() + '|' +Str(_n) + ' | ' + '600 Records DBSkip ' + ' | ' + LTrim( Str( nAct - nAnt ) ) ) nAnt:=nAct end if Enddo Conout(DToc(dDatabase) + ' ' + Time() + '|' +Str(_n) + ' | ' + 'Tempo Total DBSkip ' + ' | ' +LTrim( Str( Seconds() - nIni ) ) ) nIni := Seconds() nAnt:= nIni FOR i:= 1 to 5000 c_variable:=Str(i) Next Conout( DToc(dDatabase) + ' ' + Time() + '|' +Str(_n) + ' | ' +'Tempo Total Ciclo ' + ' | ' + LTrim( Str( Seconds() - nIni ) ) ) nAnt:= nIni FOR i:= 1 to 5000 c_variable:=GETMV("MV_BOX") Next Conout(DToc(dDatabase) + ' ' + Time() + '|' +Str(_n) + ' | ' + 'Tempo Total Lectura SX6 ' + ' | '+LTrim( Str( Seconds() - nIni ) ) ) nAnt:= nIni FOR i:= 1 to 5000 SX2->( dbSeek( "SA1" ) ) SX2->( dbSeek( "SD2" ) ) SX2->( dbSeek( "SF1" ) ) SX2->( dbSeek( "SA3" ) ) SX2->( dbSeek( "SF2" ) ) SX2->( dbSeek( "SRA" ) ) Next Conout(DToc(dDatabase) + ' ' + Time() + '|' +Str(_n) + ' | ' + 'Tempo Total Lectura SX2 ' + ' | ' +LTrim( Str( Seconds() - nIni ) ) ) Return ADVPL Básico 33 Educación Corporativa – TOTVS Protheus 10 33 de 51 Funciones básicas de manejo de tablas DBSELECTAREA(cAlias) Abre una tabla DBSEEK(cLlave) Se posiciona en el primer registro que tenga el mismo contenido que cLlave DBSKIP() Brinca al siguiente registro EOF() Fin de Archivo cuanto el resultado es verdadero RECLOCK(cAlias,lVal,.t.) Bloquea registro, de la tabla calias, si lVal es verdadera (.T.), estará abriendo un registro en blanco y bloqueado, listo para insertarle datos. Si lVal fuese falso (.F.), solo estará bloqueando el registro, para hacer alguna modificación, borrado o consulta del mismo. MSUNLOCK() Desbloqueé registro bloqueado por instrucción RECLOCK DBSETORDER(nIndice) Abre el índice nIndice, este datos es el numero de orden del índice según el configurador. RETORDEM(cAlias,cLlave) Funcion que regresa el numero de orden del índice del cAlias donde cLlave, es el índice tal cual esta creado en el configurador. POSICIONE(cAlias,nOrden,cLlave,cCampo) Localiza un registro en la tabla . cAlias, tabla en la que buscara. nOrden, Numero de Orden del Índice con el que buscara. cLlave, Datos con los que buscara (según índice) cCampo, Nombre de algún campo de la tabla, cuyo contenido será el resultado de POSICIONE. EXISTCPO(cAlias,cLlave,nOrden) Retorna si determinada llave existe o no en la tabla. cAlias, tabla en la que buscara. nOrden, Numero de Orden del Índice con el que buscara. cLlave, Datos con los que buscara (según índice) GETAREA() Almacena el ambiente del área de trabajo anterior. RESTAREA() Restaura el ambiente del área de trabajo según el último GetArea usado. DBDELETE() Elimina registro DBGOTOP() Se coloca al inicio de la tabla DBBOTTOM() Se coloca en el ultimo registro de la tabla. ADVPL Básico 34 Educación Corporativa – TOTVS Protheus 10 34 de 51 Lectura y actualización de archivos En versiones anteriores era preciso usar el comando APPEND FROM para la inserción de un registro, aunque este comando puede seguir siendo usado. Actualmente se utiliza la función RECLOCK, la cual permite insertar un nuevo registro y al mismo tiempo bloquearlo. Analicemos el ejemplo de insertar un registros la tabla SB1: //ABRE REGISTRO EN BLANCO Y LO BLOQUEA, ESTO ULTIMO LO HACE POR QUE EL 2DO. PARAMETRO ESTA EN .T. RECLOCK(“SB1”,.T.) //ASIGNA VALOR AL CAMPO B1_COD SB1->B1_COD:=”BF1234” //DESBLOQUE EL REGISTRO SB1->(MSUNLOCK()) Si se tratara de eliminar o modificar un registro el comando RECLOCK, tendrá su segundo parámetro en .f., lo cual estará indicando que solo bloque el registro y que no esta abriendo registro en blanco, entonces el ejemplo quedaría: //SELECCIONA EL INDICE POR EL QUE REALIZARA LA BUSQUEDA SB1->(DBSETORDER(RETORDEM(“SB1”,”B1_FILIAL+B1_COD”)) //Busca el registro IF SB1->(DBSEEK(XFILIAL(”SB1”)+cCodBus)) //BLOQUEA EL REGISTRO RECLOCK(“SB1”,.F.) //ACTUALIZA INFORMACION SB1->B1_NOME:=”Nuevo producto” //DESBLOQUEA REGISTRO SB1->(MSUNLOCK()) ENDIF Índices El uso de índices para la búsqueda, debe ser bien analizada con la finalidad de evitar alentar o redundar en procesos en los reportes o procesos. Los índices ayudan a optimizar las búsquedas y ciclos de procesos, por eso no deben ser subutilizados o utilizados en forma errónea. En necesario advertir, que al crear un índice (en el configurador), los datos que lo construyen deben ser del mismo tipo, por ejemplo, si la tabla X contiene los campos: cFilial C(2) cClave C(2) dFecha D(8) nNum n(2) Pueden armarse los índices: ADVPL Básico 35 Educación Corporativa – TOTVS Protheus 10 35 de 51 cFilial+cClave+DTOS(dFecha)+str(nNum) Observe que los datos que no son tipo carácter, fueron transformados con la funciones DTOS y STR respectivamente. Estatutos SQL ADVPL no es un lenguaje que actué de forma nativa sobre las tablas de bases de datos pero lo puede hacer a través de TOP CONNECT. Para ello también existen funciones especiales que permitirán la ejecución de consultas o ejecución de query con eliminación o actualización. Para el uso de estos comando los programas deberán contener la biblioteca: #INCLUDE "TOPCONN.CH" Aquí solo hablaremos de las instrucciones mas usuales en ADVPL para el manejo de información de bases de datos. Para mayor profundidad en el tema puede hacer referencia a los manuales Programação_SQL_Intermediario y Programação_SQL_Avancado. Sin embargo aquí destacaremos con ejemplos muy completos el uso del manejo de instrucciones para SQL.. CONSULTA Deberá usar el comando ChangeQuery y dbUseArea, donde el primero interpreta la consulta lanzada y el segundo coloca el resultado de la consulta en una tabla temporal. Ejemplo: //GENERA UN NOMBRE ESPECIAL PARA LA TABLA TEMPORAL cAliasBus:=criatrab(nil,.f.) //RECUPERA EL NOMBRE FISICO DE LAS TABLA EN LA BASE cSC7RetSqlName := InitSqlName( "SC7" ) cSB1RetSqlName := InitSqlName( "SB1" ) //RECUPERA LA FILIAL DE LA TABLA cFilSc7:=xfilial("SC7") cFilSB1:=xfilial("SB1") //A CONTINUACION COLOCA EN UNA VARIABLE LA SENTENCIA DE CONSULTA cQuery := "Select C7_EMISSAO,C7_FORNECE,C7_PRODUTO " cQuery += " FROM " + cSC7RetSqlName + " SC7,"+ cSB1RetSqlName + " SB1" cQuery += " WHERE C7_FILIAL = '"+cFilSc7+"'" cQuery += "AND B1_FILIAL = '"+cFilSB1+"'" cQuery += " AND C7_PRODUTO = B1_COD " cQuery += " AND C7_PRODUTO >= '"+alltrim(cProdi)+"' cQuery += " AND C7_PRODUTO <= '"+alltrim(cProdf)+"' cQuery += " AND B1_GRUPO >= '"+alltrim(cGPO1)+"' ADVPL Básico 36 Educación Corporativa – TOTVS Protheus 10 36 de 51 cQuery += " AND B1_GRUPO <= '"+alltrim(cGPO2)+"' cQuery += " AND C7_EMISSAO <= '"+DTOS(dFecSis)+"'" //OBSERVE COMO ES EL TRATAMIENTO PARA LAS FECHAS cQuery += " AND C7_EMISSAO >= '"+DTOS(dFecSis-90)+"'" cQuery += " AND SD1.D_E_L_E_T_=' ' AND SC7.D_E_L_E_T_=' '" cQuery += " order by C7_FORNECE,C7_PRODUTO" //INTERPRETA EL QUERY cQuery := ChangeQuery(cQuery) //COLOCA RESULTADO DEL QUERY EN TABLA TEMPORAL cAliasBus dbUseArea(.T.,"TOPCONN",TcGenQry(,,cQuery),cAliasBus,.T.,.T.) //PROCESA LA INFORMACION DEL RESULTADO While (cAliasBus)->(!eof()) cTmpPrv:=(cAliasBus)->C7_FORNECE cTmpCod:=(cAliasBus)->C7_PRODUTO (cAliasBus)->(dbskip()) //SALTA AL SIGUIENTE REGISTRO enddo (cAliasBus)->( dbCloseArea() ) //CIERRA TABLA TEMPORAL E INTERNAMENTE LA ELIMINA ADVPL Básico 37 Educación Corporativa – TOTVS Protheus 10 37 de 51 EIMINACION O ACTUALIZACIÓN Deberá usar el comando TcSqlExec para la ejecución del query, esta es una función que retorna un cero si fue ejecutado con éxito el comando y retorna resultados negativos si no fue así. Ejemplo: //COLOCA EN UNA VARIABLE EL COMANDO SQL PARA ELIMINACION DE REGISTROS cStrQty := "DELETE FROM " cStrQty += RetSqlName("SZ2") " //RECUPERA NOMBREFISICO DE LA TABLA ACTUA IGUAL AL COMANDO InitSqlName cStrQty += " WHERE Z2_FILIAL='"+cFilSA1+"' AND Z2_CODCLI = '"+alltrim(cCodSA1)+ "'" //EJECUTA ACCCION DEL QUERY nResultado:=TcSqlExec(cStrQty) //AVISO SI HUBO ERROR EN QUERY if nResultado <> 0 msgAlert(“No logro eliminar datos de la tabla SZ2”) endif Para este tipo de instrucciones es necesario poner cuidado cuando el borrado o actualización de registro es muy grande, y enviar las actualizaciones o eliminaciones por bloques. A continuación con el ejemplo de Actualización aprovecharemos un ejemplo con envío en bloques de registros. ADVPL Básico 38 Educación Corporativa – TOTVS Protheus 10 38 de 51 Ejemplo: //GENERA UNA CONSULTA CONDICIONADO DE LA MISMA FORMA COMO ESTARA EL QUERY DE ACTUALIZACION, CON EL OBJETIVO DE SACAR EL NUMERO DE REGISTRO FISICO MAXIMO Y MINIMO QUE PARTICIPARAN EN EL PROCESO cAliasSB2 := "SB2MA215PROC" cQuery := "SELECT MIN(R_E_C_N_O_) MINRECNO," cQuery += "MAX(R_E_C_N_O_) MAXRECNO " cQuery += "FROM "+RetSqlName("SB2")+" " cQuery += "WHERE B2_FILIAL='"+xFilial("SB2")+"' AND " cQuery += "D_E_L_E_T_=' '" cQuery := ChangeQuery(cQuery) dbUseArea(.T.,"TOPCONN",TcGenQry(,,cQuery),cAliasSB2) nMax := (cAliasSB2)->MAXRECNO nMin := (cAliasSB2)->MINRECNO cAliasSB2->(dbCloseArea()) //UNA VEZ OBTENIDAS LAS POSICIONES DELOS REGISTROS MAXIMO Y MINIMO PROCEDE ELABORAR EL QUERY dbSelectArea("SB2") cQuery := "UPDATE " cQuery += RetSqlName("SB2")+" " cQuery += "SET B2_RESERVA = 0," cQuery += "B2_RESERV2 = 0," cQuery += "B2_QEMP = 0," cQuery += "B2_QEMP2 = 0," cQuery += "B2_QEMPN = 0," cQuery += "WHERE B2_FILIAL='"+xFilial("SB2")+"' AND " cQuery += "D_E_L_E_T_=' ' AND " //EN ESTE CICLO ES DONDE ESTAR EJECUTANDO POR BLOQUES LAS ACTUALIZACIONES ALOS REGISTROS For nX := nMin To nMax+4096 STEP 4096 cChave := "R_E_C_N_O_>="+Str(nX,10,0)+" AND R_E_C_N_O_<="+Str(nX+4096,10,0)+"" TcSqlExec(cQuery+cChave) //EJECUTA QUERY Next nX ADVPL Básico 39 Educación Corporativa – TOTVS Protheus 10 39 de 51 Control de transacciones Tratandose de Base de Datos, toda y cualquier operación de inserción. Alteración o Eliminación de registro es almacenada primeramente en le área de LOG, garantizando la inserción de un registro y de todos sus campo. En caso de que no sea posible la inserción de forma completa un procedimiento llamado ROLLBAK, o sea, ignora todo el registro. Cuando usarlo Cuando tenemos una operación , que necesite varias inserciones, modificaciones o eliminaciones solo sean efectuadas cuando todas las operaciones hayan sido realizadas con éxito, garantizando con esto que no sea utilizada parcialmente una tabla o que actualice un tabla y no actualice las demás. Como Usarlo Para definir una transacción , se deben usar los comando BEGIN TRANSACTION y END TRANSACTION para definir el inicio y el fin de una transacción respectivamente. Todos lo datos que serán grabados debe estar dentro de una única transacción, sean provenientes de una o varias tablas. Se debe evitar usarlo en ciclos (WHILE,FOR) , pues el área de LOG del banco es limitada y si el volumen de información pasa el limite, ocasionara un bloque de la base de datos. El tamaño de la transacción debe ser conocido por el programador. En suma, para ejemplificar, debemos controlar la transacción de una nota y no de un conjunto ilimitado de notas. Donde NO Usarlo El control de transacción nunca deberá ser usado durante procesos que involucren interfases (pantalla como entrada de datos). El control se reduce solamente al proceso de grabación. Otro lugar donde no debe ser usado es en rutinas de reprocesamiento o recálculos, donde los datos pueden ser regenerados durante este proceso o donde podamos tener gran numero de locks. BEGIN TRANSACTION ExpN1:=FuncGraba() END TRANSACTION En caso de que exista una transacción dentro de otra, la segunda será automáticamente ignorada, cerrando la transacción principal en el comando END TRANSACTION. ADVPL Básico 40 Educación Corporativa – TOTVS Protheus 10 40 de 51 Parte IV ADVPL y Protheus Gatillos El uso de Gatillos o disparadores en registro de datos es muy común, pues a través de ellos podemos automatizar el llenado de muchos campos durante la digitación de solamente un único campo, considerando que dicho gatillo es disparado por ese campo. Ejercicio 1.- Como crear Funciones, para uso de Gatillos. Accese a la Herramienta IDE Realice el siguiente programa: #include “Rwmake.ch” User function Ejer01() cNome:= “Microsiga” msgAlert(“Ejemplo de Funcion en Gatillos” Return cNome Salve el programa con el mismo nombre que la función. Cargue el programa al Proyecto y Compile Accese al modulo del Configurador Seleccione las opciones Base de Datos/Diccionario/Disparadores Clique la opción de Incluir e informe los datA1_PAISos siguientes: ADVPL Básico 41 Educación Corporativa – TOTVS Protheus 10 41 de 51 Nota: En el campo Regla puede utilizar EXECBLOCK(“EJER01”) ó U_EJER01(). Para probar El Gatillo: Accese al modulo de Facturación Selecciones Actualizaciones/Archivos/Clientes Clic en la opción Incluir Llene el campo Dirección y presione <enter>, note que el mensaje Ejemplo de Funcion en Gatillos, es desplegado y el campo Dir. Cobranza es llenado con la palabra “Microsiga”. ADVPL Básico 42 Educación Corporativa – TOTVS Protheus 10 42 de 51 Funciones para registro de datos XCadastro Esta función es utilizada para la creación de pantallas estándares de Microsiga, donde tendremos solamente las opciones “Buscar”, “Visualizar”,”Alterar”, “Incluir” y “Eliminar”, siendo que los mismos no podrán ser modificables- Sintaxis aXCadastro(cAlias,cTitulo,cDel,cOk) Parametros cAlias Alias del archivo o tabla para el registro, debe tener su estructura creada en el SX3. cTitulo Titulo de la Ventana cDel Funcion para la validación de Eliminación cOk Nombre de función para validación de Inserción o alteración Ejercicio 1.- Como crear Pantallas de Captura. Accese a la Herramienta IDE Realice el siguiente programa: #include “Rwmake.ch” User function Ejer05() aXCadastro(“SB1”,”Ejer05 AxCadastro”) Return Salve el programa con el mismo nombre que la función. Cargue el programa al Proyecto y Compile Accese al modulo del Configurador y agréguelo a una opción del menú de Facturación, bajo la opción de Archivos, con el nombre “Ejer05” Para probar el Registro: Accese al modulo de Facturación Selecciones Actualizaciones/Archivos/Ejer05 ADVPL Básico 43 Educación Corporativa – TOTVS Protheus 10 43 de 51 Modelo 2 Esta función es utilizada para la creación de pantalla de registros donde podemos trabajar con un encabezado desarrollado solamente con el uso de variable de memoria y en la parte de abajo una pantalla con líneas, utilizadas para el registro de datos, aparentando estar trabajando con dos archivos en la pantalla, sin embargo será solo uno. Sintaxis Modelo2(cTítulo,aCabec,aRodapé,aGd ,nOp ,cLOk ,cTOk , [aGetsGD,bF4,cIniCpos,nMax,aCordw,lDelget]) Parametros cTitulo Titulo de la Ventana. aCabec Arreglo con los campos del encabezado aRodape Arreglo con los campos del pie. aGd Arreglo con las posiciones para la edición de Ítems (GETDADOS) nOp Modo de Operación (3 ó 4 Altera e Incluye ítems, 6 Altera mas no Incluye ítems, cualquier otro numero solo visualización del Ítem) cLok Funcion para validación de Línea cTok Funcion para la validación de todos los datos (en la confirmación) aGetsGD Arreglo con los campos editable (GETDADOS). Por default contiene todos. bF4 Bloque de código para la tecla F4. Default nada. cInicPos String con el nombre de los campos que deben ser inicializados al teclearlos nMax Limita numero de datos (GETDADOS) aCordw Arreglo con 4 elementos numéricos, correspondientes a la coordenadas, línea superior, columna izquierda, línea inferior y columna derecha, definiendo el are de la pantalla a ser usada. lDelGet Determina si las líneas pueden ser borradas o no (GetDados). Default .T. Retorna lRet – Retorna .T. si fue confirmadoADVPL Básico 44 Educación Corporativa – TOTVS Protheus 10 44 de 51 Ejemplo: //************************************************** // 3,4 Permitem alterar getdados e incluir linhas // 6 So permite alterar getdados e nao incluir linhas // Qualquer outro numero so visualiza nOpcx:=3 dbSelectArea(“Sx3”) dbSetOrder(1) dbSeek(“SX5”) nUsado:=0 aHeader:={} While !Eof() .And. (x3_arquivo == “SX5”) IF X3USO(x3_usado) .AND. cNivel >= x3_nivel nUsado:=nUsado+1 AADD(aHeader,{ TRIM(x3_titulo),x3_campo,; x3_picture,x3_tamanho,x3_decimal,; ”ExecBlock(‘Md2valid’,.f.,.f.)”,x3_usado,; x3_tipo, x3_arquivo, x3_context } ) Endif dbSkip() End aCols:=Array(1,nUsado+1) dbSelectArea(“Sx3”) dbSeek(“SX5”) nUsado:=0 While !Eof() .And. (x3_arquivo == “SX5”) IF X3USO(x3_usado) .AND. cNivel >= x3_nivel nUsado:=nUsado+1 IF nOpcx == 3 IF x3_tipo == “C” aCOLS[1][nUsado] := SPACE(x3_tamanho) Elseif x3_tipo == “N” aCOLS[1][nUsado] := 0 Elseif x3_tipo == “D” aCOLS[1][nUsado] := dDataBase Elseif x3_tipo == “M” aCOLS[1][nUsado] := “” Else aCOLS[1][nUsado] := .F. ADVPL Básico 45 Educación Corporativa – TOTVS Protheus 10 45 de 51 Endif Endif Endif dbSkip() End aCOLS[1][nUsado+1] := .F. cCliente:=Space(6) cLoja :=Space(2) dData :=Date() nLinGetD:=0 cTitulo:=”TESTE DE MODELO2" aC:={} // aC[n,1] = Nome da Variavel Ex.:”cCliente” // aC[n,2] = Array com coordenadas do Get [x,y], em // Windows estao em PIXEL // aC[n,3] = Titulo do Campo // aC[n,4] = Picture // aC[n,5] = Validacao // aC[n,6] = F3 // aC[n,7] = Se campo e’ editavel .t. se nao .f. #IFDEF WINDOWS AADD(aC,{“cCliente” ,{15,10} ,”Cod. do Cliente”,”@!”,; ‘ExecBlock(“MD2VLCLI”,.F.,.F.)’,”SA1",}) AADD(aC,{“cLoja” ,{15,200},”Loja”,”@!”,,,}) AADD(aC,{“dData” ,{27,10} ,”Data de Emissao”,,,,}) #ELSE AADD(aC,{“cCliente” ,{6,5} ,”Cod. do Cliente”,”@!”,; ExecBlock(“MD2VLCLI”,.F.,.F.)’,”SA1",}) AADD(aC,{“cLoja” ,{6,40},”Loja”,”@!”,,,}) AADD(aC,{“dData” ,{7,5} ,”Data de Emissao”,,,,}) #ENDIF aR:={} // aR[n,1] = Nome da Variavel Ex.:”cCliente” // aR[n,2] = Array com coordenadas do Get [x,y], em // Windows estao em PIXEL // aR[n,3] = Titulo do Campo // aR[n,4] = Picture // aR[n,5] = Validacao // aR[n,6] = F3 mailto:@! mailto:@! mailto:@! mailto:@! ADVPL Básico 46 Educación Corporativa – TOTVS Protheus 10 46 de 51 // aR[n,7] = Se campo e’ editavel .t. se nao .f. #IFDEF WINDOWS AADD(aR,{“nLinGetD” ,{120,10},”Linha na GetDados”,; “@E 999”,,,.F.}) #ELSE AADD(aR,{“nLinGetD” ,{19,05},”Linha na GetDados”,; “@E 999”,,,.F.}) #ENDIF #IFDEF WINDOWS aCGD:={44,5,118,315} #ELSE aCGD:={10,04,15,73} #ENDIF cLinhaOk := “ExecBlock(‘Md2LinOk’,.f.,.f.)” cTudoOk := “ExecBlock(‘Md2TudOk’,.f.,.f.)” // lRet = .t. se confirmou // lRet = .f. se cancelou lRet:=Modelo2(cTitulo,aC,aR,aCGD,nOpcx,cLinhaOk,cTudoOk) // No Windows existe a funcao de apoio CallMOd2Obj() que // retorna o objeto Getdados Corrente Return mailto:@E mailto:@E ADVPL Básico 47 Educación Corporativa – TOTVS Protheus 10 47 de 51 Modelo 3 Esta función es utilizada para la creación de pantalla de registros, donde podemos trabajar con un esquema de dos archivos en la pantalla, una para encabezado del catalogo y otra para el detalle del catalogo, donde se usaran líneas para la digitación. Sintaxis Modelo3(cTitulo,cAliasEnchoice,cAliasGetD,aCpoEnchoice,cLinOk,cTudOk,nOpcE,nOpcG,cFieldOk, [lVirtual,nLinhas,aAltEnchoice]) Parametros cTitulo Titulo de la Ventana. cAliasEnchoice Alias del encabezado cAliasGetD Alias de los Ítems aCpoEnchoice Arreglo con los campos que serán mostrados cLinok Funcion para validación de Línea cTudOk Funcion para la validación de todos los datos (en la confirmación) nOpcE Numero de Opción para el encabezado (Enchoice). Modo de Operación (3 ó 4 Altera e Incluye ítems, 6 Altera mas no Incluye ítems, cualquier otro numero solo visualización del Ítem) nOpcG Numero de Opción para ítems (GETDADOS). Modo de Operación (3 ó 4 Altera e Incluye ítems, 6 Altera mas no Incluye ítems, cualquier otro numero solo visualización del Ítem) cFieldOk Funcion para validar los campos de los ítems lVirtual Permite visualizar los campos virtuales en el Enchoice, default .f. nLinhas Arreglo con los campos editable (GETDADOS). Por default contiene todos. Default 99 aAltEnchoice Arreglo con los campos alterables (Enchoice) Retorna lRet – Retorna .T. si fue confirmado ADVPL Básico 48 Educación Corporativa – TOTVS Protheus 10 48 de 51 Ejemplo: aRotina := {{ “Pesquisa”,”AxPesqui”, 0 , 1},; { “Visual”,”AxVisual”, 0 , 2},; { “Inclui”,”AxInclui”, 0 , 3},; { “Altera”,”AxAltera”, 0 , 4, 20 },; { “Exclui”,”AxDeleta”, 0 , 5, 21 }} //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Opcoes de acesso para a Modelo 3 ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ cOpcao:=”VISUALIZAR” Do Case Case cOpcao==”INCLUIR”; nOpcE:=3 ; nOpcG:=3 Case cOpcao==”ALTERAR”; nOpcE:=3 ; nOpcG:=3 Case cOpcao==”VISUALIZAR”; nOpcE:=2 ; nOpcG:=2 EndCase //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Cria variaveis M->????? da Enchoice ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ RegToMemory(“SC5”,(cOpcao==”INCLUIR”)) //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Cria aHeader e aCols da GetDados ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ nUsado:=0 dbSelectArea(“SX3”) dbSeek(“SC6”) aHeader:={} While !Eof().And.(x3_arquivo==”SC6") If Alltrim(x3_campo)==”C6_ITEM” dbSkip() Loop Endif If X3USO(x3_usado).And.cNivel>=x3_nivel nUsado:=nUsado+1 Aadd(aHeader,{ TRIM(x3_titulo), x3_campo, x3_picture,; x3_tamanho, x3_decimal,”AllwaysTrue()”,; x3_usado, x3_tipo, x3_arquivo, x3_context } ) Endif dbSkip() End ADVPL Básico 49 Educación Corporativa – TOTVS Protheus 10 49 de 51 If cOpcao==”INCLUIR” aCols:={Array(nUsado+1)} aCols[1,nUsado+1]:=.F. For _ni:=1 to nUsado aCols[1,_ni]:=CriaVar(aHeader[_ni,2]) Next Else aCols:={} dbSelectArea(“SC6”) dbSetOrder(1) dbSeek(xFilial()+M->C5_NUM) While !eof().and.C6_NUM==M->C5_NUM AADD(aCols,Array(nUsado+1)) For _ni:=1 to nUsado aCols[Len(aCols),_ni]:=FieldGet(FieldPos(aHeader[_ni,2])) Next aCols[Len(aCols),nUsado+1]:=.F. dbSkip() End Endif If Len(aCols)>0 //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Executa a Modelo 3 ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ cTitulo:=”Teste de Modelo3()” cAliasEnchoice:=”SC5" cAliasGetD:=”SC6" cLinOk:=”AllwaysTrue()” cTudOk:=”AllwaysTrue()” cFieldOk:=”AllwaysTrue()” aCpoEnchoice:={“C5_CLIENTE”} _lRet:=Modelo3(cTitulo,cAliasEnchoice,cAliasGetD,aCpoEnchoice,cLinOk,cTudOk,nOpcE,nOpcG,cFieldOk) //ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ //³ Executar processamento ³ //ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ If _lRet Aviso(“Modelo3()”,”Confirmada operacao!”,{“Ok”}) Endif Endif Return ADVPL Básico 50 Educación Corporativa – TOTVS Protheus 10 50 de 51 Validaciones de Campo Este tipo de validaciones son registradas en el configurador, cuando la validación suelen ser mas complejas entonces quizás, sea necesario generar una función , de tal forma que en la validación en campo solo sea llamada tal función y en IDE desarrollar dicha función, la cual deberá retornar un valor lógico Falso o Verdadero. Regla de avance Existe un conjunto de instrucciones ADVPL que permites enviar a pantalla reglas de avance según algún proceso determinado. Regla de avance para procesos. Processa(bAccion,cTitulo,cMsg,lAborta) Despliega una pantalla inicial con mensaje de de espera, para un proceso, donde: bAccion: Bloque de código. cTitulo : Titulo de Pantalla cMsg: Mensaje de espera lAborta:Coloca opción de Cancelar en la pantalla de espera. ProcRegua(nCuantos) Inicializa barra de avance. Donde nCuantos, es el numero de procesos a ejecutar. IncProc() Incrementa barra de avance. Ejemplo: User Function <nome-da-função>( ) Local bAcao := {|lFim| Exemplo(@lFim) } Local cTitulo := '' Local
Compartir