4D v16.3

Detalles de sintaxis

Inicio

 
4D v16.3
Detalles de sintaxis

Detalles de sintaxis  


 

 

El compilador espera las reglas de sintaxis habituales de los comandos 4D, no necesita modificaciones especiales para bases que van a ser compiladas.

Sin embargo esta sección ofrece algunos recordatorios y detalles específicos:

  • Algunos comandos que influyen en el tipo de una variable pueden, si no tiene cuidado, conducir a conflictos.
  • Algunos comandos utilizan más de una sintaxis o parámetros, es importante saber cuál es el más apropiado.

Para los comandos que operan sobre cadenas, sólo la función Character code requiere atención especial. En modo interpretado, puede pasar indiferentemente una cadena no vacía o vacía a esta función.
En modo compilado, no puede pasar una cadena vacía.
Si pasa una cadena vacía y el argumento pasado a Character code es una variable, el compilador no podrá detectar un error en la compilación.

SEND VARIABLE(variable)
RECEIVE VARIABLE(variable)

Estos dos comandos se utilizan para escribir y recibir variables enviadas al disco. Las variables se pasan como parámetros a estos comandos.

El parámetro que pasa debe ser siempre del mismo tipo. Suponga que quiere enviar una lista de variables a un archivo. Para eliminar el riesgo de cambiar los tipos de datos involuntariamente, recomendamos especificar al principio de la lista el tipo de las variables enviadas. De esta forma, cuando usted recibe estas variables, siempre comenzará por obtener un indicador. Luego, cuando llama a RECEIVE VARIABLE, la transferencia se maneja por intermedio de una instrucción Case of.

Ejemplo:
 SET CHANNEL(12;"Archivo")
 If(OK=1)
    $Tipo:=Type([Cliente]Total_A)
    SEND VARIABLE($Tipo)
    For($i;1;Records in selection)
       $Enviar_A:=[Cliente]Total_A
       SEND VARIABLE($Enviar_A)
    End for
 End if
 SET CHANNEL(11)
 SET CHANNEL(13;"MiArchivo")
 If(OK=1)
    RECEIVE VARIABLE($Tipo)
    Case of
       :($Tipo=Is string var)
          RECEIVE VARIABLE($Cadena)
  `Proceso de la variable recibida
       :($Tipo=Is real)
          RECEIVE VARIABLE($Real)
  `Proceso de la variable recibida
       :($Tipo=Is text)
          RECEIVE VARIABLE($Text)
  `Proceso de la variable recibida
    End case
 End if
 SET CHANNEL(11)

Field (puntero campo) o (tabla número;campo número)
Table (puntero tabla)
o (tabla número) o (puntero campo)

Estos dos comandos devuelven los resultados de diferentes tipos de datos, de acuerdo a los parámetros pasados:

  • Si pasa un puntero a la función Table, el resultado devuelto es un número.
  • Si pasa un número a la función Table, el resultado devuelto es un puntero.

Recuerde que las referencias del documento devuelto por las funciones Open document, Append document y Create document son de tipo Hora.

Mod (valor;divisor)

La expresión “25 modulo 3” puede escribirse de dos formas diferentes en 4d:

 Variable:=Mod(25;3)

o

 Variable:=25%3

El compilador ve una diferencia entre las dos: Mod aplica a todos los tipos numéricos, mientras que el operador % aplica únicamente a Enteros y Enteros largos. Si el operando del operador % excede el rango de los Enteros largos, el resultado devuelto probablemente será errado.

IDLE
ON EVENT CALL (Method{; ProcessName})
ABORT

El comando IDLE se ha añadido al lenguaje 4D para manejar excepciones. Este comando debe utilizarse cuando utilice el comando ON EVENT CALL.

Este comando puede definirse como una directiva de gestión de eventos.
Sólo el kernel (núcleo) de 4D puede detectar un evento sistema (clic del ratón, actividad del teclado, etc.). En la mayoría de los casos, las llamadas al kernel son iniciadas por el mismo código compilado, de una manera transparente para el usuario.

Por otra parte, cuando 4D está esperando pasivamente por un evento, por ejemplo en un bucle de espera, es evidente que no habrá ninguna llamada.

  `Método de proyecto ClicRaton
 If(MouseDown=1)
    <>vPrueba:=True
    ALERT("Alguien hizo clic en el ratón")
 End if
 
  `Método Espera
 <>vPrueba:=False
 ON EVENT CALL("ClicRaton")
 While(<>vPrueba=False)
  `Bucle de atención del evento
 End while
 ON EVENT CALL("")

En este caso, se añade el comando IDLE de la forma siguiente:

  `Método Espera
 <>vPrueba:=False
 ON EVENT CALL("ClicRaton")
 While(<>vPrueba=False)
    IDLE
  `Llamar al Kernel para detectar un evento
 End while
 ON EVENT CALL("")
ABORT  

Utilice este comando sólo en métodos de proyecto de intercepción de errores. Este comando funciona exáctamente como en 4D, excepto en un método que ha sido llamado por uno de los siguientes comandos: EXECUTE FORMULA, APPLY TO SELECTION y APPLY TO SUBSELECTION. Trate de evitar esta situación.

Arrays  

Siete comandos de 4D son utilizados por el compilador para determinar el tipo de un array:

COPY ARRAY(fuente;destino)
SELECTION TO ARRAY(campo;Array)
ARRAY TO SELECTION(Array;campo)
SELECTION RANGE TO ARRAY(inicio;fin;campo;Array)
LIST TO ARRAY(lista;Array{; itemRefs})
ARRAY TO LIST(Array;lista{; itemRefs})
DISTINCT VALUES(campo;Array)

El comando COPY ARRAY acepta dos parámetros de tipo Array. Si uno de los parámetros de array no ha sido declarado, el compilador determina el tipo del array no declarado según el tipo del declarado.
Esta deducción se realiza en los dos casos siguientes:

  • El array declarado es el primer parámetro. El compilador asigna el tipo del primer array al segundo array.
  • El array declarado es el segundo parámetro. En este caso, el compilador asigna el tipo de dato del segundo array al primer array.

Como el compilador es estricto con los tipos, COPY ARRAY sólo puede hacerse desde un array de un cierto tipo a un array del mismo tipo.
Por lo tanto, si quiere copiar un array de elementos cuyos tipos son similares, es decir, Enteros, Enteros largos y Reales, o Texto y Alfas, o Alfas de diferentes longitudes, tiene que copiar los elementos uno por uno.

Imagine que quiere copiar elementos de un Array Entero a un Array Real. Puede proceder de la siguiente forma:

 $Tamaño:=Size of array(ArrInt)
 ARRAY REAL(ArrReal;$Tamaño)
  `Establecer el mismo tamaño para el array Real que para el array Entero
 For($i;1;$Size)
    ArrReal{$i}:=ArrInt{$i}
  `Copiar cada elemento
 End for


Recuerde que no puede cambiar el número de dimensiones de un array durante el proceso. Si copia un array de una dimensión en un array de bidimensional, el compilador genera un mensaje de error.

De la misma forma para 4D en modo interpretado, estos cuatro comandos no necesitan la declaración de arrays. Los arrays no declarados reciben el mismo tipo que el campo especificado en el comando.
Si escribe:

 SELECTION TO ARRAY([MiTabla]CampoEntero;MiArray)

el tipo de datos de MiArray sería Entero de una dimensión. (asumiendo que CampoEntero es un campo entero).

Si el array ha sido declarado, asegúrese de que el campo sea del mismo tipo. Aunque Entero, Entero largo y Real son tipos similares, no son equivalentes.
Por otra parte, en el caso de tipos Texto y Alfa, tiene un poco más de latitud. Por defecto, si un array no fue declarado previamente y usted aplica un comando que incluye un campo de tipo Alfa como parámetro, se atribuye el tipo Texto al array. Si el array fue declarado previamente como de tipo Alfa o de tipo Texto, estos comandos seguirán sus directivas.

Lo mismo ocurre en el caso de los campos de tipo Texto––sus directivas tienen prioridad.
Recuerde que los comandos SELECTION TO ARRAY, SELECTION RANGE TO ARRAY, ARRAY TO SELECTION y DISTINCT VALUES sólo pueden utilizarse con arrays de una dimensión.

El comando SELECTION TO ARRAY también tiene una segunda sintaxis:
SELECTION TO ARRAY(tabla;Array).
En este caso, la variable MiArray será de Array de Enteros largos. El comando SELECTION RANGE TO ARRAY funciona de la misma forma.

Los comandos LIST TO ARRAY y ARRAY TO LIST conciernen sólo a dos tipos de arrays:

  • los arrays Alfa de una dimensión y
  • los arrays Texto de una dimesnión.
    Estos comandos no necesitan la declaración del array que se pasa como parámetro. Por defecto, un array no declarado recibirá el tipo Texto. Si el Array fue declarado previamente como de tipo Alfa o Texto, estos comandos seguirán sus directivas.

El compilador no puede detectar un conflicto de tipo si usted utiliza un puntero sin referencia como parámetro de un comando de declaración de un array. Si escribe:

 SELECTION TO ARRAY([Tabla]Campo;Puntero->)

donde Puntero-> representa un array, el compilador no puede verificar que el tipo del campo y el del array son idénticos. Debe prevenir tales conflictos; debe declarar el array referenciado por el puntero.

El compilador emite una advertencia cuando encuentra una rutina de declaración de array en la cual uno de los parámetros es un puntero. Estos mensajes pueden ser útiles en la detección de este tipo de conflicto.

Si su base utiliza arrays locales (arrays reconocidos únicamente en el método en el que fueron creados), es necesario declararlos explícitamente en 4D antes de utilizarlos.

Para declarar un array local, utilice uno de los comandos de array tales como ARRAY REAL, ARRAY INTEGER, etc.

Por ejemplo, si un método crea un array local de enteros que contiene 10 elementos, debe declarar el array antes de utilizarlo. Utilice el comando:

 ARRAY INTEGER($MiArray;10)

Get pointer(varNombre)
Type (objeto)
EXECUTE FORMULA(instrucción)
TRACE
NO TRACE

Get pointer es una función que devuelve un puntero al parámetro que usted le pasó. Suponga que quiere inicializar un array de punteros. Cada elemento en ese array apunta a una variable dada. Suponga que hay doce variables llamadas V1, V2, …V12. Puede escribir:

 ARRAY POINTER(Arr;12)
 Arr{1}:=->V1
 Arr{2}:=->V2
 
 Arr{12}:=->V12

También puede escribir:

 ARRAY POINTER(Arr;12)
 For($i;1;12)
    Arr{$i}:=Get pointer("V"+String($i))
 End for

Al final de esta operación, puede obtener un array de punteros donde cada elemento apunta a una variable Vi.

Estas dos secuencias pueden compilarse. Sin embargo, si las variables V1 a V12 no se utilizan explícitamente en otra parte de la base, el compilador no puede darles un tipo. Por lo tanto, deben ser utilizadas o declaradas explícitamente en otra parte.
Esta declaración explícita puede realizarse de dos formas:

  • Declarando V1, V2, …V12 a través de una directiva de compilación:
 C_LONGINT(V1;V2;V3;V4;V5;V6;V7;V8;V9;V10;V11;V12)
  • Asignando estas variables en un método:
 V1:=0
 V2:=0
 
 V12:=0

Como cada variable en una base compilada tiene un solo tipo, esta función puede parecer no muy útil. Sin embargo, puede ser útil cuando trabaja con punteros. Por ejemplo, puede ser necesario conocer el tipo de la variable a la cual el puntero hace referencia; debido a la flexibilidad de los punteros, no siempre es posible saber a que objeto apuntan.

Este comando ofrece ventajas en modo interpretado que no ofrece en modo compilado.
En modo compilado, un nombre de método pasado como parámetro a este comando será interpretado. Por lo tanto, usted no se beneficia de las ventajas ofrecidas por el compilador y la sintaxis de su parámetro no podrá verificarse.
Además, usted no puede pasar variables locales como parámetros.
Puede reemplazar EXECUTE FORMULA por una serie de instrucciones. Estos son dos ejemplos.

Dada la siguiente secuencia:

 i:=FormFunc
 EXECUTE FORMULA("FORM SET INPUT(Form"+String(i)+")")

Puede reemplazarla por:

 i:=FormFunc
 VarForm:="Form"+String(i)
 FORM SET INPUT(VarForm)

Miremos este otro ejemplo:

 $Num:=SelPrinter
 EXECUTE FORMULA("Print"+$Num)

Acá, EXECUTE FORMULA puede reemplazarse por Case of:

 Case of
    :($Num=1)
       Print1
    :($Num=2)
       Print2
    :($Num=3)
       Print3
 End case

El comando EXECUTE FORMULA puede reemplazarse siempre. Como el método a ejecutar se elije de la lista de los métodos de proyecto de la base o de los comandos de 4D, hay un número finito de métodos. Por lo tanto, siempre es posible reemplazar el comando EXECUTE FORMULA por Case of o por otro comando. Además, su código se ejecutará más rápido.

Estos dos comandos se utilizan en el proceso de depuración. No tienen ningún objetivo en una base compilada. Sin embargo, puede manterlos en sus métodos, simplemente serán ignorados por el compilador.

Undefined(variable)
SAVE VARIABLES(documento;variable1{; variable2…})
LOAD VARIABLES(documento;variable1{; variable2…})
CLEAR VARIABLE(variable)

Teniendo en cuenta el proceso de declaración efectuado por el compilador, una variable no puede en ningún momento indefinida en modo compilado. De hecho, todas las variables han sido definidas en el momento en que termina la compilación. La función Undefined por lo tanto siempre devuelve False, sin importar el parámetro que se pase.

Nota: para saber si su aplicación está corriendo en modo compilado, llame el comando Compiled application.

En modo interpretado, puede verificar que el documento existe probando si una de las variables está indefinida después de la ejecución de LOAD VARIABLES. Esto no es posible en bases compiladas, ya que la función Undefined siempre devuelve False.

Esta prueba puede realizarse en modo interpretado o compilado:
1. Inicialice las variables que va a recibir en un valor que no sea un valor legal para cualquiera de las variables.
2. Compare una de las variables recibidas con el valor de inicialización después de LOAD VARIABLES.
El método se puede escribir de este modo:

 Var1:="xxxxxx"
  `"xxxxxx" es un valor que no puede ser devuelto por LOAD VARIABLES
 Var2:="xxxxxx"
 Var3:="xxxxxx"
 Var4:="xxxxxx"
 LOAD VARIABLES("Documento";Var1;Var2;Var3;Var4)
 If(Var1="xxxxxx")
  `Documento no encontrado
 
 Else
  `Documento encontrado
 
 End if

Esta rutina utiliza dos sintaxis diferentes en modo interpretado:
CLEAR VARIABLE(variable)
CLEAR VARIABLE("a")
En modo compilado, la primera sintaxis de CLEAR VARIABLE(variable) reinicializa la variable (puesta en cero para un numérico; cadena vacía para un cadena de caracteres o un texto, etc.), ya que ninguna variable puede estar indefinida en modo compilado.
Por lo tanto, CLEAR VARIABLE no libera memoria en modo compilado, excepto en cuatro casos: las variable de tipo Texto, Imagen, BLOB y Arrays.
Para un Array, CLEAR VARIABLE tiene el mismo efecto que una nueva declaración del array donde el tamaño se establece como cero.

Para un array MiArray cuyos elementos son de tipo Entero, CLEAR VARIABLE(MiArray) tiene el mismo efecto de una de las expresiones siguientes:

 ARRAY INTEGER(MiArray;0)
  `si es un array de una dimensión
 ARRAY INTEGER(MiArray;0;0)
  `si es un array de dos dimensiones

La segunda sintaxis, CLEAR VARIABLE("a"), no es compatible con el compilador, ya que el compilador accede a las variables por dirección, no por nombre.

Los siguientes comandos tienen una característica en común: aceptan un primer parámetro opcional [Tabla] y el segundo parámetro puede ser un puntero.

ADD TO SETLOAD SET
APPLY TO SELECTIONLOCKED BY
COPY NAMED SELECTIONORDER BY
CREATE EMPTY SETORDER BY FORMULA
CREATE SETFORM SET OUTPUT
CUT NAMED SELECTIONPAGE SETUP
DIALOGPrint form
EXPORT DIFPRINT LABEL
EXPORT SYLKQR REPORT
EXPORT TEXTQUERY
GOTO RECORDQUERY BY FORMULA
GOTO SELECTED RECORDQUERY SELECTION
_o_GRAPH TABLEQUERY SELECTION BY FORMULA
IMPORT DIFREDUCE SELECTION
IMPORT SYLKRELATE MANY
IMPORT TEXTREMOVE FROM SET
FORM SET INPUT

En modo compilado, es fácil devolver el parámetro opcional [Tabla]. Sin embargo, cuando el primer parámetro pasado a uno de estos comandos es un puntero, el compilador no sabe a que puntero está haciendo referencia; el compilador lo trata como un puntero de tabla.

Tomemos el caso del comando QUERY cuya sintaxis es la siguiente:
QUERY({tabla{;formula{;*}})

El primer elemento del parámetro formula debe ser un campo.

Si escribe:

 QUERY(PtrField->=True)

el compilador buscará un símbolo que represente un campo en el segundo elemento. Cuando encuentra el signo "=", emitirá un mensaje de error, al no poder identificar el comando con una expresión que sepa tratar.

Por otra parte, si escribe:

 QUERY(PtrTabla->;PtrCampo->=True)

o

 QUERY([Tabla];PtrCampo->=True)

evitará cualquier ambigüedad posible.

Cuando se utilizan punteros, hay una particularidad relativa a los comandos en el que el primer parámetro [unaTabla] y el segundo parámetro son opcionales. En este contexto, por razones internas, el compilador no permite un comando que devuelva un puntero (por ejemplo Current form table) para ser pasado directamente como un parámetro (se genera un error).

Este es el caso, por ejemplo, del comando FORM SCREENSHOT. El código siguiente funciona en modo interpretado, pero es rechazado durante la compilación:

  //dispara un error de compilación
 FORM SCREENSHOT(Current form table->;$formName;$myPict)


En este caso, sólo puede usar una variable intermedia para que este código sea validado por el compilador:

  //código equivalente compilable.
 C_POINTER($ptr)
 $ptr:=Current form table
 FORM SCREENSHOT($ptr->;$formName;$myPict)

Si crea sus propios recursos 4DK# (constantes), asegúrese de que los numéricos sean declarados como de tipo Entero largo (L) o Reales (R) y las cadenas de caracteres como Cadenas (S). Cualquier otro tipo generará una advertencia.



Ver también 

Consejos de optimización
Guía de declaración
Mensajes de error
Utilización de directivas de compilación

 
PROPIEDADES 

Producto: 4D
Tema: Compilador

 
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)