Manual Clipper
Manual Clipper
Manual Clipper
CONTENIDO
- Función MouseMenu()
- Función ChoiceMenu()
- La Clase Get()
- La Clase Tbrowse()
- La Función Memoedit().
- Creación de un Editor de Texto.
- Introducción
- Funciones y Comandos
- Limitaciones y Recomendaciones
- Creación de Funciones para la Apertura de Archivos.
- Creación de Funciones para el Bloqueo de Archivos y Registros.
CONCEPTOS BÁSICOS
1.- Dato
Del Latín data que significa ¨hecho¨, entidades independientes sin evaluar. Los datos pueden ser
numéricos o no numéricos. Un conjunto de datos se convierten en información cuando son evaluados y
procesados. Para que este conjunto de datos se procese eficientemente debe estar organizado lógicamente
en archivos.
1.- Archivo
Un conjunto de registros del mismo tipo recibe el nombre de Archivo. Un registro, a su vez es
un conjunto de campos con relación entre sí, y un campo es la unidad más pequeña a la que se puede referir
un dato. La figura siguiente nos muestra de una forma gráfica lo que sería un archivo, un registro y un
campo.
ARCHIVO
Sin Compararlo con DBASE podríamos decir qué sus características son:
- Compilador Profesional.
- Un conjunto de órdenes y Funciones que permiten un mejor y más fácil manejo de la programación.
- Permite programación por capas, no existiendo por lo tanto límite para la dimensión de un programa.
- Permite la definición de funciones por parte del usuario.
- Puede conectarse con rutinas externas de otros lenguajes.
En cuanto a los requerimientos de Hardware Clipper es poco exigente, sin embargo se recomienda
que el equipo tenga Disco Duro y por lo menos un Mega de memoria Ram. Sin embargo no es lo mismo
cuando se desarrollan aplicaciones ya que los requerimientos dependen en sí más de la aplicación que de
Clipper.
De la misma forma en entorno de Software necesario es mínimo, Sistema operativo DOS, y un
config.sys con Buffers no menores a 20 y Files no menores de 40.
PROGRAMACIÓN EN CLIPPER
Una variable de memoria es un pedazo de memoria del computador que recibe un nombre
o identificador y almacena temporalmente un dato. Una variable de memoria puede almacenar números,
cadenas de caracteres, una fecha o un valor lógico.
Los identificadores de variables en Clipper pueden tener hasta diez (10) caracteres y deben
empezar por una letra, no puede tener espacios, no pueden ser palabras de uso propio de Clipper (palabras
reservadas).
NUMÉRICAS: LÓGICAS
store 0 to código store .t. to ciclo
código = 0 ciclo = .t.
TIPO FECHA
Clipper dispone de la función CTOD() para crear e inicializar variables del tipo fecha.
Cuando se desea inicializar mas de una variable del mismo tipo se puede emplear cualquiera de
la siguientes formas:
TIPO ARRAY
Clipper maneja los arreglos como un conjunto de datos o variables con el mismo nombre y su
declaración es como sigue:
DECLARE VAR []
Donde var corresponde al identificador del arreglo y dentro de los corchetes se coloca un número
que le indica a Clipper cuantas variables con ese nombre va a manejar, ejemplo:
Operadores
Numéricos: Cadena
Relacionales Lógicos
> ---------------> Mayor que .and. ---------------> “Y” lógico
< ---------------> Menor que .or. ---------------> “O” lógico
= ---------------> Igual que .not. --------------->
“NO” lógico
== o ++ --------------> Exactamente igual que
<= ---------------> Menor o igual que
>= ---------------> Mayor o igual que
!= o <> ---------------> Diferente
Clipper clasifica las variables de memoria en cuatro clases: PUBLIC, PRIVATE, LOCAL Y STATIC.
- Una variable declarada como PUBLIC es visible para cualquier programa del sistema. Son
denominadas también GLOBALES.
- Una variable declarada como LOCAL solo existe mientras se esté ejecutando el programa en el
que fue declarada. El valor se pierde al retornar al programa principal.
- Las variables declaradas como STATIC funcionan de forma parecida a las locales, solo que su
valor no se pierde y sigue disponible cuando se llama por segunda vez al programa donde se encuentra.
- Cuando una variable se declara PRIVATE, ésta es visible desde todos los programas que llame
el programa en el cual fue declarada. Si una variable no es declarada específicamente automáticamente se
considera de tipo PRIVATE.
if <condición>
instrucción o instrucciones
endif
if <condición>
instrucción o instrucciones
else
instrucción o instrucciones
endif
La condición para efectuar la toma de decisiones debe ser una condición lógica o relacional,
ejemplo:
if conta = 3 if conta = 3
v=4 v=4
endif else
v = v+1
endif
if conta = .t. if conta > conta1
v=4 v=4
endif else
v = v+1
endif
DO CASE
CASE <variable> = <valor1>
instrucción o instrucciones
CASE <variable> = <valor2>
instrucción o instrucciones
CASE <variable> = <valorn>
instrucción o instrucciones
ENDCASE
Clipper trabaja con dos estructuras repetitivas, el DO WHILE y el FOR... NEXT, la sintaxis de
esta son:
DO WHILE <condición>
instrucción o instrucciones
ENDDO
Esta estructura es la principal y la más utilizada para controlar la ejecución global de un programa
en Clipper. Su funcionamiento depende de la evaluación que se hace inicialmente de la condición, si es
verdadera se ejecutan los comandos (instrucciones) que se encuentran entre el DO WHILE y el ENDDO,
al llegar al enddo el programa testea nuevamente la condición, si esta deja de cumplirse el ENDDO entrega
el control del programa a la línea siguiente del ENDDO.
El ciclo DO WHILE puede ser interrumpido usando el comando EXIT, esto es muy usado por
los programadores cuando se desea interrumpir el ciclo al cumplirse un hecho o condición.
De igual forma que el ciclo puede interrumpirse, es posible ordenarle que se repita, para ello
Clipper provee de la instrucción LOOP.
FOR <variable> = <valor inicial> TO <valor final> [STEP <incremento>]
Instrucción o instrucciones
NEXT
El ciclo se ejecuta de la siguiente forma: para la variable comenzando con valor inicial y
variando hasta valor final se ejecutan las instrucciones entre el FOR y el NEXT el cual incrementa el valor
de la variable hasta superar el valor final, momento en el cual el control del programa es transferido a la
línea siguiente al NEXT.
EDICIÓN DE UN PROGRAMA
Clipper trae un editor de programas llamado PE, sin embargo permite que las aplicaciones
puedan ser escritas en procesadores de texto como WordStar o el Edit del Sistema operativo.
Si deseamos usar el PE debemos escribir a nivel del punto indicativo del DOS: PE <nombre>
y pulsar ENTER, una vez dentro del editor podemos transcribir nuestro programa; finalizada la tarea de
transcripción debemos pulsar las teclas Ctrl-W y el editor sale al dos y salva el programa con la
extensión prg.
Si usamos otro editor debemos tener presente al salvarlo agregar la extensión prg, así si usamos
el Edit del DOS podríamos seguir el siguiente procedimiento: Edit <nombre.prg> para estar seguros de
colocar la extensión correcta, ya que sin ella Clipper no lo compila.
Clipper tiene como única exigencia que cada orden debe estar en una línea diferente ya que no
posee un separador de órdenes, por lo tanto al momento de transcribir el programa debemos pulsar enter
después de cada instrucción para separarla de la siguiente.
Cuando se desarrolla una aplicación siempre es conveniente documentarla brevemente para ello
Clipper posee cuatro formas de colocar comentarios en los programas.
* Usado para una sola línea de comentario y puede ir en cualquier parte del programa.
/* .... */ Usado cuando el comentario ocupa más de una línea
&& o // se emplea cuando el comentario se coloca en la misma línea que un comando.
La orden ? es interpretada por Clipper como que debe escribir lo que está entre comillas(si lo
hay) y/o el valor de la variable, saltando a la línea siguiente una vez ejecutada la orden. La orden ??, se
ejecuta de igual forma pero no salta a la otra línea sino que permanece en la misma línea en la que acaba
de escribir.
Es deseable que la entrada y salida de datos no esté en forma desordenada, sino que por lo
contrario muestre un aspecto agradable al usuario, para ello Clipper usa las instrucciones @ SAY, @GET
y PICTURE.
La primera de ellas permite colocar el cursor en cualquier punto de la pantalla, tomando como
base que Clipper divide la pantalla en 25 filas y 80 columnas siendo 0,0 la primera posición y 25,79 la
última; la sintaxis de la orden es:
@ fila,columna SAY “mensaje”
La orden @ Get funciona de forma similar solo que en lugar de escribir un valor o mensaje, se
coloca en la posición indicada para leer un dato.
@ fila,columna GET variable
La orden PICTURE tiene como función dar forma al dato que se va a visualizar, ello se logra
colocando después de orden y entre comilla cualquiera de los siguientes modificadores:
9o# para indicar que visualizará un dígito.
AoN para indicar que se visualizará una letra
Y para indicar que se visualizará un dato lógico
! indica que la visualización de letras se hará en Mayúsculas.
ejemplo:
@ 2,4 say “Nombre del Usuario” get Nombre picture “!x”
@ 2,4 say “Nombre del Usuario” Nombre picture “!x”
Si Ud. posee Clipper instalado en su computador por medio de una versión instaladora solo tiene
que escribir desde el punto indicativo del DOS la siguiente orden:
cl <nombrearch> <enter>
Si no tiene a Clipper instalado de esa forma debe indicarle las vías de acceso, bien sea a través de
un archivo bach o editando nuevamente el autoexec.bat y el config.sys con las instrucciones siguientes:
PATH C:\CLIPPER5\BIN;C:\NG;%PATH%
SET INCLUDE=D:\CLIPPER5\INCLUDE
SET LIB=D:\CLIPPER5\LIB
SET OBJ=D:\CLIPPER5\OBJ
SET PLL=D:\CLIPPER5\PLL
Una vez que Clipper ha creado el archivo objeto entra a funcionar Rtlink.exe que enlaza los
archivos objetos creados por Clipper con las rutinas de librería, construyendo finalmente con la unión de
ellos un archivo ejecutable.
- Realice ahora los ejercicios del numeral 1 del anexo titulado EJERCICIOS.
- Concluido los ejercicios elabore los programas del numeral 2
MANEJO DE ARCHIVOS
CREACION DE UN ARCHIVO:
DBU arch.dbf
Si se especifica el nombre de un archivo, se mostrará una pantalla de visualización BROWSE.
APERTURA DE UN ARCHIVO:
Para abrir el archivo, el comando USE se utiliza seguido del nombre del archivo :
USE nom_arch.
Para cerrar el archivo, use el comando USE sin especificar ningún argumento.
USE
Para cerrar todas las bases de datos abiertas, use el comando:
CLOSE ALL
CLOSE DATABASES
AREAS DE TRABAJO:
Se identifican por las letras de la A hasta la Z o por un número de 1 a 250. Se puede identificar
por el nombre del archivo que está abierto en cada uno. Cualquier archivo abierto sin una selección previa
será abierto en el área A.
EJEMPLO:
SELECT 1
USE cliente
SELECT 2
USE factura
FUNCION SELECT( ):
Retorna el número del área donde el archivo dado como argumento se encuentra abierto.
Su sintaxis es:
SELECT ( alias )
ADICION DE REGISTROS:
Después de la inclusión del registro en blanco, los campos vacíos deben llenarse mediante el
comando REPLACE, el cuál sustituye el contenido de los campos especificados por los resultados o el
valor de las expresiones.
Su sintaxis es:
REPLACE campo WITH expresión [ FOR condición ] [ WHILE condición ]
Con el comando APPEND FROM copia registros del archivo especificado hacia el archivo en
uso.
Su sintaxis es:
APPEND FROM nomb_arch [ FOR WHILE condición ]
GOTO TOP coloca el puntero en el primer registro del archivo y si está indexado en el primer
registro del índice.
GOTO BOTTOM coloca el puntero en el último registro del archivo o en el último registro del
índice.
El comando SKIP mueve el puntero de registros a lo largo del archivo en uso o a lo largo de un
archivo abierto en otra área.
La sintaxis es:
SKIP num_reg
Si se indica un número positivo, el puntero se moverá la cantidad de registros hacia el final del
archivo. Si por el contrario, el número es negativo se moverá en dirección hacia el inicio del archivo.
Para borrar un registro de un archivo .DBF, primero marcarlo para eliminarlo y en seguida
eliminarlo físicamente del archivo.
Si se especifica DELETE sin ningún parámetro, el registro actual se marcará para su eliminación.
FUNCION DELETE( ) :
Retorna el valor lógico .T. si el registro actual está marcado para la eliminación o .F. en caso
contrario.
Su sintaxis es:
DELETE( )
COMANDO SET DELETE:
Determina si los registros marcados para eliminación sean transparentes para comandos que
hagan búsqueda o intenten acceder al archivo.
Su sintaxis es:
SET DELETE ON / OFF
Recupera los registros que habían sido marcados para eliminación por el comando DELETE. Este
comando debe utilizarse con el comando SET DELETE OFF.
Se utiliza el comando PACK para eliminar físicamente los registros que fueron marcados con el
comando DELETE. Después que se ejecuta éste comando, no será posible recuperar los registros
eliminados.
Su sintaxis es:
PACK
COMANDO LOCATE:
Mediante el comando LOCATE se busca entro del conjunto de registros suministrados, el primer
registro que satisfaga una condición especificada.
La sintaxis de ese comando es:
LOCATE FOR condición [ WHILE condición ]
COMANDO CONTINUE:
Después del comando LOCATE se utiliza el comando CONTINUE si existe otro registro que
satisfaga la condición, en caso contrario el puntero se moverá hasta el final del archivo.
Su sintaxis es:
CONTINUE
El comando que genera un índice es el INDEX ON. Para crear cualquier archivo índice, debe
estar abierto el archivo .DBF.
Su sintaxis es:
INDEX ON clave TO nomb_arch
Abre el índice que está relacionado con el archivo en uso. Pueden abrirse hasta 15 índices
simultáneamente.
Su sintaxis es:
SET INDEX TO índices
Si se utiliza este comando sin especificar ningún índice, todos los índices abiertos en el área actual
quedan cerrados.
Los comandos que ejecutan ésta búsqueda son FIND y SEEK. Estos comandos funcionan si existe
un índice abierto.
El comando FIND localiza claves compuestas por números o cadenas literales. Si la clave es una
cadena de caracteres, deberá estar entre comillas sin comenzar con caracteres en blanco.
Su sintaxis es:
FIND cadena
Después de una búsqueda se pueden utilizar funciones como FOUND( ), EOF( ), BOF( )
y RECNO( ) para saber si la búsqueda tuvo éxito.
El comando SEEK busca por el primer registro del archivo indexado que esté en uso o que
posea la clave suministrada.
Al usar el comando SEEK con una clave alfanumérica, ésta puede ser colocada o no entre
comillas. El comando SEEK evalúa una expresión y busca su resultado, lo que permite la composición de
claves basadas en más de un campo.
Su sintaxis es:
SEEK clave
d.-*programa cuarto
#define recuadro chr(213)+chr(205)+chr(184)+chr(179)+;
chr(190)+chr(205)+chr(212)+chr(179)+chr(32)
/* usamos define para declarar la variable recuadro la cual va acompañada de 9 valores, correspondientes
al caracter ascii que da forma a la caja que se usara */
clea
store 0 to edad
store spac(25) to nombre
/* vamos a utilizar ahora las sentencias de decisión */
@ 01,01 to 24,79 double // dibuja un marco en la pantalla
@ 03,03,07,77 box recuadro
@ 04,18 say "instituto universitario de tecnología"
@ 05,25 say "curso de clipper básico"
@ 06,29 say "Fundainformatica"
@ 10,08 say "entre su nombre " get nombre pict "@!"
/* la función VALID permite validar la entrada, se usa acompañando al get */
@ 11,08 say "entre su edad " get edad pict "##" valid(edad>0)
read
@ 13,08 say "hola " + nombre
if (edad<11)
@ 14,08 say "eres un niño "
endif
if edad>11
if edad<17
@ 14,08 say "eres un adolescente "
else
if edad<= 30
@ 14,08 say "eres un joven"
endif
if edad<= 50
@ 14,08 say "eres adulto"
else
@ 14,08 say "estas cruzando la esquina"
endif
endif
endif
wait"" $$ hace una pausa hasta que se pulse una tecla
return
f.-*programa sexto
#define recuadro chr(213)+chr(205)+chr(184)+chr(179)+;
chr(190)+chr(205)+chr(212)+chr(179)+chr(32)
clea
store 0 to edad
store spac(25) to nombre
@ 01,01 to 24,79 double
@ 03,03,07,77 box recuadro
@ 04,18 say "instituto universitario de tecnología"
@ 05,25 say "curso de clipper básico"
@ 06,29 say "Fundainformatica"
do while .t.
store 0 to edad
nombre=spac(25)
@ 14,08 say " "
@ 10,06 say "entre su nombre [/ para salir]" get nombre pict "@k"
read
if nombre $"/"
EXIT
endif
@ 11,50 say "entre su edad " get edad pict "##" valid(edad>0)
@ 13,08 say "hola " + nombre
if (edad<11)
@ 14,08 say "eres un niño "
endif
if edad>11
if edad<17
@ 14,08 say "eres un adolescente "
else
if edad<= 30
@ 14,08 say "eres un joven"
endif
if edad<= 50
@ 14,08 say "eres adulto"
else
@ 14,08 say "estas cruzando la esquina"
endif
endif
endif
enddo
wait""
clea
return
a.- Pida dos números los sume y guarde su contenido en una variable temporal, posteriormente
muestre el valor de la suma. Debe usar en este ejercicio las sentencias CLEA, GET, SAY y PICTURE, así
como los comentarios para documentar el programa.
b.- Elabore un programa que pida dos números enteros y que a través de un menú se escoja una
de las cuatro operaciones básicas o salir del programa. Para ello use los recursos vistos hasta ahora, el menú
debe ser como el del ejemplo:
1.- SUMAR
2.- RESTAR
3.- MULTIPLICAR
4.- DIVIDIR
5.- SALIR
ESCOJA UNA OPCIÓN
MACROS
Recibe el nombre de macro un símbolo que informa al compilador/intérprete para que asuma el
contenido de una variable como si fuera un literal. Son usadas generalmente en rutinas genéricas o
reutilizables.
Una macro puede especificarse de dos formas: utilizando una variable o usando una expresión
que genere (devuelva) una cadena. Por lo tanto los dos principales objetivos de una macro son: la
sustitución de un texto y la compilación de una expresión durante la ejecución del programa.
Una macro se identifica con el operdor & delante del nombre de la variable que debe ser abierta.
Un caso típico de su uso es con las órdenes use y find como se muestra a continuación:
* programa c09.prg
clea
use cliente
con una macro sería:
*programa c09.prg
clea
archi=“cliente”
use &archi
En el ejemplo anterior se ha utilizado una variable para la macro sustitución, otro ejemplo puede
ser:
* programa c09.prg
clea
archi=spac(12)
@ 2,2 say “Nombre del archivo a ser usado....” get archi
read
if .not. file(“&archi”)
@ 23,10 say “archivo no existe”
else
use &archi
endif
Sin embargo las versiones 5.0 en adelante permiten usar expresiones extendidas, en lugar del
operador &, una expresión extendida se caracteriza por estar el nombre de la variable entre paréntesis.
* programa c09.prg
clea
archi=spac(12)
@ 2,2 say “Nombre del archivo a ser usado....” get archi
read
use (archi)
BLOQUE DE CODIGO
“Se entiende como tal a un tipo de dato que contiene una expresión compilada que puede ser
compilada oportunamente.”
Un bloque de código puede estar formado por una o más expresiones que son evaluadas (cuando
haya mas de una) de izquierda a derecha. Las expresiones deben estar separadas por comas, de forma tal
que el bloque de código devuelve el resultado de la última expresión.
De igual forma que una variable caracter es creada al asignarle una cadena de caracteres, o una
variable de tipo fecha es creada con CTOD(), para crear una variable de tipo bloque de código basta con
asignarle a ésta una expresión entre llaves como si se tratara de una matriz, con la diferencia que en este
caso inmediatamente despues de la primera llave se debe colocar dos barras verticales, para diferenciarla
de la matriz.
Ejemplos
a=“Albani”
b=ctod(“01/01/96”)
c:={\\ x>y}
Entre otras cosas un bloque de código tiene como finalidad Crear rutinas genéricas, Crear
opciones Alternativas en programación, Reducir el tamaño del código fuente utilizado. Es por ello que se
puede afirmar que los bloques de código son más importantes que las Funciones Definidas por el Usuario.
Un bloque de código por sí solo no tiene ninguna aplicación; por lo tanto debe ser evaluado, para
ello Clipper provee de la funciones EVAL(), AEVAL(), DBEVAL().
* programa expre.prg
clea
exp=“x > z”
x=15; z= 10;
? &exp ** devolverá .t.
*programa expre.prg
clea
x=15; z= 10;
b:={\\ x > z}
? eval(b) ** devolverá .t.
Del ejemplo anterior se deduce que una macro y un bloque de código son parecidos, sin embargo
la diferencia estriba en su compilación; mientras que una macro se compila cada vez que el programa la
necesita, el bloque de código lo hace una sola vez; demás está decir que los errores de una Macro se detectan
por lo tanto en tiempo de corridad (run-time) mientras que en el bloque de código se hace en tiempo de
compilación. Los ejemplos que siguen dan muestra de lo dicho:
* programa c10.prg
* usando una Macro
exp = “a >< b”
? &esp
Otra diferencia importante es que si la expresión usada hace llamada a una función, tiene que
tener la certeza que el compilador referenciará la función, o utilizar la orden EXTERNAL para que el
enlazador la agregue al ejecutable. En un bloque de código son referenciadas automáticamente por el
compilador y por lo tanto por el enlazador. Los siguientes programas muestran lo que sucede en cada caso:
*programa c11.prg
ac:=“funinc()”
nada=&ac
aca:={\\modfun()}
EVAL (aca)
function modfun
@ 23,10 say “se activo la funcion de modificar”
inkey(3)
return nil
*programa c12.prg
ac:=“funinc()”
nada=&ac
aca:={\\modfun()}
EVAL (aca)
function funinc
@ 23,10 say “se activo la funcion de incluir”
inkey(3)
return nil
El bloque de código presenta como característica la permitibilidad de los parámetros, cosa que
no es posible con las macros. El requerimiento para su uso es la declaración entre las barras en la definición
del bloque, caso de haber más de uno deben ir separados por comas. Ejemplo:
* programa c10par.prg
clea
x1:={\i,g\ i > g}
f:=20; a:=10
? EVAL(x1,f,a) ** devuelve .t.
k:= 5; m:=6
? EVAL(x1,k,m) ** devuelve .f.
Los parámetros son pasados por valor, si se desea pasar un prámetro por referencia debe ir
precedido de @. El siguiente ejemplo muestra el uso de los bloques de código. Los blóques de código son
muy útiles a la hora de procesar matrices o registros de una base de datos.
* PROGRAMA c11.prg
local menu:= { {“Añadir “, “Agrega Registros”, {|| funinc()}},;
{“Modificar “, “Modifica registros”, {|| funmod()}},;
{“F I N “, “Sale de la Aplicación”, {|| fin()} } }
do while .t.
clea
for i = to len(menu)
@ 2,i+15 prompt menu(i,1) message menu(i,2)
next
menu to op
if op = 0
op = 3 * forza la salida de la aplicación
endif
eval (menu[op,3]))
enddo
function funinc
@ 23,10 say “Usted entro en la rutina de añadir”
inkey(3)
return nil
function funmod
@ 23,10 say “Usted entro en la rutina de modificación”
inkey(3)
return nil
function fin
@ 23,10 say “Usted finalizó la aplicación”
inkey(3)
quit
return nil
Clase Una clase es un modelo para la creación de objetos, definiendo las operaciones y
variables asociadas a dicho objeto.
Objeto Es un modelo de una clase. Cada objeto posee uno o más parámetros llamados
variables modelos. Un modelo puede recibir mensajes y ejecutar ciertas operaciones
(métodos). Las variables modelo solo pueden recuperarse o modificar su contenido
mediante el envío de mensajes al objeto. Un objeto se crea mediante la llamada a
una función especial que depende de la clase de objeto a crear.
Selector Es el elemento que accionará el método a ser ejecutado. El nombre del método debe ser
igual al del selector.
Variables Son los atributos o datos que forman un objeto. Cada objeto tiene supropio conjunto
Modelo de variables modelo, con sus valores iniciales. Las varaibles modelo que tienen su
contenido accesible se llaman VME (Variables Modelo Exportables).
Clase GET
Esta clase proporciona objetos para la edición interactiva de campos de archivos de datos y
variables de memoria. Estos objetos proporcionan recursos para el formateo y comprobación de los
datos(mediante los bloques de código).
Un Objeto GET se asocia, en la mayoría de los casos, a una variable (llamada variable GET) que
tiene su contenido modificado mediante la valoración de un bloque de código.
El sistema GET puede dividirse en varios niveles o capas como sigue:
read
getreader
getapplykey()
getdoskey()
getprevalidate()
getpostvalidate()
El siguiente ejemplo nos muestra como trabaja el nivel Read, el cual ha sido trabajado
anteriormente pero sin las opciones color y When
* programa readcol.prg
clea
COD=spac(3);NOMBRE=spac(30); valor3:= valor2:=valor1:=0
@ 10,10 say “Codigo....” get COD pict “999” color “r/w,w/r”
@ 12,10 say “Nombre..” get NOMBRE pict “@!” color “,w/r”
@ 14,10 say “Valor1....” get valor1
@ 16,10 say “Valor2....” get valor2 color “w/b”
@ 18,10 say “Valor3....” get valor3 color “w/w”
read
* programa readwhen.prg
clea
COD=spac(3);NOMBRE=spac(30); valor3:= valor2:=valor1:=0
@ 10,10 say “Codigo....” get COD pict “999” color “r/w,w/r”
when mensget (“solo se pueden introducir números (000 salir)”)
@ 12,10 say “Nombre..” get NOMBRE pict “@!” color “,w/r”
when mensget (“teclee el nombre del empleado”)
@ 14,10 say “Valor1....” get valor1 when mensget (“”)
@ 16,10 say “Valor2....” get valor2 color “w/b”
when mensget “valor1>1000 .and. mensget (“descuentos sobre el valor 1”))
@ 18,10 say “Valor3....” get valor3 color “w/w”
read
function mensget(texto)
@ 23,10 say spac(60)
@ 23,10 texto
return .t.
Esta opción es muy útil ya que nos permite la edición del campo si el resultado de la
comprobación previa, que realiza when, es verdadera, o saltar la edición del mismo si es falsa. Además esta
opción permite el envío de un mensaje a la pantalla cada vez que el campo es editado; activando when
invocando una función que visualiza el mensaje, o combinandola con otra expresión que evalúe la edición
del campo.
NIVEL READMODAL()
Un objeto GET puede ser creado de dos formas: con la orden @..GET o con la función de creación
de la clase GET, que es GETNEW().
Cuando se ejecuta una aplicación Clipper, se crea automáticamente una matríz PUBLICA
llamada GETLIST, sin ningún contenido. Cada vez que una órden get es ejecutada, se añade un elemento
a la matríz.
Ejemplo explicativo:
* programa gets.prg
clea
Nombre=“SanJuan”
salario=0
@ 1,5 say “Introduzca su Nombre....” get Nombre
@ 2,5 say “Introduzca el salario.......”get salario
read
El procesador traduce ester código en:
Del anterior bloque de código se deduce que la función AADD incrementa en un elemento la
matriz GETLIST mediante la función interna _GET_, la cual crea un objeto GET. Se advierte además que
read ha sido sustituido por READMODAL, y que despues de su ejecución la Matriz GETLIST queda vacía.
Otra forma de crear objetos GET es mediante GETNEW() cuya sintaxis es:
GETNEW([<lin>,<col>],[<codeblock>],[<variable.]
[<picture>],[<atrib_color>])
En la versón 5 se soluciona este problema ya que permite la creación de una matriz GETLIST de
tipo LOCAL. Como es sabido todo get se convierte en un elemento de la matriz PUBLICA GETLIST, la
cual se reinicializa despues de un Read; en nuestro caso la matríz PUBLICA se usará para el primer grupo
de gets, y la LOCAL para el segundo, evitando de esta manera que se pierdan los primeros gets.
* programa ejemplo.prg
clea
set key -1 to calculo
cod=spac(3)
Nom=spac(20)
desc:=valor:=0
@ 1,1 say “codigo.......” get cod
@ 2,1 say “nombre.....” get nom
@ 3,1 say “valor.........” get valor pict “@E 999,999.99”;
valid if(valor=0 calculo(@valor),.t.)
@ 4,1 say “descuento..”get desc pict “99”
read
function calculo(varia)
local GETLIST:={}, v1:= v2:= v3:= v4:= v5:=0
pantcalc:=saveScreeen(1,50,7,61)
@ 1,50 to 7,61
@ 2,51 get v1 pict “@E 999,999.99”
@ 2,51 get v2 pict “@E 999,999.99”
@ 2,51 get v3 pict “@E 999,999.99”
@ 2,51 get v4 pict “@E 999,999.99”
@ 2,51 get v5 pict “@E 999,999.99”
read
varia=v1+v2+v3+v4+v5
keyboard varia
restorescreen (1,50,7,61, pantclac)
return .t.
Para modificar el valor de un get activo es necesario crear un objeto correspondiente al get actual
mediante la función GETACTIVE(), así:
oG:=GETACTIVE()
Para saber el nombre de la variable correspondiente a ese GET debe usar la varaible modelo
NAME, como se muestra:
? oG:NAME
Si lo que desea saber es el contenido, entonces usará:
? oG:VARGET()
Si está editando GETS contenidos en GETLIST, puede usar directamente el elemento de la matríz
para acceder a sus variables modelo, así:
? GETLIST[3]:NAME
LA CLASE TBROWSE
La clase TBROWSE facilita la manipulación de tablas al estilo de DBEDIT(), pero con más
posibilidades ya que cuenta con objetos.
Permite la presentación de datos en forma tabular, la edición de los mismos, la visualización y
selección de datos diferenciados. La recuperación de los datos es efectuada mediante la evaluación de los
bloques de código. Cada objeto TBROWSE depende de los objetos creados por la clase TBCOLUMN.
Para trabajar con el Tbrowse se utilizan dos funciones, una para datos de tableas y otra para datos
diversos: la función TBROWSEDB() y la función TBROWSENEW().
TBROWSEDB(<LinSup>,<ColSup>,<LinInf>,<ColInf>)
TBROWSENEW(<LinSup>,<ColSup>,<LinInf>,<ColInf>)
dentro de la clase Tbrowse estan disponibles las siguientes Variables Modelo Exportables(VME):
Se puede decir que el único requerimiento de Clipper para trabajar en una Red de Área Local
(LAN), es que ésta debe respaldar la llamada de Clipper a la función del DOS ya que Clipper
usa Exclusivamente llamadas al DOS para todas sus operaciones relacionadas con la Red.
Dicho de otra forma una aplicación desarrollada en Clipper corre en cualquier LAN diseñada en
el Standard del DOS.
CARACTERISTICAS
* Modalidad compartida, para permitir el uso a dos o mas usuarios de un mismo archivo.
( SET EXCLUSIVE OFF )
* Modalidad exclusiva, que anula la capacidad de compartir archivos.
( SET EXCLUSIVE ON, USE <NOMARCH> EXCLUSIVE )
* Bloqueo lógico, que evita que dos o mas usuarios actualicen el mismo archivo
simultáneamente. ( FLOCK() )
* Comprobación del bloqueo Lógico de archivos, por medio de dos funciones.
( FLOCK() Y RLOCK() )
* Desbloqueo de archivos, regresando a la modalidad compartida.
SET PRINTER TO
Comando que permite redirigir la impresión hacia la impresora compartida de la red.
FLOCK()
Intenta el bloqueo del archivo en uso, si tiene éxito devuelve el valor lógico verdadero (.T.), de lo
contrario devuelve falso (.F.). Cuando tiene éxito se deshace cualquier bloqueo anterior.
RLOCK()
Bloquea un registro del archivo en uso, si el intento tiene éxito regresa .T. , si no el valor regresado
es .F. . Cuando el bloqueo tiene éxito se deshace cualquier bloqueo anterior.
UNLOCK
Este comando es usado para deshacer el bloqueo de archivos y registros fijados previamente por
funciones de bloqueo.
NETERR()
Devuelve el valor lógico verdadero cuando fracasa una operación de la red, según la tabla
siguiente:
NETNAME()
Devuelve la identificación de la estación de trabajo en curso.
Recuerde que Ud. abrirá los archivos en modalidad compartida, luego el fracaso en la apertura
( use <nomarch> ) es una posibilidad real, por lo tanto es recomendable el uso de NETERR() para detectar
que la apertura de un archivo fué exitosa; a causa de esto no se deben abrir al mismo tiempo los archivos
índices al mismo tiempo, si no que una vez comprobada la apertura exitosa del archivo se debe colocar la
orden SET INDEX, la cual los abre en la misma modalidad en que se abrió el archivo.
El siguiente ejemplo muestra como abrir archivos e índices en un programa para redes:
* programa demo
use <nomarch> shared
if neterr()
@ 06,24 say “Archivo en uso, no puede compartirse”
break
endif
set index to <nomind>
@ 06,15 say “Apertura exitosa”
return
Es oportuno acotar aquí unas reglas sencillas a tener en cuenta en el momento de abrir archivos
para red:
* Si el comando o función escribe (modifica) el archivo la modalidad debe ser exclusiva.
* Si el comando o función lee el archivo la modalidad debe ser compartida.
Así:
APPEND FROM, COPY FILE LABEL FORM .. TO FILE, REPORT FORM ... TO FILE,
RESTORE, TYPE ... TO FILE, UP DATE Y MEMOREAD(), usan los archivos en modo de uso
compartido ( SHARED ).
Al ejemplo anterior se le agrega una función para que intente la apertura de un archivo y continúe
intentandolo por un tiempo límite o hasta que tenga éxito. La función aquí usada es una función del usuario
a la cual se le pasa como argumentos el nombre del archivo, la modalidad de apertura y el número de
segundos que debe reintentar la operación.
ANEXOS
INKEY() : Espera cierto tiempo, en segundos, a que el usuario pulse una tecla. Si no se le dá
el argumento INKEY devuelve el control inmediatamente.
Sintaxis: INKEY(valor)
VAL() : Evalúa una cadena hasta obtener un caracter no numérico o un segundo separador
decimal, devolviendo el valor numérico correspondiente.
Sintaxis: VAL(expresión)
ISUPPER() : Devuelve .T. si el primer caracter de una cadena es una letra mayúscula.
Sintaxis:ISUPPER(cadena)
STUFF() : Es una función muy versátil usada con propósitos tales como: Eliminar caracteres de una cadena,
Reemplazar caracteres de una cadena o Insertar caracteres en la cadena.
Sintaxis: STUFF(cadena,posicióninicial,longitud,cadenanueva)
DURACIÓN: 16 HORAS.
CONTENIDO
- Librerías Pre-encadenadas
- Compilación por Módulos
- Encadenamiento con Archivos ( .LNK )
- Creación de Archivos Overlay ( .OVL )
- Encadenamiento de Librerías Externas.
- Función MouseMenu()
- Función ChoiceMenu()
- La Clase Get()
- La Clase Tbrowse()
- La Función Memoedit().
- Creación de un Editor de Texto.
- Introducción
- Funciones y Comandos
- Limitaciones y Recomendaciones
- Creación de Funciones para la Apertura de Archivos.
- Creación de Funciones para el Bloqueo de Archivos y Registros.
CONCEPTOS BÁSICOS
1.- Dato
Del Latín data que significa ¨hecho¨, entidades independientes sin evaluar. Los datos pueden ser
numéricos o no numéricos. Un conjunto de datos se convierten en información cuando son evaluados y
procesados. Para que este conjunto de datos se procese eficientemente debe estar organizado lógicamente
en archivos.
1.- Archivo
Un conjunto de registros del mismo tipo recibe el nombre de Archivo. Un registro, a su vez es
un conjunto de campos con relación entre sí, y un campo es la unidad más pequeña a la que se puede referir
un dato. La figura siguiente nos muestra de una forma gráfica lo que sería un archivo, un registro y un
campo.
ARCHIVO
Sin Compararlo con DBASE podríamos decir qué sus características son:
- Compilador Profesional.
- Un conjunto de órdenes y Funciones que permiten un mejor y más fácil manejo de la programación.
- Permite programación por capas, no existiendo por lo tanto límite para la dimensión de un programa.
- Permite la definición de funciones por parte del usuario.
- Puede conectarse con rutinas externas de otros lenguajes.
En cuanto a los requerimientos de Hardware Clipper es poco exigente, sin embargo se recomienda
que el equipo tenga Disco Duro y por lo menos un Mega de memoria Ram. Sin embargo no es lo mismo
cuando se desarrollan aplicaciones ya que los requerimientos dependen en sí más de la aplicación que de
Clipper.
De la misma forma en entorno de Software necesario es mínimo, Sistema operativo DOS, y un
config.sys con Buffers no menores a 20 y Files no menores de 40.
PROGRAMACIÓN EN CLIPPER
Una variable de memoria es un pedazo de memoria del computador que recibe un nombre
o identificador y almacena temporalmente un dato. Una variable de memoria puede almacenar números,
cadenas de caracteres, una fecha o un valor lógico.
Los identificadores de variables en Clipper pueden tener hasta diez (10) caracteres y deben
empezar por una letra, no puede tener espacios, no pueden ser palabras de uso propio de Clipper (palabras
reservadas).
NUMÉRICAS: LÓGICAS
store 0 to código store .t. to ciclo
código = 0 ciclo = .t.
TIPO FECHA
Clipper dispone de la función CTOD() para crear e inicializar variables del tipo fecha.
Cuando se desea inicializar mas de una variable del mismo tipo se puede emplear cualquiera de
la siguientes formas:
TIPO ARRAY
Clipper maneja los arreglos como un conjunto de datos o variables con el mismo nombre y su
declaración es como sigue:
DECLARE VAR []
Donde var corresponde al identificador del arreglo y dentro de los corchetes se coloca un número
que le indica a Clipper cuantas variables con ese nombre va a manejar, ejemplo:
Operadores
Relacionales Lógicos
Clipper clasifica las variables de memoria en cuatro clases: PUBLIC, PRIVATE, LOCAL Y STATIC.
- Una variable declarada como PUBLIC es visible para cualquier programa del sistema. Son
denominadas también GLOBALES.
- Una variable declarada como LOCAL solo existe mientras se esté ejecutando el programa en el
que fue declarada. El valor se pierde al retornar al programa principal.
- Las variables declaradas como STATIC funcionan de forma parecida a las locales, solo que su
valor no se pierde y sigue disponible cuando se llama por segunda vez al programa donde se encuentra.
- Cuando una variable se declara PRIVATE, ésta es visible desde todos los programas que llame
el programa en el cual fue declarada. Si una variable no es declarada específicamente automáticamente se
considera de tipo PRIVATE.
if <condición>
instrucción o instrucciones
endif
if <condición>
instrucción o instrucciones
else
instrucción o instrucciones
endif
La condición para efectuar la toma de decisiones debe ser una condición lógica o relacional,
ejemplo:
if conta = 3 if conta = 3
v=4 v=4
endif else
v = v+1
endif
endif
DO CASE
CASE <variable> = <valor1>
instrucción o instrucciones
CASE <variable> = <valor2>
instrucción o instrucciones
CASE <variable> = <valorn>
instrucción o instrucciones
ENDCASE
Clipper trabaja con dos estructuras repetitivas, el DO WHILE y el FOR... NEXT, la sintaxis de
esta son:
DO WHILE <condición>
instrucción o instrucciones
ENDDO
Esta estructura es la principal y la más utilizada para controlar la ejecución global de un programa
en Clipper. Su funcionamiento depende de la evaluación que se hace inicialmente de la condición, si es
verdadera se ejecutan los comandos (instrucciones) que se encuentran entre el DO WHILE y el ENDDO,
al llegar al enddo el programa testea nuevamente la condición, si esta deja de cumplirse el ENDDO entrega
el control del programa a la línea siguiente del ENDDO.
El ciclo DO WHILE puede ser interrumpido usando el comando EXIT, esto es muy usado por
los programadores cuando se desea interrumpir el ciclo al cumplirse un hecho o condición.
De igual forma que el ciclo puede interrumpirse, es posible ordenarle que se repita, para ello
Clipper provee de la instrucción LOOP.
FOR <variable> = <valor inicial> TO <valor final> [STEP <incremento>]
Instrucción o instrucciones
NEXT
El ciclo se ejecuta de la siguiente forma: para la variable comenzando con valor inicial y
variando hasta valor final se ejecutan las instrucciones entre el FOR y el NEXT el cual incrementa el valor
de la variable hasta superar el valor final, momento en el cual el control del programa es transferido a la
línea siguiente al NEXT.
EDICIÓN DE UN PROGRAMA
Clipper trae un editor de programas llamado PE, sin embargo permite que las aplicaciones
puedan ser escritas en procesadores de texto como WordStar o el Edit del Sistema operativo.
Si deseamos usar el PE debemos escribir a nivel del punto indicativo del DOS: PE <nombre>
y pulsar ENTER, una vez dentro del editor podemos transcribir nuestro programa; finalizada la tarea de
transcripción debemos pulsar las teclas Ctrl-W y el editor sale al dos y salva el programa con la
extensión prg.
Si usamos otro editor debemos tener presente al salvarlo agregar la extensión prg, así si usamos
el Edit del DOS podríamos seguir el siguiente procedimiento: Edit <nombre.prg> para estar seguros de
colocar la extensión correcta, ya que sin ella Clipper no lo compila.
Clipper tiene como única exigencia que cada orden debe estar en una línea diferente ya que no
posee un separador de órdenes, por lo tanto al momento de transcribir el programa debemos pulsar enter
después de cada instrucción para separarla de la siguiente.
Cuando se desarrolla una aplicación siempre es conveniente documentarla brevemente para ello
Clipper posee cuatro formas de colocar comentarios en los programas.
* Usado para una sola línea de comentario y puede ir en cualquier parte del programa.
/* .... */ Usado cuando el comentario ocupa más de una línea
&& o // se emplea cuando el comentario se coloca en la misma línea que un comando.
La orden ? es interpretada por Clipper como que debe escribir lo que está entre comillas(si lo
hay) y/o el valor de la variable, saltando a la línea siguiente una vez ejecutada la orden. La orden ??, se
ejecuta de igual forma pero no salta a la otra línea sino que permanece en la misma línea en la que acaba
de escribir.
Es deseable que la entrada y salida de datos no esté en forma desordenada, sino que por lo
contrario muestre un aspecto agradable al usuario, para ello Clipper usa las instrucciones @ SAY, @GET
y PICTURE.
La primera de ellas permite colocar el cursor en cualquier punto de la pantalla, tomando como
base que Clipper divide la pantalla en 25 filas y 80 columnas siendo 0,0 la primera posición y 25,79 la
última; la sintaxis de la orden es:
@ fila,columna SAY “mensaje”
La orden @ Get funciona de forma similar solo que en lugar de escribir un valor o mensaje, se
coloca en la posición indicada para leer un dato.
@ fila,columna GET variable
La orden PICTURE tiene como función dar forma al dato que se va a visualizar, ello se logra
colocando después de orden y entre comilla cualquiera de los siguientes modificadores:
9o# para indicar que visualizará un dígito.
AoN para indicar que se visualizará una letra
Y para indicar que se visualizará un dato lógico
! indica que la visualización de letras se hará en Mayúsculas.
ejemplo:
@ 2,4 say “Nombre del Usuario” get Nombre picture “!x”
@ 2,4 say “Nombre del Usuario” Nombre picture “!x”
Si Ud. posee Clipper instalado en su computador por medio de una versión instaladora solo tiene
que escribir desde el punto indicativo del DOS la siguiente orden:
cl <nombrearch> <enter>
Si no tiene a Clipper instalado de esa forma debe indicarle las vías de acceso, bien sea a través de
un archivo bach o editando nuevamente el autoexec.bat y el config.sys con las instrucciones siguientes:
PATH C:\CLIPPER5\BIN;C:\NG;%PATH%
SET INCLUDE=D:\CLIPPER5\INCLUDE
SET LIB=D:\CLIPPER5\LIB
SET OBJ=D:\CLIPPER5\OBJ
SET PLL=D:\CLIPPER5\PLL
Una vez que Clipper ha creado el archivo objeto entra a funcionar Rtlink.exe que enlaza los
archivos objetos creados por Clipper con las rutinas de librería, construyendo finalmente con la unión de
ellos un archivo ejecutable.
- Realice ahora los ejercicios del numeral 1 del anexo titulado EJERCICIOS.
- Concluido los ejercicios elabore los programas del numeral 2
MANEJO DE ARCHIVOS
CREACION DE UN ARCHIVO:
DBU arch.dbf
Si se especifica el nombre de un archivo, se mostrará una pantalla de visualización BROWSE.
APERTURA DE UN ARCHIVO:
Para abrir el archivo, el comando USE se utiliza seguido del nombre del archivo :
USE nom_arch.
Para cerrar el archivo, use el comando USE sin especificar ningún argumento.
USE
Para cerrar todas las bases de datos abiertas, use el comando:
CLOSE ALL
CLOSE DATABASES
AREAS DE TRABAJO:
Se identifican por las letras de la A hasta la Z o por un número de 1 a 250. Se puede identificar
por el nombre del archivo que está abierto en cada uno. Cualquier archivo abierto sin una selección previa
será abierto en el área A.
EJEMPLO:
SELECT 1
USE cliente
SELECT 2
USE factura
FUNCION SELECT( ):
Retorna el número del área donde el archivo dado como argumento se encuentra abierto.
Su sintaxis es:
SELECT ( alias )
ADICION DE REGISTROS:
Después de la inclusión del registro en blanco, los campos vacíos deben llenarse mediante el
comando REPLACE, el cuál sustituye el contenido de los campos especificados por los resultados o el
valor de las expresiones.
Su sintaxis es:
REPLACE campo WITH expresión [ FOR condición ] [ WHILE condición ]
Con el comando APPEND FROM copia registros del archivo especificado hacia el archivo en
uso.
Su sintaxis es:
APPEND FROM nomb_arch [ FOR WHILE condición ]
MOVIMIENTO DENTRO DEL ARCHIVO:
GOTO TOP coloca el puntero en el primer registro del archivo y si está indexado en el primer
registro del índice.
GOTO BOTTOM coloca el puntero en el último registro del archivo o en el último registro del
índice.
El comando SKIP mueve el puntero de registros a lo largo del archivo en uso o a lo largo de un
archivo abierto en otra área.
La sintaxis es:
SKIP num_reg
Si se indica un número positivo, el puntero se moverá la cantidad de registros hacia el final del
archivo. Si por el contrario, el número es negativo se moverá en dirección hacia el inicio del archivo.
Para borrar un registro de un archivo .DBF, primero marcarlo para eliminarlo y en seguida
eliminarlo físicamente del archivo.
Si se especifica DELETE sin ningún parámetro, el registro actual se marcará para su eliminación.
FUNCION DELETE( ) :
Retorna el valor lógico .T. si el registro actual está marcado para la eliminación o .F. en caso
contrario.
Su sintaxis es:
DELETE( )
COMANDO SET DELETE:
Determina si los registros marcados para eliminación sean transparentes para comandos que
hagan búsqueda o intenten acceder al archivo.
Su sintaxis es:
SET DELETE ON / OFF
Recupera los registros que habían sido marcados para eliminación por el comando DELETE. Este
comando debe utilizarse con el comando SET DELETE OFF.
COMANDO LOCATE:
Mediante el comando LOCATE se busca entro del conjunto de registros suministrados, el primer
registro que satisfaga una condición especificada.
La sintaxis de ese comando es:
LOCATE FOR condición [ WHILE condición ]
COMANDO CONTINUE:
Después del comando LOCATE se utiliza el comando CONTINUE si existe otro registro que
satisfaga la condición, en caso contrario el puntero se moverá hasta el final del archivo.
Su sintaxis es:
CONTINUE
El comando que genera un índice es el INDEX ON. Para crear cualquier archivo índice, debe
estar abierto el archivo .DBF.
Su sintaxis es:
INDEX ON clave TO nomb_arch
Abre el índice que está relacionado con el archivo en uso. Pueden abrirse hasta 15 índices
simultáneamente.
Su sintaxis es:
SET INDEX TO índices
Si se utiliza este comando sin especificar ningún índice, todos los índices abiertos en el área actual
quedan cerrados.
Los comandos que ejecutan ésta búsqueda son FIND y SEEK. Estos comandos funcionan si existe
un índice abierto.
El comando FIND localiza claves compuestas por números o cadenas literales. Si la clave es una
cadena de caracteres, deberá estar entre comillas sin comenzar con caracteres en blanco.
Su sintaxis es:
FIND cadena
Después de una búsqueda se pueden utilizar funciones como FOUND( ), EOF( ), BOF( )
y RECNO( ) para saber si la búsqueda tuvo éxito.
El comando SEEK busca por el primer registro del archivo indexado que esté en uso o que
posea la clave suministrada.
Al usar el comando SEEK con una clave alfanumérica, ésta puede ser colocada o no entre
comillas. El comando SEEK evalúa una expresión y busca su resultado, lo que permite la composición de
claves basadas en más de un campo.
Su sintaxis es:
SEEK clave
EJERCICIOS
1.- A continuación encontrará un grupo de programas, edite con PE, salve, compile y pruebe cada uno de
ellos según lo expuesto anteriormente.
d.-*programa cuarto
#define recuadro chr(213)+chr(205)+chr(184)+chr(179)+;
chr(190)+chr(205)+chr(212)+chr(179)+chr(32)
/* usamos define para declarar la variable recuadro la cual va acompañada de 9 valores, correspondientes
al caracter ascii que da forma a la caja que se usara */
clea
store 0 to edad
store spac(25) to nombre
/* vamos a utilizar ahora las sentencias de decisión */
@ 01,01 to 24,79 double // dibuja un marco en la pantalla
@ 03,03,07,77 box recuadro
@ 04,18 say "instituto universitario de tecnología"
@ 05,25 say "curso de clipper básico"
@ 06,29 say "Fundainformatica"
@ 10,08 say "entre su nombre " get nombre pict "@!"
/* la función VALID permite validar la entrada, se usa acompañando al get */
@ 11,08 say "entre su edad " get edad pict "##" valid(edad>0)
read
@ 13,08 say "hola " + nombre
if (edad<11)
@ 14,08 say "eres un niño "
endif
if edad>11
if edad<17
@ 14,08 say "eres un adolescente "
else
if edad<= 30
@ 14,08 say "eres un joven"
endif
if edad<= 50
@ 14,08 say "eres adulto"
else
@ 14,08 say "estas cruzando la esquina"
endif
endif
endif
wait"" $$ hace una pausa hasta que se pulse una tecla
return
f.-*programa sexto
#define recuadro chr(213)+chr(205)+chr(184)+chr(179)+;
chr(190)+chr(205)+chr(212)+chr(179)+chr(32)
clea
store 0 to edad
store spac(25) to nombre
@ 01,01 to 24,79 double
@ 03,03,07,77 box recuadro
@ 04,18 say "instituto universitario de tecnología"
@ 05,25 say "curso de clipper básico"
@ 06,29 say "Fundainformatica"
do while .t.
store 0 to edad
nombre=spac(25)
@ 14,08 say " "
@ 10,06 say "entre su nombre [/ para salir]" get nombre pict "@k"
read
if nombre $"/"
EXIT
endif
@ 11,50 say "entre su edad " get edad pict "##" valid(edad>0)
@ 13,08 say "hola " + nombre
if (edad<11)
@ 14,08 say "eres un niño "
endif
if edad>11
if edad<17
@ 14,08 say "eres un adolescente "
else
if edad<= 30
@ 14,08 say "eres un joven"
endif
if edad<= 50
@ 14,08 say "eres adulto"
else
@ 14,08 say "estas cruzando la esquina"
endif
endif
endif
enddo
wait""
clea
return
a.- Pida dos números los sume y guarde su contenido en una variable temporal, posteriormente
muestre el valor de la suma. Debe usar en este ejercicio las sentencias CLEA, GET, SAY y PICTURE, así
como los comentarios para documentar el programa.
b.- Elabore un programa que pida dos números enteros y que a través de un menú se escoja una
de las cuatro operaciones básicas o salir del programa. Para ello use los recursos vistos hasta ahora, el menú
debe ser como el del ejemplo:
1.- SUMAR
2.- RESTAR
3.- MULTIPLICAR
4.- DIVIDIR
5.- SALIR
ESCOJA UNA OPCIÓN
MACROS
Recibe el nombre de macro un símbolo que informa al compilador/intérprete para que asuma el
contenido de una variable como si fuera un literal. Son usadas generalmente en rutinas genéricas o
reutilizables.
Una macro puede especificarse de dos formas: utilizando una variable o usando una expresión
que genere (devuelva) una cadena. Por lo tanto los dos principales objetivos de una macro son: la
sustitución de un texto y la compilación de una expresión durante la ejecución del programa.
Una macro se identifica con el operdor & delante del nombre de la variable que debe ser abierta.
Un caso típico de su uso es con las órdenes use y find como se muestra a continuación:
* programa c09.prg
clea
use cliente
En el ejemplo anterior se ha utilizado una variable para la macro sustitución, otro ejemplo puede
ser:
* programa c09.prg
clea
archi=spac(12)
@ 2,2 say “Nombre del archivo a ser usado....” get archi
read
if .not. file(“&archi”)
@ 23,10 say “archivo no existe”
else
use &archi
endif
Sin embargo las versiones 5.0 en adelante permiten usar expresiones extendidas, en lugar del
operador &, una expresión extendida se caracteriza por estar el nombre de la variable entre paréntesis.
* programa c09.prg
clea
archi=spac(12)
@ 2,2 say “Nombre del archivo a ser usado....” get archi
read
use (archi)
BLOQUE DE CODIGO
“Se entiende como tal a un tipo de dato que contiene una expresión compilada que puede ser
compilada oportunamente.”
Un bloque de código puede estar formado por una o más expresiones que son evaluadas (cuando
haya mas de una) de izquierda a derecha. Las expresiones deben estar separadas por comas, de forma tal
que el bloque de código devuelve el resultado de la última expresión.
De igual forma que una variable caracter es creada al asignarle una cadena de caracteres, o una
variable de tipo fecha es creada con CTOD(), para crear una variable de tipo bloque de código basta con
asignarle a ésta una expresión entre llaves como si se tratara de una matriz, con la diferencia que en este
caso inmediatamente despues de la primera llave se debe colocar dos barras verticales, para diferenciarla
de la matriz.
Ejemplos
a=“Albani”
b=ctod(“01/01/96”)
c:={\\ x>y}
Entre otras cosas un bloque de código tiene como finalidad Crear rutinas genéricas, Crear
opciones Alternativas en programación, Reducir el tamaño del código fuente utilizado. Es por ello que se
puede afirmar que los bloques de código son más importantes que las Funciones Definidas por el Usuario.
Un bloque de código por sí solo no tiene ninguna aplicación; por lo tanto debe ser evaluado, para
ello Clipper provee de la funciones EVAL(), AEVAL(), DBEVAL().
* programa expre.prg
clea
exp=“x > z”
x=15; z= 10;
? &exp ** devolverá .t.
*programa expre.prg
clea
x=15; z= 10;
b:={\\ x > z}
? eval(b) ** devolverá .t.
Del ejemplo anterior se deduce que una macro y un bloque de código son parecidos, sin embargo
la diferencia estriba en su compilación; mientras que una macro se compila cada vez que el programa la
necesita, el bloque de código lo hace una sola vez; demás está decir que los errores de una Macro se detectan
por lo tanto en tiempo de corridad (run-time) mientras que en el bloque de código se hace en tiempo de
compilación. Los ejemplos que siguen dan muestra de lo dicho:
* programa c10.prg
* usando una Macro
exp = “a >< b”
? &esp
Otra diferencia importante es que si la expresión usada hace llamada a una función, tiene que
tener la certeza que el compilador referenciará la función, o utilizar la orden EXTERNAL para que el
enlazador la agregue al ejecutable. En un bloque de código son referenciadas automáticamente por el
compilador y por lo tanto por el enlazador. Los siguientes programas muestran lo que sucede en cada caso:
*programa c11.prg
ac:=“funinc()”
nada=&ac
aca:={\\modfun()}
EVAL (aca)
function modfun
@ 23,10 say “se activo la funcion de modificar”
inkey(3)
return nil
*programa c12.prg
ac:=“funinc()”
nada=&ac
aca:={\\modfun()}
EVAL (aca)
function funinc
@ 23,10 say “se activo la funcion de incluir”
inkey(3)
return nil
El bloque de código presenta como característica la permitibilidad de los parámetros, cosa que
no es posible con las macros. El requerimiento para su uso es la declaración entre las barras en la definición
del bloque, caso de haber más de uno deben ir separados por comas. Ejemplo:
* programa c10par.prg
clea
x1:={\i,g\ i > g}
f:=20; a:=10
? EVAL(x1,f,a) ** devuelve .t.
k:= 5; m:=6
? EVAL(x1,k,m) ** devuelve .f.
Los parámetros son pasados por valor, si se desea pasar un prámetro por referencia debe ir
precedido de @. El siguiente ejemplo muestra el uso de los bloques de código. Los blóques de código son
muy útiles a la hora de procesar matrices o registros de una base de datos.
* PROGRAMA c11.prg
local menu:= { {“Añadir “, “Agrega Registros”, {|| funinc()}},;
{“Modificar “, “Modifica registros”, {|| funmod()}},;
{“F I N “, “Sale de la Aplicación”, {|| fin()} } }
do while .t.
clea
for i = to len(menu)
@ 2,i+15 prompt menu(i,1) message menu(i,2)
next
menu to op
if op = 0
op = 3 * forza la salida de la aplicación
endif
eval (menu[op,3]))
enddo
function funinc
@ 23,10 say “Usted entro en la rutina de añadir”
inkey(3)
return nil
function funmod
@ 23,10 say “Usted entro en la rutina de modificación”
inkey(3)
return nil
function fin
@ 23,10 say “Usted finalizó la aplicación”
inkey(3)
quit
return nil
Clase Una clase es un modelo para la creación de objetos, definiendo las operaciones y
variables asociadas a dicho objeto.
Objeto Es un modelo de una clase. Cada objeto posee uno o más parámetros llamados
variables modelos. Un modelo puede recibir mensajes y ejecutar ciertas operaciones
(métodos). Las variables modelo solo pueden recuperarse o modificar su contenido
mediante el envío de mensajes al objeto. Un objeto se crea mediante la llamada a
una función especial que depende de la clase de objeto a crear.
Selector Es el elemento que accionará el método a ser ejecutado. El nombre del método debe ser
igual al del selector.
Variables Son los atributos o datos que forman un objeto. Cada objeto tiene supropio conjunto
Modelo de variables modelo, con sus valores iniciales. Las varaibles modelo que tienen su
contenido accesible se llaman VME (Variables Modelo Exportables).
Clase GET
Esta clase proporciona objetos para la edición interactiva de campos de archivos de datos y
variables de memoria. Estos objetos proporcionan recursos para el formateo y comprobación de los
datos(mediante los bloques de código).
Un Objeto GET se asocia, en la mayoría de los casos, a una variable (llamada variable GET) que
tiene su contenido modificado mediante la valoración de un bloque de código.
El sistema GET puede dividirse en varios niveles o capas como sigue:
read
getreader
getapplykey()
getdoskey()
getprevalidate()
getpostvalidate()
El siguiente ejemplo nos muestra como trabaja el nivel Read, el cual ha sido trabajado
anteriormente pero sin las opciones color y When
* programa readcol.prg
clea
COD=spac(3);NOMBRE=spac(30); valor3:= valor2:=valor1:=0
@ 10,10 say “Codigo....” get COD pict “999” color “r/w,w/r”
@ 12,10 say “Nombre..” get NOMBRE pict “@!” color “,w/r”
@ 14,10 say “Valor1....” get valor1
@ 16,10 say “Valor2....” get valor2 color “w/b”
@ 18,10 say “Valor3....” get valor3 color “w/w”
read
* programa readwhen.prg
clea
COD=spac(3);NOMBRE=spac(30); valor3:= valor2:=valor1:=0
@ 10,10 say “Codigo....” get COD pict “999” color “r/w,w/r”
when mensget (“solo se pueden introducir números (000 salir)”)
@ 12,10 say “Nombre..” get NOMBRE pict “@!” color “,w/r”
when mensget (“teclee el nombre del empleado”)
@ 14,10 say “Valor1....” get valor1 when mensget (“”)
@ 16,10 say “Valor2....” get valor2 color “w/b”
when mensget “valor1>1000 .and. mensget (“descuentos sobre el valor 1”))
@ 18,10 say “Valor3....” get valor3 color “w/w”
read
function mensget(texto)
@ 23,10 say spac(60)
@ 23,10 texto
return .t.
Esta opción es muy útil ya que nos permite la edición del campo si el resultado de la
comprobación previa, que realiza when, es verdadera, o saltar la edición del mismo si es falsa. Además esta
opción permite el envío de un mensaje a la pantalla cada vez que el campo es editado; activando when
invocando una función que visualiza el mensaje, o combinandola con otra expresión que evalúe la edición
del campo.
NIVEL READMODAL()
Un objeto GET puede ser creado de dos formas: con la orden @..GET o con la función de creación
de la clase GET, que es GETNEW().
Cuando se ejecuta una aplicación Clipper, se crea automáticamente una matríz PUBLICA
llamada GETLIST, sin ningún contenido. Cada vez que una órden get es ejecutada, se añade un elemento
a la matríz.
Ejemplo explicativo:
* programa gets.prg
clea
Nombre=“SanJuan”
salario=0
@ 1,5 say “Introduzca su Nombre....” get Nombre
@ 2,5 say “Introduzca el salario.......”get salario
read
El procesador traduce ester código en:
Del anterior bloque de código se deduce que la función AADD incrementa en un elemento la
matriz GETLIST mediante la función interna _GET_, la cual crea un objeto GET. Se advierte además que
read ha sido sustituido por READMODAL, y que despues de su ejecución la Matriz GETLIST queda vacía.
Otra forma de crear objetos GET es mediante GETNEW() cuya sintaxis es:
GETNEW([<lin>,<col>],[<codeblock>],[<variable.]
[<picture>],[<atrib_color>])
En la versón 5 se soluciona este problema ya que permite la creación de una matriz GETLIST de
tipo LOCAL. Como es sabido todo get se convierte en un elemento de la matriz PUBLICA GETLIST, la
cual se reinicializa despues de un Read; en nuestro caso la matríz PUBLICA se usará para el primer grupo
de gets, y la LOCAL para el segundo, evitando de esta manera que se pierdan los primeros gets.
* programa ejemplo.prg
clea
set key -1 to calculo
cod=spac(3)
Nom=spac(20)
desc:=valor:=0
@ 1,1 say “codigo.......” get cod
@ 2,1 say “nombre.....” get nom
@ 3,1 say “valor.........” get valor pict “@E 999,999.99”;
valid if(valor=0 calculo(@valor),.t.)
@ 4,1 say “descuento..”get desc pict “99”
read
function calculo(varia)
local GETLIST:={}, v1:= v2:= v3:= v4:= v5:=0
pantcalc:=saveScreeen(1,50,7,61)
@ 1,50 to 7,61
@ 2,51 get v1 pict “@E 999,999.99”
@ 2,51 get v2 pict “@E 999,999.99”
@ 2,51 get v3 pict “@E 999,999.99”
@ 2,51 get v4 pict “@E 999,999.99”
@ 2,51 get v5 pict “@E 999,999.99”
read
varia=v1+v2+v3+v4+v5
keyboard varia
restorescreen (1,50,7,61, pantclac)
return .t.
Para modificar el valor de un get activo es necesario crear un objeto correspondiente al get actual
mediante la función GETACTIVE(), así:
oG:=GETACTIVE()
Para saber el nombre de la variable correspondiente a ese GET debe usar la varaible modelo
NAME, como se muestra:
? oG:NAME
Si está editando GETS contenidos en GETLIST, puede usar directamente el elemento de la matríz
para acceder a sus variables modelo, así:
? GETLIST[3]:NAME
LA CLASE TBROWSE
La clase TBROWSE facilita la manipulación de tablas al estilo de DBEDIT(), pero con más
posibilidades ya que cuenta con objetos.
Permite la presentación de datos en forma tabular, la edición de los mismos, la visualización y
selección de datos diferenciados. La recuperación de los datos es efectuada mediante la evaluación de los
bloques de código. Cada objeto TBROWSE depende de los objetos creados por la clase TBCOLUMN.
Para trabajar con el Tbrowse se utilizan dos funciones, una para datos de tableas y otra para datos
diversos: la función TBROWSEDB() y la función TBROWSENEW().
TBROWSEDB(<LinSup>,<ColSup>,<LinInf>,<ColInf>)
TBROWSENEW(<LinSup>,<ColSup>,<LinInf>,<ColInf>)
dentro de la clase Tbrowse estan disponibles las siguientes Variables Modelo Exportables(VME):
8 . - CLIPPER EN LA RED
Se puede decir que el único requerimiento de Clipper para trabajar en una Red de Área Local
(LAN), es que ésta debe respaldar la llamada de Clipper a la función del DOS ya que Clipper
usa Exclusivamente llamadas al DOS para todas sus operaciones relacionadas con la Red.
Dicho de otra forma una aplicación desarrollada en Clipper corre en cualquier LAN diseñada en
el Standard del DOS.
CARACTERISTICAS
* Modalidad compartida, para permitir el uso a dos o mas usuarios de un mismo archivo.
( SET EXCLUSIVE OFF )
* Modalidad exclusiva, que anula la capacidad de compartir archivos.
( SET EXCLUSIVE ON, USE <NOMARCH> EXCLUSIVE )
* Bloqueo lógico, que evita que dos o mas usuarios actualicen el mismo archivo
simultáneamente. ( FLOCK() )
* Comprobación del bloqueo Lógico de archivos, por medio de dos funciones.
( FLOCK() Y RLOCK() )
* Desbloqueo de archivos, regresando a la modalidad compartida.
SET PRINTER TO
Comando que permite redirigir la impresión hacia la impresora compartida de la red.
FLOCK()
Intenta el bloqueo del archivo en uso, si tiene éxito devuelve el valor lógico verdadero (.T.), de lo
contrario devuelve falso (.F.). Cuando tiene éxito se deshace cualquier bloqueo anterior.
RLOCK()
Bloquea un registro del archivo en uso, si el intento tiene éxito regresa .T. , si no el valor regresado
es .F. . Cuando el bloqueo tiene éxito se deshace cualquier bloqueo anterior.
UNLOCK
Este comando es usado para deshacer el bloqueo de archivos y registros fijados previamente por
funciones de bloqueo.
NETERR()
Devuelve el valor lógico verdadero cuando fracasa una operación de la red, según la tabla
siguiente:
NETNAME()
Devuelve la identificación de la estación de trabajo en curso.
Recuerde que Ud. abrirá los archivos en modalidad compartida, luego el fracaso en la apertura
( use <nomarch> ) es una posibilidad real, por lo tanto es recomendable el uso de NETERR() para detectar
que la apertura de un archivo fué exitosa; a causa de esto no se deben abrir al mismo tiempo los archivos
índices al mismo tiempo, si no que una vez comprobada la apertura exitosa del archivo se debe colocar la
orden SET INDEX, la cual los abre en la misma modalidad en que se abrió el archivo.
El siguiente ejemplo muestra como abrir archivos e índices en un programa para redes:
* programa demo
use <nomarch> shared
if neterr()
@ 06,24 say “Archivo en uso, no puede compartirse”
break
endif
set index to <nomind>
@ 06,15 say “Apertura exitosa”
return
Es oportuno acotar aquí unas reglas sencillas a tener en cuenta en el momento de abrir archivos
para red:
* Si el comando o función escribe (modifica) el archivo la modalidad debe ser exclusiva.
* Si el comando o función lee el archivo la modalidad debe ser compartida.
Así:
APPEND FROM, COPY FILE LABEL FORM .. TO FILE, REPORT FORM ... TO FILE,
RESTORE, TYPE ... TO FILE, UP DATE Y MEMOREAD(), usan los archivos en modo de uso
compartido ( SHARED ).
Al ejemplo anterior se le agrega una función para que intente la apertura de un archivo y continúe
intentandolo por un tiempo límite o hasta que tenga éxito. La función aquí usada es una función del usuario
a la cual se le pasa como argumentos el nombre del archivo, la modalidad de apertura y el número de
segundos que debe reintentar la operación.
ANEXOS
SETCOLOR() : Permite cambiar el color del video. Entrega además los valores actuales de
los colores antes de cambiarlos.
Sintaxis: SETCOLOR(valores)
INKEY() : Espera cierto tiempo, en segundos, a que el usuario pulse una tecla. Si no se le dá
el argumento INKEY devuelve el control inmediatamente.
Sintaxis: INKEY(valor)
VAL() : Evalúa una cadena hasta obtener un caracter no numérico o un segundo separador
decimal, devolviendo el valor numérico correspondiente.
Sintaxis: VAL(expresión)
ISLOWER() : Devuelve .T. si el primer caracter de una cadena es una letra minúscula.
Sintaxis:ISLOWER(cadena)
ISUPPER() : Devuelve .T. si el primer caracter de una cadena es una letra mayúscula.
Sintaxis:ISUPPER(cadena)
STUFF() : Es una función muy versátil usada con propósitos tales como: Eliminar caracteres de una cadena,
Reemplazar caracteres de una cadena o Insertar caracteres en la cadena.
Sintaxis: STUFF(cadena,posicióninicial,longitud,cadenanueva)