Indices y búsquedas

Hola víctor, nuevamente espero contar con tu apoyo lo que nquiero hacer es buscar un numero de factura en mi tabla, tengo un botón con el siguiente código:
***************
Botón buscar
LOCAL r
r=0
r=INPUTBOX("Ingrese Número de Factura","Buscar")
sele reg_compras
set order to reg_comprasC
if seek(r,'reg_compras','reg_comprasC')
thisform.mostrardatos
ELSE
=MESSAGEBOX("Nº de comprobante no existe ...!",0,"Aviso")
return 0
ENDIF
*******
Ahora lo que sucede es que al poner un numero de factura el registro se posiciona en otro registro y me muestra los datos.
En el init del formulario tengo estos indices:
index on año+mes+str(idcomp,5,0) to reg_comprasAMN &&Indice año,mes y numero
INDEX ON idcomp TO reg_comprasID ADDITIVE &&Indice del idcomp
index on año to reg_comprasA ADDITIVE &&Indice del año
index on mes to reg_comprasM ADDITIVE &&Indice del mes
INDEX ON nro_reg TO reg_comprasR ADDITIVE &&Indice del nro de registro (nro_reg)
INDEX ON numauto TO reg_comprasN ADDITIVE
INDEX on nro_comprob to reg_comprasC ADDITIVE &&Indice del nro de comprobante
No se si por usar varios indices no me busque el nro de factura que quiero. Espero tu colaboración.

1 respuesta

Respuesta
1
¿Cuál es el código de la función "mostrardatos"?
Este es el código de la función mostrar datos, dime como seria usando indices estructurados. ¿Algún ejm?.
select reg_compras.idcomp,reg_compras.fecha_emision,reg_compras.fecha_venci,;
reg_compras.nro,reg_compras.serie,reg_compras.nro_comprob,reg_compras.cod,;
reg_compras.bimponible1,reg_compras.igv1,reg_compras.adqui_no_grav,reg_compras.isc,;
reg_compras.otros,reg_compras.imp_total,reg_compras.nro_const_dep,;
reg_compras.fec_const_dep,reg_compras.tip_cambio,;
reg_compras.ruc,reg_compras.nro_reg,reg_compras.fecha_mod,;
reg_compras.tipo_comp_mod,reg_compras.serie_mod,reg_compras.nro_comp_orig,;
reg_compras.año,reg_compras.mes,comprobantes.descripcion,proveedor.rsocial,tipodoc.descripcion1;
FROM reg_compras INNER JOIN comprobantes ON reg_compras.nro=comprobantes.nro;
inner JOIN proveedor ON reg_compras.ruc=proveedor.ruc;
inner JOIN tipodoc ON reg_compras.cod=tipodoc.cod ORDER BY reg_compras.idcomp;
into cursor imprime
*select reg_compras
*SET ORDER TO reg_comprasID
*SELECT imprime
*GO bott
thisform.txtMes.value=imprime.mes
thisform.txtAño.Value=imprime.año
thisform.txtIdcomp.Value=imprime.idcomp
thisform.txtFecha_emision.value=imprime.fecha_emision
thisform.txtFecha_venci.value=imprime.fecha_venci
thisform.txtNro.value=imprime.nro
thisform.txtSerie.value=imprime.serie
thisform.txtNro_comprob.value=imprime.nro_comprob
thisform.txtCod.value=imprime.cod
thisform.txtRuc.value=imprime.ruc
thisform.txtBimponible1.value=imprime.bimponible1
thisform.txtIgv1.value=imprime.igv1
thisform.txtAdqui_no_grav.value=imprime.adqui_no_grav
thisform.txtIsc.value=imprime.isc
thisform.txtOtros.value=imprime.otros
thisform.txtImp_total.value=imprime.imp_total
thisform.txtNro_const_dep.value=imprime.nro_const_dep
thisform.txtFec_const_dep.value=imprime.fec_const_dep
thisform.txtTip_cambio.value=imprime.tip_cambio
thisform.txtNro_reg.value=imprime.nro_reg
thisform.txtFecha_mod.value=imprime.fecha_mod
thisform.txtTipo_comp_mod.value=imprime.tipo_comp_mod
thisform.txtSerie_mod.value=imprime.serie_mod
thisform.txtNro_comp_orig.value=imprime.nro_comp_orig
thisform.lblComprobante.Caption =imprime.descripcion
thisform.lblDoc.Caption =imprime.descripcion1
thisform.lblProveedor.Caption= imprime.rsocial
thisform.Refresh
Los índices estructurados se crean en el diseñador de tablas y se abren cada vez que abres la tabla.
La instrucción Select-SQL la puedes sustituí con relaciones (Set Relation), que es una función nativa de VFP ¿No?
Bueno, veré el uso de set relation, en todo caso el botón buscar no me está funcionando no entiendo por que no encuentra el doc. que busco, ¿alguna otra idea sobre este código?
Botón buscar
LOCAL r
r=0
r=INPUTBOX("Ingrese Número de Factura","Buscar")
sele reg_compras
INDEX on nro_comprob to reg_comprasC
set order to reg_comprasC
if seek(r,'reg_compras','reg_comprasC')
thisform.mostrardatos
ELSE
=MESSAGEBOX("Nº de comprobante no existe ...!",0,"Aviso")
return 0
ENDIF
set order to
¿"nro_comprob" es numérico?, porque "r" es texto
Así es nro_combrob es numérico, en todo caso como seria la búsqueda, ¿si r=0 esa variable no es numérica?.
No, InputBox no es una función nativa de VFP por lo que todo lo que regrese debe ser booleano o texto, según las reglas DDE.
¿Y tienes alguna ide de hacer una búsqueda sin usar input box?, estoy haciendo esto en el evendto vadil de una caja (text4):
sele reg_compras
INDEX on nro_comprob to reg_comprasC
set order to reg_comprasC
if SEEK(STR(thisform.text4.value,10,0),'reg_compras','reg_comprasC')
Thisform.mostrardatos
Endif
Pero sale error: function argument value, type or count is invalid.
Intenta con algo similar a:
Select reg_compras
Index On nro_comprob To reg_comprasC   && Es mejor el uso de indices estructurados
Seek This.Value
If !Eof()
     ThisForm.mostrardatos
EndIf
Si Text4 NO es numérico el código quedaría:
Index On nro_comprob To reg:comprasC
Seek Val( This.Value )
If !Eof()
     ThisForm. Mostrardatos
EndIf
Estoy probando otros códigos incluyendo el que me proporcionaste pero al poner el nº de doc. en la caja de texto me jala y me muestra otro registro.
De entrada ¿Cómo sabes que te muestra otro registro? ¿Por qué es lo que ves con la función "mostrardatos"? ¿No es posible que la función se esté "saltando" el registro? ¿Ya intentaste sin usar funciones no nativas de VFP, es decir, con "Set Relation" en lugar de "Select-SQL"?
Después, quizá la creación del índice en e momento este corrompiendo los datos (una ventaja adicional de los ínidices estructurados)
Y esos dos razonamientos me surgen de bote-pronto, si me das un tiempecito te puedo dar otras diez razones (por lo menos) de porque te muestra un registro que no es el deseado.
El código que te proporcioné es elemental para mi, lo he usado en alguna de las dos opciones desde hace más de quince años, y si en ese tiempo no me ha fallado, comprenderás que no es posible que contigo lo haga.
Bueno tampoco entiendo por que no busca el registro deseado, ahora en la tabla tengo esto indices: Nor, cod, ruc (regulares) y numauto (principal - integer autoinc) que otro indice tuviera que agregar y como lo uso en la caja de texto ya que el campo que busco es nro_comprob.
Solo requieres un solo índice por el campo nro_comprob, los demás no son necesarios, no estorban, pero no son necesarios.
Ejecuta el código paso a paso para que veas si el apuntador de la tabla en que momento se mueve (porque si no te muestra el registro deseado es porque se mueve)
Quizá agregando una inspección dura al código, por ejemplo:
Seek This.Value
? This.Value
If !Eof()
     ? reg_compras.nro_comprob
     ThisForm.mostrardatos
     ? reg_compras.nro_comprob
EndIf
(Los tres valores mostrados en pantalla deben de ser los mismos, si no lo son, el apuntador se movió).
Bueno he agregado un indice a la tabla reg_compras, el indice es nro_comp de tipo regular y en el evento valid de la caja de texto he colocado este código pero aun así no me muestra el registro que quiero, en todo caso como usaría set relation en la función mostrardatos ya que la verdad nunca usé set relation.
sele reg_compras
set order to nro_comp
Seek This.Value
If !Eof()
ThisForm.mostrardatos
EndIf
Mira he hecho lo siguiente, y me ha salido el registro que buscab los datos que estoy mostrando están en la tabla reg_compras pero hay otros registros en otras tablas que también tengo que mostrar, las tablas son comprobantes, proveedor. Eso me faltaría.
sele reg_compras
set order to nro_comp
Seek ALLTRIM(This.Value)
If !Eof()
*ThisForm.mostrardatos
thisform.txtFecha_emision.Value=fecha_emision
thisform.txtNro_comprob.Value=nro_comprob
thisform.txtSerie.Value=serie
thisform.txtIdcomp.Value=idcomp
thisform.txtAño.value=año
thisform.txtMes.value=mes
EndIf
La estructura de a función Set Relation es:
Set Relation To campo InTo tabla
En el caso de tu función sería algo similar a:
Select reg_compras
Set Relation To nro InTo comprobantes, ruc InTo proveedor, cod InTo tipodoc

ThisForm.txtMes.Value = reg_compras.mes
ThisForm.txtAño.Value = reg_compras.año
ThisForm.txtNro_reg.Value = reg_compras.nro_reg
ThisForm.txtFecha_mod.Value = reg_compras.fecha_mod
ThisForm.txtTipo_comp_mod.Value = reg_compras.tipo_comp_mod
ThisForm.txtSerie_mod.Value = reg_compras.serie_mod
ThisForm.txtNro_comp_orig.Value = reg_compras.nro_comp_orig
ThisForm.txtRuc.Value = reg_compras.ruc
ThisForm.lblComprobante.Caption = comprobantes.descripcion
ThisForm.lblDoc.Caption = tipodoc.descripcion1
ThisForm.lblProveedor.Caption = proveedor.rsocial
ThisForm.txtFecha_emision.Value = reg_compras.fecha_emision
ThisForm.txtFecha_venci.Value = reg_compras.fecha_venci
ThisForm.txtNro.Value = reg_compras.nro
ThisForm.txtSerie.Value = reg_compras.serie
ThisForm.txtNro_comprob.Value = reg_compras.nro_comprob
ThisForm.txtCod.Value = reg_compras.cod
ThisForm.txtBimponible1.Value = reg_compras.bimponible1
ThisForm.txtIgv1.Value = reg_compras.igv1
ThisForm.txtAdqui_no_grav.Value = reg_compras.adqui_no_grav
ThisForm.txtIdcomp.Value = reg_compras.idcomp
ThisForm.txtIsc.Value = reg_compras.isc
ThisForm.txtOtros.Value = reg_compras.otros
ThisForm.txtImp_total.Value = reg_compras.imp_total
ThisForm.txtNro_const_dep.Value = reg_compras.nro_const_dep
ThisForm.txtFec_const_dep.Value = reg_compras.fec_const_dep
ThisForm.txtTip_cambio.Value = reg_compras.tip_cambio
ThisForm. Refresh
Acabo de ejecuta el código pero me dice alias Comprobantes is not found (el alias no es encontrado) en la linea set relation.
¿Esta la tabla Comprobantes abierta?
No esta abierta la tabla comprobantes.
Entonces, ábrela antes de hacer la relación.
Si pongo
sele reg_compras
selec comprobantes
Me sale el mismo error
Si, porque no la has abierto.
Use Comprobantes Order nro In 0
Estoy colocando así:
Select reg_compras
Use Comprobantes Order nro In 0
USE proveedor order ruc IN 0
USE tipodoc order cod IN 0
Y cuando digito el nro de doc me dice file in use (archivos en uso)
Eso es porque estás abriendo las tablas en cada ocasión, las tablas se abren solo una vez por sesión, no cada vez que las necesitas.
Abrelas en el evento Load o Init

Añade tu respuesta

Haz clic para o