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