MEMOEDIT()
 Edita o visualiza campos memo o cadenas de carácteres
------------------------------------------------------------------------------
 Sintaxis

     MEMOEDIT([<cCadena>],
        [<nSuperior>], [<nIzquierda>],
        [<nInferior>], [<nDerecha>],
        [<lModoEdici.n>],
        [<cfunciónUsuario>],
        [<nLongitudL.nea>],
        [<nTama.oTabulador>],
        [<nFilaMemoInterTexto>],
        [<nColumnaMemoInterTexto>],
        [<nFilaVentana>],
        [<nColumnaVentana>]) --> cMemoInterTexto

 Argumentos

     <cCadena> es el campo memo o la cadena de carácteres que se va a
     copiar en la memoria intermedia de MEMOEDIT(). Si no se especifica, la
     memoria intermedia de texto est. vac.a.

     <nSuperior>, <nIzquierda>, <nInferior> y <nDerecha> son
     las coordenadas superior izquierda e inferior derecha, respectivamente,
     de la ventana. Los valores de fila especificados pueden estar
     comprendidos entre cero y MAXROW() y los de columna entre entre cero y
     MAXCOL(). Si no se especifican, las coordenadas por defecto son 0, 0,
     MAXROW() y MAXCOL().

     <lModoEdici.n> determina si la memoria intermedia de texto puede
     editarse o sólo mostrarse en pantalla. Si se especifica verdadero (.T.),
     el usuario puede modificar la memoria intermedia. Si se especifica falso
     (.F.), sólo puede visualizarla. El valor por defecto es verdadero (.T.).

     <cfunciónUsuario> es el nombre de la función que se ejecuta cuando
     se pulsa una tecla no reconocida por MEMOEDIT() y cuando no quedan
     teclas pendientes en la memoria intermedia del teclado.
     <cfunciónUsuario> se especifica como valor de carácteres, sin paréntesis
     ni argumentos. Si se especifica falso (.F.) en este argumento, se
     muestra en pantalla <cCadena> y se termina inmediatamente MEMOEDIT().
     Este argumento modifica el comportamiento autom.tico de MEMOEDIT().
     Consulte la Descripción que se da a continúa.ión.

     <nLongitudL.nea> determina la longitud de las líneas mostradas en la
     ventana de MEMOEDIT(). Si una línea es mayor que <nLongitudL.nea>, el
     texto salta autom.ticamente a la línea siguiente de la ventana. Si
     <nLongitudL.nea> es mayor que el número de columnas de la ventana, .sta
     se desplaza al llegar el cursor al borde. Si no se especifica
     <nLongitudL.nea>, la longitud de línea por defecto ser. (<nDerecha> -
     <nIzquierda>).

     <nTama.oTabulador> determina tama.o del carácter de tabulaci.n que
     se inserta cuando se pulsa la tecla Tab. Si no se especifica, se
     insertan cuatro espacios en vez de un carácter de tabulaci.n.

     <nFilaMemoInterTexto> y <nColumnaMemoInter Texto> definen la
     posición de visualización del cursor en la memoria intermedia de texto.
     <nFilaMemoInterTexto> se numera a partir de uno y
     <nColumnaMemoInterTexto> a partir de cero. Si no se especifican estos
     argumentos, el cursor se coloca en la fila uno y columna cero de la
     ventana MEMOEDIT().

     <nFilaVentana> y <nColumnaVentana> definen la posición inicial
     del cursor en la ventana MEMOEDIT(). Las filas y columnas se numeran a
     partir de cero. Si no se especifican estos argumentos, la posición
     inicial en la ventana es la fila cero y la posición de columna actual
     del cursor.

 Devuelve

     MEMOEDIT() devuelve la memoria intermedia modificada si el usuario
     finaliza la edici.n con Ctrl-W o una copia de <cCadena> si finaliza con
     Esc.

Descripción


     MEMOEDIT() es una función de interfaz de usuario y de edici.n de texto,
     que permite editar campos memo y cadenas de carácteres largas. La
     edici.n se lleva a cabo en el .rea especificada, que puede estar situada
     en cualquier parte de la pantalla. Al igual que las restántes funciónes
     de usuario, (ACHOICE() y DBEDIT()), MEMOEDIT() dispone de una serie de
     modos e incluye una función de usuario que permite reconfiguración de
     las teclas y otras actividades relacionadas con la programaci.n de la
     tarea actual de edici.n.

     .  Memoria intermedia de texto: Cuando se utiliza MEMOEDIT()
        especificando <cCadena>, .sta se copia en la memoria intermedia de
        texto. El usuario edita realmente la memoria intermedia. Si no se
        especifica <cCadena>, se muestra al usuario una memoria intermedia
        vac.a para su edici.n.

        Cuando el usuario sale de MEMOEDIT() pulsando Ctrl-W, se devuelve el
        contenido modificado de la memoria intermedia. Si sale pulsando Esc,
        se descarta la memoria intermedia y se devuelve una copia de la
        <cCadena> original. En cualquier caso, el valor de retorno puede
        asignarse m.s tarde a un campo memo o variable, o pasarse como
        argumento a otra función.

     .  Modos de edici.n: MEMOEDIT() utiliza dos modos de edici.n,
        que se controlan mediante el valor de <lModoEdici.n>. Si
        <lModoEdici.n> es verdadero (.T.), MEMOEDIT() pasa al modo de edici.n
        y el usuario puede modificar la memoria intermedia de MEMOEDIT(). Si
        <lModoEdici.n> es falso (.F.), MEMOEDIT() pasa al modo de
        visualización y el usuario sólo puede desplazarse por la memoria
        intermedia, sin editarla ni poder insertar nuevo texto. Para
        facilitar la visualización, se ha modificado el desplazamiento de
        pantalla para que las flechas Arriba y Abajo suban o bajen el texto
        de la memoria intermedia una línea dentro de la ventana de
        MEMOEDIT().

     .  Introducci.n y edici.n de texto: Con la función
        MEMOEDIT(), es posible introducir y editar texto situando el cursor y
        a.adiendo o borrando carácteres. Para facilitar la edici.n del texto,
        se han modificado algunas teclas de desplazamiento y de edici.n:

        Teclas de Desplazamiento y Edici.n de MEMOEDIT()
        ---------------------------------------------------------------------
        Tecla                    Acción
        ---------------------------------------------------------------------
        Arriba/Ctrl-E            Sube una línea
        Abajo/Ctrl-X             Baja una línea
        Izquierda/Ctrl-S         Pasa un carácter a la izquierda
        Derecha/Ctrl-D           Pasa un carácter a la derecha
        Ctrl-Izquierda/Ctrl-A    Pasa una palabra a la izquierda
        Ctrl-Derecha/Ctrl-F      Pasa una palabra a la derecha
        Inicio                   Pasa al principio de la línea actual
        Fin                      Pasa al final de la línea actual
        Ctrl-Inicio              Pasa al principio de la ventana actual
        Ctrl-Fin                 Pasa al final de la ventana actual
        ReP.g                    Pasa a la ventana de edici.n anterior
        AvP.g                    Pasa a la siguiente ventana de edici.n
        Ctrl-ReP.g               Pasa al principio del texto memo
        Ctrl-AvP.g               Pasa al final del texto memo
        Intro                    Pasa al principio de la línea siguiente
        Suprimir                 Borra el carácter de la posición del cursor
        Retroceso                Borra el carácter situado a la izquierda
                                 del cursor
        Tabulador                Inserta un carácter de tabulador o espacios
        Car.cter imprimible      Inserta ese carácter
        Ctrl-Y                   Borra la línea actual
        Ctrl-T                   Borra la palabra a la derecha
        Ctrl-B                   Da formato a un p.rrafo
        Ctrl-V/Ins               Activa/desactiva el modo de inserci.n
        Ctrl-W                   Finaliza la edici.n guardando los cambios
        Esc                      Anula edici.n y devuelve la cadena original
        ---------------------------------------------------------------------

        Para la introducci.n de texto existen dos modos: inserci.n y
        sobreescritura. Al invocar MEMOEDIT(), el modo por defecto es
        sobreescritura. Para cambiar el modo de edici.n puede pulsarse la
        tecla Ins, que intercambia los modos de inserci.n y sobreescritura.
        También puede cambiarse en una función utilizando READINSERT() o
        devolviendo 22. En el modo de inserci.n, los carácteres se introducen
        en la posición actual del cursor en la memoria intermedia,
        desplaz.ndose el resto del texto a la derecha. El modo de inserci.n
        se indica en el .rea de la línea de estado. En el modo de
        sobreescritura, los carácteres se introducen en la posición actual
        del cursor sobreescribiendo los carácteres existentes, sin
        desplazarse el resto de la memoria intermedia.

        Seg.n se introduce texto y el cursor llega al borde de la ventana
        MEMOEDIT(), la línea actual salta a la línea siguiente de la memoria
        intermedia y se inserta un retorno de carro autom.tico (CHR(141)). Si
        se especifica un argumento <nLongitudL.nea>, el texto salta cuando la
        posición del cursor coincide con <nLongitudL.nea>. Si
        <nLongitudL.nea> es mayor que la anchura de MEMOEDIT(), la ventana se
        desplaza al llegar el cursor al borde. Para iniciar explícitamente
        una nueva línea o p.rrafo, el usuario debe pulsar Intro.

     .  Pantalla de edici.n: Cuando aparece en pantalla
        MEMOEDIT(), sobreescribe el .rea de la pantalla especificada sin
        guardar la pantalla subyacente. Tampoco muestra un borde o t.tulo.
        Para realizar estas acciones, debe crear un procedimiento o función
        que realice estas acciones y, luego, invoque MEMOEDIT(). Consulte el
        siguiente ejemplo.

     .  función de usuario: <cfunciónUsuario>, especificada como
        argumento, maneja las excepciones del teclado y reconfigura las
        teclas especiales. MEMOEDIT() invoca en distintas ocasiones a la
        función de usuario, normalmente como respuesta a teclas no
        reconocidas. Las teclas que producen excepciones del teclado son
        todas las teclas de control, teclas de función y teclas Alt. Como
        MEMOEDIT() no procesa estas teclas, es posible reconfigurarlas.
        Algunas de ellas tienen asignada una acci.n por defecto. Con la
        función de usuario pueden realizarse distintas acciones, dependiendo
        del modo actual de MEMOEDIT() y del valor de retorno que indica a
        MEMOEDIT() qu. debe hacer a continúa.ión.

        Cuando se especifica como argumento la función de usuario, MEMOEDIT()
        define dos clases de teclas: no configurables y excepciones del
        teclado. Cuando se pulsa una tecla no configurable, MEMOEDIT() la
        ejecuta o, en caso contrario, genera una excepci.n del teclado e
        invoca a la función de usuario. Cuando en la memoria intermedia del
        teclado no quedan teclas para ser procesadas por MEMOEDIT(), se
        invoca de nuevo a la función de usuario.

        Cuando MEMOEDIT() llama a la función de usuario, le pasa
        autom.ticamente tres parámetros: el modo de MEMOEDIT(), la línea
        actual de la memoria intermedia y la columna actual de la memoria
        intermedia. El modo indica el estado actual de MEMOEDIT(), que
        depende de la .ltima tecla pulsada o de la .ltima acci.n realizada
        antes de ejecutar la función de usuario. A continúa.ión se indican
        los modos posibles:

        Modos de MEMOEDIT()
        ---------------------------------------------------------------------
        Modo    Memoedit.ch    Descripción
        ---------------------------------------------------------------------
        0       ME_IDLE        Inactividad, se han procesado todas las teclas
        1       ME_UNKEY       Tecla desconocida, el texto memo no se ha
                               modificado
        2       ME_UNKEYX      Tecla desconocida, el texto memo se ha
                               modificado
        3       ME_INIT        Modo de inicializaci.n
        ---------------------------------------------------------------------

        Un modo de 3 indica que MEMOEDIT() est. en modo de inicializaci.n. Al
        especificar <cfunciónUsuario>, MEMOEDIT() realiza una llamada a la
        función de usuario inmediatamente después de haberse invocado. En ese
        momento, el usuario debe devolver una petición para seleccionar los
        distintos modos de formato de texto de MEMOEDIT(): salto autom.tico
        de línea, desplazamiento de pantalla o inserci.n. MEMOEDIT() llama a
        la función varias veces, permaneciendo en el modo de inicializaci.n
        hasta que el usuario devuelva 0. Entonces la memoria intermedia se
        muestra en pantalla y el usuario pasa al modo de edici.n seleccionado
        con <lModoEdici.n>. Recuerde que, si el salto autom.ticop de línea
        est. activado cuando MEMOEDIT() pasa del modo de inicializaci.n al de
        edici.n, toda la memoria intermedia se formatea con <nLongitudL.nea>.
        Para evitar esta acci.n de formato inicial, desactive el salto
        autom.tico de línea durante la inicializaci.n. Recuerde también que
        la activaci.n/desactivaci.n del desplazamiento y el salto autom.tico
        de línea no están asignados inicialmente a ningúna tecla, pero pueden
        asignarse a una mediante la función de usuario.

        Los modos 1 y 2 indican que MEMOEDIT() ha recibido una tecla
        irreconocible o una tecla configurable. Las teclas configurables se
        procesan devolviendo 0 para ejecutar la acci.n por defecto de
        MEMOEDIT(). Si se devuelve otro valor se realiza otra acci.n,
        redefiniendo as. la tecla. Si es una tecla irreconocible, puede
        asign.rsele una acci.n que devuelva un valor que solicite una acci.n
        del teclado o que realice una acci.n predefinida.

        El modo 0 indica que MEMOEDIT() est. inactivo en ese momento porque
        no quedan teclas para procesar. Cuando MEMOEDIT() est. inactivo, se
        invoca la función de usuario. En ese momento, normalmente se
        actualizan las visualizaciónes del número de línea y de columna.

        Los otros dos parámetros, línea y columna actuales, indican la
        posición actual del cursor en la memoria intermedia al invocar la
        función de usuario. Las líneas se empiezan a contar en la posición
        uno y los de columna en la posición cero.

        En los modos 1, 2 . 3, el usuario puede devolver un valor que indique
        a MEMOEDIT() la siguiente acci.n que debe realizar. La tabla
        siguiente muestra los posibles valores devueltos y sus consecuencias:

        Valores de Retorno a la función de Usuario de MEMOEDIT()
        ---------------------------------------------------------------------
        Valor   Memoedit.ch       Acción
        ---------------------------------------------------------------------
        0       ME_DEFAULT        Realiza la acci.n por defecto
        1-31    ME_UNKEY          Procesa la acci.n solicitada que corresponde
                                  al valor de la tecla
        32      ME_IGNORE         Ignora las teclas desconocidas
        33      ME_DATA           Trata las teclas desconocidas como datos
        34      ME_TOGGLEWRAP     Activa/desactiva el modo de salto autom.tico
                                  de línea
        35      ME_TOGGLESCROLL   Activa/desactiva el modo de desplazamiento
                                  de pantalla
        100     ME_WORDRIGHT      Se desplaza una palabra a la derecha
        101     ME_BOTTOMRIGHT    Se desplaza al final del texto
        ---------------------------------------------------------------------

     .  Ficheros de cabecera: Para facilitar la memorizaci.n y
        utilización de los valores de modo y de petición, existe en
        \CLIPPER5\INCLUDE un fichero de cabecera llamado Memoedit.ch. En el
        mismo directorio existe Inkey.ch, que contiene constantes declaradas
        para todos los valores de INKEY().
Notas

     .  configuración de teclas: Si se especifica una
        <cfunciónUsuario>, pueden configurarse las teclas que se incluyen en
        la siguiente tabla.

        Teclas Configurables de MEMOEDIT()
        ---------------------------------------------------------------------
        Tecla          Acción por Defecto
        ---------------------------------------------------------------------
        Ctrl-Y         Borra la línea actual
        Ctrl-T         Borra la palabra a la derecha
        Ctrl-B         Da formato al p.rrafo
        Ctrl-V/Ins     Activa/desactiva el modo de inserci.n
        Ctrl-W         Finaliza la edici.n guardando los cambios
        Esc            Anula la edici.n devolviendo la cadena original
        ---------------------------------------------------------------------

        Si la tecla es configurable, se devuelve 0 para ejecutar la acci.n
        por defecto de MEMOEDIT(). Si se devuelve otro valor, no obstante, se
        ejecuta otra acci.n del teclado lo que redefine la tecla. Si no se
        trata una tecla configurable reconocida por MEMOEDIT(), también puede
        asign.rsele una acci.n devolviendo un valor que solicite una de las
        acciones incluidas en la tabla anterior.

     .  Salto autom.tico de línea: El salto autom.tico de línea es
        un modo de formato que puede activarse y desactivarse devolviendo 34
        desde la función de usuario. Si est. activado (opción por defecto),
        MEMOEDIT() inserta un retorno de carro/salto de línea autom.tico en
        la interrupci.n de texto m.s cercana al borde de la ventana o al
        terminar la línea (lo que ocurra primero). Si est. desactivado,
        MEMOEDIT() desplaza la memoria intermedia m.s all. del borde de la
        ventana, hasta que el cursor llegue al fin de línea. En ese punto, el
        usuario debe pulsar Intro (insertando un retorno de carro/salto de
        línea forzado) para pasar a la línea siguiente.

     .  Formato de p.rrafos: Al pulsar Ctrl-B, o devolver 2 desde
        una función de usuario, se vuelve a formatear la memoria intermedia
        hasta encontrar un retorno de carro forzado (fin de p.rrafo) o el
        final de la memoria intermedia, independientemente de que el salto
        autom.tico de línea est. activado o no.

     .  Retornos de carro autom.ticos: En CA-Clipper, la
        inserci.n de carácteres de retorno de carro/salto de línea autom.tico
        nunca se permite que cambie el contenido significativo del texto. Es
        decir, cuando se inserta un retorno de carro/salto de línea
        autom.tico entre dos palabras, se mantienen los carácteres de espacio
        que hay entre las dos palabras. Al cambiar el formato del texto, se
        eliminan todos los carácteres de retorno de carro/salto de línea
        autom.tico. Esto deja el texto en su formato original y trata
        adecuadamente los casos en los que se ha insertado un retorno de
        carro/salto de línea autom.tico en mitad de una palabra.

        En la versi.n Summer '87 de MEMOEDIT(), al insertar un retorno de
        carro/salto de línea autom.tico, se suprime un carácter de espacio en
        ese punto del texto. Si posteriormente se formatea el texto
        utilizando una anchura de línea diferente, todos los retornos de
        carro/saltos de línea autom.ticos se sustituyen por un espacio. Sin
        embargo, si la cadena de texto se formatea mediante alguna de las
        funciónes de tratamiento de texto de CA-Clipper, las palabras que
        estaban separadas por un retorno de carro/salto de línea autom.tico
        se ejecutan juntas, porque este carácter no se sustituye por un
        espacio.

        Para evitarlo, los textos formateados con la versi.n Summer '87 de
        MEMOEDIT() deben procesarse para sustituir los carácteres de retorno
        de carro /salto de línea autom.tico por espacios. Esto puede
        realizarse mediante la función STRTRAN(), tal como se indica a
        continúa.ión.

        STRTRAN( <texto>, CHR(141)+CHR(10), " " )

        Para convertir los valores memo de una base de datos existente, puede
        utilizarse el siguiente programa de dos líneas:

        USE <xcBasedeDatos>
        REPLACE ALL <idMemo> WITH ;
           STRTRAN( <idMemo>, CHR(141)+CHR(10), " " )

        Debido al formato del fichero (.dbt), la sustituci.n de todos los
        sucesos de un campo memo puede hacer que el fichero (.dbt) aumente
        notablemente. El fichero (.dbt) puede reducirse copiando el fichero
        (.dbf) en un nuevo fichero.

        En ficheros (.dbt) muy grandes, el procedimiento anterior puede no
        ser factible. En tal caso, puede utilizarse el programa DBT50.EXE,
        situado en el directorio \CLIPPER5\BIN. DBT50 examina un fichero
        (.dbt) completo, sustituyendo todos los pares de retorno de
        carro/salto de línea autom.tico por dos espacios. Aunque esto produce
        el efecto no deseado de separar determinadas palabras con dos
        espacios en vez de uno, permite procesar el fichero directamente sin
        necesidad de utilizar espacio de disco adicional. DBT50 modifica
        .nicamente los carácteres de retorno de carro/salto de línea
        autom.tico del fichero objeto. El resto del texto no se modifica.

     .  Edici.n de ficheros de texto: MEMOEDIT() edita ficheros de
        texto si pueden leerse en una variable de carácteres de CA-Clipper.
        Esto puede hacerse mediante la función MEMOREAD(). Despu.s de editar
        el contenido del fichero de texto incluido en la variable de
        carácteres, debe volver a escribirse mediante MEMOWRIT().

 Ejemplos

     .  Este ejemplo permite examinar un campo memo, pero impide
        realizar cambios en la memoria intermedia:

        USE Cliente NEW
        SET CURSOR OFF
        MEMOEDIT(NotasCli, 5, 10, 20, 69, .F.)
        SET CURSOR ON

     .  El siguiente ejemplo permite editar un campo memo, volviendo a
        asignar los cambios al mismo:

        USE Cliente NEW
        REPLACE NotasCli WITH ;
              MEMOEDIT(NotasCli, 5, 10, 20, 69)

     .  Este ejemplo crea una cadena de carácteres mediante
        MEMOEDIT():

        LOCAL cNotas
        cNotas = MEMOEDIT()

     .  El ejemplo siguiente es una función que edita una cadena de
        carácteres en una ventana emmarcada, con un t.tulo:

        FUNCTION EditMemo( cCadena, cTitulo,;
                 nSup, nIzda, nInf, nDer )
           LOCAL cPantalla := SAVESCREEN(nSup nIzda,;
                 nInf, nDer)
           @ nSup - 1, nIzda - 2 CLEAR TO nInf + 1,;
                 nDer + 2
           @ nSup - 1, nIzda - 2 TO nInf + 1, nDer + 2
           @ nSup - 1, nIzda SAY "[" + cTitulo + "]"
           cCadena = MEMOEDIT(cCadena, nSup, nIzda,;
                 nInf, nDer)
           RESTSCREEN(nSup, nIzda, nInf, nDer, cPantalla)
           RETURN (cCadena)

     .  Este ejemplo lee el contenido de un fichero de texto incluido
        en una variable de carácteres, lo edita y lo vuelve a escribir en el
        disco:

        LOCAL cCadena := MEMOREAD("Text.txt")
        cCadena := MEMOEDIT(cCadena)
        IF !MEMOWRIT("Text.txt", cCadena)
           ? "Error escritura"
           BREAK
        ENDIF
        RETURN

     .  Este ejemplo contiene una función que muestra en pantalla un
        mensaje que describe el modo actual de MEMOEDIT(). Además, en el modo
        ME_UNKEY, la función realizar. una acci.n ME_WORDRIGHT o
        ME_BOTTOMRIGHT, dependiendo de la tecla de función asociada que se
        haya pulsado:

        #include "memoedit.ch"
        #include "inkey.ch"

        PROCEDURE Main()
           USE Cliente NEW
           REPLACE NotasCli WITH;
           MEMOEDIT( NotasCli, 5, 5, 15, 75, .T., "MemoUDF" )
        RETURN

        FUNCTION MemoUDF( nModo, nLinea, nCol )
           LOCAL nTecla := LASTKEY()
           LOCAL nValDev := ME_DEFAULT         // Acción devuelta por
                                               // defecto
           DO CASE
           CASE nModo == ME_IDLE
              @ 20, 5 SAY "El modo es ME_IDLE "
           CASE nModo == ME_UNKEY
              @ 20, 5 SAY "El modo es ME_UNKEY "
              DO CASE
              CASE nTecla == K_F2
                 nValDev := ME_WORDRIGHT
              CASE nTecla == K_F3
                 nValDev := ME_BOTTOMRIGHT
              ENDCASE
              CASE nModo == ME_UNKEYX
              @ 20, 5 SAY "El modo es ME_UNKEYX"
           OTHERWISE
              @ 20, 5 SAY "El modo es ME_INIT "
           ENDCASE

        RETURN nValDev

 Ficheros: La biblioteca asociada es EXTEND.LIB,
            los ficheros de cabecera son Memoedit.ch y Inkey.ch.

MEMOLINE()
 Extrae una línea de texto de la cadena de carácteres o campo memo
------------------------------------------------------------------------------
 Sintaxis

     MEMOLINE(<cCadena>,
        [<nLongitudL.nea>],
        [<nNúmeroL.nea>],
        [<nTama.oTabulador>],
        [<lSaltoL.nea>]) --> cL.nea

 Argumentos

     <cCadena> es el campo memo o cadena de carácteres del que se va a
     extraer una línea de texto.

     <nLongitudL.nea> especifica el número de carácteres de línea y puede
     estar comprendido entre 4 y 254. Si no se especifica, la longitud de
     línea por defecto es 79.

     <nNúmeroL.nea> es el número de línea que se va a extraer. Si no se
     especifica, el valor por defecto es uno.

     <nTama.oTabulador> define el tama.o del tabulador. Si no se
     especifica, el valor por defecto es de cuatro espacios. Si
     <nTama.oTabulador> es mayor o igual que <nLongitudL.nea>, el tama.o de
     tabulador se convierte autom.ticamente en <nLongitudL.nea> - 1.

     <lSaltoL.nea> activa/desactiva el salto autom.tico de línea. Si se
     especifica verdadero (.T.) se activa el salto de línea y si de
     especifica falso (.F.) se desactiva. El valor por defecto es verdadero
     (.T.).

 Devuelve

     MEMOLINE() devuelve la línea de texto especificada por <nNúmeroL.nea> en
     <cCadena>, como cadena de carácteres. Si la línea tiene menos carácteres
     que la longitud indicada, el valor de retorno se rellena con espacios en
     blanco. Si el número de línea es mayor que el número total de líneas de
     <cCadena>, MEMOLINE() devuelve una cadena nula ("").

     Si <lSaltoL.nea> es verdadero (.T.) y la longitud de línea indicada
     interrumpe la línea en mitad de una palabra, dicha palabra no se incluye
     en el valor de retorno, sino que se muestra al principio de la siguiente
     línea extra.da mediante MEMOLINE().

     Si <lSaltoL.nea> es falso (.F.), MEMOLINE() devuelve solamente el número
     de carácteres especificado por la longitud de línea. La siguiente línea
     extra.da por MEMOLINE() comienza en el carácter que va a continúa.ión
     del siguiente retorno de carro forzado, y los carácteres intermedios no
     se procesan.

 Descripción

     MEMOLINE() es una función que se utiliza con MLCOUNT() para extraer
     líneas de texto de cadenas de carácteres y campos memo, bas.ndose en el
     número de carácteres por línea. Es la función m.s sencilla de CA-Clipper
     para mostrar en pantalla campos memo y cadenas largas.

     La forma de utilización m.s f.cil consiste en determinar el número de
     líneas del campo memo o cadena de carácteres útilizando MLCOUNT() con el
     mismo número de carácteres por línea, tama.o de tabulador y selecci.n de
     salto de línea que va a utilizar con MEMOLINE(). Este valor puede
     utilizarse como l.mite superior de FOR...NEXT para extraer las líneas
     del campo memo o cadena de carácteres mediante MEMOLINE() y procesarlas
     con cualquier combinación de funciónes y mandatos de salida necesarios.

 Ejemplos

     .  Este ejemplo muestra el m.todo general para mostrar en
        pantalla campos memo y cadenas de carácteres largas utilizando una
        combinación de las funciónes MLCOUNT() y MEMOLINE():

        LOCAL nLongitudLinea := 40, nTamanoTabulador := 3,;
              lSaltoLinea := .T.
        LOCAL nLineas, nLineaActual
        USE Cliente INDEX NombreCli NEW
        //
        nLineas := MLCOUNT(NotasCli, nLongitudLinea,;
              nTamanoTabulador, lSaltoLinea)
        //
        SET PRINTER ON
        FOR nLineaActual := 1 TO nLineas
           ? MEMOLINE(NotasCli, nLongitudLinea, nLineaActual;
                  nTamanoTabulador, lSaltoLinea)
        NEXT
        SET PRINTER OFF

 Ficheros:  La biblioteca asociada es EXTEND.LIB.


MEMOREAD()
 Devuelve el contenido de un fichero de disco en forma de cadena de carácteres
------------------------------------------------------------------------------
 Sintaxis

     MEMOREAD(<cFichero>) --> cCadena

 Argumentos

     <cFichero> es el nombre del fichero que se va a leer en el disco.
     Debe incluir una extensión, si la hay, y una vía de acceso opciónal.

 Devuelve

     MEMOREAD() devuelve el contenido de un fichero de texto en forma de
     cadena de carácteres. El máximo tama.o de fichero que puede leerse es de
     65.535 carácteres (64K), que es el tama.o máximo de una cadena. Si no se
     encuentra <cFichero>, MEMOREAD() devuelve una cadena nula ("").

 Descripción

     MEMOREAD() es una función que lee en la memoria un fichero de disco,
     donde se maneja como cadena de carácteres o se asigna a un campo memo.
     MEMOREAD() se utiliza con MEMOEDIT() y MEMOWRIT() para editar un fichero
     de disco importado y volver a escribirlo después en el disco. MEMOREAD()
     busca <cFichero> comenzando en el directorio del DOS actual. Si el
     fichero no se encuentra, MEMOREAD() busca en la vía del DOS. MEMOREAD()
     no utiliza los valores DEFAULT o PATH de CA-Clipper para la b.squeda de
     <cFichero>.

     En un entorno de red, MEMOREAD() intenta abrir el fichero especificado
     en modo compartido y de sólo lectura. Si ya ha sido abierto en modo
     exclusivo por de otro proceso, MEMOREAD() devuelve una cadena nula ("").

 Ejemplos

     .  Este ejemplo utiliza MEMOREAD() para asignar el contenido de
        un fichero de texto al campo memo Notas y a una variable de tipo
        carácter:

        REPLACE Notas WITH MEMOREAD("Temp.txt")
        cCadena = MEMOREAD("Temp.txt")

     .  Este ejemplo define una función que edita un fichero de disco:

        FUNCTION Editor( cFichero )
           LOCAL cCadena
           IF (cCadena := MEMOREAD(cFichero)) == ""
              ? "Error de lectura de " + cFichero
              RETURN .F.
           ELSE
              MEMOWRIT(cFichero, MEMOEDIT(cCadena))
              RETURN .T.
           ENDIF

 Ficheros: La biblioteca asociada es EXTEND.LIB.


MEMORY()
 Determina la cantidad de memoria libre disponible
------------------------------------------------------------------------------
 Sintaxis

     MEMORY(<nExp>) --> nKbytes

 Argumentos

     <nExp> es un valor numérico que determina el significado del valor
     que devuelve MEMORY(), como se indica a continúa.ión:

     Valores del Argumento de MEMORY()
     ------------------------------------------------------------------------
     Valor   Significado
     ------------------------------------------------------------------------
     0       Espacio total estimado disponible para valores de tipo carácter
     1       Bloque contiguo m.s grande disponible para valores de tipo
             carácter
     2       Area disponible para mandatos RUN
     ------------------------------------------------------------------------

 Devuelve

     MEMORY() devuelve un valor numérico entero que representa la cantidad de
     memoria disponible, en incrementos de un kilobyte.

 Descripción

     MEMORY() es una función de entorno que informa de los distintos estados
     del .rea de memoria disponible. (Esta zona es el .rea din.mica de la
     memoria que almacena cadenas de carácteres y ejecuta mandatos RUN.)

 Ejemplos

     .  Este ejemplo utiliza MEMORY() antes de un mandato RUN para
        determinar si se dispone de suficiente memoria para ejecutar el
        programa externo:

        #define MEM_CHAR    0
        #define MEM_BLOCK   1
        #define MEM_RUN     2
        //
        IF MEMORY(MEM_RUN) >= 128
           RUN MYPROG
        ELSE
           ? "Memoria insuficiente para ejecutar el programa"
           BREAK
        ENDIF

 Ficheros: La biblioteca asociada es CLIPPER.LIB.


MEMOTRAN()
 Sustituye los retornos de carro/saltos de línea contenidos en una cadena de
 carácteres
------------------------------------------------------------------------------
 Sintaxis

     MEMOTRAN(<cCadena>,
        [<cSustRCForzado>],
        [<cSustRCAutom.tico>]) --> cNuevaCadena

 Argumentos

     <cCadena> es la cadena de carácteres o campo memo que se va a leer.

     <cSustRCForzado> es el carácter por el que se va a sustituir cada
     retorno de carro/salto de línea forzado. Si no se especifica, el valor
     por defecto es un punto y coma (;).

     <cSustRCAutom.tico> es el carácter por el que se va a sustituir cada
     retorno de carro/salto de línea autom.tico. Si no se especifica, el
     valor por defecto es un espacio.

 Devuelve

     MEMOTRAN() devuelve una copia de <cCadena> en la que se han sustituido
     los retornos de carro/saltos de línea especificados.

 Descripción

     MEMOTRAN() es una función que convierte un campo memo o una cadena de
     carácteres larga, que contiene retornos de carro/saltos de línea
     autom.ticos y forzados, en un formato que pueda mostrarse en pantalla.
     Esta combinación de dos carácteres es un indicador de fin de línea
     colocado en una cadena por MEMOEDIT(). Se insertan retornos de carro
     autom.ticos (CHR(141)) cuando una línea que es m.s larga que la anchura
     de la ventana de MEMOEDIT() salta a la línea siguiente. Se insertan
     retornos de carro forzados (CHR(13)) cuando el usuario pulsa
     explícitamente la tecla Intro.

     MEMOTRAN() sirve para visualizar un campo memo de un REPORT FORM sin
     saltos de línea autom.ticos al encontrar retornos de carro autom.ticos.
     MEMOTRAN() lo soluciona convirtiendo los retornos de carro autom.ticos
     en espacios. Recuerde, no obstante, que es necesario declarar MEMOTRAN()
     como función externa mediante la sentencia REQUEST, si se utiliza en un
     REPORT FORM y no se especifica en ningúna otra parte del programa
     actual.

 Ejemplos

     .  El siguiente ejemplo suprime todos los carácteres de fin de
        línea de un campo memo:

        REPLACE Notas WITH MEMOTRAN(Notas)

 Ficheros:  La biblioteca asociada es EXTEND.LIB.

MEMOWRIT()
 Escribe una cadena de carácteres o un campo memo en un fichero de disco
------------------------------------------------------------------------------
 Sintaxis

     MEMOWRIT(<cFichero>, <cCadena>) --> lExito

 Argumentos

     <cFichero> es el nombre del fichero de disco de destáno, incluyendo
     la extensión y el indicador de vía y unidad opciónales.

     <cCadena> es la cadena de carácteres o campo memo que se va a
     escribir en <cFichero>.

 Devuelve

     MEMOWRIT() devuelve verdadero (.T.) si la operación.de escritura se ha
     realizado con .xito; en caso contrario, devuelve falso (.F.).

 Descripción

     MEMOWRIT() es una función que escribe una cadena de carácteres o campo
     memo en un fichero de disco. Si no se especifica la vía, MEMOWRIT()
     escribe <cFichero> en el directorio actual del DOS, en vez de en el
     directorio especificado por el valor de SET DEFAULT actual. Si
     <cFichero> ya existe, se sobreescribe.

     MEMOWRIT() se utiliza generalmente con MEMOREAD() para cargar en memoria
     ficheros de texto, donde pueden editarse, mostrarse en pantalla y volver
     a escribirse en el disco. Asimismo, MEMOWRIT() puede utilizarse como un
     m.todo r.pido de exportar un campo memo a un fichero de texto.

 Ejemplos

     .  Este ejemplo utiliza MEMOWRIT() con MEMOREAD() para permitir
        la edici.n de campos memo con un editor externo:

        LOCAL cEditor := "MYEDIT.EXE"
        USE Ventas NEW
        IF MEMOWRIT("Cliptmp.txt", Notas)

        RUN (cEditor + " Cliptmp.txt")
           REPLACE Notas WITH MEMOREAD("Cliptmp.txt")
        ELSE
           ? "Error al escribir Cliptmp.txt"
           BREAK
        ENDIF

 Ficheros:  La biblioteca asociada es EXTEND.LIB.

MEMVARBLOCK()
 Devuelve un bloque de código de asignación/lectura para una variable de
 memoria dada
------------------------------------------------------------------------------
 Sintaxis

     MEMVARBLOCK(<cNombreVarmem>) --> bBloqueVarmem

 Argumentos

     <cNombreVarmem> es el nombre de la variable a la que hace referencia
     el bloque de lectura/escritura, especificada como cadena de carácteres.

 Devuelve

     MEMVARBLOCK() devuelve un bloque de código que, al evaluarse, permite
     asignar u obtener el valor de la variable de memoria especificada. Si no
     existe la variable, MEMVARBLOCK() devuelve NIL.

 Descripción

     El bloque de código creado por MEMVARBLOCK() realiza dos operación.s,
     dependiendo de si se pasa un argumento al bloque de código cuando se
     eval.a. Si se eval.a con un argumento, asigna ese valor a
     <cNombreVarmem>. Si se eval.a sin argumento, recupera el valor de
     <cNombreVarmem>.

 Notas

     .  MEMVARBLOCK() sólo permite crear bloques de asignación/lectura
        de variables de nombres conocidos durante la ejecución.
        MEMVARBLOCK(), por tanto, no puede utilizarse para crear bloques de
        asignación/lectura de variablesólocales o estáticas. La misma
        restricci.n se aplica a la creaci.n de bloques mediante el operador
        de macro (&).

 Ejemplos

     .  Este ejemplo compara MEMVARBLOCK() con un bloque de código
        creado con el operador de macro (&). Observe que la utilización de
        MEMVARBLOCK() le permite evitar la velocidad y el tama.o iniciales
        del operador de macro:

        PRIVATE var := "Esto es una cadena"
        //
        // Bloque de asignación/lectura definido mediante
        // el operador de macro
        bLeerEscr := &( "{ |valEst|;
              IF( valEst == NIL, var, var := valEst ) }" )
        // Bloque de asignación/lectura definido mediante
        //MEMVARBLOCK()
        // el bLeerEscr creado aqu. es el equivalente
        // funciónal del bLeerEscr anterior
        bEstObt := MEMVARBLOCK("var")

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.

MIN()
 Devuelve el menor de dos valores numéricos o de fecha
------------------------------------------------------------------------------
 Sintaxis

 MIN(<nExp1>, <nExp2>) --> nMenor

 MIN(<fExp1>, <fExp2>) --> fMenor

 Argumentos

     <nExp1> y <nExp2> son los valores numéricos que se van a
     comparar.

     <fExp1> y <fExp2> son los valores de fecha que se van a
     comparar.

 Devuelve

     MIN() devuelve el menor de dos argumentos. El valor de retorno es del
     mismo tipo de datos que los argumentos.

 Descripción

     MIN() es una función numérica y de fecha que asegura que el valor de una
     expresión sea inferior a un mínimo especificado. La función inversa de
     MIN() es MAX(), que devuelve el mayor de dos valores numéricos o de
     fecha.

 Ejemplos

     .  En los siguientes ejemplos, MIN() devuelve el menor de dos
        valores numéricos:

        ? MIN(99, 100)                     // Resultado: 99
        ? MIN(100, 99)                     // Resultado: 99

     .  En los ejemplos siguientes, MIN() compara valores de fecha:

        ? DATE()                           // Resultado: 09/01/90
        ? MIN(DATE(), DATE() + 30)         // Resultado: 09/01/90

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.

MLCOUNT()
 Cuenta el número de líneas de una cadena de carácteres o de un campo memo
------------------------------------------------------------------------------
 Sintaxis

     MLCOUNT(<cCadena>, [<nLongitudL.nea>],
        [<nTama.oTabulador>], [<lSaltoL.nea>]) --> nL.neas

 Argumentos

     <cCadena> es la cadena de carácteres o el campo memo en el que se va
     a realizar el recuento.

     <nLongitudL.nea> especifica el número de carácteres por línea y
     puede estar comprendido entre 4 y 254. Si no se especifica, la longitud
     de línea por defecto es 79.

     <nTama.oTabulador> define el tama.o de tabulador. Si no se
     especifica, el valor por defecto es de cuatro espacios. Si
     <nTama.oTabulador> es mayor o igual que <nLongitudL.nea>, el tama.o de
     tabulador se convierte autom.ticamente en <nLongitudL.nea> - 1.

     <lSaltoL.nea> activa o desactiva el salto autom.tico de línea. Si se
     especifica verdadero (.T.) se activa el salto autom.tico de línea; si se
     especifica falso (.F.) se desactiva. El valor por defecto es verdadero
     (.T.).

 Devuelve

     MLCOUNT() devuelve el número de líneas de <cCadena>, dependiendo de la
     <nLongitudL.nea>, el <nTama.oTabulador> y la activaci.n o desactivaci.n
     del salto autom.tico de línea.

 Descripción

     MLCOUNT() es una función que se utiliza con MEMOLINE() para imprimir
     cadenas de carácteres y campos memo, bas.ndose en el número de
     carácteres por línea. En su forma m.s sencilla, MLCOUNT() devuelve el
     número de líneas de la cadena de carácteres o del campo memo. Luego,
     puede utilizar MEMOLINE() para extraer las líneas en el campo memo hasta
     que no quede ningúna línea.

     Si <lSaltoL.nea> es verdadero (.T.) y un fin de línea divide en dos una
     palabra, el texto pasa a la línea sigiente incluyendo esa palabra. Si
     <lSaltoL.nea> es falso (.F.), MLCOUNT() cuenta como línea actual el
     número de carácteres especificado por <nLongitudL.nea>. La siguiente
     línea comienza por el carácter que vaya detrás del siguiente retorno de
     carro forzado o autom.tico que se encuentre y los restántes carácteres
     se ignoran.

 Ejemplos

     .  Este ejemplo muestra en pantalla el contenido de todos los
        campos memo Notas del fichero de base de datos Ventas, una línea cada
        vez:

            USE Ventas NEW
            nLongLinea = 65
            //
            DO WHILE !EOF()
               nLineas = MLCOUNT(Ventas->Notas, nLongLinea)
               FOR nLineaActual = 1 TO nLineas
               ? MEMOLINE(Ventas->Notas, nLongLinea, nLineaAct)
                  NEXT
                  SKIP
                  ?
            ENDDO

 Ficheros:  La biblioteca asociada es EXTEND.LIB.


MLCTOPOS()
 Devuelve la posición absoluta del carácter en una cadena formateada en filas
 y columnas
------------------------------------------------------------------------------
 Sintaxis

     MLCTOPOS(<cTexto>, <nAnchura>, <nL.nea>, <nCol>,
              [<nTama.oTabulador>], [<lSaltoL.nea>]) -->nPosicion

 Argumentos

     <cTexto> es la cadena de texto que se va a tratar.

     <nAnchura> es la anchura del formato de línea.

     <nL.nea> es el número de línea, contando a partir de 1.

     <nCol> es el número de columna, contando a partir de 0.

     <nTama.oTabulador> es el número de columnas que hay entre las
     posiciónes de tabulaci.n. Si no se especifica, el valor por defecto es
     4.

     <lSaltoL.nea> es el indicador de salto autom.tico de línea. Si no se
     especifica, el valor por defecto es verdadero (.T.).

 Devuelve

     MLCTOPOS() devuelve la posición de byte dentro de <cTexto>, contando a
     partir de 1.

 Descripción

     MLCTOPOS() es una función memo que determina la posición de byte que
     corresponde a una línea y una columna determinadas dentro del texto
     formateado. Recuerde que la numeraci.n de líneas comienza por uno,
     mientras que la numeraci.n de columnas comienza por cero. Esta función
     es compatible con MEMOEDIT(). El valor de retorno se cuenta a partir de
     uno, lo que permite utilizarlo con SUBSTR() u otras funciónes de
     cadenas.

     MLCTOPOS() se utiliza con MPOSTOLC() para crear rutinas de b.squeda u
     otros procesamientos de texto de MEMOEDIT(). Consulte el código fuente
     del Editor de Programas, que se encuentra en el directorio
     \CLIPPER5\SOURCE\PE.

 Ejemplos

     .  Este ejemplo determina la posición de byte de la línea 5,
        columna 3 de la cadena cTexto:

     cTexto := "Recuerde en qu. lado del pan debe"+;

                    "ponerse la mantequilla."
        //
        ? MLCTOPOS(cTexto, 5, 3, 0)         // Resultado: 10

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.

MLPOS()
 Determina la posición de una línea en una cadena de carácteres o en un campo
 memo
------------------------------------------------------------------------------
 Sintaxis

     MLPOS(<cCadena>, <nLongitudL.nea>, <nL.nea>, [<nTama.oTabulador>],
           [<lSaltoL.nea>]) -->nPosici.n

 Argumentos

     <cCadena> es una cadena de carácteres o un campo memo.

     <nLongitudL.nea> especifica el número de carácteres por línea.

     <nL.nea> especifica el número de línea.

     <nTama.oTabulador> define el tama.o del tabulador. El valor por
     defecto es cuatro. Si <nTama.oTabulador> es mayor o igual que
     <nLongitudL.nea>, el tama.o del tabulador se convierte en
     <nLongitudL.nea> - 1.

     <lSaltoL.nea> activa y desactiva el salto autom.tico de línea. Si se
     especifica verdadero (.T.), se activa el salto de línea y si se
     especifica falso (.F.), se desactiva. El valor por defecto es verdadero
     (.T.).

 Devuelve

     MLPOS() devuelve la posición de carácter de <nL.nea> en <cCadena>, como
     valor numérico entero. Si <nL.nea> es mayor que el número de líneas de
     <cCadena>, MLPOS() devuelve la longitud de <cCadena>.

 Ejemplos

     .  Este ejemplo utiliza MLPOS() para buscar la posición de una
        línea determinada, suponiendo una longitud de línea dada:

        cCadena = MEMOREAD("Temp.txt")
        nLongLinea = 40
        nLinea = 5
        nPosicion = MLPOS(cCadena, nLongLinea, nLinea)
        ? SUBSTR(cCadena, nPosicion, 12)

 Ficheros:  La biblioteca asociada es EXTEND.LIB.

MOD()*
 Devuelve el resto de dos números en formato dBASE III PLUS
------------------------------------------------------------------------------
 Sintaxis

     MOD(<nDividendo>, <nDivisor>) --> nResto

 Argumentos

     <nDividendo> es el dividendo de la operación.de divisi.n.

     <nDivisor> es el divisor de la operación.de divisi.n.

 Devuelve

     MOD() devuelve un número que representa el resto de <nDividendo>
     dividido por <nDivisor>.

 Descripción

     MOD() es una función numérica que emula la función MOD() de dBASE III
     PLUS. Se ejecuta mediante el operador de resto de CA-Clipper (%).
     Recuerde que existen diferencias entre la función MOD() de dBASE III+
     y el operador de resto de CA-Clipper, que se describen en la siguiente
     tabla:

     Diferencias entre la función MOD() de dBASE III PLUS y el operador de
     resto de CA-Clipper
     ------------------------------------------------------------------------
     Dividendo   Divisor    Operador Resto    MOD()   función MOD() de dBASE
                                                             III PLUS
     ------------------------------------------------------------------------
      3           0             Error         Error              3
      3          -2               1            -1               -1
     -3           2              -1             1                1
     -3           0             Error         Error             -3
     -1           3              -1             2                2
     -2           3              -2             1                1
      2          -3               2            -1               -1
      1          -3               1            -2               -2
     ------------------------------------------------------------------------

     MOD() se incluye como función de compatibilidad y, por tanto, su
     utilización no es recomendable. Puede sustituirse completamente por el
     operador de resto (%).

 Notas

     .  Divisores cero en dBASE III PLUS: En dBASE III PLUS, un
        divisor cero devuelve el dividendo cualquiera que sea el valor del
        mismo. En CA-Clipper, por el contrario, la divisi.n de cualquier
        dividendo con un divisor cero provoca un error de ejecución.

     .  Divisores cero en versiones anteriores: En las versiones
        de            CA-Clipper anteriores a Summer '87, una divisi.n con un
        divisor cero devolvía cero cualquiera que fuera el dividendo. En las
        versiones Summer '87 y posteriores, devuelve un error de ejecución.

 Ficheros:  La biblioteca asociada es EXTEND.LIB,
            el fichero fuente es SOURCE\SAMPLE\MOD.PRG.

MONTH()
 Convierte un valor de fecha en un número de mes
------------------------------------------------------------------------------
 Sintaxis

     MONTH(<fFecha>) --> nMes

 Argumentos

     <fFecha> es el valor de fecha que se va a convertir.

 Devuelve

     MONTH() devuelve un valor numérico entero comprendido en el rango de 0 a
     12. Si se especifica una fecha nula (CTOD("")) devuelve cero.

 Descripción

     MONTH() es una función de conversión de fechas que se utiliza cuando se
     requiere un valor numérico de mes para calcular informes peri.dicos,
     etc. MONTH() forma parte de un grupo de funciónes que devuelven los
     componentes de un valor de fecha como valores numéricos. En este grupo
     incluye DAY() y YEAR(), que devuelven respectivamente los valores de d.a
     y a.o como valores numéricos. CMONTH() es una función relacionada, que
     devuelve el nombre del mes a partir de un valor de fecha.

 Ejemplos

     .  Los siguientes ejemplos devuelven el mes de la fecha del
        sistema:

        ? DATE()                       // Resultado: 09/01/90
        ? MONTH(DATE())                // Resultado: 9
        ? MONTH(DATE()) + 1            // Resultado: 10

     .  Este ejemplo muestra a MONTH() realizando una acci.n con una
        fecha nula:

        #define NULL_DATE  (CTOD(""))
        ? MONTH(NULL_DATE)             // Resultado: 0

 Ficheros:  Fichero de biblioteca CLIPPER.LIB.

MPOSTOLC()
 Devuelve la posición de línea y columna de una cadena formateada, bas.ndose
 en una posición de byte especificada
------------------------------------------------------------------------------
 Sintaxis

     MPOSTOLC(<cTexto>, <nAnchura>, <nPos>,
        [<nTama.oTabulador>], [<lSaltoL.nea>]) -->    aL.neaColumna

 Argumentos

     <cTexto> es una cadena de texto.

     <nAnchura> es la longitud de la línea formateada.

     <nPos> es la posición de byte dentro del texto, contada a partir de
     uno.

     <nTama.oTabulador> es el número de columnas que hay entre las
     posiciónes de tabulaci.n. Si no se especifica, el valor por defecto es
     cuatro.

     <lSaltoL.nea> es el indicador de salto autom.tico de línea. Si no se
     especifica, el valor por defecto es verdadero (.T.).

 Devuelve

     MPOSTOLC() devuelve una matriz que contiene los valores de línea y de
     columna de la posición de byte especificada, <nPos>.

 Descripción

     MPOSTOLC() es una función memo que determina la fila y columna
     formateadas en <cTexto> que corresponden a una posición de byte
     especificada. Recuerde que el número de fila devuelto se cuenta a partir
     de uno, mientras que el número de columna se cuenta desde cero. Esta
     función es compatible con MEMOEDIT(). <nPos> se cuenta a partir de uno,
     lo que hace esta función compatible con AT(), RAT() y otras funciónes de
     cadenas.

     MPOSTOLC(), utilizada con MLCTOPOS(), permite crear rutinas de b.squeda
     u otros procedimientos de texto para MEMOEDIT(). Consulte el código
     fuente del Editor de Programas que se encuentra en el directorio
     \CLIPPER5\SOURCE\PE.

 Ejemplos

     .  Para la cadena de texto indicada, este ejemplo determina la
        fila y la columna correspondientes al octavo carácter del texto, dada
        una anchura de formato de cinco columnas. Una anchura de formato de
        cinco columnas hace que las tres primeras palabras se coloquen cada
        una en una línea distinta. El octavo carácter del texto es la "l" de
        "lado." La palabra "lado" estar.a en la columna situada m.s a la
        izquierda de la tercera línea del texto formateado; por tanto, el
        valor de retorno es {3, 0}:

        cText := "Mire el lado del pan donde"+;
              "debe ponerse la mantequilla."
        //
        aLC := MPOSTOLC(cText, 5, 8)         // Resultado: {3, 0}

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.


NETERR()
 Determina si ha fallado alg.n mandato o función de red
------------------------------------------------------------------------------
 Sintaxis

     NETERR([<lNuevoError>]) --> lError

 Argumentos

     <lNuevoError>: Si se especifica, selecciona el valor que devuelve
     NETERR() en el estado especificado. <lNuevoError> puede ser verdadero
     (.T.) o falso (.F.). El establecimiento de NETERR() en un valor
     especificado permite al manejador de errores de ejecución controlar el
     m.todo de manejo de determinados errores. Si desea más información,
     consulte Errorsys.prg.

 Devuelve

     NETERR() devuelve verdadero (.T.) si ha fallado alg.n mandato USE o
     APPEND BLANK. El valor inicial de NETERR() es falso (.F.). Si el proceso
     actual no se ejecuta en un sistema operativo de red, NETERR() siempre
     devuelve falso (.F.).

 Descripción

     NETERR() es una función de red. Se trata de un indicador global que
     puede activarse por USE, USE...EXCLUSIVE y APPEND BLANK en un entorno de
     red. Permite comprobar si ha fallado alguno de estos mandatos,
     devolviendo verdadero (.T.) en las siguientes situaciones:

     Causas de NETERR()
     ------------------------------------------------------------------------
     Mandato             Causa
     ------------------------------------------------------------------------
     USE                 Abierto en modo exclusivo por otro proceso
     USE...EXCLUSIVE     Apertura en modo exclusivo o compartido por otro
                         proceso
     APPEND BLANK        Bloqueo por otro usuario con FLOCK() o RLOCK() de
                         LASTREC() + 1
     ------------------------------------------------------------------------

     NETERR() se aplica normalmente a un programa para comprobarlo después de
     aplicar un mandato USE o APPEND BLANK. Si devuelve falso (.F.), se puede
     realizar la siguiente operación. Si el mandato es USE, se pueden abrir
     ficheros ííndice. Si se trata de APPEND BLANK, pueden asignarse valores
     al nuevo registro mediante un mandato REPLACE o @...GET. Si no devuelve
     el valor falso, es necesario manejar el error, bien volviendo a intentar
     el mandato USE o APPEND BLANK o finalizando la operación.actual con
     BREAK o RETURN.



 Ejemplos

     .  Este ejemplo muestra la forma de utilización de NETERR(). Si
        el mandato USE concluye satisfactoriamente, se abren los ficheros
        índice y el proceso continúa. Si el mandato USE falla, aparece un
        mensaje y el control vuelve a la estructura BEGIN SEQUENCE m.s
        cercana:

        USE Cliente SHARED NEW
        IF !NETERR()
           SET INDEX TO NumCli, PedidosCli, CodPostCli
        ELSE
           ? "Otro usuario est. utilizando el fichero"
           BREAK
        ENDIF

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.


NETNAME()
 Devuelve el código identificador de la estación de trabajo actual
------------------------------------------------------------------------------
 Sintaxis

     NETNAME() --> cNombreEstaci.nTrabajo

 Devuelve

     NETNAME() devuelve el código identificador de la estación de trabajo, en
     forma de cadena con una longitud máxima de 15 carácteres. Si no se ha
     establecido la estación de trabajo o la aplicación no est. operando en
     una red de PCs IBM, devuelve una cadena nula ("").

 Ejemplos

     .  El ejemplo siguiente muestra el resultado de NETNAME() al
        arrancar una estación de trabajo como nodo de red con un
        identificador de estación de "STATION 1":

        ? NETNAME()               // Resultado: STATION 1

     .  El ejemplo siguiente muestra el resultado de NETNAME() al
        arrancar una estación de trabajo como unidad independiente:

        ? NETNAME()               // Resultado: ""

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.
NETNAME()
 Devuelve el código identificador de la estación de trabajo actual
------------------------------------------------------------------------------
 Sintaxis

     NETNAME() --> cNombreEstaci.nTrabajo

 Devuelve

     NETNAME() devuelve el código identificador de la estación de trabajo, en
     forma de cadena con una longitud máxima de 15 carácteres. Si no se ha
     establecido la estación de trabajo o la aplicación no est. operando en
     una red de PCs IBM, devuelve una cadena nula ("").

 Ejemplos

     .  El ejemplo siguiente muestra el resultado de NETNAME() al
        arrancar una estación de trabajo como nodo de red con un
        identificador de estación de "STATION 1":

        ? NETNAME()               // Resultado: STATION 1

     .  El ejemplo siguiente muestra el resultado de NETNAME() al
        arrancar una estación de trabajo como unidad independiente:

        ? NETNAME()               // Resultado: ""

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.
 



NEXTKEY()
 Lee la siguiente tecla pendiente en la memoria intermedia del teclado
------------------------------------------------------------------------------
 Sintaxis

     NEXTKEY() --> nC.digoTecla

 Devuelve

     NEXTKEY() devuelve un valor numérico entero comprendido en el rango de
     -39 a 386. Si la memoria intermedia del teclado est. vac.a, NEXTKEY()
     devuelve cero. Si SET TYPEAHEAD es cero, NEXTKEY() siempre devuelve
     cero.

 Descripción

     NEXTKEY() es una función que lee la siguiente tecla pendiente en la
     memoria intermedia del teclado sin extraerla de la misma. El valor
     devuelto es el código INKEY() de la tecla pulsada (INKEY() y LASTKEY()
     devuelven el mismo valor). NEXTKEY() devuelve valores para todos los
     carácteres ASCII, teclas de función y combinaciónes Alt-función,
     Ctrl-función, Alt-letra y Ctrl-letra.

     NEXTKEY() es similar a la función INKEY(), pero difiere en un aspecto
     fundamental. INKEY() extrae la tecla pendiente de la memoria intermedia
     del teclado y actualiza LASTKEY() con el valor de la tecla. NEXTKEY(),
     por el contrario, lee la tecla de la memoria intermedia sin extraerla y
     no actualiza LASTKEY().

     Como NEXTKEY() no elimina la tecla de la memoria intermedia del teclado,
     puede utilizarse para sondearlo y pasar el control a una rutina que
     utilice un estado de espera o función INKEY() que recoja realmente la
     tecla de la memoria.

     Si desea una lista completa de los códigos de INKEY() y las constantes
     del fichero Inkey.ch, consulte el apéíndice de Códigos Inkey de
     CA-Clipper en la gu.a de Mensajes de Error y Apííndices.

 Ejemplos

     .  Este ejemplo introduce una tecla Esc en la memoria intermedia
        del teclado y muestra seguidamente las diferencias entre INKEY(),
        LASTKEY() y NEXTKEY():

        #include "Inkey.ch"
        //
        CLEAR TYPEAHEAD
        KEYBOARD CHR(K_ESC)
        //
        ? NEXTKEY(), LASTKEY()             // Resultado: 27 0
        ? INKEY(), LASTKEY()               // Resultado: 27 27
        ? NEXTKEY()                        // Resultado: 0

 Ficheros:  La biblioteca asociada es EXTEND.LIB,
            el fichero de cabecera es Inkey.ch.

NOSNOW()
 Activa/desactiva la supresión del efecto nieve en pantalla
------------------------------------------------------------------------------
 Sintaxis

     NOSNOW(<lActivar/Desactivar>) --> NIL

 Argumentos

     <lActivar/Desactivar> es un valor l.gico que intercambia el estado
     actual de la supresión del efecto nieve. Un valor verdadero (.T.) activa
     la supresión del efecto nieve, y un valor falso (.F.) la desactiva.

 Descripción

     NOSNOW() se utiliza para suprimir el efecto en los monitores CGA.
     Normalmente, NOSNOW() aparece en la secci.n de configuración de su
     aplicación para permitir al usuario suprimir el efecto nieve.

 Ficheros:  La biblioteca asociada es CLIPPER.LIB

OS()
 Devuelve el nombre del sistema operativo
------------------------------------------------------------------------------
 Sintaxis

     OS() --> cNombreSO

 Devuelve

     OS() devuelve el nombre del sistema operativo en forma de cadena de
     carácteres.

 Descripción

     OS() es una función de entorno que devuelve el nombre del sistema
     operativo que se ejecuta en la estación de trabajo actual. El valor se
     devuelve como el nombre del sistema operativo seguido del número de
     versi.n.

 Ejemplos

                        Este ejemplo utiliza OS() para indicar el sistema
           operativo que se ejecuta en la estación de trabajo actual:

        ? OS()                  // Resultado: DOS 3.3

 Ficheros:  El fichero de biblioteca asociado es CLIPPER.LIB.

OUTERR()
 Escribe una lista de valores en el dispositivo de errores estándar
------------------------------------------------------------------------------
 Sintaxis

     OUTERR(<lista exp>) --> NIL

 Argumentos

     <lista exp> es una lista de valores que aparecen en pantalla. Puede
     estar formada por cualquier combinación de tipos de datos, incluyendo el
     tipo memo.

 Devuelve

     OUTERR() siempre devuelve NIL.

 Descripción

     OUTERR() es id.ntica a OUTSTD(), excepto en que envía la salida al
     dispositivo de error estándar, en vez de al dispositivo de salida
     estándar. La salida envíada al dispositivo de error estándar evita los
     dispositivos de consola y de salida de CA-Clipper, as. como cualquier
     redirecci.n del DOS. Normalmente se utiliza para registrar mensajes de
     error de forma que no interfieran con la salida en la pantalla o
     impresora estándar.

 Ejemplos

     .  Este ejemplo muestra en pantalla un mensaje de error junto con
        la fecha y hora de su producci.n:

        OUTERR("Fallo de bloqueo del fichero", DATE(), TIME())

 Ficheros:  El fichero de biblioteca asociado es CLIPPER.LIB.

OUTSTD()
 Escribe una lista de valores en el dispositivo de salida estándar
------------------------------------------------------------------------------
 Sintaxis

     OUTSTD(<lista exp>) --> NIL

 Argumentos

     <lista exp> es una lista de valores que aparecen en pantalla. Puede
     estar formada por cualquier combinación de tipos de datos, incluyendo el
     tipo memo.

 Devuelve

     OUTSTD() siempre devuelve NIL.

 Descripción

     OUTSTD() es una función simple de salida similar a QOUT(), excepto en
     que escribe en el dispositivo STDOUT (en vez de en la consola de CA-
     Clipper). Los programas con requisitos de salida muy sencillos (es
     decir, sin entrada o salida de pantalla completa) pueden utilizarse con
     esta función para evitar recargar los subsistemas de salida de
     terminales. El fichero de cabecera Simplio.ch redefine los mandatos ? y
     ?? para utilizar la función OUTSTD().

     Como OUTSTD() envía su salida al dispositivo de salida estándar. La
     salida puede redirigirse mediante los s.mbolos de redirecci.n del DOS
     (>, |), lo que permite redirigir la salida de un programa de CA-Clipper
     a un fichero o un encadenamiento de mandatos. Si desea más información
     sobre esta función del sistema operativo, consulte su documentaci.n del
     MS-DOS.

 Ejemplos

     .  Este ejemplo utiliza OUTSTD() para mostrar en pantalla una
        lista de expresiónes:

     OUTSTD(Nombre, PADR(RTRIM(Ciudad) + "," + ;

              Provincia, 20), CodPost)

     .  Este ejemplo redirige la salida de un programa de CA-Clipper a
        un nuevo fichero mediante el operador de redirecci.n del DOS (>):

        C>MYPROG > FILE.TXT

 Ficheros:  La biblioteca asociada es CLIPPER.LIB,
            el fichero de cabecera es Simplio.ch.

PAD()
 Llena valores de carácteres, fechas y numéricos con carácteres de relleno
------------------------------------------------------------------------------
 Sintaxis


     PADL(<exp>, <nLongitud>, [<cCarRelleno>]) --> cCadenaRellena
     PADC(<exp>, <nLongitud>, [<cCarRelleno>]) --> cCadenaRellena
     PADR(<exp>, <nLongitud>, [<cCarRelleno>]) --> cCadenaRellena

 Argumentos

     <exp> es el valor de carácteres, numérico o de fechas que se va a
     rellenar.

     <nLongitud> es la longitud de la cadena de carácteres que se va a
     devolver.

     <cCarRelleno> es el carácter con el que se va a rellenar <exp>. Si
     no se especifica, el valor por defecto es carácteres de espacio.

 Devuelve

     PADC(), PADL() y PADR() devuelven como resultado una cadena formada por
     <exp> y rellenada con <cCarRelleno> hasta una longitud total de
     <nLongitud>.

 Descripción

     PADC(), PADL() y PADR() son funciónes que rellenan valores de
     carácteres, fecha o numéricos con un carácter de relleno determinado
     creando una nueva cadena de carácteres con una longitud especificada.
     PADC() centra <exp> dentro de <nLongitud>, a.adiendo carácteres de
     relleno en los extremos izquierdo y derecho; PADL() a.ade los carácteres
     de relleno a la izquierda y PADR() los a.ade a la derecha. Si la
     longitud de <exp> excede <nLongitud>, todas las funciónes PAD() truncan
     cCadenaRellena en <nLongitud>.

     PADC(), PADL() y PADR() muestran en pantalla cadenas de longitud
     variable dentro de un .rea de longitud fija. Pueden utilizarse, por
     ejemplo, para asegurar una alíneaci.n determinada al utilizar mandatos
     ?? consecutivos. Otra aplicación es para mostrar texto en un .rea de
     pantalla de anchura fija y asegurarse de que el texto anterior se
     sobreescriba completamente.

     PADC(), PADL() y PADR() son las funciónes inversas de ALLTRIM(), RTRIM()
     y LTRIM(), que eliminan los espacios iniciales y finales en blanco de
     las cadenas de carácteres.

 Ejemplos

     .  Este ejemplo utiliza PADR() para dar formato a la
        visualización de un número de registro en una línea de estado,
        rellenando el espacio asignado:

        IF EOF()
           @ 23, 45 PADR("EOF/" + LTRIM(STR(LASTREC())), 20)
        ELSEIF BOF()
           @ 23, 45 PADR("BOF/" + LTRIM(STR(LASTREC())), 20)
        ELSE
           @ 23, 45 SAY PADR("Registro " + LTRIM(STR(RECNO()) ;
                 + "/" + LTRIM(STR(LASTREC())), 20)
        ENDIF

 Ficheros:  La biblioteca asociada es EXTEND.LIB.

PCOL()
 Devuelve la columna actual del cabezal de la impresora
------------------------------------------------------------------------------
 Sintaxis

     PCOL() --> nColumna

 Devuelve

     PCOL() devuelve un valor numérico entero que representa la posición de
     la .ltima columna impresa m.s uno. La posición de columna inicial es
     cero.

 Descripción

     PCOL() es una función que informa de la posición de columna del cabezal
     de la impresora después de la .ltima operación. PCOL() sólo se actualiza
     si SET DEVICE TO PRINTER o SET PRINTER ON están activados. PCOL() es
     similar a COL(), excepto en se aplica a la impresora en vez de a la
     pantalla. PCOL() se actualiza de las formas siguientes:

     .  Al arrancar la aplicación, PCOL() se pone a cero

     .  Al ejecutar un EJECT, PCOL() se pone a cero

     .  Cualquier operación.de impresión hace que PCOL() tome el valor
        de la posición de la .ltima columna impresa m.s uno

     .  La función SETPRC() permite establecer PCOL() en la posición
        de columna que se especifique

     PCOL() se utiliza normalmente con PROW() e imprime un valor relativo al
     último valor impreso en la misma línea. Esto facilita la alíneaci.n de
     columnas durante la impresi.n de un informe de columnas. Para imprimir
     un valor en la siguiente columna puede especificarse su posición como
     PCOL() + <desplazamiento columna>. PCOL() sólo puede alínear
     correctamente los valores en columnas cuando tienen una anchura fija.
     Para asegurarse de que los valores tengan una anchura fija, d. formato a
     la salida mediante la función TRANSFORM(), la cláusula PICTURE del
     mandato @...SAY o cualquiera de las funciónes PAD().

 Notas

     .  C.digos de control de impresora: Al envíar códigos de
        control a la impresora, PCOL() deja de estar sincronizada con la
        posición del cabezal de la impresora. Aunque los códigos de control
        no se imprimen, la discrepancia ocurre porque CA-Clipper cuenta todos
        los carácteres envíados a la impresora, independientemente de la
        forma en que .sta los trate. Para evitar la discrepancia, guarde los
        valores actuales de PROW() y PCOL(), env.e los códigos de control y
        utilice SETPRC() para restablecer los valores originales de PROW() y
        PCOL().

     .  SET MARGIN: PCOL() no puede utilizarse de manera fiable en
        una sentencia SET MARGIN para imprimir con un mandato @...SAY. Al
        imprimir con @...SAY, el valor actual de MARGIN se a.ade siempre a la
        posición de columna especificada antes de envíar la salida a la
        impresora. Esto hace que el valor MARGIN se sume al de PCOL() cada
        vez que se invoca el mandato @...SAY en una misma línea de impresión.

 Ejemplos

     .  En este ejemplo, PCOL() crea un informe sencillo que imprime
        una lista de nombres, direcciones y números telef.nicos de clientes:

        LOCAL nLinea := 99, nPagina := 1
        USE Cliente INDEX NombreCli NEW
        SET DEVICE TO PRINTER
        DO WHILE !EOF()
           IF nLinea > 55
              PaginaSup(nPagina)
              nLinea := 1
              nPagina++
           ENDIF
           @ nLinea, 10 SAY NombreCli
           @ nLinea, PCOL() + 2;
              SAY RTRIM(Ciudad) + ", " + RTRIM(Provincia) + CodigoPost;
                    PICTURE REPLICATE("X", 35)
           @ nLinea, PCOL() + 2;
              SAY Telefono;
                    PICTURE "@R (999) 999-9999"
           nLinea++
           SKIP
        ENDDO
        SET DEVICE TO SCREEN
        CLOSE

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.


PCOUNT()
 Determina la posición del último parámetro real pasado
------------------------------------------------------------------------------
 Sintaxis

     PCOUNT() --> nPosúltimoArgumento

 Devuelve

     PCOUNT() devuelve, como valor entero, la posición del último argumento
     pasado. Si no se pasan argumentos, PCOUNT() devuelve cero.

 Descripción

     PCOUNT() informa de la posición del último argumento de la lista de
     argumentos pasados al invocar un procedimiento o función. Esta
     información es útil para determinar si se han dejado argumentos al final
     de la lista de argumentos. El valor devuelto incluye, no obstante, los
     argumentos omitidos en medio de la lista.

     Para determinar si un parámetro no ha recibido un valor, compruebe si su
     valor es NIL. Los parámetros omitidos no se inicializan y, por tanto,
     devuelven NIL al acceder a ellos. Otro m.todo es comprobar los
     parámetros con VALTYPE(). Esta función permite determinar si se ha
     pasado un argumento y corregir su tipo simultáneamente. Si no se ha
     pasado el parámetro, puede asign.rsele un valor por defecto.

     Si desea más información sobre la forma de pasar parámetros, consulte el
     capítulo Conceptos Básicos de la guía de Programación y Utilidades.

 Ejemplos

     .  En este ejemplo, una función abre un fichero de base de datos
        y utiliza PCOUNT() para determinar si el procedimiento invocante ha
        pasado el nombre del fichero que se va a abrir. Si no se ha pasado el
        nombre, la función AbrirFichero() lo pregunta:

        FUNCTION AbrirFichero( cFichero )
           IF PCOUNT() = 0
              ACCEPT "Fichero que se va a utilizar: " TO cFichero
           ENDIF
           USE (cFichero)
           RETURN (NETERR())

 Ficheros: La biblioteca asociada es CLIPPER.LIB.

PROCLINE()
 Devuelve el número de la línea del módulo fuente de la activaci.n actual o de
 cualquiera de las anteriores
------------------------------------------------------------------------------
 Sintaxis

     PROCLINE([<nActivaci.n>]) --> nL.neaFuente

 Argumentos

     <nActivaci.n> es un valor numérico que especifica la activaci.n que
     se va a examinar. Cero indica la activaci.n actual, uno la activaci.n
     anterior, etc. Si no se especifica, el valor por defecto es cero.

 Devuelve

     PROCLINE() devuelve, como valor numérico entero, el número de la .ltima
     línea ejecutada en el procedimiento, función o bloque de código que se
     est. ejecutando. Si la opción de compilador /L suprime la información
     del número de línea, PROCLINE() siempre devuelve cero.

 Descripción

     PROCLINE() examina la pila de activaciones de CA-Clipper para determinar
     la .ltima línea ejecutada en el procedimiento, función o bloque de
     código que se est. ejecutando actualmente. La pila de activaci.n es una
     estructura interna que mantiene un registro de cada invocaci.n de
     procedimiento, función o bloque de código. La numeraci.n de las líneas
     comienza al principio del módulo fuente original. Cada línea incluye un
     comentario, una línea en blanco, una directiva de preprocesador y una
     continúa.ión de línea. Una línea de varias sentencias se cuenta como una
     sola línea.

     En la activaci.n actual, PROCLINE() devuelve el número de la línea
     actual. En una activaci.n anterior, PROCLINE() devuelve el número de la
     línea que invoc. al procedimiento o función que, a su vez, invoca a
     PROCLINE().

     Si la activaci.n que se examina es una evaluaci.n de bloque de código,
     PROCLINE() devuelve el número de línea del procedimiento en el que se
     defini. originalmente el bloque de código.

     PROCLINE() se utiliza con PROCNAME() para generarála información de
     depuraci.n.

 Ejemplos

     .  En este ejemplo, PROCLINE() devuelve el número de línea de la
        activaci.n actual, seguido del número de línea de la activaci.n
        anterior:

        // Primera línea del fichero fuente
        Mifunción()
           RETURN

        FUNCTION Mifunción
           ? PROCLINE()      // Resultado: 6 (activaci.n actual)
           ? PROCLINE(1)     // Resultado: 2 (activaci.n anterior)
           RETURN NIL

 Ficheros: La biblioteca asociada es CLIPPER.LIB.


PROCNAME()
 Devuelve el nombre de procedimiento o función actual o de cualquiera de los
 anteriores
------------------------------------------------------------------------------
 Sintaxis

     PROCNAME([<nActivaci.n>]) --> cNombreProcedimiento

 Argumentos

     <nActivaci.n> especifica la activaci.n que se va a examinar. Un
     valor cero indica la activaci.n actual, un valor uno la activaci.n
     anterior, etc. Si no se especifica, el valor por defecto es cero.

 Devuelve

     PROCNAME() devuelve como cadena de carácteres el nombre del
     procedimiento, función o bloque de código actualmente en ejecución.

 Descripción

     PROCNAME() examina la pila de activaci.n de CA-Clipper para determinar
     el nombre del procedimiento, función o bloque de código en ejecución. La
     pila de activaci.n es una estructura interna que mantiene un registro de
     cada invocaci.n de procedimiento, función o bloque de código.

     En la activaci.n actual, PROCNAME() devuelve el nombre del procedimiento
     o función actual. En una activaci.n anterior, PROCNAME() devuelve el
     nombre del procedimiento o función que, a su vez, ha invocado al
     procedimiento actual.

     Si la activaci.n que se examina es una evaluaci.n de bloque de código,
     PROCNAME() devuelve el nombre del procedimiento o función que defini. el
     bloque precedido por una (b). Si la activaci.n que se examina es una
     variable de memoria, PROCNAME() devuelve el nombre precedido de M->.

     PROCNAME() se utiliza con PROCLINE() para generaráinformación de
     depuraci.n.

 Ejemplos

     .  Este ejemplo es una función definida por el usuario que puede
        invocarse durante una fase de depuraci.n del programa para mostrar en
        pantalla la pila de activaci.n con los números de línea:

        FUNCTION ListaPila( cMensaje )
           LOCAL nActivacion := 1
           ? cMensaje
           DO WHILE !(PROCNAME(nActivacion) == "")
              ? "Llamada desde:", PROCNAME(nActivacion),;
                 "(" + LTRIM(STR(PROCLINE(nActivacion))) + ")"
              nActivacion++
           ENDDO
           QUIT
           RETURN NIL

 Ficheros: La biblioteca asociada es CLIPPER.LIB.

PROW()
 Devuelve la fila actual del cabezal de la impresora
------------------------------------------------------------------------------
 Sintaxis

     PROW() --> nFila

 Descripción

     PROW() devuelve un valor numérico entero que representa la posición de
     la .ltima fila impresa. La posición de fila inicial es cero.

 Descripción

     PROW() es una función que informa de la posición de fila del cabezal de
     la impresora después de la .ltima operación. PROW() se actualiza
     solamente si se ha establecido SET DEVICE TO PRINTER o SET PRINTER ON.
     PROW() es similar a ROW(), excepto en que se aplica a la impresora, en
     vez de a la pantalla. PROW() se actualiza de las formas siguientes:

     .  Al arrancar la aplicación, PROW() se pone a cero

     .  Al ejecutar un EJECT, PROW() se pone a cero

     .  Cualquier operación.de impresión hace que PROW() tome el valor
        de la posición de la .ltima fila impresa

     .  La función SETPRC() permite establecer PROW() en la posición
        de fila especificada

     PROW() se utiliza normalmente con PCOL() e imprime un valor relativo al
     último valor impreso en la misma línea. Si la cabeza de impresión se
     coloca en una nueva fila con un código de control, salto de línea
     (CHR(10)) o salto de p.gina (CHR(12)), PROW() no se actualiza y, por
     tanto, no devuelve el valor previsto. Para evitar esta discrepancia,
     desp.es de envíar cualquiera de estos valores a la impresora debe
     utilizar la función SETPRC() para reinicializar PROW() con el valor
     correcto.

 Ejemplos

     .  Este ejemplo utiliza PROW() y SETPRC() para crear un programa
        sencillo de etiquetas que se imprime con @...SAY, en vez de ?:

        USE Cliente INDEX NombreCli NEW
        SET DEVICE TO PRINTER
        SETPRC(2, 0)
        DO WHILE !EOF()
           @ PROW(), 3 SAY NombreCli
           @ PROW() + 1, 3 SAY RTRIM(Ciudad) + ",";
                 + RTRIM(Provincia) + CodigoPost
           @ PROW() + 1, 3 SAY Telefono ;
                 PICTURE "@R (999) 999-9999"
           SETPRC(2, 0)
           SKIP
        ENDDO
        SET DEVICE TO SCREEN
        CLOSE

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.

 QOUT()
 Muestra una lista de expresiónes en la salida estándar
------------------------------------------------------------------------------
 Sintaxis

     QOUT([<lista exp>]) --> NIL
     QQOUT([<lista exp>]) --> NIL

 Argumentos

     <lista exp> es la lista de expresiónes (de cualquier tipo, excepto
     matrices o bloques de código) separadas con comas que se va a mostrar en
     la consola. Si se especifica QOUT() sin argumentos, se envía a la
     consola un retorno de carro/salto de línea. Si se especifica QQOUT() sin
     argumentos, no se muestra nada.

 Devuelve

     QOUT() y QQOUT() devuelven siempre NIL.

 Descripción

     QOUT() y QQOUT() son funciónes de consola. Estas funciónes son las
     primitivas funciónales que crean los mandatos ? y ??, respectivamente.
     Igual que los mandatos ? y ??, muestran en la consola los resultados de
     una o más expresiónes. QOUT() envía algunos retornos de carro/saltos de
     línea antes de mostrar los resultados de <lista exp>. QQOUT() muestra
     los resultados de <lista exp> en la posición actual de ROW() y COL().
     Cuando QOUT() y QQOUT() muestran su salida en la consola, se actualizan
     los valores de las funciónes ROW() y COL(). Si SET PRINTER est.
     activado, los valores que se actualizan son los de PROW() y PCOL(). Si
     se especifica una <lista exp>, tanto QOUT() como QQOUT() insertan un
     espacio entre los resultados de cada expresión.

     QOUT() y QQOUT() pueden utilizarse para mostrar en la consola ciertos
     valores dentro de una expresión. Esto es especialmente .til en bloques
     de código, funciónes de iteraci.n, como AEVAL() y DBEVAL() y en listas
     de sentencias en el formato de salida de una definición de mandato.

 Ejemplos

     .  Este ejemplo utiliza QOUT() con AEVAL() para listar en la
        consola el contenido de una matriz literal:

        LOCAL aElementos := { 1, 2, 3, 4, 5 }
        AEVAL(aElementos, { |elemento| QOUT(elemento) })

 Ficheros:  La biblioteca asociada es CLIPPER.LIB.