2 de septiembre de 2005

Autocompletar en Cuadros de Textos de VFP 9.0

Introducción

Una nueva característica de Visual FoxPro 9.0 es que el control TextBox (Cuadro de Texto) tiene la funcionalidad de Autocompletar, que nos sugiere valores de una tabla, a medida que se introducen caracteres en él. Si se selecciona un valor de la lista desplegada, el cuadro de texto se completa y se actualiza la tabla que contiene los datos almacenados.

Esta nueva característica ya fue tratada en un artículo de Jorge Mota (Guatemala) publicado en PortalFox: "Usando Autocompletar en TextBoxs de VFP 9"

En este nuevo artículo veremos como podemos hacer para que Autocompletar nos sugiera valores de una tabla de nuestra aplicación.

Las nuevas propiedades

Visual FoxPro 9.0 incorporó tres nuevas propiedades al control TextBox para esta funcionalidad: AutoComplete, AutoCompSource y AutoCompTable.

Si la propiedad AutoComplete se configura con un valor distinto de cero (el valor cero indica que no está habilitado Autocompletar), a medida que se introducen caracteres, se sugieren valores con la exhibición de una lista desplegada. Esta lista muestra los valores que concuerden con los valores previamente almacenados. Según el valor que se configure esta propiedad, la lista se ordenará "Alfabéticamente", "El mas frecuentemente usado", "El mas recientemente usado" o "Personalizado", que se ordena descendentemente por el "peso" que se le da al valor mediante un algorítmo realizado por el usuario que modifique el campo Weight (Peso) de la tabla AutoComp. Los valores permitidos para esta propiedad son 0, 1, 2, 3 y 4.

La propiedad AutoCompSource almacena el nombre clave que se utilizará para buscar en la tabla AutoComp. Si se omite esta propiedad, el nombre del control será la clave de búsqueda en la tabla. Se puede lograr que varios controles del tipo TextBox, utilicen la misma lista, configurando esta propiedad con un valor igual en todos los controles.

La propiedad AutoCompTable especifica el nombre y la ruta de la tabla que almacena los datos usados por un control TextBox para sugerir los valores. El valor por omisión de esta propiedad es (HOME(7) + "autocomp.dbf"). Si la tabla no existe, VFP la creará automáticamente.
Nuestro caso

Para nuestro caso de que Autocompletar nos sugiera los valores de una tabla de nuestra aplicación, haremos hincapié en la propiedad AutoCompTable y la configuraremos con la ruta y nombre de una tabla que crearemos y poblaremos con los datos de nuestra tabla de acuerdo a la estructura y descripción de cada campo de la tabla AutoComp que es la siguiente:

CampoTipoDescripción
Source Caracter(20) Nombre de la fuente del control TextBox.
Data Caracter(254) Dato a mostrar.
Count Entero Número de veces que el dato fue seleccionado.
Weight Entero Especifica el valor a usar cuando AutoComplete esta configurado en 4.
Created DateTime Fecha y hora de creación del dato.
Updated DateTime Fecha y hora de la última modificación del dato.
User Memo Especifica información de usuario.

La tabla AutoComp esta indexada con la siguiente clave:
INDEX ON ;
  UPPER(SOURCE + LEFT(DATA,30)) + PADL(COUNT,8) ;
  TAG DATA FOR NOT DELETED()

El ejemplo

Para nuestro ejemplo tomaremos la tabla "Customers" de la base de datos "Northwind" que viene junto a los ejemplos de Visual FoxPro 9.0. Los campos que seleccionaremos e insertaremos en la tabla son "CompanyName", "ContactName", "City" y "Country".

Primeramente invocamos al método "CrearTablaAutoComp()" que crea la tabla "MiAutoComp.dbf" en el directorio de archivos temporales de Windows y la indexa.

Luego por cada control TextBox en los cuales queremos habilitar la funcionalidad de autocompletar, invocamos al método "InsertarReg()" que inserta en la tabla "lcDbfAuto", los datos de la tabla "lcDbfOrigen" y del nombre de campo y nombre de clave que pasamos como parámetros, mediante un "INSERT INTO ... FROM SELECT ..."; y configuramos las propiedades "AutoComplete", "AutoCompSource" y "AutoCompTable".

El siguiente código genera un formulario con cuatro cuadros de textos con las propiedades configuradas para que Autocompletar nos sugiera los valores de nuestra tabla "MiAutoComp".

PUBLIC goMiForm
goMiForm = CREATEOBJECT("MiForm")
goMiForm.SHOW(1)
RETURN

DEFINE CLASS MiForm AS FORM
  AUTOCENTER = .T.
  CAPTION = "Ejemplo de Autocompletar en TextBox"
  NAME = "MiForm"
  ADD OBJECT txtCompania AS TEXTBOX WITH ;
    HEIGHT = 24, ;
    LEFT = 84, ;
    TOP = 24, ;
    WIDTH = 264, ;
    NAME = "txtCompania"
  ADD OBJECT txtContacto AS TEXTBOX WITH ;
    HEIGHT = 24, ;
    LEFT = 84, ;
    TOP = 72, ;
    WIDTH = 264, ;
    NAME = "txtContacto"
  ADD OBJECT txtCiudad AS TEXTBOX WITH ;
    HEIGHT = 24, ;
    LEFT = 84, ;
    TOP = 120, ;
    WIDTH = 264, ;
    NAME = "txtCiudad"
  ADD OBJECT txtPais AS TEXTBOX WITH ;
    HEIGHT = 24, ;
    LEFT = 84, ;
    TOP = 168, ;
    WIDTH = 264, ;
    NAME = "txtPais"
  ADD OBJECT lblCompania AS LABEL WITH ;
    AUTOSIZE = .T., ;
    BACKSTYLE = 0, ;
    CAPTION = "Compañia", ;
    LEFT = 12, ;
    TOP = 28, ;
    NAME = "lblCompania"
  ADD OBJECT lblContacto AS LABEL WITH ;
    AUTOSIZE = .T., ;
    BACKSTYLE = 0, ;
    CAPTION = "Contacto", ;
    LEFT = 12, ;
    TOP = 76, ;
    NAME = "lblContacto"
  ADD OBJECT lblCiudad AS LABEL WITH ;
    AUTOSIZE = .T., ;
    BACKSTYLE = 0, ;
    CAPTION = "Ciudad", ;
    LEFT = 12, ;
    TOP = 124, ;
    NAME = "lblCiudad"
  ADD OBJECT lblPais AS LABEL WITH ;
    AUTOSIZE = .T., ;
    BACKSTYLE = 0, ;
    CAPTION = "País", ;
    LEFT = 12, ;
    TOP = 172, ;
    NAME = "lblPais"

  PROCEDURE INIT
    LOCAL lcDbfAuto, lcDbfOrigen
    *-- Ruta y nombre de la tabla AutoCompletar
    lcDbfAuto = ADDBS(SYS(2023)) + "MiAutoComp.dbf"
    *-- Creo la tabla AutoCompompletar
    THISFORM.CrearTablaAutoComp(lcDbfAuto)

    *-- Ruta y nombre de la tabla Origen
    lcDbfOrigen = ADDBS(HOME(2))+ "NorthWind\Customers.dbf"

    *-- Inserto los registros para cada campo
    *-- y configuro las propiedades de cada TextBox
    THISFORM.InsertarReg(lcDbfOrigen,lcDbfAuto,"AC_COMPANIA","CompanyName")
    THISFORM.txtCompania.AUTOCOMPLETE = 1
    THISFORM.txtCompania.AUTOCOMPSOURCE = "AC_COMPANIA"
    THISFORM.txtCompania.AUTOCOMPTABLE = lcDbfAuto

    THISFORM.InsertarReg(lcDbfOrigen,lcDbfAuto,"AC_CONTACTO","ContactName")
    THISFORM.txtContacto.AUTOCOMPLETE = 1
    THISFORM.txtContacto.AUTOCOMPSOURCE = "AC_CONTACTO"
    THISFORM.txtContacto.AUTOCOMPTABLE = lcDbfAuto

    THISFORM.InsertarReg(lcDbfOrigen,lcDbfAuto,"AC_CIUDAD","City")
    THISFORM.txtCiudad.AUTOCOMPLETE = 1
    THISFORM.txtCiudad.AUTOCOMPSOURCE = "AC_CIUDAD"
    THISFORM.txtCiudad.AUTOCOMPTABLE = lcDbfAuto

    THISFORM.InsertarReg(lcDbfOrigen, lcDbfAuto,"AC_PAIS","Country")
    THISFORM.txtPais.AUTOCOMPLETE = 1
    THISFORM.txtPais.AUTOCOMPSOURCE = "AC_PAIS"
    THISFORM.txtPais.AUTOCOMPTABLE = lcDbfAuto
  ENDPROC

  PROCEDURE CrearTablaAutoComp(tcDbfAuto)
    *-- Crea mi tabla Autocompletar
    SET SAFETY OFF
    CREATE TABLE (tcDbfAuto) FREE ;
      (SOURCE C(20), DATA C(254), COUNT I, Weight I, ;
      Created T, UPDATED T, USER M)
    *-- Indexo la tabla
    INDEX ON UPPER(SOURCE + LEFT(DATA,30)) + PADL(COUNT,8) ;
      TAG DATA FOR NOT DELETED()
    *-- Cierro tabla
    USE IN SELECT(JUSTSTEM(tcDbfAuto))
  ENDPROC

  PROCEDURE InsertarReg(tcDbfOrigen, tcDbfAuto, tcSource, tcData)
    *-- Inserto los registros a la tabla Autocompletar
    INSERT INTO (tcDbfAuto) ;
      SELECT DISTINCT UPPER(tcSource) AS SOURCE, ;
      EVALUATE(tcData) AS DATA, 0 AS COUNT, 0 AS Weight, ;
      DATETIME() AS Created, DATETIME() AS UPDATED, .F. AS USER ;
      FROM (tcDbfOrigen)
    *-- Cierro tablas
    USE IN SELECT(JUSTSTEM(tcDbfAuto))
    USE IN SELECT(JUSTSTEM(tcDbfOrigen))
  ENDPROC
ENDDEFINE

Si ejecutamos el código e introducimos valores en los cuadros de textos, se mostraran las listas con los valores sugeridos como se observa en la siguiente imagen:



El número de items mostrados en la lista desplegable por defecto es 15. Se puede configurar este número con la siguiente función:

SYS(2910,nValor) && nValor = [5..200]

Conclusiones

Este ejemplo es solo para mostrar como podemos sugerir valores en un cuadro de texto en Visual FoxPro 9.0. Queda en nosotros saber si conviene o no utilizar esta técnica con el control TextBox o elegir otro tipo de control como un ComboBox o ListBox.

Hasta la próxima.

Luis María Guayán

5 comentarios :

  1. mayor informacion sobre el código no me funciono

    ResponderBorrar
  2. Excelente!
    Gracias por compartir. Todo se quedó muy facil con este artículo!

    ResponderBorrar
  3. A small query regarding the VFP9 autocomplete text box. I am developing a POS application for a client, since it works on keyboard controls for faster data entry, and the autocomplete text box is very convenient to access the product master.

    The only problem being that if the number filtered based on keystroke (say 'LI') of products is say 20 products, and the required product is at the end of the filtered dropdown, the customer would like to have a wrap around while using the 'UP ARROW' key, i.e if it hits the top then the selected product ite starts at the bottom of the dropdown and the customer can use the 'UP ARROW' to access the required product. This is available in existing version of POS used by client, developed in VB. He has to change because the developers no longer support the product.

    Was wondering if this is technically possible, since I have no idea how to access the filtered list or under what form it is stored. Or any info on this issue will be much appreciated.

    I am not sure if your personal mail is the right forum to ask a question.

    Thanks and regards

    --
    Joseph Mathai

    ResponderBorrar

Los comentarios son moderados, por lo que pueden demorar varias horas para su publicación.