Ingeniero en Informática
Programación de teclas
Capitulo 1
Programación de teclas
INKEY(n,exp) = Devuelve el valor ASCII correspondiente a la tecla pulsada. Como es una función es posible asignar el valor de la tecla directamente a una variable o consultar dicho valor con la función LASTKEY()
Devuelve 0 si no se ha presionado ninguna tecla. Si hay varias teclas en el búfer de teclado, se devolverá el valor de la primera tecla introducida en el búfer.
Con n puedes especifica durante cuantos segundos esperará una pulsación. Si no se incluye n, devuelve inmediatamente un valor de una pulsación de tecla. Con n=0 la espera es eterna.
Exp | Acción |
S | Muestra el cursor |
H | Oculta el cursor |
M | Detecta un clic de Mouse (devuelve 151) |
E | Expandir una macro de teclado |
De forma predeterminada, INKEY() no detecta un clic del Mouse.
LASTKEY() = Devuelve el valor ASCII correspondiente a la ultima tecla pulsada. Esta función es normalmente usada después de un INKEY(), WAIT, READ, BROW, WINDOWS, INPUT, ACCEPT etc
READKEY(n) = Devuelve el valor correspondiente a la acción que ejecuta la tecla usada para salir del READ.
Si se omite n, el valor devuelto representa la tecla presionada para salir de alguno de estos comandos de edición: APPEND, BROWSE, CHANGE, CREATE, EDIT, INSERT, MODIFY y READ.
Los valores de retorno están entre 0 a 36 si los datos no se modificaron y de 256 a 292 si los datos se modificaron. Son distintos valores que LASTKEY()
Valores devueltos por READKEY, si se omite n:
Teclas | Sin | Con | Significado |
Retroceso, Flecha izquierda, Ctrl+H y Ctrl+S | 0 | 256 | Atrás 1 caracter |
Flecha derecha, Ctrl+D y Ctrl+L | 1 | 257 | Adelante 1 caracter |
Inicio y Ctrl+A | 2 | 258 | Atrás 1 palabra |
Fin y Ctrl+F | 3 | 259 | Adelante 1 palabra |
Flecha arriba, Mayús+Tab Ctrl+E y Ctrl+K | 4 | 260 | Atrás 1 campo |
Flecha abajo,Tab, Ctrl+Enter Ctrl+X, Ctrl+I y Ctrl+J | 5 | 261 | Adelante 1 campo |
Re Pág y Ctrl+R | 6 | 262 | Atrás 1 pantalla |
Av Pág y Ctrl+C | 7 | 263 | Adelante 1 pantalla |
Ctrl+Flecha Izquierda | 8 | 268 | Lleno |
Ctrl+Q y Esc | 12 | 268 | Salir sin salvar |
Ctrl+Fin y Ctrl+W | 270 | Salir y salvar | |
Enter, Ctrl+Flecha Derecha y Ctrl+M | 15 | 271 | Retorno o lleno |
Retraso | 20 | 276 | Retraso (Timeout) |
Ctrl+Inicio y Ctrl+] | 33 | 289 | Alternar visualización menú |
Ctrl+Re Pág y Ctrl+_ | 34 | 290 | Alejar |
Ctrl+Av Pág y Ctrl+^ | 35 | 291 | Acerca |
F1 | 36 | 292 | Tecla de Ayuda |
Si se incluye cualquier valor en n, se devolverá un valor que indica como se terminó el último comando READ según la siguiente tabla:
Valor | Motivo |
1 | Ninguno de los siguientes |
2 | Se ha emitido CLEAR READ issued |
3 | Se ha elegido el control de terminación |
4 | Se ha cerrado la ventana READ |
5 | La cláusula DEACTIVATE ha devuelto .T. |
6 | READ finalizado por retraso |
Teclas calientes:
En el capitulo anterior hemos visto la programación orientada a eventos de ejecución automática, pero hay que entender que la programación orientada a eventos aprovecha los momentos de pausa dados por el READ, BROWSE, EDIT, CHANGE o MENUS POPUP, para ejecutar porciones de código según el evento que ocurriese en ese momento, el cual puede ser también la presión de una tecla.
Una de los comandos mas importantes en la programación de teclas, para la programación orientada a eventos es:
ON KEY LABEL <tecla> <comando>
Especifica un comando que se ejecutará cuando presione una tecla o una combinación de teclas específica o hagas clic con el Mouse.
Se consigue detectar una tecla pulsada durante un tiempo de espera propio de intrucciones como READ, BROWSE, WINDOWS, MENU, POPUPS, EDIT y CHANGE
Se puede programar varias teclas al mismo tiempo. Para desactivarlas se usa ON KEY sin parámetros.
Si se está ejecutando un programa cuando se presiona la tecla o se hace clic con el Mouse, se ejecutará la línea de programa actual y luego se ejecutará el comando de ON KEY LABEL.
Asignaciones de etiqueta de las teclas especiales.
Rótulo la tecla | <etiqueta de tecla> | Sola | May | Ctrl | Alt |
Flecha izquierda | LEFTARROW | 19 | 19 | 26 | 155 |
Flecha derecha | RIGHTARROW | 4 | 4 | 2 | 157 |
Flecha arriba | UPARROW | 5 | 5 | 141 | 152 |
Flecha abajo | DNARROW | 24 | 24 | 145 | 160 |
Inicio | HOME | 1 | 1 | 29 | 151 |
Fin | END | 6 | 6 | 23 | 159 |
Re Pág | PGUP | 18 | 18 | 31 | 153 |
Av Pág | PGDN | 3 | 51 | 30 | 161 |
Supr | DEL | 7 | 7 | 147 | 163 |
Retroceso | BACKSPACE | 127 | 127 | 127 | 14 |
Espacio | SPACEBAR | ||||
Insertar | INS | 22 | 22 | 146 | 162 |
Tab | TAB | 9 | 15 | 148 | 165 |
Mayús Tab | BACKTAB | 15 | |||
ENTRAR | ENTER | 13 | 13 | 10 | 28 |
F1 a F12 | F1, F2... | 28 | |||
Ctrl+F1 a Ctrl+F12 | Ctrl+F1, Ctrl+F2... | 94 | |||
Mayús+F1 a Mayús+F9 | Shift+F1, Shift+F9... | 84 | |||
Mayús+F11, Mayús+F12 | Shift+F11... | 135 | |||
Alt+F1 a Alt+F12 | Alt+F1, Alt+F2... | 104 | |||
Alt+0 a Alt+9 | Alt+0, Alt+1... | 19 | |||
Alt+A a Alt+Z | Alt+A, Alt+B... | 30 | |||
Alt+Re Pág | Alt+PGUP | 153 | |||
Alt+Av Pág | Alt+PGDN | 161 | |||
Ctrl+Izqda. | Ctrl+LEFTARROW | 26 | |||
Ctrl+Dcha. | Ctrl+RIGHTARROW | 2 | |||
Ctrl+Inicio | Ctrl+HOME | 29 | |||
Ctrl+Fin | Ctrl+END | 23 | |||
Ctrl+Re Pág | Ctrl+PGUP | 31 | |||
Ctrl+Av Pág | Ctrl+PGDN | 30 | |||
Ctrl+A a Ctrl+Z | Ctrl+A, Ctrl+B... | 1 | |||
Escape | ESC | 27 | 27 | 27 | 1 |
Para reasignar el Mouse use las palabra clave: MOUSE, LEFTMOUSE y RIGHTMOUSE.
Macros de teclado:
Se pueden definir desde el menú con una ventana de dialogo. Todas estas macros se pueden guardar en un archivo de extensión .FKY con la orden SAVE MACROS TO <archivo> para recuperarlas después con RESTORE MACROS FROM <archivo>.
Se puede borrar todas las macros con CLEAR MACROS
SET FUNCTION <#>/<tecla> TO <comandos> = Asigna uno o mas comandos a una tecla determinada.
ON(<exp1> [, <exp2>])
Devuelve el comando asignado a ON ERROR, ON ESCAPE, ON KEY, ON KEY LABEL, ON PAGE, ON READERROR o ON SHUTDOWN.
Puede asignarse un comando a cada uno estos comandos para control de eventos:
Cuando se produce un evento que está interceptado por alguno de los comandos de control de eventos anteriores, se ejecuta el comando asignado al comando controlador de eventos. ON() devuelve el comando que ha asignado como comando controlador de eventos. Se devolverá la cadena nula si un comando no ésta asignado actualmente al comando de control de eventos que especifique.
La expresión alfanumérica <exp1> especifica uno de los comandos controladores de eventos anteriores.
ON ERROR <comando> = Si se produce un error, FoxPRO ejecuta el comando. Puedes usar la función ERROR() y PROGRAM() para evaluar el código de error.
ON ESCAPE <comando> = Se ejecuta el comando al pulsar <Esc>, a no ser que este desactivada con SET ESCAPE OFF.
ON KEY [<=#>] <comando> = Se consigue detectar una tecla pulsada durante un READ y ejecutar un comando. Si no se incluye numero de tecla el comando se ejecutara al pulsar cualquier tecla.
ON PAGE AT LINE n <comando> = Ejecuta el comando cuando la salida impresa llega a una línea concreta en un informe o se emita EJECT. El valor de la variable _PLINENO se compara contra n.
ON READERROR <comando> = Especifica un comando a ejecutarse en caso de producirse un error en el ingreso de datos.
Los errores pueden ser:
Fechas incorrectas
Valores fuera de rango
Cuando no se cumple la condición del VALID
ON (Exp1,Exp2) = Devuelve el comando asignado a la expresión consignada como parámetro.
Comando | Exp1 |
ON ERROR | ERROR |
ON ESCAPE | ESCAPE |
ON KEY ON KEY LABEL | KEY |
ON PAGE | PAGE |
ON READERROR | READERROR |
Solo en caso de que Exp1 sea KEY se podrá especificar que tela queremos ver su comando asignado.
? ON(`ERROR')
? ON(`KEY','F7')
KEYBOARD <tecla> [PLAIN] [CLEAR] = Permite enviar al buffer de teclado un tecla, según las etiquetas usadas en ON KEY LABEL.
PLAIN hace ignorar las asignaciones de ON KEY LABEL poniendo la tecla en el buffer de teclado y no el comando.
CLEAR vacía el buffer de teclado antes de poner la tecla especificada.
FKLABEL(argumento) = Da el nombre de la función que corresponde al argumento dado.
FKMAX() = Da el # máximo de teclas de función que pueden programarse
Nota: En el archivo CONFIG.FP se puede configurar teclas antes de iniciar el FoxPRO. Ejemplo F4 = DIR
PUSH y POP
PUSH KEY sitúa todos los parámetros de los comandos ON KEY LABEL actuales en una pila en la memoria, lo que le permite cambiar o añadir las asignaciones y restaurar luego las asignaciones previas con POP KEY.
Si se incluye la cláusula CLEAR, todas las asignaciones de tecla ON KEY LABEL se guardarán en la pila y luego se borrarán las asignaciones de tecla.
Las instrucciones ON KEY LABEL se ponen y se quitan de la memoria en orden FIFO: "la primera que entra, es la primera que sale".
Para impedir llamadas recursivas durante la ejecución de un procedimiento, incluya PUSH KEY CLEAR al principio del procedimiento para desactivar todas las asignaciones y luego al final del procedimiento las puede activar con POP KEY.
Ejemplos:
xTECLA=INKEY(0)
ON KEY =315 DO procedimiento
SET FUNTION F10 TO [CLEAR;USE abc;LIST
ON KEY LABEL leftarrow ? `Flecha izquierda'
ON KEY LABEL F10 DO procedimiento
KEYBOARD `{CTRL+C}'
Ejemplo 1:
En el ejemplo siguiente, los datos del registros actual de CLIENTES.DBF se sitúan en una matriz con SCATTER y luego se muestran para editar. Presione Esc para cancelar los cambios.
CLEAR
USE clientes
SCATTER MEMVAR
@ 1,3 SAY 'Clientes: ' GET m.empresa
@ 3,3 SAY 'Dirección: ' GET m.dirección
@ 5,3 SAY 'Ciudad: ' GET m.ciudad
READ
*--- Si ni se presionó Esc
IF READKEY() # 268
GATHER MEMVAR
ENDIF
RELE WIND mentrar
Ejemplo 2:
En este ejemplo, se muestra una ventana de entrada de datos y se espera durante 20 segundos. Si no se presiona una tecla o no se hace clic con el Mouse, el programa se cancelará.
CLEA
@ 1,3 SAY 'Cliente:' GET mcliente DEFA SPACE(40)
@ 3,3 SAY 'Dirección:' GET mdirecc DEFA SPACE(40)
@ 5,3 SAY 'Ciudad:' GET mciudad DEFA SPACE(24
@ 7,3 SAY 'Estado:' GET mestado DEFA ` `
@ 7,18 SAY 'C_Postal:' GET mcp DEFA SPACE(10)
@ 1,14 SAY ''
xTECLA= INKEY(20, 'M')
IF xTECLA = 0
CLEAR GETS
ELSE
IF xTECLA # 151
KEYBOARD CHR(xTECLA)
ENDIF
READ
ENDIF
CLOSE ALL
Ejemplo 3:
Detección de doble clic del Mouse y teclado
CLEAR
*** Crear y abrir una ventana ***
DEFI WIND W1 FROM 4,4 TO 20,75
ACTI WIND W1
@ 6,16 SAY 'Presione una tecla, haga clic para comenzar o <Esc>'
*** Inicializar la variable de memoria de Inkey ***
x1=0
*** Bucle principal del programa ***
DO WHILE .T.
*** Tomar INKEY(), ocultar cursor, comprobar Mouse ***
x1=INKEY(0.06,'HM')
DO CASE
*** No hay pulsación de tecla ni Mouse ***
CASE x1=0
LOOP
*** Presiono <Esc>, quiere salir ***
CASE x1=27
EXIT
*** Clic sencillo de Mouse ***
CASE x1=151
*** Tomar la posición del puntero del Mouse ***
fila = MROW()
colu = MCOL()
*** Tiempo para doble clic ***
xTIME = SECONDS() + _DBLCLICK
x2=0
*** Comprueba el clic del Mouse ***
*** y el puntero del Mouse dentro de la ventana ***
DO WHILE SECONDS() < xTIME
x2 = INKEY('HM')
*** doble clic en el Mouse ***
IF x2=151 .AND. colu # -1 .AND. fila # -1
CLEAR
@ 7,11 SAY 'Doble clic en '
?? 'fila '+ALLT(STR(fila))+', Columna ' + ALLT(STR(colu)) + ' de esta ventana'
EXIT
ENDIF
ENDDO
*** Clic del Mouse sencillo ***
*** y puntero dentro de la ventana ***
IF x2=0 .AND. colu # -1 .AND. fila # -1
CLEAR
@ 7,11 SAY 'Clic sencillo en '
?? 'fila ' + ALLT(STR(fila)) + ', Columna '
+ ALLT(STR(colu)) + ' de ésta ventana'
ENDIF
*** Puntero de Mouse fuera de la ventana ***
IF colu = -1 .OR. fila = -1
CLEAR
@ 7,17 SAY 'El Mouse se ha presionado fuera de ésta ventana'
LOOP
ENDIF
ENDCASE
*** Carácter del teclado presionado ***
*** Valor CHR() correcto ***
IF x1 # 151 .AND. BETW(x1, 0, 256)
CLEAR
@ 7,18 SAY 'Carácter tecleado:'
?? ' '+CHR(x1)+', código ASCII '+ALLT(STR(x1))
ENDIF
ENDDO
*** Restaurar el entorno original ***
RELE WIND W1
Capitulo 2
Sistemas de menú
Definición:
DEFINE MENU <nombre> [BAR [AT LINE <#>]] [IN SCREEN/WIND <ventana>] [MESSAGE <mensaje>] [KEY <tecla>] [MARK <exp>]
DEFINE PAD <nombre> OF <menu> PROMPT <exp> [AT <f,c>] [SKIP [FOR <exp>]] [MESSAGE <exp>]
DEFINE POPUP <nombre> FROM <fil>,<col> TO <fil>,<col>
PROMPT FILES [LIKE <archivos>] /FIELD <campos>/STRUCTURE
MESSAGE <mensaje>SHADOW COLOR <# / #>
DEFINE BAR <#> OF <popup> PROMPT <opción> [MESS <exp>][KEY <tecla>,<exp>][MARK <exp>][SKIP [FOR <exp>]]
Relación:
ON SELE MENU <menu>/ALL <comando>/[ACTIU POPUP <popup>/ACTIVATE MENU <menu>]
ON [SELE] PAD <nombre> OF <menu> <comando>
ON [SELE] POPUP <nombre>/ALL <comando>
ON [SELE] BAR <exp> OF <popup> [ACTIVATE POPUP <popup>/ACTIVATE MENU <menu>]
Activación:
ACTIVATE MENU <nombre> [NOWAIT [PAD <pad>]]
ACTIVATE POPUP <nombre> [AT <col>,<fil>] [BAR <exp>] [NOWAIT]
Otros:
DEAC MENU/POPUP <nombre>
SHOW MENU/POPUP <lista de nombres>/ALL
HIDE MENU/POPUP <lista de nombres>/ALL
RELE MENU/POPUP <lista de nombres>
CLEA MENUS/POPUPS
Funciones:
MENU()
PAD()
PRMPAD() = Texto del menu
POPUP()
BAR()
CNTBAR() = # barra del emergente
GETBAR() = # de la barra del emergente
GETPAD() = Nombre del bloque
Menu simple de barras:
@ <fil>,<col> PROMPT <opción> [MESS <mensaje>]
MENU TO <variable>
Menu desplegable simple:
@ <fil>,<col> MENU <matriz>,<# Opc>[,<# Opc visibles>] [TITLE <Exp>] [SHADOW]
READ MENU TO <variable>
Menu desplegable multiple:
MENU BAR <matriz>,<# Opc>
MENU <#>,<matriz>,<# Opc>[,<# Opc visibles>]
READ MENU BAR TO <var1>,<var2> [SAVE]
SET MESSAGE TO [<#> [LEFT/CENTER/RIGHT] ]
Donde se pondra el <#> de la linea donde quieres que aparesca el mensaje.
Capitulo 3
Macrosustitucion
&<var> [. <expC>]
La sustitución de macro trata el `contenido' de una variable o elemento de una matriz de tipo caracteres, como una simple cadena de caracteres. Es decir el contenido de la variable sustituye a la referencia de la macro.
Puede usar la sustitución macro en cualquier comando o función que acepte un literal de cadena de caracteres.
Sugerencias:
-
Siempre que sea posible, use la cadena de caracteres en lugar de una macro sustitución ya que esto acelerar la ejecución en forma significativa.
-
En lo posible debes usar () en lugar de &, pero lamentablemente () no siempre funciona.
Si bien los comandos siguientes son aceptables:
xDBF='Clientes'
xTAG=`Empresa'
USE &xDBF ORDER &xTAG
es mejor usar en su lugar:
USE (xDBF) ORDER (xTAG)
La sustitución de macro es útil para sustituir una palabra clave en un comando. En el ejemplo siguiente, el ajuste de TALK se guarda en una variable de memoria para que pueda restaurarse después en el programa. El ajuste original de TALK se restaura con la sustitución de macro.
xTALK= SET('TALK')
SET TALK OFF
*
* Código de programa adicional
*
SET TALK TO &xTALK && Restaura el ajuste original de TALK
<varmem>
Este es el nombre de la variable o elemento de matriz a referenciar en la sustitución de macro.
-
No incluya el prefijo M, que distingue las variables de memoria de los campos. Esto provoca un error de sintaxis.
-
La macro no debe exceder la longitud de instrucción máxima permitida en FoxPRO.
-
Una variable no puede hacer referencia a sí misma de forma recursiva en una sustitución de macro.
Por ejemplo, lo siguiente genera un mensaje de error:
X='&X'
? &X
Las instrucciones de sustitución de macro que aparecen en DO WHILE, FOR y SCAN se evalúan únicamente al inicio del bucle y no se vuelven a evaluar en las iteraciones subsecuentes. No se reconocerán los cambios que se hagan a la variable o elemento de matriz de memoria dentro del bucle.
<ExpC>
El delimitador opcional . (punto) y la expresión alfanumérica <ExpC> se utilizan para añadir caracteres adicionales a una macro. La expresión alfanumérica <expC> añadida a la macro con .<ExpC> puede ser también una macro.
Ejemplos:
xNUM='21'
? 'El numero de serie es &xNUM o algo mas...' ---> si funciona
? 'El numero de serie es (xNUM) o algo mas...' ---> no funciona
xFILE='ventas'
USE &xFILE ---> funciona como USE ventas
o mejor
USE (xFILE)
xi="3"
? '&xi.) Titulo' ---> 3) Titulo
xCOND=[xCODI='21' .AND. xEDAD<30]
LIST OFF FOR &xCOND
SET FILTER TO &xCOND
En este ejemplo se capturan
DIME xNOM(FCOUNT()),xCON(FCOUNT(),RECC())
xNOM=&(FIELD(i)) ---> obtienes el contenido del campo i
FOR i=1 to FCOUNT()
xNOM(i)=FIELD(i) ---> obtienes el nombre del campo
GO TOP
FOR j=1 TO RECC()
xCON=&xNOM ---> obtienes contenido del campo
SKIP
ENDFOR
ENDFOR
Realiza una sustitución de macro.
xSUC=`PIU'
WAIT WIND `Procesando... &xSUC' NOWAIT
Ejemplo 1: En un procedimiento o función de usuario que sea llamado desde varias áreas, para que vuelva al área en que se encontraba.
xAREA=STR(SELE())
****
****
SELE &xAREA
Ejemplo 2: Para introducir una variable carácter como fecha.
xDIA=`08'
xFECHA={&xDIA-02-99}
Ejemplo 3: Para introducir una variable numérica como fecha:
x=7
xMES=TRAN(x,' @L 99')
? CMONT{1-&xMES-99}
--> Julio
Ejemplo 4: Para introducir el mes como parte del nombre de una tabla y activar esta:
xMES=TRAN(MONTH(DATE()),' @L 99')
USE `MAE'+&xMES
Capitulo 4
Imprimiendo en FoxPRO
Hay cuatro maneras de imprimir en FoxPRO:
Usando el parámetro TO PRIN en LIST, DISP, REPO FORM, LABE FORM etc
Activar la impresora con SET PRIN ON y usar: ? | ?? PICT <Exp>. Si no quieres que salga por pantalla pones además SET CONS OFF. No afecta a las salidas @ x,y SAT ni TEXT.
Redirigir salida a impresora con SET DEVI TO PRIN, esto desvía las salidas de @ x,y SAY a la impresora.
Redirigir salida a un archivo con: SET DEVI TO FILE o SET PRIN TO <archivo>|Lpt1|Com1|PRN e imprimir después el archivo.
SET PRINT ON/OFF
Pone en paralelo la impresora con el monitor para las salidas producidas con ?, ??, LIST, DISP, REPO, LABEL etc
No afecta a las salidas de SAY y TEXT
SET PRINT TO <archivo>
Desvía hacia un archivo testo todas las salidas.
SET DEVICE TO PRINT/FILE/SCREEN
Desvía a la impresora las ordenes SAY y TEXT.
No afecta a las salidas de ?, ??, LIST, DISP, REPO ni LABEL.
Nota: Recuerde poner SET DEVI TO SCREEN nuevamente para continuar normalmente. En caso de desvío hacia un archivo hay que cerrar dicho archivo con SET PRINT TO
Capitulo 5
Trabajando con campos MEMO
Para mostrar el contido de un campo MEMO puedes usar el comando ?, el ancho de las lineas lo gobiernas con SET MEMOWIDTH TO <n> donde n por omision es 50, pero puede ser entre 8 y 254.
Si estas en un BROW puedes hacer doble clic o <Ctrl><Inicio> para ver el contenido del campo memo en el regsitro actual.
@ <fila>,<columna> EDIT <nombre> SIZE <alto>,<ancho> [NOMODIFY]
MODI MEMO <nombre> [NOEDIT] [NOWAIT] [SAVE]
Nota: Para salir del campo memo grabando se hace ^W, para salir sin salvar simplemente <Esc>
APPE MEMO <nombre> FROM <archivo> [ADDI]
Copia el contenido del archivo sobre el campo memo
COPY MEMO >nombre> TO <archivo> [ADDI]
Copia el contenido del campo memo sobre el archivo
También se puede guardar una ventana en un campo memo así:
SAVE WIND <ventana> TO MEMO <campo>
REST WIND >ventana> FROM MEMO <campo>
Ejemplo 1:
Si quieres imprimir un campo MEMO:
SET MEMOWIDH TO 75
SET PRINT ON
??? CHR(27)+CHR(78)+CHR(6)
FOR y=1 TO MEML(<nombre>)
? MLINE (<nombre>)
ENDFOR
EJECT
SET PRINT OFF
Ejemplo 2:
Si quieres exportar un campo memo:
xTXT=`C:\Prueba.TXT'
@ 5,5 SAY `nombre del archivo:' GET xTXT
READ
IF LASTKEY()=13
COPY MEMO prueb TO &xTXT
ENDIF
CLEA
Capitulo 6
CONSULTAS SQL (RQBE)
SELECT [ALL | DISTINCT]
[<alias>.]<campo>[AS <titulo>][,[<alias>.]<campo>[AS <titulo]...]
FROM <tabla> [<alias>][,<tabla> [<alias>]...]
[WHERE <unión>
[AND <unión> ...]
[AND | OR <filtro> ...]]]
[GROUP BY <campo>[,<campo> ...]]
[HAVING <filtro>]
[ORDER BY <campo1> [ASC | DESC]
[,<campo2> [ASC | DESC]...]]
[UNION [ALL] <comando SELECT>]
[[INTO <destino>]
| [TO FILE <archivo> [ADDITIVE]
| TO PRINTER
| TO SCREEN]]
[PREFERENCE <nombre>]
[NOCONSOLE]
[PLAIN]
[NOWAIT]
SELECT es un comando SQL de consulta usado para recuperar datos de una o más tablas.
Puede crear una consulta SELECT:
Desde la ventana de Comandos
Desde un programa
En la ventana RQBE
Cuando se tiene SET TALK ON y se ejecuta una consulta, FoxPRO muestra la duración de la consulta en segundos y el número de registros del resultado.
[ALL | DISTINCT]
De forma predeterminada, se muestran todos los campos (ALL) en el resultado de la consulta. Incluya DISTINCT para excluir campos duplicados.
Precaución: Use DISTINCT solo una vez por cláusula SELECT.
[<alias>.]<campo>[AS <titulo>][,[<alias>.]<campo>[AS <titulo] ...]
La cláusula SELECT especifica los campos, constantes y expresiones que se mostrarán en el resultado de la consulta.
<campo> puede ser uno de los siguientes elementos:
El nombre de un campo de una tabla incluida en FROM.
Una constante, en cuyo caso el mismo valor constante ha de aparecer en cada registro del resultado de la consulta.
Una expresión o una función definida por el usuario (FDU).
Cada elemento que especifique con <campo> generará una columna en el resultado de la consulta. Si hay más de una columna con el mismo nombre, asegúrese de diferenciar los nombres incluyendo el alias de la tabla y un punto antes del nombre del campo.
Precaución: A pesar de que se permite el uso de FDUs en la cláusula SELECT, también debe tener en cuenta las restricciones siguientes:
La velocidad de las operaciones realizadas por SELECT puede verse limitada por la velocidad a la que se ejecute la FDU. Las manipulaciones de grandes volúmenes mediante FDU pueden implementarse mejor usando API y FDU escritas en C o en lenguaje ensamblador.
No puede asumir nada sobre la entrada/salida (I/O) de FoxPRO o el entorno de tabla en las FDU invocadas desde SELECT. En general no sabe qué zona de trabajo está seleccionada, el nombre de la tabla o ni siquiera los nombres de los campos que se están procesando. El valor de estas variables depende del punto exacto del proceso de optimización en el que se invoca la FDU.
No es seguro cambiar la I/O de FoxPRO o el entorno de tabla en las FDU invocadas desde SELECT. En general, los resultados son impredecibles.
La única forma fiable de pasar valores a las FDU invocadas desde SELECT es mediante la lista de argumentos que se pasa a la función cuando se invoca.
Si experimenta y descubre una manipulación supuestamente prohibida que funciona correctamente con una versión determinada de FoxPRO, no hay ninguna garantía de que continuará funcionando en las versiones posteriores.
Aparte de estas restricciones, use las FDU con total libertad. Sin embargo, no olvide el efecto de la utilización de SELECT en el rendimiento.
Las funciones de campo siguientes están disponibles para usarse como un elemento de selección, que sea un campo o una expresión que involucre un campo:
-
AVG(<campo>) - Promedio de un campo de datos numéricos.
-
COUNT(<campo>) - Cuenta el número de registros de un campo. COUNT(*) cuenta el número de registros de salida.
-
MIN(<campo>) - Determina el valor más pequeño del campo.
-
MAX(<campo>) - Determina el valor más grande del campo.
-
SUM(<campo>) - Totaliza un campo de datos numéricos.
No puede anidar funciones de campo.
La cláusula opcional AS <campo> especifica la cabecera de una columna en la salida de la consulta. Esto es útil cuando <campo> es una expresión o contiene una función de campo y quiere darle a la columna un nombre con significado. <campo> puede ser una expresión pero no puede contener caracteres (por ejemplo, espacios) que no estén permitidos en nombres de campos de tablas.
FROM <tabla1> [<alias1>][,<tabla2> [<alias2>]...]
La cláusula FROM lista las tablas que contienen los datos a recuperar por la consulta. Si no se encuentra una tabla en el directorio actual de trabajo, aparecerá el cuadro de diálogo Abrir para que pueda especificar la localización del archivo.
Si una tabla de la consulta no está abierta en una zona de trabajo, se abrirá y permanecerá abierta en una zona de trabajo una vez que se termine la consulta.
<alias> es un sobrenombre temporal de la tabla especificado con <tabla>.
WHERE <unión>
[AND <unión> ...]
[AND | OR <filtro>
[AND | OR <filtro>...]]
WHERE es necesario para recuperar datos de varias tablas. Indica a FoxPRO que incluya únicamente ciertos registros en el resultado de la consulta.
<unión> especifica los campos que unen a las tablas de la cláusula FROM. Si incluye más de una tabla en una consulta, deberá especificar una condición de unión para cada tabla después de la primera.
Precaución: Si incluye dos tablas en una consulta y no especifica una condición de unión, cada registro de la primera tabla se unirá con cada registro de la segunda tabla mientras que se cumplan las condiciones del filtro. Una consulta semejante puede producir resultados muy extraños.
Tenga cuidado al usar funciones (DELETED(), RECNO(), EOF(), FOUND(), RECCOUNT(), etc.) que soportan un alias opcional de zona de trabajo en las condiciones de unión. La inclusión de un alias o una zona de trabajo en estas funciones puede producir resultados imprevistos. SELECT no usa sus zonas de trabajo; realiza el equivalente a USE ... AGAIN. Las consultas sobre una sola tabla que utilicen estas funciones sin un alias o zona de trabajo opcional devolverán los resultados apropiados. Sin embargo, las consultas sobre varias tablas que utilicen estas funciones - incluso sin un alias o zona de trabajo opcional - pueden devolver resultados inesperados.
Tenga cuidado al unir tablas con campos vacíos porque FoxPRO empareja los campos vacíos. Por ejemplo, si une por CLIENTE.CP y FACTURA.CP y CLIENTE contiene 100 códigos postales vacíos y FACTURA contiene 400 códigos postales vacíos, la salida de la consulta contendrá 40,000 registros de más como resultado de los campos vacíos. Utilice la función EMPTY() para eliminar los registros vacíos de la salida de la consulta.
Las condiciones de unión múltiple deben conectarse mediante el operador AND. Cada condición de unión tiene la forma siguiente:
<campo1> <comparación> <campo2>
Donde <campo1> es el nombre de un campo de una tabla, <campo2> es el nombre de un campo de otra tabla y <comparación> es uno de los operadores siguientes: =, <>, !=, #, ==, >, >=, < o <=.
Cuando usa el operador = con cadenas, actúa de forma distinta dependiendo del ajuste de SET ANSI. Cuando SET ANSI está OFF, FoxPRO trata las comparaciones alfanuméricas en la forma habitual en xBase. Cuando SET ANSI está ON, las comparaciones alfanuméricas siguen las normas ANSI.
<filtro> especifica los criterios que deben cumplir los registros para que se incluyan en el resultado de la consulta. Una consulta puede incluir tantas condiciones de filtro como se deseen, conectadas con el operador AND y OR. También puede utilizar el operador NOT para invertir el valor de una expresión lógica o usar EMPTY() para comprobar si un campo está vacío.
<filtro> puede presentar una de estas formas:
Forma: <campo1> <comparación> <campo2>
Ejemplo: clientes.codcli = pagos.codcli
Forma: <campo> <comparación> <expresión>
Ejemplo: pagos.importe >= 1000
Forma: <campo> <comparación> ALL (<subconsulta>)
Ejemplo: tipoimp < ALL ;
(SELECT tipoimp FROM clientes WHERE estado = "WA")
Cuando la condición de filtro incluye ALL, el campo debe cumplir la condición de comparación para todos los valores generados por la subconsulta antes de que se incluya el registro en el resultado de la consulta.
Forma: <campo> <comparación> ANY | SOME (<subconsulta>)
Ejemplo: tipoimp < ANY ;
(SELECT tipoimp FROM clientes WHERE estado = "WA")
Cuando la condición de filtro incluye ANY o SOME, el campo debe cumplir la condición de comparación en al menos uno de los valores generados por la subconsulta.
Forma: <campo> [NOT] BETWEEN <inicio_rango> AND <fin_rango>
Ejemplo: clientes.tipoimp BETWEEN 5.50 AND 6.00
Este ejemplo comprueba si los valores del campo están dentro de un rango de valores especificado.
Forma: [NOT] EXISTS (<subconsulta>)
Ejemplo: EXISTS ;
(SELECT * FROM facturas WHERE clientes.cp = facturas.cp)
Este ejemplo comprueba si al menos una línea cumple los criterios de la subconsulta. Cuando la condición de filtro incluye EXISTS, la condición de filtro se evalúa como verdadera a no ser que la subconsulta sea un conjunto vacío.
Forma: <campo> [NOT] IN <conjunto_valores>
Ejemplo: clientes.cp NOT IN ("98052","98072","98034")
Cuando una condición de filtro incluye IN, el campo debe contener uno de los valores antes de que el registro se incluya en los resultados de la consulta.
Forma: <campo> [NOT] IN (<subconsulta>)
Ejemplo: clientes.códcli IN ;
(SELECT archtran.códcli FROM archtran WHERE archtran.elem="FoxPro")
Aquí, el campo debe contener uno de los valores devueltos por la subconsulta antes de que su registro se incluya en los resultados de la consulta.
Forma: <campo> [NOT] LIKE <expC>
Ejemplo: clientes.estado NOT LIKE "WA"
Esta condición de filtro busca cada uno de los campos que coinciden con <expC>. Puede usar los caracteres comodín % (signo de porcentaje) y _(subrayado) como parte de <expC>. El subrayado representa un solo carácter desconocido en la cadena.
Una subconsulta es un SELECT dentro de un SELECT y debe encerrarse entre paréntesis. Puede tener varias subconsultas en el mismo nivel (no anidadas) en la cláusula WHERE. Las subconsultas pueden contener múltiples condiciones de unión.
GROUP BY <campo> [,<campo>...]
Agrupa registros basándose en los valores de un campo o función de campo.
Si la tabla posee datos repetidos en algún campo, se podrá agrupar dicho campo. Por ejemplo en la tabla MATRI podremos agrupar por CODALU para ver los cursos que lleva un alumno o por CODCUR para ver los alumnos que llevan cierto curso.
La inclusión de la cláusula GROUP BY agrupará los campos de la consulta basándose en los valores de uno o más campos. <campo> puede ser el nombre de un campo normal de una tabla, o un campo que incluya una función de campo SQL, o una expresión numérica indicando la posición de la columna en la tabla resultado (la columna más a la izquierda tiene el número 1).
HAVING <filtro>
Agrupa registros basándose en cierta condición.
Si incluye la cláusula HAVING, FoxPRO incluirá grupos en el resultado de la consulta mientras que cumplan la condición de filtro especificada. <filtro> no puede contener una subconsulta.
HAVING <filtro> debe usarse con GROUP BY para especificar los criterios que deben cumplir los grupos para que se incluyan en los resultados de la consulta. HAVING puede incluir tantas condiciones de filtro como se deseen, conectadas con el operador AND u OR. También puede usar NOT para invertir el valor de una expresión lógica.
Una cláusula HAVING sin una cláusula GROUP BY actúa como una cláusula WHERE.
Puede utilizar alias locales y funciones de campo en la cláusula HAVING.
Use una cláusula WHERE para acelerar el rendimiento si su cláusula HAVING no contiene funciones de campo.
ORDER BY <campo> [ASC | DESC][,<campo> [ASC | DESC] ...]
ORDER BY clasifica el resultado de la consulta dependiendo de los datos de una o más campos. Cada elemento de orden debe corresponderse con un campo en el resultado de la consulta y puede ser uno de los siguientes:
Un campo de una tabla FROM que sea también un elemento de selección en la cláusula SELECT principal (no en una subconsulta).
Una expresión numérica indicando la posición de la columna en la tabla resultado. (La columna más a la izquierda es la número 1).
Puede especificar la palabra clave opcional DESC si quiere que los resultados de su consulta aparezcan en orden descendente de acuerdo con el elemento o elementos del orden. ASC especifica un orden ascendente en el resultado de la consulta y es el valor predeterminado para ORDER BY.
Los resultados de la consulta aparecerán desordenados si no especifica un orden con ORDER BY.
[UNION [ALL] <comando SELECT>]
Incluya la cláusula UNION para combinar el resultado final de una SELECT con el resultado final de otra SELECT. De forma predeterminada, UNION comprueba el resultado combinado y elimina las filas duplicadas. Utilice la palabra clave opcional ALL para impedir que UNION elimine filas duplicadas de los resultados combinados.
Puede utilizar paréntesis para combinar múltiples cláusulas UNION.
Las cláusulas UNION siguen las reglas siguientes:
No puede utilizar UNION para combinar subconsultas.
La salida de ambos SELECT debe tener el mismo número de columnas.
Cada campo de resultado de la consulta de un SELECT debe tener el mismo tipo de dato y anchura que su columna correspondiente en el otro SELECT.
Unicamente el SELECT final puede tener una cláusula ORDER BY, que debe referirse a las columnas de salida por su número. Si se incluye otra cláusula ORDER BY, afectará al resultado completo.
También puede usar una cláusula UNION para simular una unión externa.
Cuando una dos tablas en una consulta, sólo se incluirán en los resultados los registros que tengan valores coincidentes en los campos de unión. Si un registro de la tabla principal no tiene un registro coincidente en la tabla dependiente, el registro de la tabla principal no se incluirá en los resultados. Una unión externa permite incluir en los resultados todos los registros de la tabla principal, junto con los campos coincidentes de la tabla dependiente. Para crear una unión externa en FoxPRO, necesitará usar un comando USE anidado, como se muestra en el siguiente ejemplo:
SELECT cliente.empresa, factura.no, factura.total ;
FROM cliente, factura ;
WHERE cliente.cod = facturas.cod ;
UNION ;
SELECT cliente.empresa, 0, 0.00 ; && 0 y 0.00 son valores ficticios
FROM cliente ;
WHERE cliente.cod NOT IN ;
(SELECT factura.cod FROM factura)
Nota: Asegúrese de incluir el espacio inmediatamente antes de cada signo de punto y coma. De lo contrario, se producirá un error.
La sección del comando anterior a la cláusula UNION selecciona registros que tengan valores coincidentes en ambas tablas. Las empresas clientes que no tengan facturas asociadas no se incluyen. La sección del comando posterior a la cláusula UNION selecciona registros de la tabla CLIENTE que no tengan registros coincidentes en la tabla FACTURA.
En la segunda sección del comando:
SELECT cliente.empresa, 0, 0.00 ;
FROM cliente ;
WHERE cliente.cod NOT IN ;
(SELECT factura.cod FROM factura)
Primero se procesa la instrucción SELECT que aparece entre paréntesis. Esta instrucción selecciona todos los números de cliente de la tabla FACTURA.
La cláusula WHERE busca todos los números de cliente de la tabla CLIENTE que no se encuentran en la tabla FACTURA. Como la primera sección del comando proporcionaba todas las empresas que tenían un número de cliente en la tabla FACTURA, todas las empresas de la tabla clientes quedarán incluidas en los resultados de la consulta.
Debido a que las estructuras de las tablas que se incluyen en una UNION deben ser idénticas, en la segunda instrucción hay dos valores ficticios para representar a los campos FACTURA.NUM y FACTURA.TOTAL de la primera instrucción SELECT.
Nota: Los valores ficticios deben ser del mismo tipo que los campos que representan. Si el campo es de tipo fecha, el valor ficticio debería ser { / / }, para un campo caracter, el valor debería ser " ".
INTO <destino>
La cláusula INTO determina donde se almacenan los resultados de la consulta. Si incluye la cláusula INTO, no se producirá visualización de la salida.
Esto significa que si incluye una cláusula INTO y una cláusula TO en la misma consulta, la cláusula TO se ignorará. Si no incluye la cláusula INTO, los resultados de la consulta se mostrarán en la ventana Examinar. Los resultados de la consulta pueden dirigirse también a la impresora o a un archivo mediante la cláusula TO.
<destino> puede ser uno de los siguientes:
-
ARRAY <matriz> - Almacena los resultados de la consulta en una matriz de variables de memoria llamada <matriz>. Si la consulta selecciona 0 registros, la matriz no se creará.
-
CURSOR <cursor> - Almacena los resultados de la consulta en un cursor llamado <cursor>. Si especifica el nombre de una tabla abierta, FoxPRO cerrará la tabla y creará un cursor para ese nombre sin avisar, si SET SAFETY está OFF. Después de que se ejecute SELECT, el cursor temporal permanecerá abierto y estará activo pero solamente para lectura. Una vez que cierre este cursor temporal, se borrará.
-
DBF <tabla> | TABLE <tabla> - Almacena el resultado de la consulta en una tabla llamada <tabla>. Si especifica una tabla que ya esté abierta, FoxPRO cerrará la tabla y la volverá a abrir sin avisar, si SET SAFETY está OFF. Si no especifica una extensión, la tabla tendrá la extensión .DBF. La tabla permanecerá abierta y activa después de que se ejecute SELECT.
TO FILE <archivo> [ADDITIVE]
| TO PRINTER
| TO SCREEN
Si incluye una cláusula TO pero no una cláusula INTO, podrá dirigir el resultado de la consulta a un archivo de texto ASCII llamado <archivo> o a la impresora además de al escritorio o la ventana FoxPRO principal.
Si el resultado de la consulta se dirige a un archivo de texto, la inclusión de ADDITIVE añadirá la salida al contenido que tenga el archivo.
De forma predeterminada, el resultado de la consulta se envía a la ventana Examinar. Incluya TO SCREEN para dirigir el resultado de la consulta al escritorio o una ventana definida por el usuario activa.
Cuando se saca el resultado de la consulta, los nombres de las columnas siguen las siguientes reglas:
-
Si un elemento de selección es un campo con un nombre único, el nombre de la columna de salida será el nombre del campo.
-
Si hay más de un campo con el mismo nombre (por ejemplo, CLIENTE.CP y ESTADO.CP) las columnas de salida tendrán los nombres <campo>_A y <campo>_B (CP_A y CP_B). Para campos con nombres de mas de 10 caracteres, el nombre se truncará para añadir el subrayado y la letra.
-
Si un elemento de selección es una expresión, su columna de salida se llamará EXP_A. El resto de las expresiones se llamará EXP_B, EXP_C, etc.
-
Si un elemento de selección contiene una función de campo tal que COUNT(). La columna de salida se llamará CNT_A. Si otro elemento de selección contiene SUM(), su columna de salida se llamará SUM_B.
PREFERENCE <nombre>
Si el resultado de una consulta se envía a una ventana Examinar, podrá incluir PREFERENCE para guardar los atributos y opciones de la ventana Examinar para utilizarlos después. PREFERENCE guarda los atributos de la ventana Examinar por tiempo indefinido en el archivo de recursos FOXUSER. Las preferencias pueden recuperarse en cualquier momento.
Emitiendo SELECT con un <nombre> de PREFERENCE, la primera vez se crea la preferencia. Emitiendo posteriormente SELECT con el mismo nombre de preferencia, se restaurará la ventana Examinar con el mismo estado de preferencia. Cuando se cierra la ventana Examinar, se actualiza la preferencia.
Si sale de una ventana Examinar presionando Ctrl+Q, no se guardarán los cambios de la ventana Examinar en el archivo de recurso.
NOCONSOLE
La inclusión de NOCONSOLE impide que el resultado de la consulta se muestre sobre el escritorio o la ventana FoxPRO principal. NOCONSOLE puede usarse tanto si está presente una cláusula TO como si no. Si se incluye una cláusula INTO, se ignorará NOCONSOLE.
PLAIN
La inclusión de PLAIN impide que aparezcan las cabeceras de las columnas al mostrar la salida de la consulta. Si se incluye una cláusula TO, se ignorará PLAIN.
NOWAIT
Cuando los resultados de la consulta se dirigen a una ventana Examinar desde un programa, la inclusión de NOWAIT continuará con la ejecución del programa después de que se abra la ventana Examinar.
Cuando se incluye TO SCREEN para dirigir la salida hacia el escritorio o una ventana definida por el usuario, la salida se detiene cuando el escritorio o la ventana FoxPRO principal se llena con resultados de la consulta. Presione una tecla para ver el siguiente conjunto de resultados de la consulta. Si se incluye NOWAIT, los resultados de la consulta se desplazarán fuera del escritorio, la ventana FoxPRO principal o una ventana definida por el usuario sin esperar a que se presione una tecla. NOWAIT se ignora si se incluye con la cláusula INTO.
Ejemplos:
1. Este ejemplo muestra los nombres de todas las empresas de CLIENTES.DBF
SELECT clientes.empresa FROM clientes
2. Este ejemplo muestra el contenido de tres campos de dos tablas y une las dos tablas basándose en el campo CODCLI. Usa alias locales para ambas tablas.
SELECT a.empresa, b.fechafac, b.impfac ;
FROM clientes a, facturas b ;
WHERE a.códcli = b.códcli
3. Este ejemplo muestra únicamente registros con datos únicos en los campos especificados.
SELECT DISTINCT a.empresa, b.fechfac, b.impfac ;
FROM clientes a, facturas b ;
WHERE a.códcli = b.códcli
4. Este ejemplo muestra los campos STATE, ZIP y COMPANY en orden ascendente.
SELECT estado, cp, empresa, códcli;
FROM clientes ;
ORDER BY estado, cp, empresa
5. Este ejemplo almacena el contenido de los campos de dos tablas en una tercera tabla.
SELECT a.empresa, b.fechafac, b.impfac ;
FROM clientes a, facturas b ;
WHERE a.códcli = b.códcli ;
INTO TABLE clifac.dbf
6. Este ejemplo muestra únicamente los registros con una fecha de factura anterior al 05-08-90.
SELECT a.empresa, b.fechfac, b.impfac ;
FROM clientes a, facturas b ;
WHERE a.códcli = b.códcli ;
AND b.fechfac < {05-08-90}
7. Este ejemplo muestra los nombres de todas las empresas de CLIENTES.DBF con un código postal que coincida con el código postal de la tabla FACTURAS.
SELECT empresa FROM clientes a WHERE ;
EXISTS (SELECT * FROM oficinas b WHERE a.cp = b.cp)
8. Este ejemplo muestra todos los registros de CLIENTES.DBF que tengan un nombre de empresa que comience con una C mayúscula y tenga cualquier longitud.
SELECT * FROM clientes a WHERE a.empresa LIKE "C%"
9. Este ejemplo muestra todos los registros de CLIENTES.DBF que tengan un nombre de estado que comience con N mayúscula seguido de un carácter desconocido.
SELECT * FROM clientes a WHERE a.estado LIKE "N_"
10. Este ejemplo muestra los nombres de todas las ciudades de CLIENTES.DBF en mayúsculas y llama ListaCiud a la columna de salida.
SELECT UPPER(ciudad) AS ListaCiud FROM clientes
Capitulo 7
Sistemas multiusuario
Las aplicaciones multiusuario son las que pueden correr en redes de area local (LAN) y su ventaja es la de compartir datos.
En una aplicacion monousuario no tenemos que preocuparnos de que alguien trate de modificar el archivo o registro en uso ya que estan abiertos para uso exclusivo.
En una aplicacion multiusuario uno debe evitar abrir archivos de forma exclusiva (SET EXCLUSIVE ON o USE <tabla> EXCL) a no ser que sea absolutamente necesario (como en PACK, ZAP o REINDEX), porque esto elimina la posibilidad de compartir datos con otros usuarios. Es por esto que hay que reducir los bloqueos momentanos de archivos (FLOCK) o mejor a un grupo de registros (RLOCK).
En muchos casos el FoxPRO bloquea de forma automatica un registro o un archivo al hacer actualizaciones y despues de la operacion quita el bloqueo de forma automatica tambien.
En cierta ocaciones tendra que bloquear manualmente un archivo o un registro con las funciones FLOCK() y RLOCK() respectivamente en ese caso tendra que desbloquearlo despues con el comando UNLOCK [ALL]. El bloqueo tambien es liberado cuando el archivo es cerrado. Con la funcion SYS(2011) se puede obtener la cadena de status de bloqueo del area en uso.
En un comando @...GET [LOCK|NOLOCK] especifica el bloqueo del registro durante el READ.
Tambien se puede usar adicionalemente la tecnica de FLAGs.
SET EXCLUSIVE ON/off
Determina como se abriran las tablas, por omision esta en ON.
El cambio de este seteo no cambia el estado de las tablas ya abiertas, es decir este comando no es retroactivo.
Algunos comandos requieren que la tabla sea abierta en forma exclusiva, estos son:
INSERT | MODI STRU | REINDEX |
PACK | ZAP |
Tambien se puede abrir una tabla de forma exclusiva sin importar el estado de SET EXCL, con USE <tabla> EXCL
FLOCK([<expN> | <expC>])
Intenta bloquear la tabla en el area en uso o en el area indicada por <expN> o por su ALIAS con <expC> y da un verdadero (.T.) si lo logra y falso (.F.) si ya esta bloqueada por otro usuario.
Cuando una tabla es bloqueada esta permitida la lectura y escritura para quien bloqueo el archivo y solo lectura para los otros usuarios y permacera bloqueada hasta que el mismo usuario haga UNLOCK, cierre la tabla (USE, CLEAR ALL o CLOSE DATABASES) o salga de FoxPRO.
La funcion FLOCK() solo intentara el bloqueo una vez. Use SET REPROCESS para reintentar automaticamente el bloqueo cuando el primer intento falle. SET REPROCESS determina el numero de intentos o un tiempo limite.
Cuando tenga tablas relacionadas con SET RELATION, recuerde poner bloqueo a cada una de de las tablas, padre e hijos.
Ejemplo 1:
SET REPR TO 3 SECONDS
IF FLOCK()
REPLACE ALL BASICO WITH 1.2*BASICO, AUMENTO WITH 'Si'
WAIT 'Espere un momento' WIND NOWA
ELSE
WAIT WIND 'No pude bloquear la base, intenta mas tarde' NOWA
ENDIF
RLOCK([<expN> | <expC1>] | [<expC2>, <expN> | <expC1>])
Intenta bloquear el registro activo en el area en uso o en la especificada por <expN> o por su ALIAS con <expC1>, y devuelve un verdadero (.T.) si lo logra o un falso (.F.) si ya esta bloqueado por otro usuario.
Cuando un registro es bloqueado esta permitida la lectura y escritura para quien bloqueo el registro y solo lectura para los otros usuarios y permacera bloqueado hasta que el mismo usuario haga UNLOCK, cierre la tabla (USE, CLEAR ALL o CLOSE DATABASES) o salga de FoxPRO.
La funcion RLOCK() solo intentara el bloqueo una vez. Use SET REPROCESS para reintentar automaticamente el bloqueo cuando el primer intento falle. SET REPROCESS determina el numero de intentos o un tiempo limite.
Cuando tenga tablas relacionadas con SET RELATION, recuerde poner bloqueo a cada una de de las bases, padre e hijos.
SET MULTILOCKS determina la posibilidd de bloqueo de mutiples registros en una base de datos. Si MULTILOCKS esta en OFF (default) solo se podra bloquear un registro a la vez
<expC2> se usa para intentar bloquear multiples registros, siempre que MULTILOCKS este en ON. Es una lista de los numeros de registro separados por coma, ejemplo 1, 12, 32, 49.
Tambien se puede hacer bloqueos multiples moviendo el puntero a cada registro y haciendo un simple RLOCK() ya que este proceso es aditivo.
El numero maximo de registros que puedes bloquear en cada area es aprox 8,000 asi que si sospecha requerir mas mejor bloquea la tabla completa.
Ejemplo 2:
SET REPR TO 3 AUTOMATIC
SET EXCL OFF
vLOCK='1,2,3,4'
*--- Bloquea reg. 1, 2, 3 y 4 en area en uso
? RLOCK(vLOCK)
*--- Bloquea reg. 21 y 34 del area B
? RLOCK('21,34',B)
UNLOCK ALL
UNLOCK [IN <expN> | <expC> | ALL]
Desbloquea todo en el area en uso o la especificada por <expN> o con su ALIAS en <expC> o en todas las areas con ALL.
El UNLOCK no afecta a los archivos abiertos en forma exclusiva.
READ
Las clausulas LOCK y NOLOCK del comando READ especifican de bloquear automaticamente o no si los GETs contienen campos.
Si seleccionas NOLOCK entonces los campos con GET seran solo lectura y no podras editarlo, se mostrara de otro color.
RETRY
Re-ejecuta el comando previo en busca de consiguir un resultado
positivo, como el bloqueo de un registro de forma manual.
La diferencia con RETURN es que este retorna a la siguiente instruccion en cambio RETRY a la misma.
Ejemplo 3:
SET ESCA ON
ON ERROR DO stop
SET DEVICE TO PRINTER
SCAN
@ PROW()+1,10 SAY 'Cia: '+vCIA
ENDSCAN
SET DEVICE TO SCREEN
ON ERROR
*--------------
PROC stop
*--------------
IF ERROR()=125
WAIT WIND 'Alista tu impresora y presiona cualquier tecla'
SET DEVI TO PRIN
RETRY
ENDIF
SET LOCK on | OFF
Abilita o no la posibilidad del bloqueo automatico por parte de ciertos camandos.
FoxPRO no pone bloqueo en algunos comando cuando el SET LOCK es OFF estos son:
AVERAGE | LIST | INDEX |
CALCULATE | LABEL | JOIN (ambos archiv.) |
COPY TO | REPORT | COUNT |
COPY TO ARRAY | SORT | SUM |
DISPLAY | TOTAL |
SET MULTILOCKS on | OFF
Determina si puedes o no bloquear multiples registros usando el comando RLOCK(). Por omision esta en OFF.
Este comando si es retroactivo es decir al pasarlo a OFF se genera un UNLOCK ALL y todas las bases en todas las areas se desbloquean.
SET REPROCESS TO <expN> [SECONDS] | TO AUTOMATIC
Especifica cuantas veces o por cuanto tiempo (segundos) se intentara lograr el bloqueo. Por omision <expN>=0.
Con <expN> = -1 o TO AUTOMATIC se intentara indefinidamente hasta que lo logre o se presione <Esc>.
READ LOCK | nolock
Cuando la tabla está abierta para uso compartido en una red, por omision el READ asume LOCK, de manera que se bloquea automaticamente el registro actual durante el READ, si se especifico un campo en lugar de variable en el GET.
Si se incluye NOLOCK, no se bloquearán los registros usado en los objetos y todos los GET definidos para usar campos en lugar de variables se harán de solo lectura y no podrá seleccionarse el control y se mostrará en colores desactivados.
Un campo memo es la excepcion ya que al modificar este, el registro se bloqueará automáticamente.
CODIGOS DE ERROR
ERROR 108 File is in use by another.
ERROR 109 Record is in use by another.
Estas intentando escribir en un registro bloqueado por otro usuario de la red.
ERROR 130 Record is not locked.
Estas intentando hacer un BROWSE, CHANGE, EDIT, DELETE, GATHER, MODIFY MEMO, READ, RECALL o REPLACE a un registro que no esta bloqueado.
ERROR 1101 Cannot open file.
FoxPRO no puede abrir el archivo requerido porque esta bloqueado por otro usuario de la red.
ERROR 1503 File cannot be locked.
FoxPRO no puede bloquear el archivo requerido porque esta bloqueado por otro usuario de la red.
Capitulo 8
Practica
Buscar una cadena especifica en un campo MEMO
Crear una función que determine si un numero es múltiplo de otro.
Crear una función que realice una animación de una cadena de caracteres en la pantalla (la desplace hacia un lado por ejemplo)
Crear una función que devuelva el elemento mayor / menor de una matriz.
Crear una funcion de usuario capaz de dado un campo que contiene apellidos paterno y materno, separados solo por un espacio y algunos en mayusculas y otros en minusculas, uniformice todos poniendo la primera letra de cada apellido en mayusculas y el resto en minisculas.
Crear un programa que almacene una matriz en un archivo y luego la pueda recuperar a voluntad nuevamente.
Crear un procedimiento para el ingreso de nombres y claves de acceso, las claves no deben ser visibles y luego se valide el ingreso de dicho usuario. Trata de encriptar las claves.
Capitulo 9
Bibliografía:
Programación en base a eventos
- Cesar A. Bustamante Gutierrez - UNI
FoxPRO 2.6 para DOS y Windows a su alcance
- José Javier García Badell - McGraw Hill
Programación basica con FoxPRO
- Ramón M. Chordá - Rama
Al dia en una hora en FoxPRO 2.6
- José Carlos Corrales - Anaya Multimedia
Guia practica FoxPRO 2.6
- Alejandro Dominguez - Anaya Multimedia
Diseño de programas: 200 algoritmos y un proyectos
- Julio Vasquez Paragulla - Editorial San Marcos
Microsoft FoxPRO for DOS and Windows, lenguage reference
- Microsoft Press
Descargar
Enviado por: | El remitente no desea revelar su nombre |
Idioma: | castellano |
País: | España |