Evitar ruptura de tablas nativas mediante usar cursores

Visto 357 veces
Saltar al primer mensaje no leído

TheNewInquirer

no leída,
3 feb 2012, 23:41:493/2/12
a Comunidad de Visual Foxpro en Español
Leyendo en el foro, alguien mencionó que evita poner en uso tablas que
pueden ser susceptibles de dañarse si se apaga la energía eléctrica u
por otras razones.

La idea era usar cursores que levanten los datos de la tabla a la
memoria ram y reducir al mínimo la apertura y cierre de las tablas
originales.

Sé que la solución a este problema es usar un motor de datos.

Sin embargo, los desarrollos en los que estoy trabajando son sencillos
y serán escalados en su momento a Firebird.

Mientras tanto, me interesa el tema de los cursores.

¿Cómo creo manualmente un cursor?...

¿Como borro, actualizo o inserto datos en un cursor?..

¿Como envío los datos de una consulta select a un grid?..

Hasta ahora uso un simple filtro y presento los datos en un grid. Lo
bonito de los filtros es que me aceptan realizar un filtro sobre un
filtro anterior. ¿Se puede hacer eso con los selects?...

¿La versión 6 permite usar los cursores?.. ¿Algún truco para volverlos
lectura-escritura?

¿Algun enlace para leer todo acerca del uso de cursores?...

No considero tiempo perdido, el estudiar acerca de esto en Visual Fox,
porque se que los motores de datos funcionarán de forma similar.

Además, alguien incluso comento que el SQL Server implementó la
tecnología Rush More apenas en su versión 7 y que por eso es probable
que MS aun mantenga a Fox como codigo no liberado porque sería como
revelar un secreto industrial jeje

Es por eso que considero, que para ustedes que son grandes maestrazos
de Fox, será cosa de niños entender los lenguajes web del lado del
servidor (PHP, Ruby on Rails, Python, Java, ASP, etc) y los de
moviles(Android) una vez que le encuentren el hilo al asunto.

Según leo, por el lado del cliente ya arman y desarman con el web
jaja!

Aunque claro, para desarrollos de escritorio, nos quedamos con Fox,
hasta las últimas consecuencias jeje!

Vaya historia la del Fox jeje Hollywood debería dedicarle una película
por lo menos jaja!

http://www.foxprohistory.org/communitylinks.htm

Irlandes 1960

no leída,
4 feb 2012, 1:01:564/2/12
a publice...@googlegroups.com
¿Cómo creo manualmente un cursor?... 
dos opciones
1) create cursor Mycursor (campo1 .....  donde vas definiendo cada campo y su formato y característica. Desde Siempre fue de escritura - grabación, permite indexarlo y filtrarlo y lo que quieras hacer, es simplemente una DBF temporal, que desaparece al cerrarla.
2) select sql combinando los campos que quieras, indicando la clausula INTO CURSOR MyCursor  Originariamente de solo lectura, incorpora la clausula READWRITE creo que en la ultima versión, en la 5 no estaba y creo que en la 6 tampoco, con lo cual puede modificarse su contenido , indexarlo y filtrarlo, etc, ya que en esencia resulta ser lo mismo que lo creado en 1)  

Si queres crearlo vacío, por ejemplo para tener el origen de datos de los objetos de un form, pones la clausula WHERE .F.  y después haces un append blank

Si el cursor lo estás armando en base a datos pre existentes, te conviene la opción 2) ya que las características de cada campo se definen automáticamente al heredarlas del campo de la tabla.

Una variante es hacerlo INTO DBF con el requerimiento previo al select de calcular un nombre/path no utilizado . De hecho yo lo tengo todo armado así, ya que la mecánica fue establecida en VFP 5 y la mantengo

¿Como borro, actualizo o inserto datos en un cursor?..
es igual que cualquier dbf. Yo no trabajo con borrado de registros, sino con anulación, la información ingresada en el sistema nunca se borra, nunca desaparece ya que despues no fue nadie y la culpa es tuya que se pierde información. Las consultas siempre incorporan como filtro EMPTY(ANULADO) en forma predeterminada, pero pueden pedirse que incluya los anulados tambien.
En ese caso, en la grilla que muestra los resultados, se incluye una clausula para pintar el fondo de gris, del tipo    .SETALL('DYNAMICBACKCOLOR','IIF(EMPTY(ANULADO),RGB(255,255,255),RGB(192,192,192))','COLUMN') 

Uso del cursor como origen de datos en el form ¿Porque?
Yo en ningún caso uso los campos originales de las tablas como controlsource en ningún objeto, sino que suelo referenciarlos a su equivalente en un cursor creado en el entorno de datos del formulario
Esto permite para comenzar que si mañana quiero migrar a un motor SQL no tengo que tocar esa propiedad objeto por objeto, sino simplemente reescribir la instrucción sql que hoy me genera el cursor desde las dbf nativas, capturando lo mismo pero desde el motor sql
Mantiene la ventaja de "capturar" en el objeto características del campo de la tabla, como su formato, largo y cantidad de decimales si corresponde.
Recién toco las tablas reales en el momento de la grabación, encapsulada en una transacción que previene actualizaciones parciales (ver comando begin transaction) 
Y nuevamente, si mañana decido migrar la aplicación a un motor SQL tendré que cambiar los insert / update nativos de VFP a los de la versión que corresponda, pero no el enfoque de toda la rutina.

Sé que la solución a este problema es usar un motor de datos.
bueno, el de VFP es un motor de datos, más que suficiente para una PYME, y con la tendencia a volver a centralizar en el servidor el procesamiento de toda la aplicación, usando terminal server y sus evoluciones posteriores, no se hasta que punto se gana o no con los motores sql, donde justamente el gran argumento es que gran parte de la lógica se ejecuta en el servidor y no circulan por la red más que los datos indispensables, que se derrumba estrepitosamente cuando planteas que por la red no circula nada de nada, ya que todo se procesa en el servidor. VFP es libre de mantenimiento y crece solito. Recordemos que los motores SQL nacen para entre otras cosas mantener el diseño de datos aislado de los desarrolladores de las aplicaciones, creando el perfil del administrador de la base de datos que armaba las vistas quew se requerían  por parte de los desarrolladores de aplicaciones, todo lo cual en el entorno en el cual me desenvuelvo no tiene sentido.

¿Como envío los datos de una consulta select a un grid?. 
asignando la propiedad recordsource del grid.
PERO tene presente que antes de disparar la consulta, tenes que liberar la grilla sino pierde toda la definición de columnas y títulos que armaste. Algo así como
thisform.grdgral1.recordsource = ' '
select tabla1.* from tabla1 into cursor cursor1 where empty(anulado) and ....
thisform.grdgral1.recordsource = 'cursor1'
thisform.grdgral1.refresh()
Esto en la práctica me ha llevado a que sobre el entorno de diseño armo la grilla con sus columnas, títulos, anchos, etc,  y en algún evento asigno el origen de datos y que campo corresponde a cada columna

¿Se puede filtrar el resultado de un select?
Yo trabajo sobre los DBF nativos de VFP, aunque supongo que esto mismo es aplicable a SQL 
Dado que el resultado del select es un dbf , sobre el mismo suelo crear varios indices que permiten al usuario reordenar el resultado dinamicamente, y si quiere filtrarlo.
Mis intentos por incluir filtros en el form no me han dado resultado. En esa etapa el usuario suele preferir volcar los datos al excel y filtrar allí, entorno que le resulta más familiar y amigable a la hora de analizar la información.
Por ello es habitual que en las pantallas donde se presenta la grilla de resultado de la consulta, incluyo un botón para pasar los datos al excel.


TheNewInquirer

no leída,
4 feb 2012, 1:29:254/2/12
a Comunidad de Visual Foxpro en Español
Irlandés, gracias por tu tiempo !

Pues esto es lo que hago para filtrar los datos de cierto periodo de
fechas en un grid por si acaso te sirve:

En pantalla tengo un form con 2 textos de fechas que dicen: desde:
hasta:

Abajo vemos un grid donde muestra los datos filtrados una vez que el
usuario presiona un enter en el text de hasta:

El código de ese 2o. text en el evento lostfocus sería algo así:

Evento Load del form:
Sele 3
Use mitabla

Lostfocus del 2o. text:

SELE mitabla

A=CTOD(ALLTRIM(THISFORM.TEXT1.VALUE))
B=CTOD(ALLTRIM(THISFORM.TEXT2.VALUE))

IF A<=B

GO TOP

SET FILTER TO BETWEEN(FECHA,A,B)

THISFORM.GRID1.VISIBLE=.T.
THISFORM.GRID1.SETFOCUS()
THISFORM.GRID1.CLICK()

ELSE
WAIT 'EL PERIODO NO ES CORRECTO' WINDOW AT 15,40 TIMEOUT 2
ENDIF

Luego solo presiono un boton de comando que llama un archivo de
informe y lo presenta como preview.

A ver si encuentro otro codigo más anidado con ANDS.

Gracias!

TheNewInquirer

no leída,
4 feb 2012, 1:46:194/2/12
a Comunidad de Visual Foxpro en Español
Esto es lo que hago para filtrar los datos de cierto periodo de fechas
en un grid CON UN COMBOBOX ADICIONAL a considerar en el filtro:

En pantalla tengo un form con 2 textos de fechas que dicen: desde:
hasta:

Ademas AHORA TENGO UN COMBOBOX, que despliega los departamentos.

Abajo vemos un grid donde muestra los datos filtrados una vez que el
usuario presiona un enter en el COMBOBOX
El código de ese 2o. text en el evento lostfocus sería algo así:

En el load del form:
Sele 3
Use mitabla
Sele 5
Use mitabladepartamentos

En el evento lostfocus del combobox:

SELE mitabla

A=CTOD(ALLTRIM(THISFORM.TEXT1.VALUE))
B=CTOD(ALLTRIM(THISFORM.TEXT2.VALUE))

IF A<=B

STORE SPACE(60) TO XCOMBODEPTO
XCOMBODEPTO=ALLTRIM(THISFORM.combodepto.VALUE)

GO TOP

SET FILTER TO BETWEEN(FECHA,A,B) AND ALLTRIM(DEPTO) =
ALLTRIM(XCOMBODEPTO)

THISFORM.GRID1.VISIBLE=.T.
THISFORM.GRID1.SETFOCUS()
THISFORM.GRID1.CLICK()
GO TOP

ELSE

WAIT 'EL PERIODO NO ES CORRECTO' WINDOW AT 15,40 TIMEOUT 1

ENDIF

Espero te sirvan.

Cuidate!

Irlandes 1960

no leída,
4 feb 2012, 2:08:144/2/12
a publice...@googlegroups.com
Mirá, el enfoque que estás poniendo no es muy sustentable, sirve para tablas muy chiquitas y situaciones muy simples.
Pensá como van a ser las cosas cuando tengas 30.000 registros, y los filtros no sean solo dos fechas, sino que te pidan agregar zona, provincia, cliente, tipo de formulario, producto, proveedor, y treinta cosas mas.
Yo te diria que ya te plantees trabajar de movida en otro enfoque.
Tipicamente las consultas son dos pantallas, la primera de filtros de selección, y la segunda de mostrar los resultados.
Yo suelo resolver esto con un form, en el cual está un pageframe de dos solapas con tabs = .f. para que no se vean.
En la primer solapa, dispongo de los filtros, que nunca bajan de dos o tres cosas diferentes (fijate que vos ya agregaste a las fechas, la selección de departamento en un combo) 
Un botón para procesar, que ejecuta un select sql capturando los datos que quieras desplegar, para el cual se arma la condición where en base a los filtros de la primer solapa.
conceptualmente el codigo sería:
LCAND = ''
IF !EMPTY(ThisForm.Pgfgral1.Page1.Spnfecha1.TxtFecha.Value)
LCAND = LCAND + ' AND COMPROB.FECHAEMI >= {' + DTOC(ThisForm.Pgfgral1.Page1.Spnfecha1.TxtFecha.Value) + '} '
ENDIF 
IF !EMPTY(ThisForm.Pgfgral1.Page1.Spnfecha2.TxtFecha.Value)
LCAND = LCAND + ' AND COMPROB.FECHAEMI <= {' + DTOC(ThisForm.Pgfgral1.Page1.Spnfecha2.TxtFecha.Value) + '} '
ENDIF 
IF !EMPTY(ThisForm.Pgfgral1.Page1.Cbomov.Value)
LCAND = LCAND + ' AND COMPROB.CODMOVESP = "' +ThisForm.Pgfgral1.Page1.Cbomov.Value + '" '
ENDIF 
IF !EMPTY(ThisForm.Pgfgral1.Page1.CBOMONEDA.Value)
LCAND = LCAND + ' AND COMPROB.MONEDA = "' +ThisForm.Pgfgral1.Page1.CBOMONEDA.Value + '" '
ENDIF 
* libero la grilla para no perder su diseño
ThisForm.Pgfgral1.Page2.Grdgral1.RecordSource = ' '
SELECT * ;
FROM COMPROB;
INTO cursor CURCOMPROB;
WHERE EMPTY(ANULADO)  &LCAND

WITH ThisForm.Pgfgral1.Page2.Grdgral1
.RecordSource = 'CURCOMPROB'
.column1.controlsource = 'CODMOVESP+" "+formletra+" "+ALLTRIM(STR(formce))+"-"+PADR(formnro,9)'
.column2.controlsource = 'fechaemi'
.column3.controlsource = 'nroasie'
.column4.controlsource = 'trans(importe,"@Z 99,999,999.99")'
.column5.controlsource = 'trans(EXENTO,"@Z 99,999,999.99")'
.column6.controlsource = 'trans(GRAVADO,"@Z 99,999,999.99")'
.column7.controlsource = 'trans(IVAIMP1,"@Z 99,999,999.99")'
.column8.controlsource = 'trans(PERCIVA+PERCGAN+PERCIBRUTO+PERCADIC,"@Z 99,999,999.99")'
.column9.controlsource = 'circuito'
.column10.controlsource = 'coment'
.REFRESH()
ENDWITH 
ThisForm.Pgfgral1.ActivePage = 2

Al pasar de pagina, prendo y apago botones (evento activate de cada una) 
En general suele haber un botón de selección prendido en la primer solapa que se paga al pasar a la segunda, y viceversa, botón de retroceso a la primer solapa para armar otra selección, y algun botón más seguro, como una salida al excel.

Guarda que esto es en realidad una extrema simplificación, la realidad es mucho más compleja.
Es habitual que el select sql combine varias tablas, por ejemplo el padrón de clientes para obtener su razón social.

Al resultado de la consulta suelo indexarlo con diferentes combinaciones asociadas a las columnas para reordenar la grilla según se le ocurra al usuario, por ejemplo puede querer verlos x cliente-fecha, o por numero de comprobante, o por fecha de emisión.
en ese caso se agrega En el evento click del header de la columna, algo así como 
sele (this.parent.parent.recordsource)  && esto para generalizar, te asegura que este parado en el cursor
set order to clifecha    && el nombre del tag que corresponda
this.parent.parent.refresh()

A esto agregale que seguro vas a desembocar en consultas que muestren la entidad principal, y una o dos entidades relacionadas y coordinadas entre si
Para este ejemplo, podría ser el detalle de la factura con producto, precio, cantidad, en una grilla asociada que se reescribe al moverse en la grilla principal al cambiar de registro, y ponele una tercer grilla con el detalle de las cobranzas de esa factura.

En resumen, ya planteá las consultas con un esquema que soporte después ir escalando de complejidad sin tirar todo a la basura.


TheNewInquirer

no leída,
5 feb 2012, 0:08:305/2/12
a Comunidad de Visual Foxpro en Español
Gracias! Sigo tratando de entender el tema de los cursores.

http://msdn.microsoft.com/es-es/library/tdd4h271(v=vs.80).aspx

Daniel Sánchez

no leída,
5 feb 2012, 1:38:405/2/12
a publice...@googlegroups.com
Los cursores no son mas que tablas, funcionan igual, se graba y lee igual, se puede indexar igual, se puede filtrar igual, hasta se puede obtener con un select sql otro cursor del cursor anterior, más que nada debes entender los cursores como copias de una tabla origen si fuera dbf de vfp, o resultado de datos traídos desde un SGBD. En el caso de usarlo como copias es manejo del programador mantener actualizada el original en relación al cursor que pueda ser modificado debe reflejarse el cambio también en la tabla DBF o en la tabla en un SGBD. Para el realizar una actualización automática sin mayores problemas para el programador te recomendaría usar los cursoradapters que te simplifica bastante el tema de la actualización del cursor en relación a la tabla origen, yo los uso en mas del 80% de los casos en mis sistemas.

Saludos

--
Daniel Sánchez Escobar
Investigación y Desarrollo
Reset Software & Sistemas
Móvil +051-949398047
Trujillo - Perú

GeoSys Diseño de Software

no leída,
5 feb 2012, 11:44:105/2/12
a publice...@googlegroups.com
*!* Copia y pega esto en un prg o en un botón de comando de un formulario.
*!* Puedes estudiar el código que es lo mismo que manipular una tabla DBF.

*- Hago un cursor (Tabla Temporal), con tres campos.
CREATE CURSOR primercursor;
(numero C(12), fecha D(8), detalle C(40))
INDEX on numero tag numero && Creo un ídices por número
FOR consecutivo = 1 to 20 && Empiezo el bucle.
numero1 = VAL(numero)+1 && Convierto a número y sumo 1.
numero1 = PADL(transform(numero1), 12, "0") && conviento a carácter y relleno con ceros a la izquierda.
APPEND BLANK
REPLACE numero with numero1
replace fecha with DATE()
ENDFOR && Termino el bucle.
BROWSE 
*!* Ya tenemos un cursor (Tabla Temporal DBF), ahora a este cursor le hacemos una consulta, sobreescribible.
*!* y almacenamos en un segundo cursor.
SELECT numero, detalle from primercursor order by numero desc into cursor segundocursor READWRITE
BROWSE
replace all detalle with "Prueba"
*- Como puedes ver, un cursor es una tabla temporal, a la tabla temporarl puedes hacerle consula y sobreescribir el cursor.
BROWSE

*!* Con SELECT SQL, puedes consultar las DBF, Cursores o tablas de otra base de datos como Firebird o SQL Server.
*!* Ahora, los cambios que hagas en los cursores los estás haciendo allí, para pasar la información a las tablas o; 
bases de datos originales las tienes que hacer con los comandos de SQL:

*!* INSERT into (Inserta un registro nuevo)
*!* UPDATE (Modifica campos)
*!* DELETE FROM (Elimina Registros)

*!* Puedes ver los comandos SELECT-SQL en la ayuda de VFP.

Saludos

Anthony Contreas Peralta

Costa Rica.

TheNewInquirer

no leída,
5 feb 2012, 14:47:365/2/12
a Comunidad de Visual Foxpro en Español
And the winner is... jeje Directly from Costa Rica...Anthony
Contreas Peralta !!!

Gracias compañeros !!

Con esto no creo que no logre entenderlo.

Saludos!

Carlos Miguel FARIAS

no leída,
5 feb 2012, 19:48:365/2/12
a publice...@googlegroups.com
La fragilidad de las dbf me parece bastante un mito emergente de malas prácticas de programación.
En cualquier sistemas que se corte la luz, o se tilde el sistema operativo, a los archivos de las bd se les producen fallas.
La diferencia entre un sgbd y las dbf, es que mientras el sgbd es el único que accede a los archivos, y estos archivos están en el mismo equipo que corre el motor, en las dbf, son multiples "qsgbd" (la q de quasi) que pueden estar, distribuidos en multiples máquinas, que además acceden a traves de la red.
Cuando el servidor se apaga (mal), las archivos pueden quedar dañados, pero al arrancar, el servidor controla que el apagado haya sido correcto, si detecta que no lo fue (y para ello lleva un sistema de bitacora para detectar que grabo y que no) se fija que no esta completamente grabado, lo borra, reorganiza los indices, limpia la basura y recien te deja la bd disponible para los usuarios.
En fox eso hay que programarlo.
Una manera es tener una tabla, o archivo de texto plano o un archivo mem que deje indicado si la tabla esta abierta o no. Cuando el sistema la cierra, quita la marca de ese archivo. En entorno multiusuarios, hay que llevar un especie de contador (cada use tabla, suma, cada use in tabla, descuenta).
En el equipo que estan las dbf, debe haber un programa que corre no bien arranca el equipo, ese programa debe intentar abrir todas las tablas en forma exclusiva (o al menos la que tienen un contador de opens mayor 1).
A esas tablas, les debera si o si reconstruir los indices.
Además, para control de transacciones, cuando se inserta un nuevo registro, se debería grabar con un estado de "creandose", y cuando se va a modificar ponerle un estado de modificandose, y luego de modificado, grabar que se modifico.
Para mas simplicidad, crean una tabla (o archivo plano, tal vez mas seguro), donde antes de guardar los cambios a un registro, se guarda nombre tabla, nombre campo, valor anterior, valor actual, fecha y hora, usuario, pc y les queda una bitacora no solo para recupero, si no para auditoria.
Este último párrafo es mucho trabajo, no creo, calculo que en 50 lineas de codigo se puede resolver, y además es único para cualquier tabla.
Por si les interesa, el proyecto del vfpserver fue liberado.
Por supuesto, si podes usar un sgbd como firebird o postgres "más mejor".
Saludos: Miguel, Santa Rosa (LP)

TheNewInquirer

no leída,
6 feb 2012, 16:52:116/2/12
a Comunidad de Visual Foxpro en Español
Ya puedo enviar datos de una consulta a un grid a través de un cursor.

Lo hago, según me indicaron con esto:

En el evento Load del form:
Use mitabla IN 0

La propiedad Recorsource del grid1 en la precarga es mitabla y muestra
los datos de la tabla original en su orden normal.

En un boton de comando del form referenciado al grid:

Thisform.grid1.recordsource = ' '

SELECT campo1, campo2 FROM mitabla INTO CURSOR micursor  ORDER BY
campodeorden

thisform.grid1.recordsource = 'micursor'
thisform.grid1.refresh()

Mi error era que en INTO CURSOR ponia otra vez "mitabla" en vez de
"micursor". Ahora entiendo que el cursor debe tener OTRO NOMBRE ya que
se trata de practicamente otra tabla, solo que temporal(o solo en
memoria).

Soy nuevo en esto de los cursores y el desarrollo robusto.

Ahora bien..

Cuando uso filtros, puesto que estos hacen referencia a la tabla de
origen, solo pongo un Boton de Comando que tiene el código que llama a
un archivo de informe y lo presenta en vista preliminar.

REPORT FORM "resumenordenado.frx" TO PRINTER PROMPT PREVIEW

Cuando uso filtros, puesto que estos solo le dejar ver los datos
filtrados al comando REPORT FROM de su origen de datos que es la
tabla, solo presentará dichos datos filtrados en pantalla y no TODA LA
TABLA.

Como envío los datos generados en una consulta SELECT a un archivo de
informe con solo que el usuario presione un boton de comando
IMPRIMIR ?...

No quisiera volver a teclear la consulta en el INIT del entorno de
datos del archivo de informe.

No soy de la idea de "duplicar codigo" (como en este caso, en el form
y luego en el init del entorno de dato del report).

Hay alguna otra forma "mas limpia" de trabajarlo?..

Gracias a todos!

Hugo Carlos Aguilar Zapata

no leída,
7 feb 2012, 12:03:167/2/12
a publice...@googlegroups.com
Mis sugerencias son:
1. Maneja el origen de datos de tu grid en un cursor, no inicies primero con la tabla y luego cambies a un select SQL.
2. Quita el entorno de datos del report y el codigo
3. en la accion que genera el reporte pudes escribir
Select Micursor (los datos de grid que imagino son el detalle del reporte)
report form MiReporte to printer prompt preview

saludos

El 6 de febrero de 2012 15:52, TheNewInquirer <fresass...@gmail.com> escribió:
Ya puedo enviar datos de una consulta a un grid a través de un cursor.

Lo hago, según me indicaron con esto:

En el evento Load del form:
Use mitabla IN 0

La propiedad Recorsource del grid1 en la precarga es mitabla y muestra
los datos de la tabla original en su orden normal.

En un boton de comando del form referenciado al grid:

Thisform.grid1.recordsource = ' '

SELECT campo1, campo2 FROM mitabla INTO CURSOR micursor  ORDER BY
campodeorden

thisform.grid1.recordsource = 'micursor'
thisform.grid1.refresh()

Mi error era que en INTO CURSOR ponia otra vez "mitabla" en vez de
"micursor". Ahora entiendo que el cursor debe tener OTRO NOMBRE ya que
se trata de practicamente otra tabla, solo que temporal(o solo en
memoria).

Soy nuevo en esto de los cursores y el desarrollo robusto.

Ahora bien..

Cuando uso filtros, puesto que estos hacen referencia a la tabla de
origen, solo pongo un Boton de Comando que tiene el código que llama a
un archivo de informe y lo presenta en vista preliminar.

REPORT FORM "resumenordenado.frx"c

Intel Man

no leída,
9 feb 2012, 13:52:269/2/12
a publice...@googlegroups.com
Hola, no se si esto ya te contestaron:


> Como envío los datos generados en una consulta SELECT a un archivo de
> informe con solo que el usuario presione un boton de comando
> IMPRIMIR ?...
>

Pero puedes hacer lo siguiente:

Luego de haber generado tu select, llamas a tu reporte

report form tu_reporte

Y en tu reporte en la parte de campos a jalar harias referencia a los campos de esta manera:

micursor.campo1
micursor.campo2
etc

Espero te sirva

Saludos


> Date: Mon, 6 Feb 2012 13:52:11 -0800
> Subject: [vfp] Re: Evitar ruptura de tablas nativas mediante usar cursores
> From: fresass...@gmail.com
> To: publice...@googlegroups.com

TheNewInquirer

no leída,
9 feb 2012, 14:01:559/2/12
a Comunidad de Visual Foxpro en Español
Gracias Intel Man. El tema de como evitar perder codigo y
características en un grid ya fue resuelto.

http://groups.google.com/group/publicesvfoxpro/browse_thread/thread/8b0b7c6ed54ddaeb#

Para el de enviar una consulta a una preview, ya abrí un nuevo hilo,
para que quede más organizado.

Intentaré hacer lo que comentas..
Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos