23 de marzo de 2011

La grandeza de VFP 9 viene en paquetes pequeños

Artículo original: Big VFP 9 thingd come in small package
Autor: Drew Speedie (QEPD)
Traducido por: Ana María Bisbé York

Nota de la traductora

Este texto corresponde a la sesión que fue preparada por el MS VFP MVP Drew Speedie para la Conferencia Southwest Fox 2005. Pocos meses antes de la conferencia, Drew Speedie falleció; pero su trabajo fue presentado por otro de los grandes de la comunidad VFP, el también MS VFP MVP, Andy Kramek.

Deseamos agradecer a Andy Kramek y Russ Swall de Vision Pace, donde trabajaba Drew Speedie, por la posibilidad que nos han brindado de distribuir la obra de Drew y que todos sigamos aprendiendo de el. Sirva este trabajo de traducción como homenaje de recordación a Drew Speedie. ¡Gracias Drew!

Resumen

Cada nueva versión de cualquier software contiene siempre varias "pequeñas" mejoras que no reciben mucha publicidad. Estos pequeños avances no merecen un tema para una hora de sesión en conferencias de desarrolladores. Sin embargo, si se agrupan todos juntos, comprenden una parte significativa de lo que vamos a utilizar a diario en el desarrollo de nuestras aplicaciones VFP 9.
Código de ejemplo Los archivos con código de ejemplo para esta presentación consta de un único archivo EXAMPLES.APP. Ejecute DO EXAMPLES, y el código de ejemplo para todos estos elementos se copiará en su disco en la misma carpeta que EXAMPLES.APP al seleccionar alguno de los botones Source (Código fuente) o Run (Ejecutar)
Palabra clave ADDITIVE para el comando SET PATH Agregar nuevas rutas al SET PATH actual ha sido siempre una tarea tediosa en VFP, típicamente lo hacíamos así:
LOCAL lcPath 
lcPath = SET("PATH") + ";C:\Projects\MyApp\Data"
SET PATH TO &lcPath 
En VFP 9, el comando SET PATH se ha mejorado para soportar la palabra clave ADDITIVE, por lo que se reduce a lo siguiente:
SET PATH TO "C:\Projects\MyApp\Data" ADDITIVE 
Todo lo que aparece a continuación funciona en VFP 9 para agregar una ruta por programa:
LOCAL lcDataPath
lcDataPath = "C:\Projects\MyApp\Data"
SET PATH TO (m.lcDataPath) ADDITIVE 
LOCAL lcDataPath
lcDataPath = ["C:\Projects\MyApp\Data"]
SET PATH TO &lcDataPath ADDITIVE 
LOCAL lcDataPath
lcDataPath = "C:\Projects\MyApp\Data"
SET PATH TO "&lcDataPath" ADDITIVE 
Cuando utiliza macrosustitución, se requiere el conjunto extra de delimitadores, debido a que en versiones anteriores ha podido asignar a SET PATH una carpeta llamada \ADDITIVE:
SET PATH TO ADDITIVE 
SELECT … WITH (BUFFERING = .T.) VFP 9 tiene muchas mejoras. Una de los que podría utilizar frecuentemente es la cláusula nueva WITH (Buffering = <lExpr>).

Antes de VFP 9, cuando el cursor (tabla, vista, etc) era guardado en buffer, la sentencia SELECT SQL siempre recibía los registros del disco. Los registros almacenados en buffer eran siempre ignorados, de tal forma que tenía que buscar otras vías para recibir los registros desde el cursor en buffer.

Esta mejora permite especificar si la sentencia SELECT va a utilizar los registros en buffer o los registros en disco; solamente añadiendo una cláusula WITH (Buffering = .T.) después de cada tabla deseada en la cláusula FROM ya el SELECT recibe los registros en buffer en lugar de los registros en disco.

Por ejemplo, he estado utilizando esta nueva cláusula para simplificar el código que recibía un registro de un cursor de tabla en buffer, para verificar algún valor. El código antiguo tenía este aspecto:
LOCAL lnRecno, lnSelect, lnValue
lnSelect = SELECT(0)
lnRecno = IIF(EOF(),0,RECNO())
SELECT TargetCursor
LOCATE FOR <SomeCondition>
lnValue = <SomeFieldValueOrWhatever>
IF m.lnRecno = 0
  GO BOTTOM
  IF NOT EOF()
    SKIP
  ENDIF
ELSE
  GOTO (m.lnRecno)
ENDIF
SELECT (m.lnSelect) 
...el código nuevo es este:
LOCAL lnValue
SELECT * FROM TargetCursor ;
  WITH (BUFFERING=.T.) ;
  FOR <SomeCondition> ;
  INTO CURSOR Junk
lnValue = <SomeFieldValueOrWhatever>
USE IN SELECT("Junk") 
O, ¿qué tal este código para obtener un cursor llamado InvoiceTotal del cursor LineItems (buffered) durante una entrada de datos:
SELECT SUM(Quantity*Price) AS TheTotal ;
  FROM LineItems WITH (BUFFERING=.T.) ;
  INTO CURSOR InvoiceTotal 
Notas:
  • Especificar WITH (Buffering=.F.) es lo mismo que omitir la cláusula WITH - tendremos el comportamiento predeterminado.
  • Cuando el cursor especificado en FROM no está almacenado en buffer, no hay ningún efecto al especificar WITH (Buffering=.T.), la cláusula es ignorada.
  • La cláusula WITH se aplica a nivel de tabla - específicamente para aquellas tablas del FROM, para las que desee ese comportamiento.
    Si está habilitado el buffer por filas, la ejecución de SELECT dispara un TABLEUPDATE() implícito para cada tabla con buffer de líneas en SELECT para las que ha especificado WITH (BUFFERING = .T.)
  • El nuevo comando SET SQLBUFFERING está igualado a OFF, póngalo en ON para especificar que todas las sentencias SELECT utilizan implícitamente WITH (BUFFERING = .T.) para todas las tablas en la cláusula FROM.
Se pueden realizar transacciones de tablas libres. VFP 9 agrega la posibilidad de realizar transacciones sobre tablas libres y cursores creados con CREATE CURSOR - las actualizaciones a los cursores pueden ejecutar ROLLBACK junto con todas las otras tablas contenidas y vistas en una transacción VFP.

Esta característica está basada en dos nuevas funciones:
  • MAKETRANSACTABLE()
  • ISTRANSACTABLE()
Un uso importante de esta nueva funcionalidad es en sistemas de herencia, donde debe actualizar una combinación, o para todas las tablas libres, o para alguna combinación de las tablas contenidas y las tablas libres, - antes, solamente las actualizaciones a tablas contenidas podían ser deshechas si fallaba la transacción.


Sin embargo, asegúrese de leer en la Ayuda de VFP, MAKETRANSACTABLE(), ya que hay algunas limitaciones. Por ejemplo, no puede hacer que una tabla libre o cursor sean TRANSACTABLE si tiene activo buffer de tabla, si tiene buffer de filas y el buffer está sucio, se realiza un TABLEUPDATE() implícito antes de que el cursor pueda emplearse en una transacción. Para poder deshacer (ROLLBACK) cambios en múltiples filas de una transacción, debe desactivar el buffering y hacer todos los cambios en el cursor después de BEGIN TRANSACTION.
NEWOBJECT(ClassName,ClassLibrary,0) Ahora se puede pasar un cero como tercer parámetro a la función NEWOBJECT(). Al hacerlo, VFP instancia la clase especificada de forma similar a como lo hace el Diseñador de clases, instanciando la clase sin ningún código Init/Destroy para la clase o alguno de sus miembros. Como otras funciones NEWOBJECT() utilizadas, el objeto no se hará visible.

Esto permite instanciar una clase en entorno de desarrollo para verificar cualquier cosa que necesita sobre su jerarquía de herencia, la jerarquía de contenedores, miembros, etc. Puede utilizar también AMEMBERS() para ver sus miembros.

¿Cuándo emplearlo? Pues al escribir herramientas para desarrolladores, asistentes, generadores, etc. Antes, la única forma de verificar la jerarquía y los miembros era abriendo el archivo VCX e inspeccionando manualmente sus metadatos. Esta tarea era mucho más tediosa que instanciar la clase e inspeccionar sus miembros directamente.

Asegúrese de leer esta advertencia que aparece en el archivo Ayuda de VFP para esta función NEWOBJECT(): "Observe que el código en la clase no debe ser ejecutado nunca - la extensión no está admitida y puede provocar que sea inestable VFP.. Nunca debe llamar un evento o método o darle valor directamente a propiedades. Para darle valor a las propiedades puede llamar a los métodos Access y Assign."
Script para propiedades El FoxTeam agregó mucha extensibilidad en el IDE de VFP 9, la mayoría en la ventana propiedades con el "motor" de la propiedad _MemberData y el Editor de MemberData. Creo que lo más útil de MemberData es que puede agregar un script a cualquier propiedad de usuario.
¿Qué es un script? El código VFP que escribimos (o tomamos de algún otro lugar) y adjuntamos a una propiedad al especificar que el código snippet en el atributo Script para esta propiedad, en la propiedad _MemberData (¡Utilice el editor MemberData!). Cuando especifique un Script para una propiedad, al seleccionar la propiedad, se hace visible y se habilita el botón de comandos elipse, editor de propiedades (vea la figura siguiente)



He agregado una propiedad de usuario con el único propósito de tener un sitio donde asociar código (el script) que se ejecuta cuando se hace clic sobre el boton elipse editor de propiedades (lo puede ver donde apunta el cursor del ratón, junto al cuadro de texto de valor de la propiedad).



Aquí está el código script para la propiedad "summonsubform" en el Editor de MemberData - para cualquier propiedad que especifique un script, VFP instala el botón elipse del editor para esa propiedad en la ventana Propiedades y ejecuta el script cuando hace clic en el botón elipse de la propiedad.

El empleo más frecuente para un script es invocar un editor de propiedades. Ha utilizado esta cualidad durante años, ya que muchas propiedades nativas de VFP incluyendo ForeColor, Anchor, y MemberClass/MemberClassLibrary tienen su editor de propiedad, si hace clic en el correspondiente botón elipse, aparece el editor de propiedad. Ahora puede implementar esta misma posibilidad en propiedades de usuario.

La creación de editores personalizados para propiedades de usuario es una cualidad muy poderosa; pero los scripts extienden la ventana Propiedades más allá de su empleo típico. Los Scripts son ganchos en la ficha Propiedades que permiten ejecutar cualquier código VFP que desee.
El ejemplo EX144.SCX en EXAMPLES.APP da una idea. EX144.SCX es para los propósitos de un demo con "formulario principal" de sólo lectura, cuando hace Clic en los botones <Update...> (Actualizar) o <Add...> (Agregar) invoca a un "subformulario" donde el usuario va a ser la entrada de datos real. En este caso tan común, se está moviendo constantemente entre dos formularios en el diseñador. Cuando está trabajando con el "formulario principal" tiene que recordar el nombre del "subformulario" si está basado en SCX o VCX y además, tiene que cargarlo cada vez que necesita trabajarlo. Utilice una propiedad para eliminar el aburrimiento. Desplácese hacia abajo a la propiedad de usuario "summonsubform" al final de la Ventana propiedades. Parece como si contuviera el nombre del subformulario "EX144s.SCX"; pero vea que su comando editor de propiedades está disponible (vea la figura arriba). Haga clic para que el subformulario se cargue en el Diseñador de formularios.

Vea que la acción de editor de propiedades script no modifica en algún modo la propiedad de usuario "summonsubform". El script es un gancho en el Diseñador de Formularios o Clases que permite tener un código que haga lo que desee. Verifique el script para la propiedad "summonsubform" en el editor de MemberData y verá que controla escenarios donde la propiedad "summonsubform" está igualada a ClassName,VCXFileName, en lugar de un subformulario basado en VCX.

En lugar de codificar por completo el script en el _MemberData, en algunos casos puede hacer una simple llamada DO <NombrePrograma> en el script, manteniendo el código que en realidad realiza la función, fuera del script.

Para más información sobre los scripts de propiedades vea mi artículo "VFP 9 Form and Class Design Enhancements" publicado en la revista FoxPro Advisor en Julio de 2004 y el artículo de Tamar Granor titulado "Build Your Own Property Editors", publicado en la misma revista en Diciembre 2004.

Nota de la traductora: Una versión ampliada del artículo "VFP 9 Form and Class Design Enhancements" fue traducida y se publicó bajo el título "VFP 9.0. Mejoras en diseñador de formularios y clases" en ... 
SET COVERAGE disponible en tiempo de ejecución La posibilidad de hacer un log de la ejecución a través del comando SET COVERAGE ha sido siempre una gran vía para solucionar problemas de rendimiento. Sin embargo, hasta ahora podía utilizar solamente SET COVERAGE en entorno de desarrollo. VFP 9 admite SET COVERAGE en los ejecutables distribuidos, así que cuando un usuario se queje del rendimiento, puede insertar comandos SET COVERAGE dentro de la aplicación y examinar el archivo con el log resultante.
Por supuesto, necesita ser juicioso en el uso de SET COVERAGE en entorno productivo, ya que hace más lenta la aplicación y el archivo con el log creado puede crecer demasiado. Puede crear un SET COVERAGE dentro de una llamada IF ... ENDIF para que verifique la condición que permita activar segun la demanda, para el administrador del sistema.

Asegúrese de que el dibujo grabado en el archivo del trayecto en el entorno de producción no coincida con el entorno de desarrollo. Si tiene que pedirle al usuario que le envíe el log de cobertura obtenido, debe actualizar las rutas a los archivos de código fuente si desea cargar el archivo log en el Analizador de trayecto.
Explorador de datos VFP 9 incluye una nueva herramienta "Explorador de datos" que es muy similar al Explorador de datos de otras herramientas. El Explorador de datos es difícil de encontrar porque no se le agregó una entrada para él en el menú Herramientas. En lugar de esto, está escondido como un panel del Administrador del panel de tareas.

Afortunadamente, el Explorador de datos, es una herramienta standalone, DataExplorer.APP, en la carpeta raíz de VFP. En esta carpeta encontrará las otras aplicaciones escritas en VFP. Las aplicaciones como Examinador de clases, Examinador de objetos, Caja de herramientas, Analizador de trayecto, Editor de MemberData, etc. Esto significa que lo puede ejecutar independientemente del Panel de tareas, he aquí algunas formas de acceso rápido al Explorador de datos.
  1. Llamarlo directamente desde la ventana comandos:
DO (HOME(1)+"DataExplorer.APP") 
  1. Agregarlo al menú Herramientas con esta línea de código en su código de inicio de sesión VFP
DO (HOME(1)+"DataExplorer.APP") WITH "-M" 
  1. Agregar un registro en IntelliSense en su tabla _FoxCode. El elemento 147 en EXAMPLES.APP incluye EX147.PRG que agrega o actualiza un registro "DX" en la tabla FoxCode.DBF. Después de ejecutarlo, siempre que introduzca DX y luego deje un espacio en la ventana comandos, se muestra el Explorador de datos. Por supuesto, puede modificar el script que aparece en el campo Data si desea.
Una vez que está cargado el Explorador de datos, ¿qué puede hacer con el? Sería magnífico si alguien recopilara y publicara una lista comprensible de todas sus funcionalidades, parece que cada vez que lo utilizo le encuentro algo nuevo.
La acción más obvia es hacer Clic derecho en el nodo Connections y seleccionar Add Visual FoxPro Database y agregar una de sus Bases de datos VFP. Entonces puede hacer cosas como:
  • Hacer clic derecho en el nodo de la base de datos, seleccione Propiedades, luego ordenar las tablas, campos, etc y escoger si incluir información de la columna, la que se muestra a la derecha de cada nodo campo (y que también está incluida en el panel Description, si ha seleccionado mostrarla allí.)
  • Arrastrar una tabla en la ventana de comandos, un .PRG o un método. El resultado es una sentencia SELECT pre-generada, lo que es un ahorro real de tiempo para la creación de consultas aunque sea un simple SELECT *.
  • Arrastrar un campo a la ventana de comandos, un .PRG o un método para generar una sentencia SELECT que incluya precisamente ese campo.
  • Arrastrar una tabla o un campo a un formulario u otro contenedor en el Diseñador de Formularios y Clases. Vea que el resultado es un grid base de VFP, ya que el Explorador de Datos no admite representación de campos (field mapping).
  • Sin embargo, si selecciona el botón <Options> cerca del borde superior del Explorador de datos, una de las opciones es <Manage Drag/Drop>, vea que puede personalizar la operación arrastrar y soltar desde el Explorador de datos en un área de diseño para implementar cualquier comportamiento que desee.
Esto es muy bueno; pero pienso que el Explorador de datos realmente brilla cuando lo utiliza como explorador de Bases de datos remotas. Por ejemplo, el explorador de datos es como tener el Administrador Empresarial de SQL, El Administrador de consultas y mucho más al alcance de su mano, todo en una única herramienta. Si estamos ejecutando un SQL Server local, sus bases de datos se cargan automáticamente en el nodo local, bajo Connections. Puede ver también los SQL locales bajo el nodo SQL Servers al igual que el resto de sus SQL Servers disponibles. Agregue tantos servidores de datos remotos como necesite. Para Bases de datos remotos, se puede hacer lo siguiente:
  • Seleccionar el botón <Options> cerca del borde superior del Explorador de datos y asegurarse de que está seleccionada la casilla Show Column Info. Cuando se expande el árbol hacia abajo el nivel de campos, vea que se incluye el dato de el tipo de dato y el tamaño para cada campo (la información de la columna también está disponible en el panel Description, si desea que se mantenga mostrada.)
  • Arrastrar y soltar una tabla o campo en la ventana Comandos, o preferiblemente, un .PRG o método. El script resultante es un SELECT de un cursor VFP a través de ADO y un Cursor Adapter.
  • Arrastrar y soltar una tabla o campo en un formulario u otro contenedor en el Diseñador de Clases o Formulario. El Grid es simple, pero tiene el valor de la propiedad ControlSource para cada control. Como ya dije antes, no hay representación de campos; pero probablemente pueda personalizar el comportamiento de Arrastrar y soltar en Options>Manage Drag/Drop.
  • Haga clic derecho sobre cualquier tabla y seleccione la opción Browse. Vea que es mucho más rápido que la carga del Browse VFP comparando con la misma acción desde el Administrador Corporativo.
  • Intente ejecutar la opción Run Query desde el menú contextual que obtiene al hacer Clic derecho en cada nodo. El resultado es que activa un formulario VFP - Administrador de consultas para los nodos tablas y campos, una consulta inicial ya está escrita, lista para ser ejecutada.
  • Expanda el nodo Stored Procedures. Puede expandir el nodo para cada procedimiento almacenado y para cada parámetro en lista (por ejemplo, vea los Procedimientos Almacenados que viene con SQL Server).
  • Haga Clic derecho en el nodo Stored Procedures y vea que tiene una opción para crear un nuevo procedimiento almacenado New Stored Procedure. El menú contextual para cada Procedimiento almacenado admite modificar y eliminar, así como repetir la opción New Stored Procedure.
Esto ha sido sólo una primera lista de posibilidades para iniciarse. Encontrará más y más utilidad cuando explore el Explorador de datos por sí mismo.
Palabra clave FORCE para el comando FLUSH El comando Flush fue mejorado en VFP 9.0 para que haga finalmente lo que debía hacer: vaciar todas las actualizaciones de datos en el disco.
Sin embargo, un simple comando FLUSH solamente envía una solicitud al sistema operativo Windows para volcar los cambios en el disco - Windows decide cuando realizar la tarea; pero llama a la función API FlushFileBuffers para cada tabla actualizada.
Cuando se ejecuta el comando FLUSH FORCE, VFP indica a Windows que realice inmediatamente el FlushFileBuffers, lo que posiblemente hará que haga implícitamente un TABLEUPDATE(), o después END TRANSACTION o FLUSH. Este no es el caso; pero ahora puede seguir TABLEUPDATE() o END TRANSACTION con un FLUSH FORCE.
Sin embargo FLUSH FORCE se hace notablemente lento cuando tiene más tablas abiertas en VFP. Para mejorar el rendimiento del comando FLUSH FORCE especifique el nombre de la tabla a ser vaciada.
FLUSH FORCE IN <WorkArea/Alias> 
Por ejemplo, si tiene un lugar en su código abstracto donde hace END TRANSACTION, puede realizar un FLUSH FORCE IN para cada tabla VFP que esté actualizada en realidad.
Al utilizar FLUSH FORCE IN, el cursor que especifica no tiene que tener el nombre de la tabla - debe ser el alias bajo la cual se abrió la tabla, y VFP pasa la llamada a Windows, con el nombre de la tabla.
Colorear la sintaxis en los campos Memo VFP 9 agrega la posibilidad de mantener la sintaxis coloreada dentro de los campos memo. De forma predeterminada no está habilitada para mantener compatibilidad hacia atrás.
Para activar/desactivar la sintaxis coloreada para todos los campos memo, utilice la ficha IDE de la ventana Opciones del menú Herramientas. La lista desplegable Tipo ahora incluye el elemento "Campos memo". Para habilitar/inhabilitar la sintaxis coloreada para un campo memo en particular, que sobreescriba cualquiera que sea la configuración establecida en Herramientas > Opciones > IDE, haga Clic derecho en el campo memo abierto y seleccione la opción Propiedades... Debe desmarcar la casilla Ajuste automático de línea para poder marcar la casilla Colorear la sintaxis.
Esta cualidad es más útil para aquellos memos que contienen código VFP. Se pueden incluir sentencias SELECT o bloques de código que ejecute en tiempo de ejecución. Si "Explora" sus tablas de metadatos .SCX/.VCX, apreciará esta cualidad cuando vea el contenido de Métodos en el campo memo. El script MemberData es mucho más fácil de modificar cuando tiene activada la sintaxis coloreada para el campo memo que obtiene cuando hace clic sobre el botón Zoom del script del Editor de MemberData.

Esta característica es también muy buena cuando crea o depura scripts de IntelliSense guardados en el campo Data de la tabla FoxCode. Vea las diferencias al colorear la sintaxis si coloca código en el campo Data de alguno de esos registros:
USE (_FoxCode)
BROWSE LAST FOR "LPARAMETERS" $ UPPER(Data) 

Contenido de campos Memo visible

Los grids y BROWSE han sido mejorados para mostrar el contenido del campo cuando pasa el ratón sobre cualquier celda cuyo contenido no sea completamente visible. También se puede obtener esta información de los campos memo, funciona independientemente de si el registro actual es aquel por donde pasa el ratón.

Para ver el contenido de los campos largos y los campos Memo en los BROWSE, _Screen.ShowTips debe ser igual a .T.

Esta cualidad es muy útil especialmente para los BROWSE en entorno de desarrollo.
Sin embargo, hay un comportamiento incómodo con los grids. Para las columnas de tipo Número/Entero, VFP aparentemente hace un TRANSFORM() del valor de la celda para determinar si todo el contenido de la celda es visible o no, y entonces, mostrar el resto. En dependencia del ancho de la columna, el campo se muestra, incluso cuando cabe el contenido en su totalidad, como demuestra el ejemplo EX154.SCX. En este caso EX154.SCX requiere que el ControlSource de la columna esté establecido a una expresión que cree un valor suficientemente corto para que cree esa información. Asegúrese de emplear una expresión para el ControlSource que genera la columna de sólo lectura.

Luego de realizar DO FORM EX154, seleccione la opción Info... desde el formulario para obtener más información.
Registro "MENUHIT" de IntelliSense Este aspecto trata de todo el nuevo poder añadido a un único registro en su tabla IntelliSense, cuya localización está contenida en la variable de sistema _FoxCode.

En lugar de incluir aquí una larga explicación del registro opcional "MENUHIT", he incluido un documento MenuHit.DOC en EXAMPLES.APP que acompañan esta sesión. Haga DO EXAMPLES.APP y seleccione el elemento # 159, "MENUHIT IntelliSense script to customize the VFP system menu". Haga Clic en el botón <Run> que copia en su disco varios archivos de apoyo y cargue MenuHit.DOC en Microsoft Word.

Además de otras cosas, MenuHit.DOC describe cómo crear / modificar su registro "MENUHIT" en IntelliSense para especificar un script en el campo Data que ejecute el programa (si existe) especificado en el campo Tip. Como se describe allí, haga el campo Tip igual a "MenuHitHandler.PRG" (sin comillas). Entonces, seleccione Archivo - Abrir desde el menú de VFP, se dispara el programa MenuHitHandler.PRG, el que a su vez, llama a los programas FileOpenDialog.PRG. y FileOpenDialog.PRG. Esta es mi forma de hacer que Archivo - Abrir tenga un comportamiento más inteligente en entorno de desarrollo VFP, como se describe en MenuHit.DOC.

Un registro en su tabla IntelliSense es algo pequeño; pero aporta un gran resultado, cuando llama a su programa controlador de menú y personaliza cualquier selección desde el menú principal de VFP en entorno de desarrollo.

Para más información sobre MenuHit, vea mi artículo "Would You Care To See The Menu?" en Octubre de 2004 en la revista FoxPro Advisor.
Visor de documentos: Ordenar por Nombre de los métodos. La ventana Visor de documentos ha sido mejorada en VFP 9, con la opción Sort by Name (Ordenar por nombre) en el menú contextual del diseñador de formularios y clases. Yo prefiero la opción Ordenar por nombre que ordenar por localización (Sort by Location), que era la única existente hasta el momento.

Por otra parte, normalmente prefiero ordenar por Localización cuando estoy trabajando en un prg que contiene procedimientos locales organizados en orden lógico y con los cuales yo estoy familiarizado. No se la forma de establecer preferencias para la opción de ordenar ni para los editores de PRG ni para los Diseñadores.
Imprimir texto seleccionado Puede seleccionar texto en la ventana de comandos, un .PRG, un método, un campo memo, etc e imprimir justamente el texto seleccionado. Con el texto que desea imprimir seleccionado, seleccione la opción Imprimir ... del menú Archivos. Antes de VFP 9, en el Rango de impresión (Print range) la opción Seleccionado estaba inhabilitada, ahora no sólo está habilitada, sino que es la opción predeterminada.
SET TABLEPROMPT (OFF) VFP 9, agregó un comando nuevo SET TABLEPROMPT. El valor predetermindo es ON, para compatibilidad hacia atrás. Sin embargo, puede considerar colocar esta línea al inicio de sus aplicaciones :
SET TABLEPROMPT OFF 
Este nuevo parámetro elimina el cuadro de diálogo LOCFILE() que VFP da al usuario cuando algunos comandos no pueden encontrar la tabla indicada. Los comandos afectados están enumerados en el tópico SET TABLEPROMPT de la Ayuda de VFP.

El comportamiento SET TABLEPROMPT ON/LOCFILE(), no es una buena idea para una aplicación en producción, porque el usuario puede raramente (si acaso) hacer una determinación adecuada de la tabla necesaria para el comando en questión. En su lugar, el código debe atrapar la posibilidad y realizar la acción adecuada. Incluso es preferible que aborte la ejecución, a que el usuario seleccione la tabla inadecuada para esa operación.
TYPE() se puede utilizar en matrices y colecciones Finalmente VFP 9 añadió la posibilidad de depurar las variables que están en una matriz. La función TYPE() ha sido mejorada para aceptar un segundo parámetro opcional que verifique las colecciones
? TYPE("UnaMatriz",1) && "A"rray 
? TYPE("UnaColeccion",1) && "C"ollection 
? TYPE("NiMatrizNiColeccion",1) && "U" 
Vea que TYPE("cExpression",1) devuelve "C" para colección, lo mismo que TYPE("cExpression") devuelve "C" para cadena de caracteres. Una verificación comprensible de un bloque de código preguntará primero con TYPE(...,1) y si devuelve "U", entonces preguntará por el TYPE(...) "regular".

EX168.PRG demuestra que la nueva funcionalidad TYPE(), en un procedimiento AllTypes verifica TYPE("cExpression",1) primero, y devuelve "U", luego realiza la verificación habitual TYPE("cExpression"). AllTypes() diferencia también entre una Colección y un carácter - puede modificar este código según sus necesidades y colocarlo en una biblioteca de procedimientos.
MousePointer, MouseIcon, para Columns/Headers VFP 9 agregó propiedades MousePointer y MouseIcon a las clases base Columns y Headers. Desde VFP 3, los desarrolladores tenían que tratar de eliminar el "punto de intersección" MousePointer para Columns y cambir el MousePointer para Headers. Ahora se puede. Por ejemplo, puede establecer la siguiente configuración para MousePointer para todas las columnas y encabezados de un grid como una flecha, de esta forma:
Grid.SetAll("MousePointer",1) 
Igualar MousePointer a 99 y especifique el archivo Icon en la propiedad MouseIcon para que el puntero del ratón tenga el icono deseado. Esto es particularmente útil para encabezados, facilitando al usuario una clave visual para los encabezados que son movibles, ordenables, etc.

El ejemplo EX170.SCX en EXAMPLES.APP demuestra estas propiedades. Luego de ejecutar DO FORM EX170, seleccione la opción Info... del menú contextual del formulario para más información.
Grid.Optimize Antes de VFP 9, la optimización Rushmore no trabajaba para el RecordSoruce de un grid. Si un grid tiene muchos registros y se estableció un filtro optimizable por Rushmore, la navegación por el grid es muy lento, porque el RecordSoruce no estaba optimizado por Rushmore.

A partir de VFP 9, establezca la propiedad Grid.Optimize a .T. en su clase base grid y aproveche las ventajas de optimización Rushmore.

El ejemplo EX171.SCX demuestra esto. Ejecute el formulario, haga clic derecho sobre el área del formulario, seleccione "Info..." y siga las instrucciones para ver el comportamiento anterior (no optimizado). Vea lo despacio que se realiza la navegación por el grid. Luego, modifique el formulario EX171.SCX y descomente la primera línea de código del Grid.Init, para establecer la propiedad Optimize en .T. Vuelva a ejecutar y vea lo rápido que responde el grid, porque admite optimización Rushmore.

1 comentario :