FoxPro/Visual FoxPro - Ayuda! ¿Cómo harían un form de consulta??

 
Vista:

Ayuda! ¿Cómo harían un form de consulta??

Publicado por Andrea (325 intervenciones) el 06/12/2010 19:52:52
Hola a todos nuevamente.

Hoy me llamaron desde el lugar donde tienen mi programa (tipo supermercado) porque se tildaba la búsqueda de productos.

Explico:

EN el formulario FACTURACION hay un TEXTBOX donde se carga el código del artículo (Código de Barras)

Si el cajero presiona una tecla, aparece un formulario con TODOS los productos del super ordenados x nombre (en un LISTBOX) para buscar el producto secuencialmente.

Antes, el origen de datos del LISTBOX era un SELECT SQL pero era MUUUYYY lento (3 a 4 segundos por producto)

Ahora le cambié el origen de datos: agregué tipo CAMPOS, y en el ENTORNO DE DATOS del FORM de consulta lo declaré como SESIÓN PRIVADA DE DATOS pero....

EVIDENTEMENTE NO FUNCIONA!!! o se traba.

-----> Pregunta...

¿¿¿¿COMO HARÍAN USTEDES UN FORMULARIO DE CONSULTA??? (todos los artículos del super)

Gracias =)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil

RE:Ayuda! ¿Cómo harían un form de consulta??

Publicado por victor perez (278 intervenciones) el 07/12/2010 00:52:08
Hola,

Yo hago las consultas en el programa de facturacion de la clinica, como Tu lo hacias inicialmente y no he tenido ningun problema.

Ahora bien, hago consultas en bases de datos con mas de 30,000 registros y no hay lentitud en el sistema...al estar ordenado por un campo clave.

No sé que decirte !!! Esperemos a ver si alguien da otra opinión al respecto.

Victor - Panama
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Ayuda! ¿Cómo harían un form de consulta??

Publicado por xx (378 intervenciones) el 07/12/2010 13:15:19
Primero te comento que los LISTBOX y COMBOBOX no son apropiados para contener gran cantidad de registros.

Te recomendaria que primero des la posibilidad al usuario que elija que buscará, si un codigo o un nombre de producto, luego habilitas un cuadro de texto adecuado para que este introduzca el codigo o el nombre a buscar y luego seleccionas (SELECT SQL) de tu lista de productos los que coincidan con lo buscado y lo reflejas en la una grilla luego envias el foco a la grilla y el usuario dara enter para seleccionar el producto actual o en todo caso se desplazara hasta encontrar el producto que busca y dara ENTER para seleccionarlo luego podrias pedir cantidad y precio del producto seleccionado.

Bueno la idea principal es no traigas todos los productos de una vez trae una seleccion reducida para que el usuario agarre uno, Es una idea, tu decides

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

RE:Ayuda! ¿Cómo harían un form de consulta??

Publicado por victor perez (278 intervenciones) el 07/12/2010 19:56:17
Exacto..Asi lo hago Yo...al no encontrar el producto el sistema abre una Mascara donde hay un TEXTBOX. Alli el usuario introduce algunas letras o numeros de la descripcion del producto y entonces la Grilla se alimenta segun esa info, al hacer la consulta SQL.

Saludos,

Victor - Panama
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Ayuda! ¿Cómo harían un form de consulta??

Publicado por jorge (1 intervención) el 07/12/2010 21:22:09
Hola Andrea como estas?
Viendo esta consulta me doy cuenta, cual es tu problema con la lentitud en la red, que era motivo de una consulta anterior.
Hace muchos años que programo en Foxpro (desde D.O.S.) y muchas de esas aplicaciones corren en red, utilizando lenguaje y tablas nativas de Fox, sin ningun tipo de problema y con la velocidad que siempre caracterizo a nuestro querido Zorro.
El tema esta en que debes adecuar tu forma de trabajar al modo de red, que quiero decir con esto? Simple, cuando tu peticionas hacia el servidor una determinada cantidad de datos, mientras mas grande sea esa peticion mas lenta sera tu respuesta en la red.
Para evitar esto debes tener en cuenta algunas cosas por ejemplo:
a) utilizar SIEMPRE la tabla indexada
b)no utilizar SET FILTER
c)no utilizar InteractiveChage
Si por ejemplo buscas un articulo como 'ACEITE' que la busqueda lo ubique y muestre el primer articulo que empiece con esa denominacion en una grilla por ejemplo, sin SET FILTER
Busca crear tablas temporales o cursores. Estos se crean en la maquina donde se esta ejecutando el sistema, no en el servidor, por esta razon son mas rapidas las busquedas sobre las mismas.
Son muchas las cosas que debes tener en cuenta en tu forma de trabajar en red, esto es un simple indicativo para empezar a pensar...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Ayuda! ¿Cómo harían un form de consulta??

Publicado por es_binario (757 intervenciones) el 08/12/2010 00:03:55
Coincido con Jorge, si bien recuerdo este problema que tienes va a cumplir un año o mas, es decir que de una forma u otra has logrado medio parchar los males de tu aplicacion, que seguramente y tiene bastante tiempo en el mercado en el super para ser exacto, funcionando de forma casi magica.

El problema es la red pero no tu cableado o tus tarjetas de red, sino la forma en la que accedes a ella con foxpro.

Coincido con jorge cuando se tenga que buscar un producto por descripcion pon otro form con otro textbox y una grilla pero esta en blanco y sin datos pon el cursor en el textbox y a un lado pon el boton de buscar y solo hasta que el usuario escriba una palabra o frase que realize la consulta, no cambio nada unicamente la forma en la que el usuario interactua con los datos

Recuerda que si haces un Select * from articulos esto te traera el total de tu digamos unos 3mb si es lo que pesa la tabla pero si ya tiene un peso de digamos unos 10 mb tendra una tardanza notable.

La mejor solucion la has reuido de alguna manera es migrar a un motor Cliente Servidor como Mysql, Sql server, tambien cuenta la memoria del servidor y la velocidad de su disco duro asi como los antivirus que verifican todo el trafico por red. si usas wifi sera un poco mas lenta la respuesta por la encriptacion y desencriptacion.

-- Ademas cuando usas una tabla en red es decir una unica tabla contenida en un servidor bueno una base de datos como no usas los locks para escribir o leer en el servidor tus clientes que se conectan a ella con el paso del tiempo mas bien de los minutos es decir que entre mas la consulten mas lenta se hace debido a que el servidor en este caso windows cualquiera cree que hay mas de un usuario usandola simultaneamente por lo que se reduce el rendimiento a su acceso

Para mi la mejor solucion es que ya migres a un motor cliente servidor, pero si todabia no estas listas podrias hacer una modificacion que todos los esten en los clientes y que unicamente mande los cambios al servidor.

la tabla mas consultada en un super es la tabla de articulos para realizar la suma los totales etc. luego a la hora de cobrar hay que registrar unicamente los articulos vendidos lo que representa poco trafico asi, si tienes la tabla en cada cliente sera muy rapida la venta, no debes usar vistas usa cursores para mostrar informacion en pantalla. aqui viene un detalle que solucionas con sokets, debes tener un par de sockets uno para el cleinte y otro para el servidor, entonces mandas y registras la venta en el servidor evidentemente afecta a tu caja pero tambien a tus inventarios.
la funcion del socket es de indicarle a los demas clientes que ocurrio un cambio, es decir que debe actualizar las existencias de x producto, esto a travez de sockets, como funciona, es una red colectiva en la que todos saben lo que hacen todos a si siempre estan actualizadas las existencias, es decir aunque una cajo no este operable debe de actualizar sus existencias al momento con sockets y al iniciar la aplicacion lo primero que debe hacer es actualizar tanto las nuevas existencias asi como productos nuevos que hayan ingresado al super.

suerte.
Saludos desde Mexico.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

A todos... GRACIAS y...

Publicado por Andrea (325 intervenciones) el 08/12/2010 16:36:38
Realmente gracias por sus sugerencias y experiencias (victor, jorge, xx, es_binario).
Es muy enriquecedor poder tener un lugar donde cada uno aporte sus aventuras, desventuras y aciertos con este mundo de la programación =)

Tal como dice es_binario, este problema es algo que viene "sobreviviendo" hace un tiempo largo y por lo cual estoy empezando a desarrollar algo paralelo en MySQL.

Lo extraño de todo esto es que muchas de las cosas que ustedes me sugirieron ya están funcionando, como las tablas indexadas, no usar vistas, usar SELECT SQL optimizable (por un índice), etc.

Y también lo extraño es que tengo un programa parecido en otro lugar (también pariente) y pasa algo parecido: de golpe la red se pone lenta y pesada para consultas de artículo, clientes, etc

Si soy un poco más profunda, el "kernel" del programa lo hicimos (en la época de estudiantes) con unos compañeros, basado en el libro de Rubén Iglesias (creo que editorial Ra-Ma) donde hacía un desarrollo completo de un programa basándose en Programación Orientada Objetos y en formularios con sistemas de buffer para trabajar en red (novedad en esa época con respecto al Clipper o FoxPro para DOS, que utilizaban comandos como RLOCK y FLOCK)

Volviendo al post, una de las cosas que descubrí es que si en la instrucción SELECT SQL que "filtra" los artículos le saco la parte "ORDER BY", la consuta es RAPIDÍSIMA.
Si le agrego esa parte tarda 4 o 5 segundos más que, les confieso, es un tiempo enorme cuando hay alguien esperando en la cola del cajero.

Voy a releer mas tranquila todos los post y ni bien tenga una mejora en el rendimiento se las transmito así les sirve a todos!

Gracias =)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Releyendo...

Publicado por Andrea (325 intervenciones) el 08/12/2010 18:56:58
Hay un párrafo del post de es binario en el que "pinta" el problema

"Ademas cuando usas una tabla en red es decir una unica tabla contenida en un servidor bueno una base de datos como no usas los locks para escribir o leer en el servidor tus clientes que se conectan a ella con el paso del tiempo mas bien de los minutos es decir que entre mas la consulten mas lenta se hace debido a que el servidor en este caso windows cualquiera cree que hay mas de un usuario usandola simultaneamente por lo que se reduce el rendimiento a su acceso "

Me parece que ahí se genera el problema

¿USTEDES CONOCEN ALGUNA FORMA POR CÓDIGO DE "VACIAR" EL TRÁFICO DE RED PARA QUE NO GENERE ESE EFECTO??
Siempre partiendo de la premisa que el programa está mal hecho (mal, pero funcionando ja ja)...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Releyendo...

Publicado por es_binario (757 intervenciones) el 09/12/2010 21:32:33
El problema vamos a hablar de las talbas dbf. Es que windows las trata como un fichero y no como parte de una base de datos, bueno cuando uno accede a un archivo mientras uno lo tiene abierto windows bloquea la funcion de modificar y de borrar dicho archivo, solo le permite leerlo a varios usuarios. Pues bien cuando tu haces una consulta en realidad lo que hace foxpro es crear una tabla temporal sobre los datos consultados digamos sobre la tabla articulos

articulos tiene 23000 registros

Select * from articulos where ariculos.descripcion like "LONOL"

te arroja 3 resultados en mi caso (ipotesis)

bueno en realidad foxpro lo que hizo fue crear una tabla temporal que es la que te muestra esos 3 registros, el primer problema que cuando haces esta consulta que es la mejor via para una tabla en red es que la consulta se crea en tu disco duro y no en el servidor es decir las tablas temporales.

el otro problema es que de esta forma no hay ninguna indicacion que le diga a xp o windows server o x sistema operativo del servidor que ya la dejaste de usar, xp (supongamos) no sabe que ya terminaste tu consulta y para el todabia la estas usando.

Bueno una segunda maquina hace una consulta sobre esa misma tabla fichero para xp, lo que hace xp es que crea un cache es decir una copia identica del fichero para responder esto debido a que otro usuario se supone la esta usando y continua el problema para xp a menos que se apague el equipo remoto el la va a seguir usando, pero si a esto le añadimos el hecho de que no es una unica tabla sino que son unas 10 las que usa cada maquina en red y son mas de una maquina finalmente el cache se vuelve lento y en muchos casos obsoleto y puede arrojar datos incorrectos.

Si no desea migrar a un motor cliente servidor como mysql ... etc.

Entonces debes acceder a los ficheros a las tablas dbf de tal forma que despues de cada consulta le informes a xp que ya no lo ocupas, esto lo puedes hacer de 2 formas una es usar ADO para conectarte a tus tablas o bases de datos foxpro en donde se especifica la conexion con la ip o nombre del servidor y la otra es usar ODBC de foxpro para acceder a los datos al ser ODBC o ADO los que te comunican windows dejara de tratar a la dbf como un fichero y lo comenzara a usar como una base de datos con sus consecuentes optimizaciones.

Para mejorar el rendimiento a un mas puedes crar tiggers en las bases de datos o procedimientos almacenados de consultas frecuentes para que sea en el servidor donde se ejecuten y no en foxpro.

Como veras, tambien hay que escribir mucho codigo para hacer que funcione bien la aplicacion.

Saludos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Releyendo...

Publicado por Andrea (325 intervenciones) el 09/12/2010 22:08:32
Gracias Es_binario:

Como siempre, has sido MUY DIDÁCTICO y claro con tus explicaciones.

Saludos =)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Releyendo...

Publicado por xx (378 intervenciones) el 10/12/2010 12:55:34
Para complementar un poco lo que dice es_binario:

Durante la apertura en red de tablas nativas o DBF sucede lo siguiente:

Se abre un descriptor de archivo y asigna un espacio de memoria para dicho archivo y se copia en este espacio parte del archivo, y este pequeño segmento del archivo leido es enviado atravez de la red al terminar y al programa que solicito la apertura.

Como se nota la apertura de tablas no conlleva mucha sobre carga ni trafico de red, cuando una tabla tiene un indice este es tratado del mismo modo que el dbf es decir se abre un descriptor y asigna memoria y se envia al terminal hasta ahora todo normal.

Cuando se busca un registro con seek() este trae por partes el archivo CDX o IDX desde el servidor pero como generalmente este es pequeñito no constituye mucha sobre carga y este culmina su funcion de localizar el registro y el proceso termina sin demora.

Esto es lo mismo que ejecutar un SELECT pero ooojjjooo sobre un campo indexado es decir la clausua WHERE sobre un campo indexado, resultando en un o pocos registros, por eso se recomienda el uso de indices sobre campos claves.

Ahora que sucede si ejecutamos un SELECT sobre una tabla que no tiene indices o la clausula WHERE no contiene campos indexados, pues el programa tiene que solicitar todo el DBF al servidor para ir analizando registro por registro, si es una tablita chiquita no hay demora pero una con varios miles de registros y varios campos podria ocacionar el cuelgue de tu red y si a todo esto le sumas 2 o mas terminales haciendo el mismo proceso, imaginate!!!.

La tecnologia de seleccion basado en campos indexados tambien es aplicado en motores SQL, los motores SQL tambien fallaran ante un mal uso es decir si tu ejecutas un SELECT sobre una tabla no indexada o una clausula WHERE sin campos indexados con una cantidad considerable de registros y varios usuarios simultaneos(mejor dicho no fallaran sino que demoraran!! jejeje).

Ojala sirva la info.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

RE:Has pensado en la función SEEK()

Publicado por neo (1604 intervenciones) el 10/12/2010 21:20:23
Yo tambien he realizado aplicaciones en red, y me va mejor con la funcion SEEK para buscar un articulo en 0 segundos.

Ejemplo:

Select Mi_tabla
set order to Articulo
Seek Alltrim(Thisform.text1.value) &&el campo donde se ingreso un articulo
If Found()
browse
else
Wait window "No se encontró el articulo ingresado, intente de nuevo..." Timeout .8
endif


Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Has pensado en la función SEEK()

Publicado por Andrea (325 intervenciones) el 10/12/2010 22:37:25
Hola Neo:
SI, de hecho uso SEEK() en varias partes.
Lo que pasa es que el problema (que vengo "emparchando" desde hace un año) es que toda la red se vuelve lenta al cargar formularios o al hacer una consulta con varios articulos.
De todas maneras, con la explicacion técnica de xx y de es_binario (sobre la manera que VFP maneja las conexiones) puedo ir mejorando la performance en varios aspectos.
Saludos =)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Has pensado en la función SEEK()

Publicado por alberto (404 intervenciones) el 13/12/2010 02:55:28
hola andrea , te cuento , que despues de leer los comentarios de nuestros amigos del foro me puse a hacer pruebas com mi sistema de gestion comercial en una red innalambrica que tengo en casa con mi pc personal y una notebook mia , cree indices por los campos que hagos los select en el where y me dio un resultado fantastico, el sistema vuela en la notebook conectada a la pc , hice una prueba con una tabla de 800.000 registros con :

select cliente , direccion , telefono , fecha from cli000 ;
where fecha >=dato1 and fecha <= dato2 into cursor tempo
select tempo
brow
y en la red en la notebook demora como un minuto en mostrar los datos , el la pc lo muestra rapido , y agregando estos 2 comandos :

select cli000
set order to fecha /// indice por fecha
select cliente , direccion , telefono , fecha from cli000 ;
where fecha >=dato1 and fecha <= dato2 into cursor tempo
select tempo
brow

VUELA !!! EN LA RED , EN 0 SEGUNDOS ME TIRA LOS DATOS CON UNA TABLA DE 800.000 REGISTROS , PARA TENERLO EN CUENTA , NO ?
saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar