VFP 6.0 hacer cursor de lectura escritura

1,582 views
Skip to first unread message

mpulla

unread,
Dec 4, 2015, 9:49:05 AM12/4/15
to Comunidad de Visual Foxpro en Español
Buen día foxeros.

Tengo que trabajar exclusivamente con VFP 6.0 sin SP y tengo el siguiente Sql

Select campo1, campo2, .T. As Activo, 0.00 As Valor;
From MiTabla;
Into Cursor rs nofilter

Necesito trabajar sobre el cursor, pero en vfp 6.0 el cursor es de lectura, me parece que había una forma de convertirlo en lectura escritura alguien sabe como?

No puedo convertirlo en una tabla porque tengo problemas de permisos, tiene que ser un cursor.

Saludos.
Mauricio

francisco prieto

unread,
Dec 4, 2015, 10:04:52 AM12/4/15
to publicesvfoxpro
Argentina

mpulla

unread,
Dec 4, 2015, 10:20:13 AM12/4/15
to Comunidad de Visual Foxpro en Español
Gracias Francisco 

El Link ya lo estaba revisando, pero ya recordé que había algo mas corto.

select codigo, nombres, .T. As soynuevo, 0.00 as misueldo;
From personal;
into cursor rs1 Nofilter

use dbf('rs1') In 0 again alias rs
use in(select('rs1'))

Saludos.
Mauricio

Jorge Montúfar

unread,
Dec 4, 2015, 10:34:45 AM12/4/15
to publicesvfoxpro
solo es de agregar readwrite al final


select codigo, nombres, .T. As soynuevo, 0.00 as misueldo;
From personal;
into cursor rs1 Nofilter readwrite



francisco prieto

unread,
Dec 4, 2015, 11:04:40 AM12/4/15
to publicesvfoxpro
Jorge,

en VFP6 el ReadWrite no existe.

Saludos,

Pancho
Córdoba
Argentina

Jorge Montúfar

unread,
Dec 4, 2015, 11:25:50 AM12/4/15
to publicesvfoxpro
jajaja mil perdones con que razon no trabajo con 6, si ya vi se puede ingresar a una tabla

· CURSOR NombreCursor [NOFILTER], que almacena los resultados de la consulta en un cursor. Si especifica el nombre de una tabla abierta, Visual FoxPro generará un mensaje de error. 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á. Los cursores pueden existir como un archivo temporal en la unidad SORTWORK.

Incluya NOFILTER para crear un cursor que se pueda usar en consultas posteriores. En versiones anteriores de Visual FoxPro, era necesario incluir una expresión o una constante adicional como un filtro para crear un cursor utilizable en consultas posteriores. Por ejemplo, la adición de un Logical verdadero como una expresión de filtro creaba una consulta utilizable en consultas posteriores:

SELECT *, .T. FROM customers INTO CURSOR myquery

Si se incluye NOFILTER es posible que disminuya el rendimiento de la consulta, puesto que se creará una consulta temporal en el disco. Cuando se cierre el cursor se eliminará del disco la consulta temporal.

· DBF | TABLE NombreTabla
[DATABASE NombreBaseDatos [NAME NombreLargoTabla]] que almacena el resultado de la consulta en una tabla. Si especifica una tabla que ya esté abierta y SET SAFETY está en OFF, Visual FoxPro sobrescribirá la tabla sin previo aviso. Si no ha especificado ninguna extensión, Visual FoxPro dará una extensión .DBF a la tabla. La tabla permanecerá abierta y activa después de ejecutar SELECT.

Incluya DATABASE NombreBaseDatos para especificar una base de datos a la que se agregará la tabla. Incluya NAME NombreLargoTabla para especificar un nombre largo para la tabla. Los nombres largos pueden contener un máximo de 128 caracteres y pueden utilizarse en lugar de nombres cortos en la base de datos.

Victor Espina

unread,
Dec 4, 2015, 11:48:33 AM12/4/15
to Comunidad de Visual Foxpro en Español
Es correcto, pero esa tecnica no respeta las columnas de nombres largos; cualquier columna en el cursor que contenga mas de 10 caracteres sera truncada a 10 cars.  Esa es la principal ventaja de la rutina expuesta en mi blog, que mantiene el cursor exactamente igual con columnas de nombres largos incluidos.

Victor

mpulla

unread,
Dec 4, 2015, 7:16:59 PM12/4/15
to Comunidad de Visual Foxpro en Español
Gracias Victor.

Al momento estoy trabajando con tablas sueltas.

Saludos.
Mauricio.

HernanCano

unread,
Dec 6, 2015, 1:01:55 AM12/6/15
to Comunidad de Visual Foxpro en Español
Buenas tardes, amigos.
Este mensaje va para Víctor.

Víctor:
Gracias por participar. Este comentario mío también es para ayudar a Mauricio, aunque vaya en contra de tu comentario.

Mira, Víctor: esa tecnica (la que encontró Mauricio) sí respeta las columnas de nombres largos., ya que no está basada en la "errónea" (basada en COPY TO) que mencionas (y corriges/mejoras) en tu blog.

Efectivamente una solución basada en COPY TO tiene el inconveniente que indicas en tu blog (se "recortan" los nombres largos), pero la que encontró Mauricio está basada en USE IN AGAIN, que considero muy acertada.... y la probé!!!!! Chequea el sgte script.....

<< adjunto PRUEBA.PRG >>
** no pude anexarlo.... perdón.....
** 
clear
close tables all
close databases all

   =MessageBox('Observa que estos dos campos tienen nombre largo';
     +chr(13)+'OBSERVACION' ;
     +chr(13)+'FECHA_NACIMIENTO')

create cursor PERSONAL ( CODIGO C(10), NOMBRES C(40), OBSERVACION C(40), FECHA_NACIMIENTO D )

insert into PERSONAL ( CODIGO, NOMBRES, OBSERVACION, FECHA_NACIMIENTO ) values ( "001", "ALBERTO", "Primer Registro" , {^2015.01.01} )
insert into PERSONAL ( CODIGO, NOMBRES, OBSERVACION, FECHA_NACIMIENTO ) values ( "002", "BYRON"  , "Segundo Registro", {^2015.02.02} )
insert into PERSONAL ( CODIGO, NOMBRES, OBSERVACION, FECHA_NACIMIENTO ) values ( "003", "CARLOS" , "Tercer Registro" , {^2015.03.03} )

select *, .T. as SOYNUEVO, 0.00 as MISUELDO;
  from PERSONAL;
  into cursor RS1 Nofilter

if IsReadOnly('RS1')
   =MessageBox('El cursor RS1 es de sólo lectura')
else                      
   =MessageBox('El cursor RS1 es de lectura-escritura')
endif  

use dbf('RS1') In 0 again alias RS
use in select('RS1')

if IsReadOnly('RS')
   =MessageBox('El cursor RS es de sólo lectura')
else                      
   =MessageBox('El cursor RS es de lectura-escritura')
endif  

replace all NOMBRES          with repli(alltrim(NOMBRES    )+' ',3) in RS
replace all OBSERVACION      with repli(alltrim(OBSERVACION)+' ',2) in RS
replace all FECHA_NACIMIENTO with gomonth(FECHA_NACIMIENTO,12 )     in RS
replace     SOYNUEVO         with .f. for recno()=2                 in RS

select RS
afields(TT,'RS')
? "============================================="
? " Estructura del cursor final --RS--"
? "============================================="
display memory like TT
? "---------------------------------------------"
? " Fin de mostrar el arreglo con la estructura"
? "---------------------------------------------"
wait window "Pulse una tecla para continuar"
clear
display structure
? "---------------------------------------------"
? " Fin de mostrar la estructura"
? "---------------------------------------------"
wait window "Pulse una tecla para continuar"

browse noedit && freeze FECHA_NACIMIENTO

close tables all

**

Victor Espina

unread,
Dec 7, 2015, 11:59:50 AM12/7/15
to Comunidad de Visual Foxpro en Español
Hernan, pues me has dejado de una pieza.   El problema con el USE AGAIN es que el cursor queda abierto para lectura/escritura, pero si afectas su estructura (por ejemplo, incluyendo una nueva columna con ALTER TABLE ADD COLUMN), las columnas con nombres largos se cortaran.  Estaba preparando un programa de ejemplo para mostrar esto y como con mi rutina esto se evitaba, cuando me lleve la sorpresa que TAMBIEN con mi rutina (que crea el cursor en memoria desde cero con CREATE CURSOR) sucede lo mismo.

Victor

Hector Kuhn

unread,
Dec 11, 2015, 3:30:27 PM12/11/15
to publicesvfoxpro
*-------------------------------------
*-- CONVIERTE UN CURSOR EN MODIFICABLE
procedure hazmodificable

    lparameters m.alias

    use (dbf(m.alias)) in 0 again alias hazmodificable
    use in (m.alias)
    use (dbf("hazmodificable")) in 0 again alias (m.alias)
    use in hazmodificable

endproc

ejemplo
create cursor csrPrecaudar(nCap n(13,2),nInt n(13,2),nMora n(13,2),cperiodo c(6),ncantidad n(5,0),nid n(8),codigo n(6))

=Hazmodificable('CsrPrecaudar')



Fidel Charny

unread,
Dec 11, 2015, 4:59:12 PM12/11/15
to Comunidad de Visual Foxpro en Español
ejemplo
create cursor csrPrecaudar(nCap n(13,2),nInt n(13,2),nMora n(13,2),cperiodo c(6),ncantidad n(5,0),nid n(8),codigo n(6))
=Hazmodificable('CsrPrecaudar')



VIERNES: De qué serviría CREATE CURSOR si no generara un cursor modificable?

HernanCano

unread,
Dec 12, 2015, 2:28:26 AM12/12/15
to Comunidad de Visual Foxpro en Español
Fidel:
Te pìdo disculpas si estoy enturbiando el hilo con mi intervención anterior (y quizá con la de Víctor).

El interés mío era nada más aclararle a Víctor que basa su solución en un supuesto bug en la solución que otro colega propuso (Mauricio).

Veamos: Víctor dijo que la solución de Mauricio falla (pues se pierden los nombres largos) y da la explicación; en su explicación dice que es porque se usa COPY TO.... (es cierto que pase lo que dice Víctor, pero COPY TO no se usa en la solución de Mauricio...).

Esto es lo que pretendía explicar... Y para ello propuse un script que fuera usado para ensayar mi teoría... y para ello decidí crear una cursor desde cero (con CREATE CURSOR ....).

Repito: en mi intervención se incluye el comando CREATE CURSOR, que evidentemente crea un cursor de lectura y escritura, que no es referente al hilo original.

Mi intervención lo que pretendía era mostrar que los nombres largos sí se mantienen con el método de solución propuesto por Mauricio... El centro de mi solución no era el comando CREATE CURSOR.... sino mostrar que los nombres largos sí se mantienen, que es lo que "critica" Víctor (tranquilo, Víctor, es sólo una forma de decirlo).

Con respecto a la pregunta "inicial", lo que tú, Fidel, dices, es correcto: un CREATE CURSOR y/o CREATE TABLE/DBF, crean el archivo y lo dejan abierto en exclusiva y de lectura escritura (por lo tanto no es necesario hacer lo que se dice en las diferentes soluciones propuestas).

Chao.

Fidel Charny

unread,
Dec 12, 2015, 10:09:43 AM12/12/15
to Comunidad de Visual Foxpro en Español
Hernan: En realidad le puse "VIERNES" al comentario, como para que nadie lo tome en serio.
De paso, tiro otra idea basada en aFields(), modificando la estructura del cursor original.
El cursor "curSource" se utiliza en reemplazo de una tabla con nombres de campo largos, igual que en el ejemplo de Hernán.
El cálculo del Alen(array,2) es porque en VFP 6 aFields() daba un array de 16 o 17 (no recuerdo bien) columnas.

#DEFINE _RELLENO_    "VALOR DEL CAMPO "
LOCAL lnPruebas
,;
    i
,;
    lnRand
,;
    lnFields
,;
    lnCols
,;
    lNull_Allowed

LOCAL ARRAY laFields
(1)

*<Crea cursor Prueba>    
lnPruebas
= 100
CREATE CURSOR curSource
("CampoLargo1" c(40) , "CampoLargo2" n(12,2),"CampoLargo3" n(12,2))
RAND
(-1)

FOR i
= 1 TO m.lnPruebas
    lnRand
= RAND()*1000
    INSERT INTO curSource
(Campolargo1,CampoLargo2,CampoLargo3) ;
        VALUES
(_RELLENO_+TRANSFORM(I), ROUND((m.lnRand + m.lnRand^2)/2,2), ROUND(m.lnRand*i/100,2))
NEXT
*</Crea cursor Prueba>

*<Crea cursor No ReadWrite>
SELECT
CampoLargo1,CampoLargo2,CampoLargo3 FROM cursource WHERE .t. INTO CURSOR curReadOnly
*</Crea cursor No ReadWrite>

*<Genera Array de estructura>
lnFields
= AFIELDS(lafields,"curReadOnly") + 1
lnCols
= ALEN(laFields,2)

*<Modifica el Array agregando un campo>
DIMENSION laFields
(m.lnFields,m.lnCols)
laFields
[m.lnFields,1]="CampoLargoSuma"
laFields
[m.lnFields,2]="N"
laFields
[m.lnfields,3]=12
laFields
[m.lnfields,4]=2
laFields
[m.lnfields,5]=m.lNull_Allowed
laFields
[m.lnfields,6]=.f.
FOR i
= 7 TO m.lnCols
    laFields
[m.lnfields, m.i ] = ""
NEXT
* Prevenir versiones anteriores de VFP
IF m
.lnCols > 16
    FOR i
= 17 TO m.lnCols
        laFields
[m.lnfields,i]=0
    NEXT
ENDIF
*</Modifica el Array agregando un campo>

*<Crea Cursor a partir del array modificado>
CREATE CURSOR curTarget FROM ARRAY laFields
*</Crea Cursor a partir del array modificado>

*<Agrega valores y suma>
SELECT curTarget
APPEND FROM DBF
("curReadOnly")
SCAN
    replace
CampoLargoSuma WITH CampoLargo2 + CampoLargo3
ENDSCAN
*</Agrega valores y suma>

GO top
BROWSE

USE IN curSource
USE IN curReadOnly
USE IN curTarget
 


Reply all
Reply to author
Forward
0 new messages