GUÍA DE SENTENCIAS CLIPPER
ANNOUNCE
Declara un identificador de módulo
------------------------------------------------------------------------------
Sintaxis
ANNOUNCE <idM.dulo>
Argumentos
<idM.dulo> es el nombre de un identificador de módulo.
Descripción
ANNOUNCE es una sentencia que define un identificador de módulo. Los
enlazadores útilizan m.s tarde este identificador para las sentencias
REQUEST pendientes. ANNOUNCE y REQUEST sirven de mecanismo de manejo de
módulos de aplicación (ficheros .prg).
Las sentencias ANNOUNCE deben especificarse en el módulo fuente antes
que cualquier sentencia ejecutable. Un fichero fuente (.prg) sólo puede
tener un identificador de módulo; todas las declaraciónes ANNOUNCE
posteriores generan una advertencia de compilador y se ignoran. Los
identificadores de módulo deben ser exclusivos y no deben duplicar el
nombre de ningún procedimiento o función del fichero fuente (.prg).
Ejemplos
. El ejemplo siguiente muestra una declaración ANNOUNCE:
ANNOUNCE InicPerson
INIT PROCEDURE MiInic
? "Industrias Hipot.ticas S.A."
RETURN
El módulo de programa anterior, InicPerson, debe compilarse con la
opción /N. M.s tarde, este programa puede direccionarse en el código
fuente de cualquier otro módulo mediante una sentencia REQUEST:
REQUEST InicPerson
que hace que el módulo InicPerson se enlace en el fichero (.exe)
resultante.
BEGIN SEQUENCE
Define una secuencia de sentencias que se interrumpe con un BREAK
------------------------------------------------------------------------------
Sintaxis
BEGIN SEQUENCE
<sentencias>...
[BREAK [<exp>]]
<sentencias>...
[RECOVER [USING <idVar>]]
<sentencias>...
END [SEQUENCE]
Argumentos
BREAK <exp> bifurca la ejecución a la sentencia inmediatamente
después del RECOVER m.s cercano, si se ha especificado uno, o de la
sentencia END SEQUENCE en caso contrario. <exp> es el valor de retorno,
que se almacena en la <idVar> especificada en la cláusula USING de la
sentencia RECOVER.
RECOVER USING <idVar> define un punto de recuperaci.n en la
estructura SEQUENCE. El control pasa a este punto después de una
sentencia BREAK. Si se especifica la cláusula USING <idVar>, esta
variable recibe el valor de retorno de la sentencia BREAK, que suele ser
un objeto de error.
END define el punto final de la estructura SEQUENCE. Despu.s de un
BREAK, el control se bifurca a la primera sentencia después del END si
no se ha especificado una secuencia RECOVER.
Descripción
BEGIN SEQUENCE...END es una estructura de control que se utiliza para el
manejo de excepciones y errores de ejecución. Delimita un bloque de
sentencias que incluye todos procedimientos y funciónes invocados. Si se
encuentra un BREAK en el bloque de sentencias comprendido entre BEGIN
SEQUENCE y el RECOVER correspondiente, el control se bifurca a la
sentencia inmediatamente después de RECOVER. Si no se especifica una
sentencia RECOVER, el control pasa a la sentencia después de END y
finaliza la estructura SEQUENCE. Si el control llega a la sentencia
RECOVER sin encontrar antes un BREAK, pasa a la sentencia después del
END correspondiente.
La sentencia RECOVER puede recibir, opciónalmente, un parámetro pasado
por la sentencia BREAK como valor de retorno. Normalmente es un objeto
error, generado y devuelto por el bloque actual de manejo de errores
definido con ERRORBLOCK(). Si se devuelve un objeto de error, pueden
envíarse mensajes para solicitar información sobre el error. Con esta
información, los errores de ejecución pueden manejarse en el mismo
contexto de la operación. en vez de en el manejador actual de errores de
ejecución. Consulte el ejemplo siguiente.
En una estructura SEQUENCE existen algunas restricciones sobre las
sentencias permitidas entre BEGIN SEQUENCE y RECOVER. No pueden
ejecutarse sentencias RETURN, LOOP o EXIT. Dentro del bloque de
sentencias de RECOVER, no obstante, pueden ejecutarse sentencias LOOP,
EXIT, BREAK o RETURN, ya que la estructura SEQUENCE ha finalizado
pr.cticamente en este punto. La utilización de un LOOP en el bloque de
sentencias de RECOVER permite volver a ejecutar el bloque de sentencias
de SEQUENCE. Consulte el ejemplo siguiente.
Las estructuras SEQUENCE son bastante flexibles. Pueden anidarse y puede
haber varias en un mismo procedimiento o función. Si se especifica m.s
de una estructura SEQUENCE, cada una debe delimitar una operación.bien
definida.
Si desea más información sobre los objetos de error, consulte la clase
Error en este capítulo.
Ejemplos
. El siguiente fragmento de código muestra una estructura
SEQUENCE en la que aparece una sentencia BREAK dentro del
procedimiento actual:
BEGIN SEQUENCE
<sentencias>...
IF lCondBreak
BREAK
ENDIF
RECOVER
<sentencias de recuperaci.n>...
END
<sentencias de recuperaci.n>...
. El ejemplo siguiente muestra un manejador de errores que
devuelve un objeto de error a la variable especificada en la cláusula
USING de la sentencia RECOVER:
LOCAL objLocal, búltimoManejador
//
// Salvar el manejador actual y crear
// un nuevo manejador de errores
búltimoManejador := ERRORBLOCK({ |objErr| ;
MiManejador(objErr, .T.) })
//
BEGIN SEQUENCE
.
. <operación.que puede fallar>
.
RECOVER USING objLocal
//
// Envíar mensajes a objLocal y manejar el error
? "Error: "
IF objLocal:genCode != 0
?? objLocal:description
ENDIF
.
.
.
END
//
// Restablecer el manejador de errores anterior
ERRORBLOCK( búltimoManejador )
FUNCTION MiManejador( objError, lManejadorLocal)
//
// Manejar los erroresólocalmente devolviendo
// el objeto de error
IF lManejadorLocal
BREAK objError
ENDIF
.
. <otras sentencias para manejar el error>
.
RETURN NIL
. El ejemplo siguiente vuelve a ejecutar el bloque de sentencias
de SEQUENCE por medio de un LOOP en el bloque de sentencias de
RECOVER:
DO WHILE .T.
BEGIN SEQUENCE
.
. <operación.que puede fallar>
.
RECOVER
IF ImprimirRecup()
LOOP // Repetir el bloque de sentencias SEQUENCE
ENDIF
END
EXIT // Salir de la operación. ENDDO
DECLARE*
Crea e inicializa matrices y variables de memoria privadas
------------------------------------------------------------------------------
Sintaxis
DECLARE <identificador> [[:= <inicializador>], ... ]
Argumentos
<identificador> es el nombre de una variable privada o matriz que se
va a crear. Si <identificador> va seguido por corchetes ([ ]), se crea
una matriz. En tal caso, la sintaxis para especificar el número de
elementos para cada dimensión es matriz[<nElementos>, <nElementos2>,...]
o matriz[<nElementos>][<nElementos2>]... El número máximo de elementos
por dimensión es 4096.
<inicializador> es la asignación opciónal de un valor a una nueva
variable privada. La expresión de <inicializador> para una variable
privada est. formada por el operador de asignación en línea (:=) seguido
por cualquier expresión víaacute;lida de CA-Clipper, incluyendo una matriz
literal. Si no se especifica ningún <inicializador> explícito, la
variable recibe un valor inicial de NIL. En el caso de una matriz, cada
uno de sus elementos tiene un valor NIL. No pueden asignarse valores a
los elementos de una matriz mediante un <inicializador>.
DECLARE puede crear e inicializar, opciónalmente, una lista de matrices
de variables, separando las definiciónes con comas.
Descripción
DECLARE es una sentencia de compatibilidad y es sin.nima de la sentencia
PRIVATE. No se recomienda su utilización general. PRIVATE debe
utilizarse en todos los casos. Consulte PRIVATE si desea m.s
información.
DO*
Llama a un procedimiento
------------------------------------------------------------------------------
Sintaxis
DO <idProcedimiento> [WITH <lista argumentos>]
Argumentos
<idProcedimiento> es el nombre del procedimiento o función definida
por el usuario que va a ejecutarse.
<lista argumentos> WITH especifica un máximo de 128 argumentos,
separados por comas, que se van a pasar a <idProcedimiento>. Cada
argumento puede ser una variable sencilla, un campo, una matriz, un
elemento de una matriz, una expresión o un objeto. Los argumentos pueden
omitirse o dejarse al final de la lista.
Descripción
La sentencia DO llama a un procedimiento o función pasando,
opciónalmente, argumentos a la rutina invocada. Realiza la misma acci.n
que una función o procedimiento especificado en una línea, con la
excepci.n de que las variables que no sean de campo se pasan por
referencia por defecto. Para pasar una variable de campo como argumento,
debe encerrarla entre paréntesis, a menos que la declare con una
sentencia FIELD o con un alias.
En CA-Clipper, no es necesario que el número de argumentos especificados
sea igual al de parámetros especificados en el procedimiento invocado.
Si el número de argumentos es menor que el número de parámetros, las
variables de parámetros sin argumentos correspondientes se inicializan
con un valor NIL. Del mismo modo, si se omite un argumento de la <lista
argumentos>, dejando un lugar vac.o con una coma, el argumento
correspondiente se inicializa con un valor NIL. Si desea conocer la
posición del último argumento pasado en la <lista argumentos>, utilice
PCOUNT(). Para saber si se ha omitido un argumento, compare el parámetro
recibido con el valor NIL.
Además de invocar a un procedimiento o función, DO tiene un efecto sobre
la compilación si compila el módulo fuente actual sin la opción /M. Si
el compilador de CA-Clipper encuentra una sentencia DO y el
procedimiento especificado no se ha compilado todavía, el compilador
busca el fichero (.prg) en el directorio actual con el mismo nombre y lo
compila. Si no se encuentra dicho fichero, el procedimiento invocado se
supone externo y se a.ade una referencia al fichero objeto (.OBJ). En el
momento del enlace, el enlazador busca en otros ficheros objeto y
bibliotecas con esta referencia externa.
En CA-Clipper, DO es una sentencia de compatibilidad y su utilización no
es recomendable. Es preferible hacer una llamada al procedimiento o
función en una línea independiente. Puesto que en la convenci.n de
llamadas preferible los parámetros se pasan normalmente por valor, si
desea pasar un argumento por referencia debe precederlo con el operador
pasar por referencia (@). Si utiliza las sentencias DO para hacer m.s
legible una llamada de procedimientos, los mandatos definidos con una
directiva #command ofrecen una mayor legibilidad sin sacrificar la
seguridad de las variables pasadas como parámetros.
Si desea más información sobre la forma de paso de parámetros, consulte
el apartado funciónes y Procedimientos del capítulo Conceptos Básicos de
la gu.a Programaci.n y Utilidades.
Ejemplos
. Este ejemplo ejecuta un procedimiento sin parámetros:
DO InfoCuentas
InfoCuentas() // M.todo preferible
. Este ejemplo ejecuta un procedimiento pasando dos constantes:
DO InfoTrimestral WITH "2.", "Divisi.n Ventas"
InfoTrimestral("2.", "Divisi.n Ventas") // M.todo preferible
. Este ejemplo ejecuta un procedimiento con el primer argumento
pasado por valor y el segundo pasado por referencia:
nNúmero := 12
DO InfoAnual WITH nNúmero + 12, nNúmero
InfoAnual(nNúmero + 12, @nNúmero) // M.todo preferible
. Aqu., se llama a un procedimiento con argumentos saltados
incluidos en la lista de argumentos:
DO MostrarPantalla WITH ,,,,"Mi Ventana"
MostrarPantalla(,,,,"Mi Ventana") // M.todo preferible
DO CASE
Ejecuta un bloque de sentencias dependiendo de una condición
------------------------------------------------------------------------------
Sintaxis
DO CASE
CASE <lCondici.n1>
<sentencias>...
[CASE <lCondici.n2>]
<sentencias>...
[OTHERWISE]
<sentencias>...
END[CASE]
Argumentos
CASE <lCondici.n> define el bloque de sentencias que se van a
ejecutar si <lCondici.n> resulta verdadera (.T.).
OTHERWISE define un bloque de sentencias que se van a ejecutar si
ningúna de las condiciónes CASE especificadas resulta verdadera (.T.).
Descripción
DO CASE...ENDCASE es una estructura de control que ejecuta uno de varios
posibles bloques de sentencias, dependiendo del resultado de evaluar las
condiciónes asociadas. Bifurca la ejecución a las sentencias situadas
después de la primera condición, que resulte verdadera. La ejecución
prosigue hasta que se encuentra el siguiente CASE, OTHERWISE o ENDCASE.
El control pasa entonces a la primera sentencia que siga a la pr.xima
sentencia ENDCASE.
Si ningúna de las condiciónes CASE resulta verdadera, las sentencias que
siguen a la sentencia OTHERWISE se ejecutan hasta la sentencia ENDCASE
correspondiente. Si se omite una sentencia OTHERWISE, el control pasa a
la primera sentencia que sigue a la sentencia ENDCASE correspondiente.
Es posible anidar cualquier número de sentencias dentro de una sentencia
DO CASE, incluyendo otras estructuras de control (es decir, DO WHILE y
FOR). En una estructura DO CASE sencilla no existe un l.mite fijo en el
número de sentencias CASE que puede contener.
DO CASE...ENDCASE es id.ntica a IF...ELSEIF...ENDIF sin que ningúna de
estas sintaxis tenga alguna ventaja espec.fica sobre la otra.
Ejemplos
. Este ejemplo utiliza DO CASE en una estructura de men.s para
bifurcar el control seg.n la selecci.n del usuario:
@ 3, 25 PROMPT "Primera opción"
@ 4, 25 PROMPT "Segunda opción"
MENU TO nOpcion
//
DO CASE
CASE nOpcion = 0
RETURN
CASE nOpcion = 1
OpcionUno()
CASE nOpcion = 2
OpcionDos()
ENDCASE
DO WHILE
Ejecuta un bucle si una condición resulta verdadera
------------------------------------------------------------------------------
Sintaxis
[DO] WHILE <lCondici.n>
<sentencias>...
[EXIT]
<sentencias>...
[LOOP]
<sentencias>...
END[DO]
Argumentos
<lCondici.n> es la expresión de control l.gica del bucle DO WHILE.
EXIT bifurca incondiciónalmente el control de una estructura DO
WHILE o FOR...NEXT a la sentencia inmediatamente después de la pr.xima
ENDDO o NEXT.
LOOP bifurca el control a la sentencia DO WHILE o FOR ejecutada m.s
recientemente.
Descripción
DO WHILE...ENDDO es una estructura de control de secuencia que ejecuta
repetitivamente un bloque de sentencias mientras <lCondici.n> sea
verdadera. Mientras esta condición resulte verdadera, el control pasa a
la estructura y continúa.hasta encontrar una sentencia EXIT, LOOP o
ENDDO. ENDDO devuelve el control a la sentencia DO WHILE y el proceso se
repite. Si se encuentra una sentencia EXIT, el control se bifurca a la
sentencia ENDDO o NEXT m.s pr.xima. Si se encuentra una sentencia LOOP,
el control se bifurca a la sentencia DO WHILE o FOR m.s pr.xima. Cuando
la condición es falsa, finaliza la estructura DO WHILE y el control pasa
a la sentencia inmediatamente siguiente a ENDDO.
EXIT permite terminar una estructura DO WHILE con una condición distinta
a la condición DO WHILE original. LOOP, sin embargo, no permite ejecutar
sentencias dentro de DO WHILE basadas en una condición intermedia y
devuelve el control a la sentencia DO WHILE m.s reciente.
La estructura DO WHILE puede anidarse dentro de otras estructuras de
control a cualquier profundidad. El .nico requisito es que cada
estructura de control se anide adecuadamente.
Ejemplos
. Este ejemplo muestra una estructura de control t.pica de un
informe sencillo agrupado:
LOCAL cVendedorAnterior, nTotalCantidad
USE Ventas INDEX Vendedor NEW
DO WHILE .NOT. EOF()
cVendedorAnterior := Ventas->Vendedor
nTotalCantidad := 0
DO WHILE cVendedorAnterior = Ventas->Vendedor ;
.AND. (.NOT. EOF())
? Ventas->Vendedor, Ventas->Cantidad
nTotalCantidad := nTotalCantidad + Ventas->Cantidad
SKIP
ENDDO
? "Total: ", nTotalCantidad, "del", cVendedorAnterior
ENDDO
CLOSE Ventas
. Este fragmento de código muestra c.mo puede utilizarse LOOP
para establecer un tratamiento condiciónal:
DO WHILE <lCondici.n>
<tratamiento inicial>...
IF <Condici.n intermedia>
LOOP
ENDIF
<tratamiento restánte>...
ENDDO
. Este ejemplo muestra la utilización de DO WHILE para emular
una repetición en una estructura de bucle:
LOCAL lMas := .T.
DO WHILE lMas
<sentencias>...
lMas := (<lCondici.n>)
ENDDO
. Este ejemplo utiliza un bucle DO WHILE para desplazarse
secuencialmente por un fichero de base de datos:
DO WHILE .NOT. EOF()
<sentencias>...
SKIP
ENDDO
EXIT PROCEDURE
Declara un procedimiento de clausura
------------------------------------------------------------------------------
Sintaxis
EXIT PROCEDURE <idProcedimiento>
[FIELD <lista idCampo> [IN <idAlias>]]
[LOCAL <identificador> [[:= <inicializador>]]]
[MEMVAR <lista identificador>]
.
. <sentencias ejecutables>
.
[RETURN]
Argumentos
EXIT PROCEDURE declara un procedimiento que se ejecuta en la
terminaci.n del programa.
<idProcedimiento> es el nombre del procedimiento de clausura que se
va a declarar. Los nombres de procedimientos de clausura pueden tener
cualquier longitud, pero sólo son significativosólos primeros 10
carácteres. Los nombres no deben comenzar con un signo de subrayado,
pero pueden contener cualquier combinación de carácteres, números o
signos de subrayado.
FIELD declara una lista de identificadores para utilizar como
nombres de campo siempre que se encuentren. Si se especifica la cláusula
IN, la referencia al nombre declarado incluye una referencia impl.cita
al alias especificado.
LOCAL declara y, opciónalmente, inicializa una lista de variables o
matrices, cuya visibilidad y vida es la del procedimiento actual.
MEMVAR declara una lista de identificadores para utilizar como
variables o matrices de memoria privadas o públicas, siempre que se
encuentren.
RETURN pasa el control al siguiente procedimiento de clausura o al
sistema operativo, si no hay pendiente ningún otro procedimiento de
clausura.
Descripción
La sentencia EXIT PROCEDURE declara un procedimiento que se ejecutar.
cuando finalice el programa. Los procedimientos de clausura se llaman
después de que se haya completado la .ltima sentencia ejecutable en una
aplicación de CA-Clipper. Las sentencias EXIT PROCEDURE pueden
utilizarse para ejecutar tareas de mantenimiento habituales, como por
ejemplo, guardar los parámetros de configuración en un fichero, cerrar
un fichero de registro o concluir una sesi.n de comunicaciones.
La visibilidad de los procedimientos de clausura est. limitada al
sistema; por lo tanto, no es posible llamar a un procedimiento de
clausura desde un procedimiento o función definido por el usuario. Los
procedimientos de clausura no reciben parámetros.
Una vez que se ha completado la .ltima sentencia ejecutable, el control
pasa de un procedimiento de clausura al siguiente hasta que se ha
llamado a todos los procedimientos de la lista de clausura. El control
pasa seguidamente al sistema operativo.
La sentencia ANNOUNCE declara un identificador de módulo para un módulo
fuente (.prg). Una vez declarado, se hace referencia a las sentencias
EXIT PROCEDURE con este identificador de módulo. Una aplicación puede
utilizar cualquier número de procedimientos de clausura, solicitando de
forma expl.cita mediante REQUEST sus identificadores de módulo.
Los procedimientos de clausura solicitados para una aplicación se
mencionan, de forma colectiva, como la lista de clausura. No existe un
orden de ejecución obligatorio de procedimientos en la lista de
clausura; sin embargo, si un procedimiento de clausura se declara en el
mismo módulo fuente (.prg) que la rutina principal o ra.z, .ste ser. el
primer procedimiento de clausura llamado.
La terminaci.n de una aplicación de CA-Clipper dada puede atribuirse a
alguna de las siguientes causas:
. RETURN desde la rutina principal o ra.z
. el mandato QUIT
. la ejecución de un BREAK sin incluir BEGIN SEQUENCE...END
. error irrecuperable
No se puede garantizar la ejecución de un procedimiento de clausura
cuando el sistema detecta un error irrecuperable. Si se ha producido un
error durante un procedimiento de clausura, el sistema vuelve al DOS.
Los procedimientos de clausura pendientes no se llaman.
Ejemplos
. En este ejemplo se ilustra la construcci.n de un mecanismo de
temporizaci.n simple, utilizando INIT y EXIT PROCEDURE:
// imprime la cantidad de tiempo necesario para,
// leer, ordenar y mostrar una lista de nombres
// de ficheros.
ANNOUNCE MiSistema
STATIC nInicio
PROCEDURE Main()
AEVAL( ASORT( DIRECTORY( "*.*" ) ),;
{ | aInfoFichero | QOUT( aInfoFichero[ 1 ] ) } )
RETURN
INIT PROCEDURE MiInicio()
nInicio := SECONDS()
RETURN
EXIT PROCEDURE MiClausura()
?
? "Tiempo transcurrido: "
?? SECONDS() - nInicio
RETURN
EXTERNAL*
Declara al enlazador una lista de nombres de procedimientos o funciónes
definidas por el usuario para que se incluyan en el ejecutable
------------------------------------------------------------------------------
Sintaxis
EXTERNAL <lista idProcedimientos>
Argumentos
<lista idProcedimientos> es la lista de procedimientos, funciónes
definidas por el usuario o procedimientos de formato que deben a.adirse
a la lista de rutinas que se enlazar.n en el fichero ejecutable actual
(.EXE).
Descripción
EXTERNAL es una sentencia de declaración que especifica referencias sin
codificar para el enlazador. Al igual que con el resto de sentencias de
declaración, una sentencia EXTERNAL debe especificarse antes de
cualquier sentencia ejecutable en cualquier fichero de programa o en una
definición de procedimiento o función definida por el usuario.
Durante la compilación del código fuente de CA-Clipper, todas las
referencias expl.citas a los procedimientos y funciónes definidas por el
usuario se pasan al enlazador. En algunos casos, no existen referencias
a los nombres de procedimientos o de funciónes definidas por el usuario
hasta el tiempo de ejecución. EXTERNAL resuelve esta situaci.n forzando
a los procedimientos nombrados o funciónes definidas por el usuario a
ser enlazados aunque no se haga referencia expl.cita a ellos en ningún
módulo fuente. Esto es importante en diversos casos:
. Procedimientos, funciónes definidas por el usuario o formatos
a los que se hace referencia mediante macroexprexiones o variables
que las contengan
. Procedimientos y funciónes definidas por el usuario utilizadas
en REPORT y LABEL FORMs y no referidos en el código fuente
. funciónes definidas por el usuario en las claves de índice y
no referidas en el código fuente
. funciónes de usuario ACHOICE(), DBEDIT() o MEMOEDIT()
Para agrupar declaraciónes EXTERNAL comunes, sit.elas en un fichero de
cabecera y después incluya mediante #include el fichero de cabecera en
cada módulo de programa (.prg) que pueda utilizarlas de forma indirecta.
EXTERNAL es una sentencia de compatibilidad y por lo tanto, no es
recomendable. Ha sido sustituida por la sentencia REQUEST que define una
lista de identificadores de módulo para el enlazador.
Ejemplos
. Estos ejemplos son ficheros de cabecera equivalentes que
constan de referencias EXTERNAL comunes para REPORT FORMs:
// Externals.ch
EXTERNAL HARDCR
EXTERNAL TONE
EXTERNAL MEMOTRAN
EXTERNAL STRTRAN
// Externals.ch
EXTERNAL HARDCR, TONE, MEMOTRAN, STRTRAN
FIELD
Declara nombres de campo de base de datos
------------------------------------------------------------------------------
Sintaxis
FIELD <lista idCampos> [IN <idAlias>]
Argumentos
<lista idCampos> es una lista de nombres para declarar como campos
para el compilador.
IN <idAlias> especifica un alias que debe asumirse cuando existen
referencias sin alias a los nombres especificados en la <lista
idCampos>. Las referencias sin alias a las variables en <lista idCampos>
se tratan como si estuvieran precedidas por el alias de campo especial
(FIELD->).
Descripción
La sentencia FIELD declara los nombres de campos de base de datos para
el compilador y, opciónalmente, proporciona un alias impl.cito para cada
nombre. Esto permite al compilador resolver referencias a variables sin
alias explícito--asumiendo impl.citamente el <idAlias> especificado.
S.lo se ven afectadas las referencias expl.citas sin alias a los campos
especificados en <lista idCampos>. La sentencia FIELD, al igual que
todas las declaraciónes, no tiene efecto sobre las referencias
efectuadas dentro de macroexpresiónes o variables que las contengan.
La sentencia FIELD no abre un fichero de base de datos ni verifica la
existencia de campos especificados. Esto es útil, especialmente, para
garantizar las referencias correctas a los campos cuya accesibilidad se
conoce en el tiempo de ejecución. Si se intenta acceder a campos cuando
la base de datos asociada no est. en uso, se produce un error.
El ámbito de la declaración FIELD es el procedimiento o función en la
que se produce o todo el módulo fuente (.prg) si la declaración precede
todas las declaraciónes PROCEDURE o FUNCTION y se especifica la opción
de compilador /N.
Las sentencias FIELD, al igual que otras declaraciónes, deben preceder a
cualquier sentencia ejecutable en la definición de procedimiento o
función, o en el módulo fuente (.prg) si la declaración tiene un ámbito
de módulo.
FIELD utilizado con la opción de compilador /W ejecuta una comprobaci.n
de variables no declaradas durante la compilación.
Si desea obtener más información sobre declaraciónes y ámbitos de
variables, consulte el apartado Variables del capítulo Conceptos Básicos
de la gu.a Programaci.n y Utilidades.
Ejemplos
. Esta función definida por el usuario incluye sentencias para
declarar nombres de campos de bases de datos tanto en el .rea de
trabajo actual como en el .rea Empleado:
FUNCTION MuestraRegistro
FIELD NoClie, NoPedido, Vendedor
FIELD NomEmp, CodEmp IN Empleado
USE Empleado NEW
USE Pedidos NEW
//
? NoClie // Refiere a Pedidos->NoClie
? NomEmp // Refiere a Empleado->NomEmp
//
CLOSE Pedidos
CLOSE Empleado
RETURN NIL
FOR
Ejecuta un bloque de sentencias un número determinado de veces
------------------------------------------------------------------------------
Sintaxis
FOR <idContador> := <nInicio> TO <nFin>
[STEP <nIncremento>]
<sentencias>...
[EXIT]
<sentencias>...
[LOOP]
NEXT
Argumentos
<idContador> es el nombre de la variable de control o contador del
bucle. Si el <idContador> especificado no es visible o no existe, se
crea una variable privada.
<nInicio> es el valor inicial asignado a <idContador>. Si
<nIncremento> es negativo, <nInicio> debe ser mayor que <nFin>.
TO <nFin> define el valor final de <idContador>. Si <nIncremento> es
negativo, <nInicio> debe ser superior a <nFin>; en caso contrario,
<nInicio> debe ser menor que <nFin>.
STEP <nIncremento> define la cantidad en que var.a <idContador> para
cada iteraci.n del bucle. <nIncremento> puede ser positivo o negativo.
Si no se especifica la cláusula STEP, <idContador> se incrementa en uno
en cada iteraci.n del bucle.
EXIT bifurca el control incondiciónalmente a la sentencia
inmediatamente siguiente a la sentencia NEXT m.s pr.xima.
LOOP bifurca el control a la sentencia FOR o DO WHILE ejecutada m.s
recientemente.
Descripción
FOR...NEXT es una estructura de control que ejecuta un bloque de
sentencias un número de veces especificado. La estructura de control
efect.a un bucle desde el valor inicial de <idContador> hasta el l.mite
especificado por <nFin>, desplaz.ndose a trav.s del rango de valores de
la variable de control con un incremento especificado mediante
<nIncremento>. Todas las expresiónes de la sentencia FOR se reeval.an en
cada iteraci.n del bucle. Por lo tanto, las expresiónes <nInicio> y
<nFin> pueden cambiarse a medida que act.a la estructura de control.
Un bucle FOR funcióna hasta que <idContador> es mayor que <nFin> o se
encuentra una sentencia EXIT. El control bifurca entonces a la sentencia
siguiente a la sentencia NEXT correspondiente. Si se encuentra una
sentencia LOOP, el control bifurca de nuevo a la sentencia FOR actual.
Si <nIncremento> es un valor negativo, <idContador> se reduce en lugar
de incrementarse. Sin embargo, el bucle FOR continúa.hasta que
<idContador> es menor que <nFin>. Esto significa que <nFin> debe ser
menor que <nInicio> cuando comienza el bucle FOR.
Los bucles FOR son .tiles para recorrer matrices donde se utiliza
<idContador> como subíndice de matriz. Consulte el ejemplo que se
muestra m.s adelante.
Las construcciones FOR...NEXT pueden anidarse dentro de otras
estructuras de control a cualquier profundidad. El .nico requisito es
que cada estructura de control se anide de forma adecuada.
Ejemplos
. Este ejemplo recorre una matriz en orden ascendente:
nLongMatriz := LEN(aMatriz)
FOR i := 1 TO nLongMatriz
<sentencias>...
NEXT
. Para recorrer una matriz en orden descendente:
nLongMatriz := LEN(aMatriz)
FOR i := nLongMatriz TO 1 STEP -1
<sentencias>...
NEXT
FUNCTION
Declara el nombre y parámetros formales de una función definida por el
usuario
------------------------------------------------------------------------------
Sintaxis
[STATIC] FUNCTION <idfunción>
[(<idLista Par.metros>)]
[LOCAL <identificador> [[:= <inicializador>], ... ]]
[STATIC <identificador> [[:= <inicializador>], ... ]]
[FIELD <lista identificadores> [IN <idAlias>]]
[MEMVAR <lista identificadores>]
.
. <sentencias ejecutables>
.
RETURN <exp>
Argumentos
<idfunción> es el nombre de la función definida por el usuario que
debe declararse. Los nombres de función definidos por el usuario pueden
tener cualquier longitud, pero sólo son significativosólos primeros 10
carácteres. Los nombres pueden contener cualquier combinación de
carácteres, números o signos de subrayado, pero deben comenzar con un
carácter o signo de subrayado. Los subrayados iniciales no son
recomendables puesto que están reservados para funciónes internas.
<idLista Par.metros> es la declaración de una o más variables de
parámetro. Las variables especificadas en esta lista se han declarado
como locales.
STATIC FUNCTION declara una función definida por el usuario que sólo
puede llamarse desde procedimientos y funciónes definidas por el
usuario, declaradas en el mismo módulo fuente (.prg).
LOCAL declara y, opciónalmente, inicializa una lista de variables o
matrices cuya visibilidad y tiempo de vida es la función actual.
STATIC declara y, opciónalmente, inicializa una lista de variables o
matrices, cuya visibilidad es la función actual definida por el usuario
y cuyo tiempo de vida es la duraci.n del programa.
FIELD declara una lista de identificadores para utilizar como
nombres de campo siempre que se encuentren. Si se especifica la cláusula
IN, las referencias al nombre declarado incluyen una referencia
impl.cita al alias especificado.
MEMVAR declara una lista de identificadores para utilizar como
variables de memoria privadas o públicas o matrices siempre que se
encuentren.
<identificador> y <lista identificadores> son etiquetas que
deben utilizarse como nombres de variables o matrices.
<inicializador> es un valor que se asigna originalmente a una matriz
o variable en una expresión de inicializaci.n en línea.
RETURN <exp> pasa el control de nuevo al procedimiento o función
definida por el usuario que la ha llamado, devolviendo el resultado de
<exp> como valor de retorno de la función. Cada función debe tener, como
mínimo, una sentencia RETURN que devuelva un valor. Las sentencias
RETURN pueden colocarse en cualquier parte del cuerpo de una función.
Descripción
La sentencia FUNCTION declara una función definida por el usuario y una
lista opciónal de variablesólocales para recibir parámetros, que con
frecuencia se denominan parámetros formales. Una función definida por el
usuario es un subprograma compuesto por un conjunto de declaraciónes y
sentencias, que se ejecutan siempre que se hace referencia a <idfunción>
seguido por un par de paréntesis de apertura y cierre. Una definición de
función comienza con una sentencia FUNCTION y finaliza con la siguiente
sentencia FUNCTION o PROCEDURE o el final del fichero.
Las funciónes encapsulan un bloque de código de c.lculo y después, crean
expresiónes útilizando el valor devuelto. Las funciónes y procedimientos
aumentan tanto la legibilidad como la modularidad, aislan los cambios y
ayudan a manejar situaciones complejas.
Una función de CA-Clipper es igual que un procedimiento, con la
excepci.n de que debe devolver un valor. El valor devuelto puede ser
cualquier tipo de datos incluyendo una matriz, un bloque de código o
NIL. Cada función debe comenzar con una sentencia FUNCTION y contener,
por lo menos, una sentencia RETURN con un argumento. Las declaraciónes
de funciónes no pueden anidarse dentro de otras definiciónes de función.
Una función definida por el usuario puede utilizarse dondequiera que se
admitan funciónes estándar, incluyendo expresiónes.
La visibilidad de los nombres de función se divide en dos clases. Las
funciónes que son visibles en cualquier lugar de un programa se
denominan funciónes públicas y se declaran con una sentencia FUNCTION.
Las funciónes que son visibles sólo dentro del módulo fuente actual
(.prg) se denominan funciónes estáticas y se declaran con una sentencia
STATIC FUNCTION. Las funciónes estáticas tienen ámbito de módulo.
Las funciónes estáticas limitan la visibilidad de un nombre de función,
restringiendo por tanto el acceso a las mismas. Por este motivo, los
subsistemas definidos dentro de un módulo fuente simple (.prg) pueden
proporcionar un protocolo de acceso con una serie de funciónes públicas
y ocultar los detalles de implantaci.n del subsistema dentro de
funciónes y procedimientos estáticos. Puesto que las referencias de
función estáticas se resuelven en el tiempo de compilación, .stas se
apropian de las referencias a las funciónes públicas, que se resuelven
en el tiempo de enlace. Esto garantiza que, dentro de un módulo fuente,
una referencia a una función estática ejecutar. esa función si existe un
conflicto de nombre con una función pública.
Para más información sobre funciónes definidas por el usuario,
declaraciónes de variables y paso de parámetros, consulte el capítulo
Conceptos Básicos en la gu.a Programaci.n y Utilidades.
Notas
. Llamada a una función definida por el usuario: Utilice la
misma notaci.n para llamar a una función definida por el usuario que
cuando efect.a una llamada a una función de CA-Clipper estándar:
<idfunción>([<lista argumentos>])
Puede llamar a una función definida por el usuario dentro de una
expresión o en una línea, por s. misma. En el segundo caso, el valor
de retorno se ignora.
También puede llamar a una función definida por el usuario como una
expresión de alias, precedi.ndola con un alias e incluy.ndola entre
paréntesis:
<idAlias>->(<idfunción>(<lista argumentos>))
Cuando se llama a una función definida por el usuario como una
expresión de alias, se selecciona el área de trabajo asociada con
<idAlias>, la expresión se ejecuta y el área de trabajo original se
selecciona de nuevo. Puede especificar una expresión de alias en una
línea, por s. misma, del mismo modo que har.a con cualquier otra
expresión.
Una función definida por el usuario en CA-Clipper puede llamarse a s.
misma, repetidamente. Esto significa que puede efectuar una
referencia a una función definida por el usuario en sentencias o
expresiónes iguales a la definición de función efectuada por el
usuario.
. Par.metros: Tanto las funciónes definidas por el usuario,
como los procedimientos, pueden recibir parámetros pasados por el
procedimiento o función que los invoca, o desde la línea de mandatos
del DOS. Un parámetro es un espacio reservado para un valor o una
referencia. En CA-Clipper, existen dos formas de expresar parámetros:
puede declarar una lista de nombres de variablesólocales como parte
de la declaración FUNCTION (referida como parámetros formales) o
puede especificar una lista de variables privadas en una sentencia
PARAMETERS independiente. Observe que no puede mezclar una
declaración de parámetros formales con una sentencia PARAMETERS. Si
intenta hacerlo de ese modo, se genera un error de compilación.
Las funciónes reciben parámetros en el orden que se les han pasado.
En CA-Clipper, el número de parámetros no tiene por qu. coincidir con
el número de argumentos pasados. Puede saltarse argumentos u
omitirlos de la lista de argumentos. Un parámetro que no recibe un
valor o la referencia se inicializa con NIL. Puede saltarse un
parámetro pasando NIL. Si se especifican argumentos, PCOUNT()
devuelve la posición del último argumento pasado.
Los parámetros especificados en una función definida por el usuario
pueden recibir argumentos pasados por valor o referencia. El m.todo
por defecto para expresiónes y variables es por valor. Esto incluye
variables que contienen referencias a matrices y objetos. Todas las
variables excepto las de campo, cuando están precedidas por el
operador pasar por referencia (@), se pasan por referencia. Las
variables de campo no pueden pasarse por referencia y se pasan
siempre por valor.
Ejemplos
. Este ejemplo muestra una función definida por el usuario que
da formato a valores numéricos como moneda:
? Moneda( 1000 ) // Resultado: $1,000.00
FUNCTION Moneda( nNúmero )
LOCAL cnúmero
IF nNúmero < 0
cnúmero := TRANSFORM(-1 * nNúmero, ;
"999,999,999,999.99")
cnúmero := PADL("($" + LTRIM(cnúmero) + ")", ;
LEN(cnúmero))
ELSE
cnúmero := TRANSFORM(nNúmero, ;
"999,999,999,999.99")
cnúmero := PADL("$" + LTRIM(cnúmero), ;
LEN(cnúmero))
ENDIF
RETURN cnúmero
. En este ejemplo se muestra una función definida por el usuario
que toma una cadena de carácteres con formato como una lista separada
por comas y devuelve una matriz con un elemento por objeto:
aLista := ListaComoMatriz("Uno, Dos")
// Resultado: {"Uno", "Dos"}
FUNCTION ListaComoMatriz( cLista )
LOCAL nPos
// Definir una matriz vac.a
LOCAL aLista := {}
//
DO WHILE (nPos := AT(",", cLista)) != 0
// A.adir un nuevo elemento
AADD(aLista, SUBSTR(cLista, 1, nPos - 1))
cLista := SUBSTR(cLista, nPos + 1)
ENDDO
AADD(aLista, cLista)
//
// Devolver la matriz
RETURN aLista
. En este ejemplo se comprueba si se ha saltado alg.n argumento,
comparando el parámetro con NIL:
FUNCTION MiFunc( param1, param2, param3 )
IF param2 == NIL
param2 := "valor por defecto"
ENDIF
.
. <sentencias>
.
RETURN NIL
. En este ejemplo se utiliza la función definida por el usuario,
Moneda() (definida anteriormente), como una expresión con alias:
USE Facturas NEW
USE Cliente NEW
? Facturas->(Moneda(Cantidad))
IF
Ejecuta uno o m.s bloques alternativos de sentencias
------------------------------------------------------------------------------
Sintaxis
IF <lCondici.n1>
<sentencias>...
[ELSEIF <lCondici.n2>]
<sentencias>...
[ELSE]
<sentencias>...
END[IF]
Argumentos
<lCondici.n> es una expresión l.gica de control. Si resulta
verdadera (.T.), todas las sentencias siguientes se ejecutan hasta que
se encuentra una sentencia ELSEIF, ELSE o ENDIF.
ELSEIF <lCondici.n> identifica las sentencias que se van a ejecutar
si la condición asociada resulta verdadera (.T.) y todas las condiciónes
IF o ELSEIF anteriores son falsas (.F.). Puede especificarse cualquier
número de sentencias ELSEIF en la misma estructura de control
IF...ENDIF.
ELSE identifica las sentencias que se deben ejecutar si la condición
IF y todas las condiciónes ELSEIF anteriores son falsas (.F.).
Descripción
La estructura de control IF act.a bifurcando la ejecución a las
sentencias situadas después de la primera condición que resulte
verdadera (.T.), en la sentencia IF o en alguna de las ELSEIF. La
ejecución continúa.hasta que se encuentre la siguiente sentencia ELSEIF,
ELSE o ENDIF, donde la ejecución salta a la primera sentencia situada
después del ENDIF.
Si ningúna condición resulta verdadera (.T.) el control pasa a la
primera sentencia situada después de la sentencia ELSE. Si no se
especifica ningúna sentencia ELSE, el control pasa a la primera
sentencia situada después de la sentencia ENDIF.
Las estructuras IF...ENDIF pueden anidarse dentro de otras estructura
IF...ENDIF y otras estructuras de control. Estas estructuras, no
obstante, deben estar correctamente anidadas.
La forma IF...ELSEIF...ENDIF de la estructura IF es id.ntica a la
estructura DO CASE...ENDCASE. No existe ningúna ventaja espec.fica de
una sintaxis sobre la otra. La estructura IF es también similar a la
función IF() que puede utilizarse dentro de expresiónes.
Ejemplos
. Este ejemplo eval.a un número de condiciónes útilizando una
estructura IFELSEIF...ENDIF :
LOCAL nNúmero := 0
//
IF nNúmero < 50
? "Menor que 50"
ELSEIF nNúmero = 50
? "Igual a 50"
ELSE
? "Mayor que 50"
ENDIF
INIT PROCEDURE
Declara un procedimiento de inicializaci.n
------------------------------------------------------------------------------
Sintaxis
INIT PROCEDURE <idProcedimiento> [(<lista idPar.m>)]
[FIELD <lista idCampos> [IN <idAlias>]]
[LOCAL <identificador> [[:= <inicializador>]]]
[MEMVAR <Lista Identificadores>]
.
. <sentencias ejecutables>
.
[RETURN]
Argumentos
INIT PROCEDURE declara un procedimiento que se ejecutar. cada vez
que se inicie el programa.
<idProcedimiento> es el nombre del procedimiento de inicializaci.n
que se va a declarar. Los nombres de procedimiento de inicializaci.n
pueden tener cualquier longitud pero sólo los 10 primeros carácteres son
significativos. Los nombres no pueden comenzar con el carácter de
subrayado, pero pueden contener cualquier combinación de carácteres,
números o subrayados.
<lista idPar.m> es la declaración de una o más variables de
parámetros. Las variables especificadas en esta lista se declaran como
variablesólocales.
FIELD declara una lista de identificadores que se utilizan como
nombres de campos cuando se encuentran. Si se especifica la cláusula IN,
la referencia al nombre declarado incluye cualquier referencia impl.cita
al alias especificado.
LOCAL declara y, opciónalmente, inicializa una lista de variables o
matrices cuya visibilidad y tiempo de vida se limitan al procedimiento
actual.
MEMVAR declara una lista de identificadores que se utilizar.n como
matrices o variables de memoria públicas o privadas cuando se
encuentran.
RETURN pasa el control al siguiente procedimiento de inicializaci.n
o a la primera rutina ejecutable del programa si no hay otros
procedimientos de inicializaci.n pendientes.
Descripción
La sentencia INIT PROCEDURE declara un procedimiento que se ejecuta cada
vez que se inicia el programa. Los procedimientos de inicializaci.n se
invocan antes de la primera sentencia ejecutable de una aplicación CA-
Clipper y son .tiles para realizar tareas de inicializaci.n frecuentes,
como lectura de configuraciónes o apertura de un puerto de
comunicaciones.
Los procedimientos de inicializaci.n son ejecutados impl.citamente por
CA-Clipper al inicio del programa. La visibilidad de estos procesos se
limita al sistema, por lo que no es posible invocar un procedimiento de
inicializaci.n desde un procedimiento o función definida por el usuario.
Cada procedimiento de inicializaci.n recibe una copia de los argumentos
de la línea de mandatos del DOS utilizada para invocar la aplicación.
El control pasa de un procedimiento de inicializaci.n al siguiente,
hasta que se hayan ejecutado todos los procedimientos de inicializaci.n.
El control pasa entonces a la primera sentencia ejecutable del programa.
La sentencia ANNOUNCE declara un identificador de módulo para un módulo
fuente (.prg). Una vez declarados, se hace referencia a los
procedimientos de inicializaci.n mediante este identificador de módulo.
Una aplicación puede utilizar cualquier número de procedimientos de
inicializaci.n solicitando con REQUEST sus identificadores de módulo.
Los procedimientos de inicializaci.n solicitados por una aplicación se
denominan colectivamente como lista de inicializaci.n. Aunque no hay un
orden de ejecución por defecto en los procedimientos de la lista de
inicializaci.n, se aplican las siguientes reglas:
. El procedimiento de inicializaci.n de CA-Clipper, CLIPINIT, se
invoca siempre el primero.
. Si se declara un procedimiento de inicializaci.n en el mismo
módulo fuente (.prg) que la rutina principal de la aplicación, ser.
el último procedimiento de inicializaci.n invocado.
CLIPINIT es invocado el primero para asegurar la integridad del sistema
instalando el sistema de recuperaci.n de errores por defecto (ErrorSys).
Cuando termina CLIPINIT, el control pasa al primer procedimiento de la
lista de inicializaci.n.
Si se produce un error durante el arranque del sistema, el sistema
vuelve al DOS sin invocar los restántes procedimientos de
inicializaci.n.
Ejemplos
. Este ejemplo utiliza INIT y EXIT PROCEDURE para guardar y
restablecer el contenido del sistema operativo. Solicitando con
REQUEST "GuardarDos" en su módulo fuente principal, se preserva el
contenido del sistema operativo:
ANNOUNCE GuardarDos
#define DOS_SCREEN 1
#define DOS_ROW 2
#define DOS_COL 3
#define DOS_CURSOR 4
#define DOS_COUNT 4
STATIC saGuardarDos[ SD_COUNT ]
INIT PROCEDURE GuardarDos()
SAVE SCREEN TO saGuardarDos[ DOS_SCREEN ]
saGuardarDos[ DOS_ROW ] := ROW()
saGuardarDos[ DOS_COL ] := COL()
saGuardarDos[ DOS_CURSOR ] := SETCURSOR()
RETURN
EXIT PROCEDURE RestablecerDos()
RESTORE SCREEN FROM saGuardarDos[ DOS_SCREEN ]
SETPOS ( saGuardarDos[ DOS_ROW ], saGuardarDos[ DOS_COL ] )
SETCURSOR( saGuardarDos[ DOS_CURSOR ] )
RETURN
LOCAL
Declara e inicializa variables y matricesólocales
------------------------------------------------------------------------------
Sintaxis
LOCAL <identificador> [[:= <inicializador>],...]
Argumentos
<identificador> es el nombre de una variable o matriz que se declara
como local. Si el <identificador> va seguido de corchetes ([]), se crea
una matriz. Si el <identificador> es una matriz, la sintaxis para
especificar el número de elementos de cada dimensión puede ser
matriz[<nElementos>, <nElementos2>,...] o
matriz[<nElementos>][<nElementos2>]... El número máximo de elementos por
dimensión es 4.096. El número máximo de dimensiónes por matriz sólo est.
limitado por la memoria disponible.
<inicializador> es la asignación opciónal de un valor a una nueva
variable local. Los identificadores de matrices, no obstante, no pueden
recibir valores con un <inicializador>. Un <inicializador> para una
variable local est. formado por el operador de asignación en línea (:=)
seguido por cualquier expresión víaacute;lida de CA-Clipper incluyendo una
matriz literal. Si no se especifica ningún <inicializador> explícito, se
asigna a la variable un valor inicial NIL. En caso de una matriz, todos
los elementos son NIL.
Nota: El operador de macroexpresiónes (&) no puede utilizarse en una
declaración LOCAL.
Descripción
LOCAL es una sentencia que declara locales una o más variables o
matrices respecto al procedimiento o función actual definida por el
usuario y debe especificarse antes que cualquier sentencia ejecutable,
incluyendo PRIVATE, PUBLIC y PARAMETERS. Las declaraciónes de variables
locales ocultan todas las variables privadas heredadas o públicas
visibles que tengan el mismo nombre. No obstante, una sentencia LOCAL
que declare una variable ya declarada causa un error de compilación y no
se genera código objeto (.OBJ). Este error puede suceder por existir dos
declaraciónes de la misma variable en la misma rutina o como resultado
de declarar una variable con ámbito víaacute;lido en todo el fichero. Las
sentencias de declaración incluyen FIELD, MEMVAR y STATIC.
Las variablesólocales son visibles sólo dentro del procedimiento o
función actual definida por el usuario y, a diferencia de las variables
privadas, no son visibles en las rutinas invocadas. Las variables
locales se crean autom.ticamente cada vez que se ejecuta el
procedimiento en el que están declaradas. Contin.an existiendo y
mantienen sus valores hasta que el procedimiento o función definido por
el usuario en el que están declaradas devuelve el control al código que
lo invoc.. Si un procedimiento o función definido por el usuario se
invoca recursivamente (se llama a s. mismo), cada activaci.n crea un
nuevo conjunto de variablesólocales.
El valor inicial de las variablesólocales y elementos de matriz es NIL
si no se inicializan explícitamente en la lista del inicializador o con
una asignación. La expresión del inicializador puede ser cualquier
expresión víaacute;lida de CA-Clipper, incluyendo llamadas a función. Recuerde
que las declaraciónes de matrices no pueden tener un inicializador.
El número máximo de variablesólocales en un programa sólo está limitado
por la memoria disponible. No obstante, las matrices asignadas a una
variable local tienen un l.mite de 4.096 elementos por dimensión.
Si desea más información sobre las declaraciónes y ámbitos de variables,
consulte el apartado Variables en el capítulo Conceptos Básicos de la
gu.a Programaci.n y Utilidades.
Notas
. Inspección de variablesólocales en el depurador: Para
acceder a nombres de variablesólocales con el depurador de CA-
Clipper, debe compilar los ficheros de programa (prg) utilizando la
opción /B para incluir la información de la variable local en el
fichero objeto.
. Par.metrosólocales: Declare una lista de parámetros
locales como parte de una declaración FUNCTION o PROCEDURE,
encerrando la lista entre paréntesis después de <idfunción>:
FUNCTION <idfunción>(<lista idPar.m>)
La declaración de parámetrosólocales tiene precedencia sobre la
creaci.n de parámetros privados con la sentencia PARAMETERS.
. Macroexpresiónes: No se puede hacer referencia a variables
locales en macroexpresiónes o variables que las contengan. Si hace
referencia a una variable local dentro de una variable que contiene
una macroexpresión, se hace referencia en su lugar a alguna variable
pública o privada que tenga el mismo nombre. Si no existe tal
variable, se produce un error de ejecución.
. Ficheros de memoria: Las variablesólocales no pueden
guardarse o restablecerse (SAVE o RESTORE) desde ficheros de memoria
(.mem).
. Tipo de una variable local: Dado que TYPE() utiliza el
operador de macroexpresiónes (&) para evaluar su argumento, no puede
utilizarse para determinar el tipo de una variable local o estática o
una expresión que contenga alguna referencia de variable local o
estática. La función VALTYPE() sirve para averiguar este valor.
VALTYPE() eval.a el argumento y devuelve su tipo.
Ejemplos
. Este ejemplo declara dos matricesólocales y dos variables
locales:
LOCAL aMatr1[20, 10], aMatr2[20][10], var1, var2
. Este ejemplo declara dos variablesólocales con
inicializadores. La primera se inicializa con un valor de fecha y la
segunda con una matriz literal:
LOCAL dCuando := DATE()
LOCAL aVegetales := {"Tomate", "Col", "Jud.a"}
MEMVAR
Declara nombres de variables privadas y públicas
------------------------------------------------------------------------------
Sintaxis
MEMVAR <idLista varmem>
Argumentos
<idLista varmem> es la lista de nombres de variables públicas y
privadas que se van a declarar al compilador.
Descripción
MEMVAR es una declaración que hace que el compilador resuelva las
referencias a variables especificadas sin un alias explícito, asumiendo
impl.citamente un alias de variable de memoria (MEMVAR->). Esto sólo
afecta a las referencias expl.citas sin alias de las variables
especificadas. MEMVAR, como todas las declaraciónes, no afecta a las
referencias realizadas dentro de macroexpresiónes o variables que las
contengan.
La sentencia MEMVAR no crea variables ni comprueba su existencia. Sirve
para asegurar que sean correctas las referencias a variables que se sabe
que existir.n durante la ejecución. Durante la ejecución, las variables
especificadas deben crearse con sentencias PRIVATE, PARAMETERS o PUBLIC.
Esto puede ocurrir en el procedimiento que contiene la declaración
MEMVAR o en un procedimiento de nivel superior. Si se intenta acceder a
las variables antes de que se hayan creado, se produce un error.
El ámbito de la declaración MEMVAR es el procedimiento o función en el
que aparece, o todo el fichero fuente si precede a una sentencia
PROCEDURE o FUNCTION y se utiliza la opción de compilador /N. La opción
/N suprime la definición autom.tica de un procedimiento que tiene el
mismo nombre que el módulo fuente (.prg).
Al igual que las restántes declaraciónes, MEMVAR debe preceder a todas
las sentencias ejecutables, incluyendo las sentencias PARAMETERS, PUBLIC
y PRIVATE de una definición de procedimiento o función; o debe situarse
al principio del módulo fuente (.prg) si el ámbito de la declaración es
todo el módulo.
MEMVAR puede utilizarse con la opción de compilador /W, que genera
mensajes de advertencia para referencias a variables ambiguas, lo que
permite comprobar la existencia de variables no declaradas durante la
compilación.
Si desea más información sobre las declaraciónes de variables y su
ámbito, consulte el apartado Variables del capítulo Conceptos Básicos de
la guía de Programación y Utilidades.
Ejemplos
. Este ejemplo muestra la relaci.n que existe entre una variable
privada y una variable campo que tienen el mismo nombre. La variable
privada se declara con la sentencia MEMVAR:
FUNCTION Ejemplo
MEMVAR cantidad, direccion
PRIVATE cantidad := 100
USE Cliente NEW
//
? cantidad // Se refiere a la variable
// privada cantidad
? Cliente->Cantidad
// Se refiere a la variable de
// campo Cantidad
//
RETURN NIL
PARAMETERS
Crea variables privadas donde se recibirán parámetros
------------------------------------------------------------------------------
Sintaxis
PARAMETERS <idLista privadas>
Argumentos
<idLista privadas> es una o más variables de parámetro, separadas
por comas. El número de variables receptoras no tiene que ser igual al
de argumentos pasados por el procedimiento o función que lo invoca.
Descripción
La sentencia PARAMETERS crea variables privadas que reciben los valores
o referencias pasados. Las variables receptoras se denominan parámetros.
Los valores o referencias realmente pasados por una llamada a un
procedimiento o función se denominan argumentos.
Cuando se ejecuta una sentencia PARAMETERS, todas las variables de la
lista de parámetros se crean como variables privadas y todas las
variables públicas o privadas que tengan el mismo nombre se ocultan
hasta que finalice el proceso o función actual. La sentencia PARAMETERS
es una sentencia ejecutable y puede aparecer en cualquier parte de un
procedimiento o función, pero siempre después de las declaraciónes de
variables de compilación, como FIELD, LOCAL, MEMVAR y STATIC.
Los parámetros también pueden declararse como variablesólocales si se
especifican como parte de una declaración PROCEDURE o FUNCTION (consulte
el ejemplo). Los parámetros que se especifiquen de esta forma se
denominan parámetros formales. Recuerde que en una definición de función
o procedimiento no pueden especificarse simultáneamente parámetros
formales y sentencias PARAMETERS. Si intenta hacerlo, se producirá un
error fatal de compilación y no se generará el fichero objeto.
En CA-Clipper, el número de argumentos no tiene que ser igual al número
de parámetros. Si se especifican más argumentos que parámetros, se
ignoran los argumentos restántes. Si se especifican menos argumentos que
parámetros, a los restántes parámetros se les asigna el valor NIL. Si se
omite un argumento, el parámetro correspondiente se inicializa con un
valor NIL. La función PCOUNT() devuelve la posición del último argumento
pasado en la lista de argumentos. Esta posición no es igual al número de
parámetros pasados, ya que incluye los parámetros omitidos.
Si desea más información sobre el modo de pasar parámetros, consulte el
apartado funciónes y Procedimientos del capítulo Conceptos Básicos de la
guía de Programación y Utilidades.
Ejemplos
. Esta función definida por el usuario recibe valores pasados
como parámetros privados con una sentencia PARAMETERS:
FUNCTION Mifunción
PARAMETERS cUno, cDos, cTres
? cUno, cDos, cTres
RETURN NIL
. Este ejemplo es similar al anterior, pero recibe valores
pasados como variablesólocales, declarando las variables de
parámetros en la declaración FUNCTION:
FUNCTION Mifunción( cUno, cDos, cTres )
? cUno, cDos, cTres
RETURN NIL
PRIVATE
Crea e inicializa matrices y variables de memoria privadas
------------------------------------------------------------------------------
Sintaxis
PRIVATE <identificador> [[:= <inicializador>], ... ]
Argumentos
<identificador> es el nombre de la variable o matriz privada que se
va a crear. Si <identificador> va seguido de corchetes ([ ]), se crea
una matriz y se asigna a <identificador>. Si <identificador> se
especifica como una matriz, la sintaxis para indicar el número de
elementos de cada dimensión puede ser matriz[<nElementos>,
<nElementos2>,...] o matriz[<nElementos>][<nElementos2>]... El número
máximo de elementos por dimensión es 4096. El número máximo de
dimensiónes sólo depende de la cantidad de memoria disponible.
<inicializador> es el valor que se asigna opciónalmente a la nueva
variable privada. No es posible asignar valores a una matriz con
<inicializador>. El <inicializador> para una variable privada est.
formado por el operador de asignación en línea (:=) seguido de cualquier
expresión víaacute;lida de CA-Clipper, incluyendo matrices literales. Si no se
especifica un <inicializador>, la variable se inicializa con el valor
NIL. Con una matriz, todos sus elementos se inicializa con el valor NIL.
Es posible crear y, opciónalmente, inicializar una lista de variables y
matrices en la misma sentencia PRIVATE, separando las definiciónes
mediante comas.
Descripción
La sentencia PRIVATE crea variables y matrices que sólo son visibles
dentro de los procedimientos y funciónes que las crean y las invocadas
por ellas. La clase de almacenamiento PRIVATE es de ámbito dinámico. Las
variables privadas existen mientras el procedimiento que las cre. no
finalice o hasta que se liberan explícitamente con CLEAR ALL, CLEAR
MEMORY o RELEASE. Al crear una matriz o variable privada, las variables
privadas y públicas visibles que tengan el mismo nombre se ocultan hasta
que termine el procedimiento o función actual.
Si se intenta especificar una variable PRIVATE en conflicto con una
declaración FIELD, LOCAL o STATIC del mismo nombre se produce un error
fatal de compilación, independientemente del ámbito de la declaración.
Las sentencias PRIVATE son sentencias ejecutables, por lo que deben
especificarse en el cuerpo del procedimiento o función después de todas
las declaraciónes de variables, como FIELD, LOCAL, MEMVAR y STATIC.
Además de la sentencia PRIVATE, también pueden crearse variables
privadas de estas dos formas:
. Una asignación de una variable inexistente o no visible crear.
una variable privada
. Los parámetros recibidos con la sentencia PARAMETERS se crean
como variables privadas con la misma visibilidad y tiempo de vida
No puede haber más de 2048 matrices y variables públicas y privadas
dentro de un mismo programa.
Si desea más información sobre las declaraciónes de variables y su
ámbito, consulte el apartado Variables del capítulo Conceptos Básicos de
la guía de Programación y Utilidades.
Notas
. Compatibilidad: Las cláusulas ALL, LIKE y EXCEPT de la
sentencia PRIVATE utilizada en otros dialectos dBASE no pueden
utilizarse en CA-Clipper.
Ejemplos
. Este ejemplo crea dos matrices y tres variables PRIVATE:
PRIVATE aMatriz1[10], aMatriz2[20], var1, var2, var3
. Este ejemplo crea matrices privadas multidimensiónales
utilizando las dos notaciones:
PRIVATE aMatriz1[10][10][10], aMatriz2[10, 10, 10]
. Este ejemplo utiliza sentencias PRIVATE para crear e
inicializar matrices y variables:
PRIVATE aMatriz := { 1, 2, 3, 4 }, ;
aMatriz2 := ARRAY(12, 24)
PRIVATE cCar := SPACE(10), cColor := SETCOLOR()
PROCEDURE
Declara un nombre de procedimiento y sus parámetros formales
------------------------------------------------------------------------------
Sintaxis
[STATIC] PROCEDURE <idProcedimiento> [(<idLista par.m>)]
[FIELD <idLista campos> [IN <idAlias>]
[LOCAL <identificador> [[:= <inicializador>], ... ]]
[MEMVAR <lista identificadores>]
[STATIC <identificador> [[:= <inicializador>], ... ]]
.
. <sentencias ejecutables>
.
[RETURN]
Argumentos
<idProcedimiento> es el nombre del procedimiento que se declara. Los
nombres de procedimiento pueden tener cualquier longitud, pero sólo son
significativosólos 10 primeros carácteres. Pueden contener cualquier
combinación de letras, números o carácteres de subrayado, pero los
subrayados iniciales están reservados.
<idLista par.m> es la declaración de una o más variables de
parámetro. Las variables especificadas en esta lista se declaran como
locales.
STATIC PROCEDURE declara un procedimiento que sólo puede invocarse
por los otros procedimientos o funciónes declarados en el mismo módulo
fuente (.prg).
FIELD declara una lista de identificadores, <idLista campos>, que se
van a utilizar como nombres de campo cuando se encuentren. Una cláusula
IN que preceda al <idAlias> declarado, crea una referencia al .rea de
trabajo correspondiente de la base de datos especificada.
LOCAL declara y, opciónalmente, inicializa una lista de variables o
matrices de visibilidad y duraci.n limitadas al procedimiento actual.
<identificador>, <lista identificadores> es una etiqueta o etiquetas
utilizadas como el nombre de la variable o matriz que se va a crear. Si
<identificador> va seguido de corchetes ([ ]), se crea una matriz y se
asigna a <identificador>. Si <identificador> se especifica como una
matriz, la sintaxis para indicar el número de elementos de cada
dimensión puede ser matriz[<nElementos>, <nElementos2>,...] o
matriz[<nElementos>][<nElementos2>]... El número máximo de elementos por
dimensión es 4096. El número máximo de dimensiónes sólo depende de la
cantidad de memoria disponible.
<inicializador> es el valor que se asigna opciónalmente a la nueva
variable privada. No es posible asignar valores a una matriz con
<inicializador>. El <inicializador> para una variable privada est.
formado por el operador de asignación en línea (:=) seguido de cualquier
expresión víaacute;lida de CA-Clipper, incluyendo matrices literales. Si no se
especifica un <inicializador>, la variable se inicializa con el valor
NIL. Con una matriz, todos sus elementos se inicializan con el valor
NIL.
MEMVAR declara una lista de identificadores, <lista
identificadores>, que se utilizan como matrices o variables de memoria
privadas o públicas cuando se encuentran.
STATIC declara y, opciónalmente, inicializa una lista de variables
de ámbito de visibilidad en el procedimiento actual y cuyo tiempo de
vida es toda la aplicación.
RETURN devuelve el control al procedimiento o función invocante. Si
no se especifica RETURN, el control se devuelve a la rutina invocante al
terminar la definición del procedimiento. En cualquier caso, el
compilador finaliza la definición de procedimiento si encuentra otra
sentencia PROCEDURE, FUNCTION o un carácter de fin de fichero.
Descripción
La sentencia PROCEDURE declara un procedimiento y una lista opciónal de
variablesólocales para recibir los parámetros pasados por la rutina
invocante. Un procedimiento es un subprograma compuesto por un grupo de
declaraciónes y sentencias que se ejecutan cuando se escribe
<idProcedimiento> seguido de un paréntesis inicial y final o mediante
una sentencia DO. Una definición de procedimiento comienza con la
sentencia PROCEDURE y finaliza en la siguiente sentencia PROCEDURE,
sentencia FUNCTION o carácter de fin de fichero.
Los procedimientos permiten encapsular bloques de código de c.lculo para
mejorar la legibilidad y modularidad, aislar los cambios y ayudar a
manejar programas complejos.
En CA-Clipper, un procedimiento es id.ntico a una función definida por
el usuario, excepto en que siempre devuelve NIL. Cada procedimiento debe
comenzar con una sentencia PROCEDURE y puede contener una sentencia
RETURN para devolver el control al procedimiento o función invocante.
Sin embargo, la sentencia RETURN no es imprescindible. Las declaraciónes
de procedimiento no pueden anidarse dentro de otras definiciónes de
procedimiento.
Hay dos clases de visibilidad de nombres de procedimiento. Los
procedimientos visibles desde cualquier parte de un programa se
denominan procedimientos p.blicos y se declaran dentro de una sentencia
PROCEDURE. Los procedimientos sólo visibles en el módulo fuente (.prg)
actual se denominan procedimientos estáticos y se declaran con una
sentencia STATIC PROCEDURE. El ámbito de los procedimientos estáticos es
todo el fichero.
Los procedimientos estáticos son bastante .tiles por varias razones. En
primer lugar, limitan la visibilidad a un procedimiento, restringiendo
as. el acceso a ese procedimiento. Debido a esto, los subsistemas
definidos en un mismo módulo fuente (.prg) pueden ofrecer un protocolo
de acceso mediante una serie de procedimientos p.blicos y ocultar los
detalles internos del subsistema mediante funciónes y procedimientos
estáticos. En segundo lugar, las referencias a los procedimientos
estáticos se resuelven durante la compilación por lo que tienen
preferencia sobre las referencias a funciónes y procedimientos p.blicos
que se resuelven durante el enlazado. Esto garantiza que, si existe en
un módulo fuente un conflicto de nombres entre un procedimiento estático
y un procedimiento o función p.blico, se ejecute la referencia al
procedimiento estático.
Si desea más información sobre los procedimientos, declaraciónes de
variables y paso de parámetros, consulte el capítulo Conceptos Básicos
de la guía de Programación y Utilidades.
Notas
. Llamada a un procedimiento: En CA-Clipper, un
procedimiento puede llamarse de dos formas. La primera, y preferible,
es la convenci.n de llamada de funciónes. Este m.todo para invocar un
procedimiento es id.ntico al que se utiliza para invocar una función,
en una línea individual:
<idProcedimiento>([<lista argumentos>])
El segundo m.todo es la convenci.n de llamada mediante el mandato
DO...WITH. Los dos m.todos difieren sólo en la forma de paso de
parámetros por defecto. La convenci.n funciónal de llamada pasa las
variables por valor, mientras que la convenci.n de llamada por
mandato los pasa por referencia.
Un procedimiento también puede invocarse con una expresión de alias,
si va precedido de un alias y se invoca mediante la convenci.n de
llamada de funciónes, tal como se indica a continúa.ión:
<idAlias> ->(<idProcedimiento>(<lista argumentos>))
Al invocarse con una expresión de alias, se selecciona el .rea de
trabajo correspondiente a <idAlias>, se ejecuta el procedimiento y se
vuelve a seleccionar el área de trabajo original. Al iguak que una
expresión o función, un procedimiento puede estar incluido en una
expresión de alias.
En CA-Clipper, un procedimiento puede invocarse recursivamente. Esto
significa que se puede llamar al procedimiento dentro de la misma
definición de procedimiento.
. Par.metros: Los procedimientos, al igual que las funciónes
definidas por el usuario, pueden recibir parámetros pasados por el
procedimiento que los llam., por una función definida por el usuario
o por la línea de mandato del DOS. Un parámetro es un lugar para un
valor o una referencia. En CA-Clipper, existen dos formas de recibir
parámetros: puede declararse una lista de nombres de variables
locales como parte de la declaración PROCEDURE (parámetros formales)
o puede especificarse una lista de variables privadas en una
sentencia PARAMETERS independiente. Recuerde que no puede mezclarse
una declaración de parámetros formales con una sentencia PARAMETERS.
Si se intenta hacerlo, se produce un error de compilación.
Los procedimientos reciben los parámetros en el mismo orden en el que
se pasan. En CA-Clipper, el número de parámetros no tiene que ser
igual al número de argumentos pasados. Los argumentos pueden omitirse
o dejarse al final de la lista de argumentos. Un parámetro que no
reciba un valor o referencia se inicializa con el valor NIL. Si se
especifican argumentos, PCOUNT() devuelve la posición del último
argumento pasado.
Los parámetros especificados en un procedimiento pueden recibir
argumentos pasados por valor o por referencia. El m.todo por defecto
para las expresiónes y variables depende de la convenci.n de llamada.
En la convenci.n de llamada de funciónes, el m.todo por defecto para
pasar expresiónes y variables es por valor, incluyendo variables que
contienen referencias a matrices y objetos. En la convenci.n de
llamada de mandatos, el m.todo por defecto para pasar variables es
por referencia, excepto para las variables de campo, que siempre se
pasan por valor. Cuando se pasa una variable de campo, debe
encerrarse entre paréntesis, a menos que se declare con la sentencia
FIELD. En caso contrario, se produce un error de ejecución.
Ejemplos
. Este ejemplo muestra el esquema de un procedimiento de
CA-Clipper que utiliza variables de ámbito resoluble en compilación:
PROCEDURE Esqueleto( cNombre, cClase, nHuesos, ;
nArticulaciones )
LOCAL nHuesosTrans, aEnMano := {"cr.neo", ;
"metacarpianos"}
STATIC nContador := 0
.
. <sentencias ejecutables>
.
RETURN
. Este ejemplo determina si se ha omitido alg.n argumento
compar.ndolo con NIL:
PROCEDURE MiProc( param1, param2, param3 )
IF param2 != NIL
param2 := "valor por defecto"
ENDIF
.
. <sentencias>
.
RETURN
. Este ejemplo invoca al procedimiento, ActualizarCantidad(),
con una expresión de alias:
USE Facturas NEW
USE Cliente NEW
Facturas->(ActualizarCantidad(Importe + Importe * nInteres))
PUBLIC
Crea e inicializa matrices y variables de memoria públicas
------------------------------------------------------------------------------
Sintaxis
PUBLIC <identificador> [[:= <inicializador>], ... ]
Argumentos
<identificador> es el nombre de una matriz o variable pública que se
va a crear. Si el <identificador> va seguido de corchetes ([ ]), se crea
como matriz. Si el <identificador> es una matriz, la sintaxis para la
especificación del número de elementos para cada dimensión puede ser
matriz[<nElementos>, <nElementos2>,...] o
matriz[<nElementos>][<nElementos2>]... El número máximo de elementos por
dimensión es 4096. El número máximo de dimensiónes por matriz est.
limitado .nicamente por la cantidad de memoria disponible.
<inicializador> es la asignación opciónal de un valor a una nueva
variable pública. No obstante, no es posible dar valores a los
identificadores de matriz con el <inicializador>. Un <inicializador>
para una variable pública consiste en el operador de asignación en línea
(:=) seguido de cualquier expresión de CA-Clipper víaacute;lida, incluyendo una
matriz en forma literal. Excepto en el caso de las matrices, si no se
especifica <inicializador>, las variables públicas se inicializan en
falso (.F.). Esta es una excepci.n a la regla general de que las
variables sin inicializar son valores NIL. En el caso de las matrices,
sin embargo, el valor inicial de todos los elementos es NIL.
Puede crearse una lista de variables y matrices y, opciónalmente,
inicializarla con una sentencia PUBLIC, si las definiciónes están
separadas por comas.
Descripción
La sentencia PUBLIC crea variables y matrices visibles para todos los
procedimientos y funciónes definidas por el usuario de un programa. Las
variables públicas existen durante todo el programa o hasta que se
liberan explícitamente con CLEAR ALL, CLEAR MEMORY o RELEASE. La
declaración de matrices o variables privadas, locales o estáticas con el
mismo nombre que las variables públicas existentes oculta temporalmente
estas variables públicas hasta que las variables que las solapan se
liberan o dejan de estar visibles. Los intentos de crear una variable
pública con el mismo nombre que una variable privada visible y existente
simplemente se ignoran (consulte las Notas de la siguiente p.gina para
ver una excepci.n).
Los intentos de especificar una variable pública que entre en conflicto
con una declaración FIELD, LOCAL o STATIC prevía del mismo nombre dan
como resultado un error de compilador fatal. Esto es as.,
independientemente del ámbito de la declaración.
Las sentencias PUBLIC son sentencias ejecutables y, por tanto, deben
especificarse dentro de una definición de procedimiento o función
definida por el usuario. Asimismo, deben ir detrás de todas las
declaraciónes de compilación, tales como FIELD, LOCAL, MEMVAR y STATIC.
El número máximo de matrices y variables públicas y privadas que pueden
existir simultáneamente en un mismo programa es de 2048.
Si desea más información sobre las declaraciónes de variable y su
ámbito, consulte el apartado Variables del capítulo Conceptos Básicos de
la guía de Programación y Utilidades.
Notas
. Clipper PUBLIC: Para incluir extensiónes de CA-Clipper en
un programa y, no obstante, permitir que el programa se ejecute en
dBASE III PLUS, la variable pública especial Clipper se inicializa en
verdadero (.T.) cuando se crea como PUBLIC.
. Nombre de matriz pública entra en conflicto con variables
privadas existentes: La sentencia PUBLIC x[10] no crear. la matriz
pública x si ya existe una variable privada o pública x. Sin embargo,
destruye el contenido de la x existente, sustituy.ndola por una
referencia a una matriz de diez elementos.
Ejemplos
. Este ejemplo crea dos matrices públicas y una variable
pública:
PUBLIC aMatriz1[10, 10], var2
PUBLIC aMatriz2[20][10]
. La siguiente sentencia PUBLIC crea variables y las inicializa
con valores:
PUBLIC cCadena := SPACE(10), cColor := SETCOLOR()
PUBLIC aMatriz := {1, 2, 3}, aMatriz2 := ARRAY(12, 24)
REQUEST
Declara una lista de enlazado de módulos
------------------------------------------------------------------------------
Sintaxis
REQUEST <idLista módulos>
Argumentos
<idLista módulos> es la lista de los módulos que se van a enlazar en
el fichero ejecutable (.EXE) actual.
Descripción
REQUEST es una declaración que define una lista de identificadores de
módulo para el enlazador. Al igual que las restántes declaraciónes, las
sentencias REQUEST deben especificarse antes que cualquier sentencia
ejecutable, ya sea en el módulo fuente, o en una definición de
procedimiento o función.
Durante la compilación del código fuente, todas las referencias
expl.citas a procedimientos y funciónes se pasan al enlazador. En
algunos casos, en un fichero fuente puede no hacerse referencias a
nombres de procedimientos o funciónes hasta la ejecución. REQUEST
resuelve esta situaci.n forzando el enlazado de los procedimientos y
funciónes nombrados, incluso si existe una referencia expl.cita a ellos
en el fichero fuente. Esto es importante en los siguientes casos:
. Procedimientos, funciónes o formatos referenciados por
macroexpresiónes o variables que las contengan.
. Procedimientos y funciónes útilizadas en REPORT y LABEL FORM
sin referencias en el código fuente
. funciónes útilizadas en claves de índice y sin referencias en
el código fuente
. funciónes de usuario ACHOICE(), DBEDIT() o MEMOEDIT()
. Procedimientos de inicializaci.n declarados con la sentencia
INIT PROCEDIMIENTO
. Procedimientos de clausura declarados con la sentencia EXIT
PROCEDIMIENTO
Para agrupar sentencias REQUEST comunes, col.quelas en un fichero de
cabecera y, a continúa.ión, incluya el fichero de cabecera en todos los
módulos fuente (.prg) que podr.an utilizarlas indirectamente.
Ejemplos
. Este ejemplo muestra un fichero de cabecera t.pico que
contiene sentencias REQUEST comunes para mandatos REPORT FORM:
// Request.ch
REQUEST HARDCR
REQUEST TONE
REQUEST MEMOTRAN
REQUEST STRTRAN
RETURN
Finaliza un procedimiento, función o programa
------------------------------------------------------------------------------
Sintaxis
RETURN [<exp>]
Argumentos
<exp> es una expresión de cualquier tipo que da como resultado el
valor de retorno para funciónes de usuario. Si una función finaliza sin
una sentencia RETURN, el valor de retorno es NIL.
Descripción
RETURN finaliza un procedimiento, función o programa, devolviendo el
control al procedimiento o función que la invoc.. Si se ejecuta un
RETURN en el procedimiento de nivel m.s alto, el control pasa al sistema
operativo. Al devolverse el control al procedimiento llamante, se
liberan todas las variables privadas creadas y las variablesólocales
declaradas en el procedimiento o función actual.
En un procedimiento o función puede haber más de una sentencia RETURN.
Aunque no es imprescindible que termine en dicha sentencia, como todas
las funciónes deben devolver un valor, la función debe contener al menos
una sentencia RETURN con un argumento.
Nota: Una definición de procedimiento o función finaliza al
encontrarse la siguiente sentencia PROCEDIMIENTO, FUNCTION o carácter de
fin de fichero, no al encontrarse una sentencia RETURN
Notas
. Matrices: Las matrices son un tipo de datos como otro
cualquiera, las apariciones de matrices son realmente valores como
cadenas de carácteres y, por tanto, pueden devolverse desde una
función.
. RETURN TO MASTER: CA-Clipper no permite la utilización de
RETURN TO MASTER ni las dem.s formas de RETURN que especifican el
nivel al que debe devolverse el control. Sin embargo, es posible
simular estas operación.s con BEGIN SEQUENCE...END.
Ejemplos
. Estos ejemplos muestran el formato general de la sentencia
RETURN en un procedimiento y en una función :
PROCEDIMIENTO <idProcedimiento>
//
<sentencias>...
//
RETURN
FUNCTION <idfunción>
//
<sentencias>...
//
RETURN <expDevuelto>
. Este ejemplo devuelve una matriz creada en una función al
procedimiento o función que la ha invocado:
FUNCTION DevolverMatriz
PRIVATE aMatriz[10][10]
aMatriz[1][1] = "miCadena"
RETURN aMatriz
STATIC
Declara e inicializa variables y matrices estáticas
------------------------------------------------------------------------------
Sintaxis
STATIC <identificador> [[:= <inicializador>], ... ]
Argumentos
<identificador> es el nombre de la variable o matriz que debe
declararse como estática. Si el <identificador> va seguido de corchetes
([ ]), se crea como una matriz. Si el <identificador> es una matriz, la
sintaxis para especificar el número de elementos para cada dimensión
puede ser matriz[<nElementos>, <nElementos2>,...] o matriz[<nElementos>]
[<nElementos2>]... El número máximo de elementos por dimensión es 4096.
El número máximo de dimensiónes está limitado sólo por la memoria
disponible.
<inicializador> es la asignación opciónal de un valor a una nueva
variable estática. Un <inicializador> para una variable estática consta
de una operador de asignación en línea (:=) seguido de una expresión
constante de tiempo de compilación formada por constantes y operadores o
una matriz en forma literal. Si no se especifica un <inicializador>
explícito, se asigna a la variable un valor inicial de NIL. En el caso
de una matriz, cada uno de sus elementos es NIL. No pueden asignarse
valores a los identificadores de matrices con un <inicializador>.
Nota: El operador de macro (&) no puede utilizarse en una sentencia
STATIC.
Descripción
La sentencia STATIC declara variables y matrices que tienen un tiempo de
vida igual al de programa pero que sólo son visibles dentro de la
entidad que las crea. Estas variables sólo son visibles dentro de un
procedimiento o función si se declaran después de una sentencia
PROCEDURE o FUNCTION. Las variables estáticas son visibles para todos
los procedimientos y funciónes de un módulo fuente (.pgr) (es decir,
tienen un ámbito a nivel de módulo) si se declaran antes de la primera
definición de procedimiento o función del fichero. Utilice la opción de
compilador /N para compilar un programa cuyas variables tengan ámbito a
nivel de módulo.
Todas las variables estáticas de un programa se crean cuando se invoca
al programa por primera vez y todos los valores especificados en un
<inicializador> estático se asignan a la variable antes del inicio de la
ejecución del programa.
Las declaraciónes de variables estáticas dentro de un procedimiento o
función definida por el usuario deben producirse antes de cualquier
sentencia ejecutable incluyendo PRIVATE, PUBLIC y PARAMETERS. Si se
declara una variable del mismo nombre FIELD, LOCAL o MEMVAR dentro de un
procedimiento o función, se produce un error de compilación y no se
genera ningún fichero objeto (.OBJ).
El número máximo de variables estáticas de un programa está limitado
solamente por la memoria disponible.
Notas
. Inspección de variables estáticas dentro del Depurador:
Para acceder a los nombres de las variables estáticas dentro del
Depurador de CA-Clipper, debe compilar los módulos fuente (.prg)
utilizando la opción /B de modo que la información sobre variables
estáticas se incluya en el fichero objeto (.OBJ).
. Macroexpresiónes: No debe hacer referencia a variables
estáticas dentro de macroexpresiónes o variables que las contengan.
Si as. lo hace, se intentar. acceder a una variable privada o pública
que tenga el mismo nombre. Si no existe tal variable, se genera un
error de ejecución.
. Ficheros de memoria: Las variables estáticas no pueden
guardarse ni recuperarse de ficheros de memoria (.mem).
. Tipo de una variable local estática: Puesto que TYPE()
utiliza el operador de macro (&) para evaluar su argumento, no puede
utilizar esta función para determinar el tipo de una variable local o
estática o de una expresión que contenga una referencia a variable
local o estática. La función VALTYPE() ofrece esta posibilidad
evaluando el argumento de la función y devolviendo el tipo de datos
de su valor de retorno.
Ejemplos
. Este ejemplo declara variables estáticas con y sin
inicializadores:
STATIC aMatriz1[20, 10], aMatriz2[20][10]
STATIC cVar, cVar2
STATIC cCadena := "mi cadena", var
STATIC aMatriz := {1, 2, 3}
. Este ejemplo maneja una variable estática dentro de una
función definida por el usuario. En este ejemplo, una variable de
contador se incrementa a s. misma cada vez que se llama a la función:
FUNCTION MiContador( nValorNuevo )
STATIC nContador := 0 // Valor inicial asignado una vez
IF nValorNuevo != NIL
nContador:= nValorNuevo // Valor nuevo para nContador
ELSE
nContador++ // Incremento nContador
ENDIF
RETURN nContador
. Este ejemplo muestra una declaración de variable estática que
tiene ámbito a nivel de módulo. En este fragmento de código, aMatriz
es visible para los dos procedimientos que siguen a la declaración:
STATIC aMatriz := {1, 2, 3, 4}
FUNCTION Uno
? aMatriz[1] // Resultado: 1
RETURN NIL
FUNCTION Dos
? aMatriz[3] // Resultado: 3
RETURN NIL
