4D v16.3

Métodos de proyecto

Inicio

 
4D v16.3
Métodos de proyecto

Métodos de proyecto  


 

 

Los métodos de proyecto, como su nombre lo indica, se aplican a la totalidad de su proyecto. Mientras los métodos de formulario y de objeto están asociados a formularios y objetos, un método de proyecto está disponible en todas partes; no está asociado específicamente a ningún objeto en particular de la base. Un método de proyecto puede tener uno de los siguientes papeles, dependiendo de cómo se ejecute y utilice:

  • Método de menú
  • Subrutina y función
  • Método de proceso
  • Método de gestión de eventos
  • Método de gestión de errores

Estos términos no distinguen los métodos de proyecto por lo que son, si no por lo que hacen.

Un método menú es un método de proyecto llamado desde un menú personalizado, que dirige el flujo de su aplicación. Los métodos de menú controlan, cuando es necesario, la presentación de formularios, la generación de informes y en general administración de su base de datos.

La subrutina es un método de proyecto que puede ser como considerado como un empleado. Realiza aquellas tareas que otros métodos le piden que realice. Una función es una subrutina que devuelve un valor al método que la llamó.

Un método de proceso es un método de proyecto que se llama cuando se inicia un proceso. El proceso dura mientras el método de proceso se ejecuta. Para mayor información sobre procesos, consulte las sección Procesos. Observe que un método de menú asociado a un comando de menú para el cual la propiedad Nuevo proceso está seleccionada, también es el método de proceso para el nuevo proceso iniciado.

Un método de gestión de eventos se ejecuta en un proceso separado como el método de proceso de gestión de eventos. Generalmente, usted le permite a 4D hacer la mayoría del trabajo de gestión de eventos. Por ejemplo, durante la entrada de datos, 4D detecta los clics y las teclas presionadas, luego llama los métodos de objeto y formulario correspondientes, de manera que responda apropiadamente a los eventos desde estos métodos. En otras circunstancias, usted podría querer manejar directamente los eventos. Por ejemplo, si ejecuta una operación larga (tal como un bucle For...End for a cada registro), usted podría interrumpir la operación al presionar Ctrl-Punto (Windows) o Cmd-Punto (Macintosh). En este caso, debe utilizar un método de gestión de eventos para hacerlo. Para mayor información, consulte la descripción del comando ON EVENT CALL.

Un método de gestión de errores es un método de proyecto de interrupción. Cada vez que un error o una excepción ocurre, se ejecuta en el proceso en el cual fue instalado. Para mayor información, vea la descripción del comando ON ERR CALL.

Un método de menú se llama en el entorno de Aplicación cuando se selecciona el comando de menú al que está asociado. Usted asigna el método al comando de menú en el editor de menús. El menú se ejecuta cuando el comando de menú es seleccionado. Este proceso es uno de los principales aspectos de la personalización de una base de datos. Creando menús personalizados con métodos de menú que realizan acciones específicas, usted personaliza su base. Consulte el Manual de Diseño para mayor información sobre el editor de menús.

Los comandos de menús personalizados pueden hacer que una o más actividades tomen lugar. Por ejemplo, un comando de menú para introducir registros podría llamar un método que efectúe dos tareas: mostrar el formulario de entrada apropiado, y llamar al comando ADD RECORD hasta que el usuario cancele la entrada de datos.

La automatización de secuencias de acciones es una posibilidad muy poderosa del lenguaje de programación. Utilizando menús personalizados, puede automatizar secuencias de tareas y ofrecer mayor orientación a los usuarios de la base de datos.

Cuando crea un método de proyecto, el método se vuelve parte del lenguaje de la base en la cual fue creado. Entonces puede llamar al método de proyecto de la misma forma como llama a los comandos integrados de 4D. Un método de proyecto utilizado de esta manera se llama una subrutina.

Usted utiliza subrutinas para:

  • Reducir código repetitivo
  • Aclarar sus métodos
  • Facilitar los cambios en sus métodos
  • Modularizar su código

Por ejemplo, imagine que tiene una base de clientes. A medida que personaliza la base, encuentra que hay algunas tareas que usted realiza repetidamente, tales como encontrar un cliente y modificar su registro. El código para hacer esto se vería así:

  ` Buscar un cliente
 QUERY BY EXAMPLE([Clientes])
  ` Seleccionar el formulario de entrada
 FORM SET INPUT([Clientes];"Entrada de datos")
  ` Modificación del registro del cliente
 MODIFY RECORD([Clientes])

Si no utiliza subrutinas, tendrá que escribir el código cada vez que quiera modificar el registro de un cliente. Si esta operación se realiza en su base personalizada diez veces, usted tendrá que escribir el código diez veces. Si utiliza subrutinas, sólo tendrá que escribir el código una vez. Esta es la primera ventaja de las subrutinas, reducir la cantidad de código.

Si el código descrito anteriormente fuera un método llamado MODIFICAR CLIENTE, lo ejecutaría simplemente utilizando el nombre del método en otro método. Por ejemplo, para modificar el registro de un cliente y luego imprimirlo, debe escribir este método:

 MODIFICAR CLIENTE
 PRINT SELECTION([Clientes])

Esta posibilidad simplifica dramáticamente sus métodos. En el ejemplo, usted no necesita saber cómo funciona el método MODIFICAR CLIENTE, sólo lo que hace. Esta es la segunda razón para utilizar subrutinas, para aclarar sus métodos. De esta forma, sus métodos se vuelven extensiones del lenguaje de 4D.

Si tiene que cambiar su método de buscar clientes en esta base de ejemplo, tendrá que cambiar sólo un método, no diez. Esta es la siguiente razón para utilizar subrutinas, facilitar los cambios en sus métodos.

Utilizando subrutinas, usted hace su código modular. Esto significa simplemente dividir su código en módulos (subrutinas), cada una de las cuales realiza una tarea lógica. Examine el siguiente código de una base de una cuenta corriente:

 BUSCAR CHEQUES EMITIDOS ` Buscar los cheques emitidos
 CONCILIAR CUENTA ` Conciliar la cuenta
 IMPRIMIR INFORME CHEQUERA ` Imprimir un informe de chequera

Incluso para alguien que no conoce la base, el código es claro. No es necesario examinar cada subrutina. Cada subrutina podría tener muchas líneas y realizar algunas operaciones complejas, pero acá lo único importante es que realice su tarea.

Recomendamos que divida su código en tareas lógicas, o módulos, cada vez que sea posible.

Con frecuencia encontrará que necesita pasar datos a sus métodos. Esto se hace fácilmente con parámetros.

Los Parámetros (o argumentos) son los datos que un método necesita para realizar su tarea. Los términos parámetro y argumento se utilizan indiferentemente en este manual. Igualmente, los parámetros se pasan a los comandos integrados de 4D. En este ejemplo, la cadena “Hola” es un argumento del comando ALERT:

 ALERT("Hola")

Los parámetros se pasan a los métodos de la misma forma. Por ejemplo, si un método llamado HACER ALGO acepta tres parámetros, una llamada al método podría verse de esta forma:

 HACER ALGO(ConEsto;yEsto;Asi)

Los parámetros se separan por punto y comas (;).

En la subrutina (el método llamado), el valor de cada parámetro se copia automáticamente de manera secuencial en las variables locales numeradas: $1, $2, $3, etc. La numeración de las variables locales representa el orden de los parámetros.

  //Código del método DO SOMETHING
  //Asumiendo que todos los parámetros son de tipo texto
 C_TEXT($1;$2;$3)
 ALERT("I received "+$1+" and "+$2+" and also "+$3)
  //$1 contiene el parámetro WithThis
  //$2 contiene el parámetro AndThat
  //$3 contiene el parámetro ThisWay

Dentro de la subrutina, puede utilizar los parámetros $1, $2... de la misma forma que utilizaría cualquier otra variable local.

Sin embargo, en caso de que utilice los comandos que modifican el valor de la variable pasada como parámetro (por ejemplo, Find in field), los parámetros $1, $2, etc. no pueden utilizarse directamente. Primero debe copiarlos en las variables estándar locales (por ejemplo: $mivar:=$1).

Nota avanzada: los métodos de proyecto 4D aceptan un número variable de parámetros del mismo tipo, empezando por la derecha. Para declarar estos parámetros, se utiliza una directiva de compilador a la que se lepasa ${N} como parámetro, donde N especifica el primer parámetro. Por ejemplo, la declaración C_LONGINT(${5}) indica a 4D y al compilador que a partir del quinto parámetro, el método puede recibir un número variable de parámetros de tipo entero largo. Utilizando el comando [#cmd id="259"/] puede entonces tratar esos parámetros con un bucle For y la sintaxis de indirección de parámetros. Para más información, consulte el ejemplo 2 del comando Count parameters.

of the local parameter will modify the source value.Dependiendo de su tipo, los parámetros se pasan por copia o por referencia:

  • Cuando un parámetro se pasa por copia, las variables/parámetros locales no son los campos, las variables o las expresiones reales pasadas por el método llamante; Sólo contienen los valores que se han pasado. Dado que su alcance es local, si el valor de un parámetro se modifica en la subrutina, no cambia el valor en el método de llamada
  • Cuando un parámetro se pasa por referencia, las variables/parámetros locales contienen referencias que apuntan a los campos fuente, variables o expresiones reales pasadas por el método llamante; Modificar el valor del parámetro local modificará el valor de la fuente.
La siguiente tabla muestra cómo se pueden pasar los diferentes tipos de elementos:
Tipo de parámetroCómo se pasaComentario
Campo, variable o expresión de un tipo escalar (número, texto, fecha...)por valorSe puede pasar por referencia a través de un puntero, ver abajo
Campo, variable o expresión de tipo Objetopor referenciaVer ejemplo a continuación
Variable o expresión de tipo Colecciónpor referencia
Variable o expresión de tipo Punteropor referenciaVer Pasar punteros a métodos
ArrayNo se puede pasar directamente como parámetroSe puede pasar por referencia a través de un puntero, ver Arrays y punteros
TableNo se puede pasar directamente como parámetroSe puede pasar por referencia a través de un puntero, ver Punteros

Cuando se utilizan campos, variables y expresiones de tipo escalar como parámetros de método, sólo se pasan copias de valores.

Como $1, $2... son variables locales, están disponibles sólo dentro de la subrutina y son borradas al final de la subrutina. Por esta razón, una subrutina no puede cambiar el valor real de los campos o variables pasadas como parámetros al nivel del método llamante. Por ejemplo:

  ` He aquí parte del método MI MÉTODO
  ` ...
 HACER ALGO([Personas]Apellido) ` Supongamos que [Personas]Apellido es igual a "pérez"
 ALERT(([Personas]Apellido)
 
  ` Este es el código del método HACER ALGO
 $1:=Uppercase($1)
 ALERT($1)

La caja de diálogo de alerta mostrada por HACER ALGO contendrá “PÉREZ” y la caja de diálogo mostrada por MI METODO contendrá “pérez”. El método ha modificado localmente el valor del parámetro $1, pero esto no afecta el valor del campo [Personas]Apellido pasado como parámetro por el método MI METODO.

Hay dos maneras de hacer que el método HACER ALGO cambie el valor del campo:

1. En lugar de pasar el campo al método, pasar un apuntador, escriba:

  ` He aquí parte del método MI METODO
  ` ...
 HACER ALGO(->[Personas]Apellido) ` Digamos que [Personas]Apellido es igual a "pérez"
 ALERT([Personas]Apellido)
 
  ` Este es el código del método HACER ALGO
 $1->:=Uppercase($1->)
 ALERT($1->)

Aquí el parámetro no es el campo, sino un puntero al campo. Por lo tanto, dentro del método HACER ALGO, $1 ya no es el valor del campo sino un puntero hacia el campo. El objeto referenciado por $1 ($1-> en el código anterior) es el campo real. Por consiguiente, la modificación del objeto referenciado va más allá del alcance de la subrutina, y el campo real es afectado. En este ejemplo, ambas cajas de alerta mostrarán “PÉREZ”.

Para mayor información sobre Punteros, consulte la sección Punteros.

2. En lugar de tener al método HACER ALGO “haciendo algo”, puede reescribir el método de manera que devuelva un valor. De esta forma usted escribiría:

  ` He aquí parte del código del método MI METODO
  ` ...
 [Personas]Apellido:=HACER ALGO([Personas]Apellido) ` Supongamos que [Personas]Apellido es igual a "pérez"
 ALERT([Personas]Apellido)
  ` Here the code of the method <span class="rte4d_met">HACER ALGO</span>
 $0:=Uppercase($1)
 ALERT($0)

Esta segunda técnica de que una subrutina devuelva un valor se llama “utilizar una función.” Este punto se describe en los párrafos siguientes.

Cuando se utilizan variables, expresiones o campos de tipo objeto o colección como parámetros de método, se pasan referencias a los valores fuente reales. En este caso, $1, $2... no contienen valores sino referencias. La modificación del valor de los parámetros $1, $2... dentro de la subrutina se propagará donde quiera que se utilice el objeto o la colección fuente. Este es el mismo principio que para los punteros, excepto que los parámetros $1, $2... no necesitan ser desreferenciados en la subrutina.

Por ejemplo:

  //El método CreatePerson crea un objeto y lo envía como un parámetro
 C_OBJECT($person)
 $person:=New object("Name";"Smith";"Age";40)
 ChangeAge($person)
 ALERT(String(OB get($person;"Age")))

  //El método ChangeAge añade 10 al atributo Age del objeto recibido
 C_OBJECT($1)
 OB SET($1;"Age";OB Get($1;"Age")+10)
 ALERT(String(OB get($1;"Age")))

Si ejecuta el método CreatePerson,
ambos cuadros de alerta dirán "50" ya que la misma referencia es manejada por ambos métodos.

4D Server: cuando los parámetros se pasan entre métodos que no se ejecutan en la misma máquina (utilizando por ejemplo la opción Ejecutar en servidor, ver Propiedades de los métodos proyecto), las referencias no se pueden utilizar. En estos casos, se envían copias de los parámetros de objeto y colección en lugar de referencias.

Los métodos pueden devolver valores. Un método que devuelve un valor se llama función.

Los comandos de 4D o de los plug-ins que devuelven un valor también se llaman funciones.

Por ejemplo, la siguiente línea es una instrucción que utiliza la función integrada, Length, para devolver la longitud de una cadena. La instrucción coloca el valor devuelto por Length en una variable llamadaMiLongitud. Esta es la instrucción:

 MiLongitud:=Length("¿'Cómo llegué acá?")

Toda subrutina puede devolver un valor. El valor a devolver se coloca en la variable local $0.

Por ejemplo, la siguiente función, llamada Mayusculas4, devuelve una cadena con los primeros cuatro caracteres de la cadena pasados a mayúsculas:

 $0:=Uppercase(Substring($1;1;4))+Substring($1;5)

El siguiente es un ejemplo que utiliza la función Mayusculas4 :

 NuevaFrase:=Mayusculas4("Esto está bien.")

En este ejemplo, la variable NuevaFrase toma el valor “ESTO está bien.”

El resultado de la función, $0, es una variable local dentro de la subrutina. Puede ser utilizada como tal dentro de la subrutina. Por ejemplo, en el ejemplo anterior el método HACER ALGO, $0 primero fue asignado al valor $1, luego fue utilizado como parámetro del comando ALERT. Dentro de la subrutina, puede utilizar $0 de la misma forma que utilizaría otra variable local. 4D devuelve el valor de $0 (el valor actual cuando la subrutina termina) al método llamado.

Los métodos de proyecto pueden llamarse entre sí. Por ejemplo:

  • El método A podría llamar al método B el cual podría llamar a A, entonces A llamará a B de nuevo, etc.
  • Un método puede llamarse a sí mismo.

Esto se llama recursividad. El lenguaje de 4D soporta totalmente la recursividad.

Este es un ejemplo. Supongamos que tiene una tabla [Amigos y familiares] compuesta del siguiente conjunto de campos:
- [Amigos y familiares]Nombre
- [Amigos y familiares]NinosNombre

Para este ejemplo, asumimos que los valores en los campos son únicos (no hay dos personas con el mismo nombre). A partir de un nombre, usted quiere construir una frase “Un amigo mio, Juan el hijo de Pedro hijo de Ana hija de Roberto hijo de Eleonor, ¡hace esto para vivir!”:

1. Puede construir la frase de esta forma:

 $vsNombre:=Request("Introduzca el nombre:";"Juan")
 If(OK=1)
    QUERY([Amigos y familiares];[Amigos y familiares]Nombre=$vsNombre)
    If(Records in selection([Amigos y familiares])>0)
       $vtTodalahistoria:="Un amigo mio, "+$vsNombre
       Repeat
          QUERY([Amigos y familiares];[Amigos y familiares]NinosNombre=$vsNombre)
          $vlQueryResult:=Records in selection([Amigos y familiares])
          If($vlQueryResult>0)
             $vtTodalahistoria:=$vtTodalahistoria+" el hijo de "+[Amigos y familiares]Nombre
             $vsNombre:=[Amigos y familiares]Nombre
          End if
       Until($vlQueryResult=0)
       $vtTodalahistoria:=$vtTodalahistoria+", ¡hace esto para vivir!"
       ALERT($vtTodalahistoria)
    End if
 End if

2. También la puede construir de esta forma:

 $vsNombre:=Request("Introduzca el nombre:";"Juan")
 If(OK=1)
    QUERY([Amigos y familiares];[Amigos y familiares]Nombre=$vsNombre)
    If(Records in selection([Amigos y familiares])>0)
       ALERT("Un amigo mio, "+Genealogia de($vsName)+", ¡hace esto para vivir!")
    End if
 End if

con la función recursiva Genealogia de listada aquí:

  ` Método de proyecto Genealogia de
  ` Genealogia de ( Cadena ) -> Texto
  ` Genealogia de ( Nombre ) -> Parte de la frase
 
 $0:=$1
 QUERY([Amigos y familiares];[Amigos y familiares]NinosNombre=$1)
 If(Records in selection([Amigos y familiares])>0)
    $0:=$0+" hijo de "+Genealogia de([Amigos y familiares]Nombre)
 End if

Observe que el método Genealogia de se llama a sí mismo.

La primera forma es un algoritmo iterativo. La segunda es un algoritmo recursivo.

Cuando implemente código para casos como el del ejemplo anterior, es importante tener en cuenta que usted siempre puede escribir métodos utilizando iteración y recursividad. Generalmente, la recursividad ofrece código más conciso, fácil de leer y de mantener, pero su uso no es obligatorio.

Algunos usos típicos de recursividad en 4D son:

  • Tratar registros dentro de tablas que relacionan unas a otras de la misma manera que en el ejemplo.
  • Navegar en los documentos y carpetas de su disco, utilizando los comandos FOLDER LIST y DOCUMENT LIST. Una carpeta puede contener carpetas y documentos, las subcarpetas pueden contener carpetas y documentos, y así sucesivamente.

Importante: las llamadas recursivas deben terminar en algún momento. En el ejemplo, el método Genealogia de deja de llamarse a sí mismo cuando la búsqueda no devuelve registros. Sin esta condición, el método se llamaría a sí mismo indefinidamente; finalmente, 4D devolvería un error “Pila llena” porque no habría espacio para “apilar” las llamadas (así como los parámetros y las variables locales utilizadas en el método).



Ver también 

Condiciones y bucles
Métodos
Métodos de base de datos

 
PROPIEDADES 

Producto: 4D
Tema: Presentación del lenguaje

 
HISTORIA 

 
ARTICLE USAGE

Manual de lenguaje 4D ( 4D v16)
Manual de lenguaje 4D ( 4D v16.1)
Manual de lenguaje 4D ( 4D v16.2)
Manual de lenguaje 4D ( 4D v16.3)