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