¿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.