Sistema en servidor
Hola, tengo un sistema ya trabajando, pero es para trabajar en red, el sistema es operativo, trabaja en un servidor con windows 2003, y lo acceso desde terminales con windows xp, lo unico que hice fue crear una unidad de red en las terminales y ejecutar el .EXE desde las mismas, es el mismo ejecutable en todas, hasta aki todo bien, el problema, es que cuando realizo una busqueda de un producto, en la tabla que tiene mas de 10,000 registros, demora hasta 1 minuto en mostrarme resultados, kiero agilizar esto, he estado leyendo que use bases de datos de SQL, pero entiendo que tendria que cambiar todos los codigos, y obviamente las tablas, el programa graba bien los registros, no tengo problemas mas q cuando realiza la busqueda. Me gustaria ver, si me puedes ayudar con algun codigo que conecte mi programa, corriendolo desde las terminales, y que conecte las tablas en el servidor o algo asi, la vdd, no se como seria mas rapido, tengo ya mas de dos semanas haciendo pruebas y no logro mejorar el rendimiento, ya habilite el SET OPTIMIZE en mis formularios, elimine los codigos que no funcionan con RUSHMORE, pero no me funciona, ayuda por favor...
De antemano, gracias.
1 respuesta
Como realizas la búsqueda en la tabla de productos: ¿Utilizas Seek?
ESTE ES EL CÓDIGO DE LOSTFOCUS DE MI CAMPO:
if !empty(this.value)
if empty(thisform.xcodigo.value)
select 1
use products order tag descrip alias products
go top
locate for substr(alltrim(descrip),at(alltrim(this.value),descrip)) = alltrim(this.value) .or. substr(alltrim(cpp),at(alltrim(this.value),cpp)) = alltrim(this.value)
if eof()
messagebox('no existe ese producto, favor de verificar',64,'')
this.value = ""
thisform.xcodigo.setfocus
return
endif
with thisform
set filter to !deleted() .and. substr(alltrim(descrip),at(alltrim(.xproducto.value),descrip)) = alltrim(.xproducto.value) .or. substr(alltrim(cpp),at(alltrim(.xproducto.value),cpp)) = alltrim(.xproducto.value)
define popup búsqueda from 4,0 to 28,194 font "courier new",11 prompt field padre(alltrim(str(código)),20,' ')+padre(alltrim(descrip),65,' ')+ str(pventa1,12,2) scroll title "seleccione el producto y pulse <enter> para continuar..." shortcut
activate popup búsqueda rest
endwith
with thisform
.xcodigo.value = código
.xproducto.value = descrip
.xpventa1.value = pventa1
.xpventa2.value = pventa2
.xpventa3.value = pventa3
.xpventa4.value = pventa4
.xpventa5.value = pventa5
.xpventa6.value = pventa6
.xexiste.value = existe
.xclave.value = clave
.xmarca.value = marca
.xnotas.value = notas
.xfecha.value = fecact
endwith
foto = space(0)
if file("articulos/"+alltrim(str(thisform.xcodigo.value))+".jpg")
foto = "articulos/"+alltrim(str(thisform.xcodigo.value))+".jpg"
else
if file("articulos/"+alltrim(str(thisform.xcodigo.value))+".gif")
foto = "articulos/"+alltrim(str(thisform.xcodigo.value))+".gif"
else
if file("articulos/"+alltrim(str(thisform.xcodigo.value))+".bmp")
foto = "articulos/"+alltrim(str(thisform.xcodigo.value))+".bmp"
else
foto = "articulos/no disponible.jpg"
endif
endif
endif
thisform.ximagen.picture = foto
set filter to
endif
endif
1. No abras la tabla en el lostfocus del campo, ponla en el entorno de datos de tu form.
2. Crea un indice por código del producto.
3. En el lostfocus del campo código utiliza este código.
lcCodigo = This.Value.
nFind = SEEK(lcCodigo,"productos","código")
If !nFind
=Messagebox("Código No Existe",64,"Error")
Return 0
Endif
Y de allí si pones el código tuyo.
En la sección INIT de mi formulario abro todos los SELECT a usar, y ya solo mando llamar según la necesidad, aquí use nuevamente el USE para ordenar por descripción, lo que pasa es que también busco por código, y si no lo encuentra, entonces lo hace por descripción, y para el código solo uso un LOCATE, también demora, pero es menos que cuando hago la búsqueda, si gustas te puedo enviar el formulario completo para que analices todo el código y me digas en donde mas hay error. Otra cosa es que no cargo ninguna tabla en el entono de datos, todas se mandan llamar en el INIT del formulario mediante SELECT #
Voy a intentar con la corrección que me enviaste y si gustas me dices a que correo te puedo enviar mi problema, me seria de mucha ayuda...
Gracias nuevamente :)
Para alternar el orden de la tabla lo puedes hacer con el siguiente comando sin necesidad de usar nuevamente la tabla.
SET ORDER TO TAG descripción IN productos
SET ORDER TO TAG código IN productos
Ok, muchas gracias, me funciono bien, gracias. Ahora tengo otro problema, en otra pantalla del mismo sistema, el resultado de esta búsqueda, lo mando a un pop up, como lo envíe en el ejemplo, pero como las comptadoras aun demoran un rato en rescatar la información del filtro, a veces el popup se me desactiva y me selecciona un elemento que no deseo, entonces quiero enviar ese filtro a un grid, ya lo conseguí, pero me gustaría que cuando en el grid, presione ENTER, me lo seleccione y lo envíe al formulario, inserte el código en el evento KEYPRESS del grid, pero no me lee...
Ponlo en el evento AftrerRowColChange, y le pones:
Thisform.txtCodigo.Value = This.Column1.Text1.Value
Este es el código que tengo en keypress:
lparameters nkeycode, nshiftaltctrl
if nkeycode = 13
thisform.xcodigo.value = código
thisform.xproducto.value = descrip
thisform.xprecio_u.value = pventa1
thisform.xubica.value = ubica
thisform.xexiste.value = existe
foto = space(0)
if file("artículos/"+alltrim(str(thisform.xcodigo.value))+".jpg")
foto = "artículos/"+alltrim(str(thisform.xcodigo.value))+".jpg"
else
if file("artículos/"+alltrim(str(thisform.xcodigo.value))+".gif")
foto = "artículos/"+alltrim(str(thisform.xcodigo.value))+".gif"
else
if file("artículos/"+alltrim(str(thisform.xcodigo.value))+".bmp")
foto = "artículos/"+alltrim(str(thisform.xcodigo.value))+".bmp"
else
foto = "artículos/no disponible.jpg"
endif
endif
endif
thisform.ximagen.picture = foto
set filter to
endif
thisform.xcompra.setfocus
Una ves que se realiza el filtro, lo envío a un grid, eso lo hace, y el grid toma el enfoque, me despliego por el grid con las flechas, selecciono el elemento que quiero, pero cuando pulso ENTER, solo me brinca de columna, y yo deseo que el grid desaparezca y me asigne los valores a los campos... no se si me explique...
No, lo que pasa es que la grid se crea en el lostfocus, cuando realizo la búsqueda, y no se como meterlo ahí, lo intente con un procedure, pero me marca error.. Así creo la GRID:
with thisform
.removeobject("grid1")
.addobject( "grid1", "grid" )
with .grid1
.columncount = 4
.deletemark = .f.
.gridlines = 1
.gridlinewidth = 1
.headerheight = 20
.height = 348
.left = 12
.panel = 1
.readonly = .t.
.recordmark = .f.
.recordsource = "products"
.scrollbars = 2
.tabstop = .t.
.top = 276
.width = 947
.forecolor = rgb( 0,0,0 )
.backcolor = rgb( 128,128,255 )
.gridlinecolor = rgb( 255,255,255 )
.name = "grid1"
.optimize = .t.
with .column1
.fontsize = 11
.alignment = 0
.width = 80
.readonly = .t.
.visible = .t.
.inputmask = "999999999"
.forecolor = rgb( 0,0,0 )
.backcolor = rgb( 128,128,255 )
.name = "column1"
with .header1
.fontbold = .t.
.fontsize = 11
.alignment = 2
.caption = "código"
.forecolor = rgb( 255,255,255 )
.backcolor = rgb( 0,0,0 )
endwith
with .text1
.controlsource = "products.codigo"
.fontsize = 11
.alignment = 0
.borderstyle = 0
.margin = 0
.readonly = .t.
.visible = .t.
.forecolor = rgb( 0,0,0 )
.backcolor = rgb( 128,128,255 )
.name = "text1"
endwith
endwith
y luego hay otras 3 columnas mas, y luego ya cierro la grid, el código lo tengo en el keypress de la grid, solo trace una grid en el form para poder añadirle el código, pero no tiene ninguna columna definida, ya que se remueve y se vuelve a crear...
Haz lo siguiente, declara una variable publica xCodigo en Init del form,
Public xCodigo
xCodigo="" o 0 si es numérico el campo de tu tabla,
pon un botón Seleccionar en el form de tu grid, el el click del botón pones, xCodigo = producs.codigo y en tu form haces la búsqueda por esta variable xCodigo.
Muchas gracias, justo hice eso. Me esta funcionando bien, me gusta la apariencia que toma, y me parece practico, tuve un problema por que las computadoras demoran en la búsqueda en ocasiones y se traban, ocasionando esto que la pulsación anticipada de cualquier botón, sea este un enter o un ESC o cualquier acción, genere errores en ocasiones, no se como controlarlos, por que me mandan el mensaje de cancelar, ignorar o ayuda, pero si han pulsado un ENTER, por ejemplo, este se acepta y se cancela el programa. Se que es error de las computadoras, pero aun así, es algo que me tiene un poco insatisfecho :( ¿Alguna sugerencia?
Utiliza rutinas de manejo de errores con ON ERROR, mas o menos funciona así:
Me imagino que tienes un programa de procedimientos y funciones, allí en ese programa agregas un procedimiento llamado ErrHand con el siguiente código
Procedure ErrHand
Parameters lcError, lcMessage, lcPrograma, lcLinea
IF TXNLEVEL() > 0
ROLLBACK
ENDIF
nAnswer=MESSAGEBOX("Error "+ALLTRIM(lcMessage)+CHR(13)+"Programa "+lcPrograma+" Linea "+STR(lcLinea),2,64,"Error")
Do Case
Case nAnswer=3
Cancel
Case nAnswer=4
Retry
Case nAnswer=5
Return
Endcase
Return
Y en tu programa de inicio o tu form de inicio pones este código
On Error Do ErrHand With Error(), Message(), Program(), Lineno()
Ok, intentare eso. Tengo un PRG de procedimientos que verifica si existe una tabla, si no la crea, no se si sea eso a lo que te refieres. Ahí mando llamar mis procedimientos como: DO PROCEDURE XYZ ON CREATABLAS
que es como se llama el PRG ¿Puedo meterlo ahí? por que si creo indico procedimiento en algún evento del form o un objeto, me marca error :/
- Compartir respuesta