Page 1 of 1

Relacionar 2 o mas DBF

Posted: Wed Jul 26, 2006 10:05 pm
by joseluisysturiz
Hola a todos, se que para muchso esto debe ser pan conmio, siempre he trabajadon con 1 DBF a la ves, pero ahora debo trabajar on 1 o mas al mismo tiempo, es decir al hacer click o deslizarme por 1 registro me cambie 1 ò 2 DBF al instante mostraondoem los registros que esten relacionados. Ejm. 1 inventario y este a unos lotes que varian pero en el mismo codigo de producto, intente con relacion de DBF, pero me perdi.gracias por la ayuda y si hay algun pequeño ej, mejor.salu2 :shock:

Posted: Wed Jul 26, 2006 11:04 pm
by Raymundo Islas M.
Hola Jose Luis

Podrian mencionarse varias formas para hacer lo que comentas :

Con bases Relacionadas, con scopes, y por UDF's

Habria tambien que ver como estas manejando los browses : con DBF's o con Arrays.

Lo basico para hacer eso, ( desde mi punto de vista :wink: ), ya que tengas definidos y armados tus browses, desde el Principal, que uses la clausula ON CHANGE y mandes llamar a una Funcion que te "llene" los browses secundarios con datos relacionados al valor que le indiques : podria ser el numero de parte de un item, el folio de una factura, etc.
Esto obviamente, va a ser relativo a como estructures tus browses.

Espero te sirva

SALUDOS

Posted: Thu Jul 27, 2006 2:58 am
by R.F.
SET RELATION es uno de los comandos mas poderosos del XBASE pero la gente se complica mucho la vida usandolo, o definitivamente no lo usa.

En realidad no tiene nada de complicado, y es super poderoso, porque te permite "sincronizar" bases de datos, es excelente para cuando tienes campos relacionados y te interesa que las tablas dbf se "dejen huellas" entre si y no quieres hacer un SELECT para buscar en otra area

Funciona de la siguiente manera.

En este ejemplo vamos a relacionar 3 tablas "hijas" contra una tabla "padre" asumimos que por cada registro en la tabla padre, existe uno o mas registros correspondientes en las tablas hijas.

1) Se abren primero las tablas "hijas", estas tablas es conveniente que esten indexadas en base al campo sobre el cual se establece la relacion.

Code: Select all

USE pv.dbf shared new
pv->(ORDSETFOCUS("pvcode"))
pv->(DBGOTOP())

USE groups.dbf shared new
groups->(ORDSETFOCUS("groucode"))
groups->(DBGOTOP())

USE channel.dbf SHARED NEW
channel->(ORDSETFOCUS("chancode"))
channel->(DBGOTOP())
Es muy importante, aunque no necesario, que el campo que relaciona las tablas se llame IGUAL en todas la tablas y sea del mismo tipo, mismo tamaño y mismo numero de decimales en caso de ser un campo numerico.

2) Como seguno paso. Se abre la base de datos "padre", y se indexa por cualquier criterio.
USE agents.dbf SHARED NEW
agents->(ORDSETFOCUS("IATA"))
3) y ahora viene la magia, vamos a relacionar campos de la tabla padre, con sus correspondientes en las tablas hijas:

Code: Select all

   SET RELATION TO channelcod INTO channel ADDITIVE
   SET RELATION TO groupcode INTO group ADDITIVE
   SET RELATION TO pvcode INTO pv ADDITIVE
   (cAliasAgents)->(DBGOTOP())
El comando SET RELATION recibe como clausulas EL NOMBRE DEL CAMPO DENTRO DE LA TABLA PADRE (channelcod, groupcode y pvcode) el INTO establece el ALIAS de la tabla hija. ¿ Como sabe la relacion contra que campo en tabla hija se asocia el padre ?, muy facil, la tabla hija tiene un campo CON EL MISMO NOMBRE que el campo en la tabla padre, es decir, que si en la tabla padre existe un campo llamado channelcod, en la tabla channel tambien existe un campo con el mismo nombre y preferentemente con las mismas características, como mencione anteriormente, no es necesario que el campo este indexado en la tabla hija, pero si es deseable porque esto acelera mucho el acceso a los datos cuando estamos trabajando con relaciones.

Finalmente la clausula ADDITIVE sirve para añadir nuevas relaciones al area padre, si no pones la clausula ADDITIVE, cada nueva relacion que añadas destruye a la anterior, poniendo ADDITIVE, eso no pasa.

3) El acceso a los datos es super mega facil, si estoy en la base de datos padre, y quiero saber el nombre de un campo hago:

agents->nombre

Y si quiero saber el valor del campo nombre, pero que esta en la base de datos hija channel, simplemente pregunto por el campo, indicando el alias de la tabla hija:

channel->nombre

Si yo muevo el puntero en la base de datos padre, AUTOMATICAMENTE todos lo punteros de TODAS las bases de datos hijas se mueven para reflejar la relacion correspondiente

4) ¿ que pasa si no existe un registro relacionado en la base de datos hija ?, no pasa nada, simplmente se devuelve un campo vacio (en realidad el puntero de la base de datos hija esta apuntando a EOF).

Bien, pero que pasa si quiero en un browse tener columnas que vienen de disintas tablas, sin tener que ir a buscarlas, ni tener que hacer un archivo temporal (es decir, matar pulgas a cañonazos) .... jejeje, pues es muy facil.

Si ya tengo relacionadas las tablas pues basta con definir el browse asi:

REDEFINE LISTBOX oBrw FIELDS agents->nombre, channel->nombre, pv->precio ID .......

las columnas relacionadas cambian automaticamente cuando te mueves sobre el browse.

5) ¿ Que pasa si en la tabla hija, hay mas de un registro que coincide con el registro relacionado en tabla padre? por ejemplo en un maestro detalle, donde solo hay un registro padre, y varios registros hijos, por ejemplo de una factura.

Bien, la relacion apuntara AL PRIMER elemento de la tabla hija, luego entonces buscar los registros hijos, no tiene mucha complicacion.

Una de las cosas que poca gente sabe, e ignoro si esta soportada en (x)Harbour y que tenia Clipper 5.3, es la clausula SCOPED dentro del SET RELATION, la clausula SCOPED establece un SCOPE automatico en la tabla hija, filtrando los _ vez que te mueves en la tabla padre.

6) las relaciones se pueden anidar, porque a su vez, las tablas hijas, pueden ser a su vez, tablas padres y asi sucesivamente, es decir, podemos tener una tabla padre, una hija, una nieta, una bisnieta, etc, etc. etc.

Para acceder a los datos de la tabla nieta, entonces hacemos

aliastablahija->aliastablanieta->campoentablanieta

Si te mueves en la tabla padre, la tabla hija se mueve, y obviamente el puntero de la tabla nieta, tambien se mueve.

Como verán, mas facil, no se puede y ahorra miles de lineas de codigo.

Posted: Thu Jul 27, 2006 4:59 am
by Raymundo Islas M.
Master Flores

Como siempre, toda una ponencia :P

Muchas Gracias por el aporte.

Deberias usar una playera que diga : Wiki-Man :wink:


SALUDOS

Posted: Thu Jul 27, 2006 6:42 am
by jose_murugosa
René,

Es bueno saber que contamos con gente que no solamente sabe, sino que tiene la disposición y se toma el tiempo de compartir ese conocimiento y ayudar a los que comienzan. :D

Posted: Thu Jul 27, 2006 8:08 pm
by joseluisysturiz
Gracias a todos por su ayuda y apoyo, no esperaba menos, voy a probar como comenta Mr.Rene, me aclaraste algunas dudas, no estaba tan perdido, luego les hablo sobre mi experiencia y como resolvi esto con su ayuda :lol: , voy a usar DBF y Arreglos al principio para crear los Browse con datos temporales y luego los guardo a la DBF, espero me sirva, gracias una vez mas... :shock: , disculpa, se me paso una "S", ya esta resuelto, al Cesar lo del Cesar y a Rene lo de Rene...

Posted: Thu Jul 27, 2006 10:40 pm
by Armando
Master:

BPS (Breve Pero Substancioso), como siempre.

Por cierto cuando cambiaste de _ (MRS) :-)

Saludos, Armando