Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   usar el tabset en un dbgrid (https://www.clubdelphi.com/foros/showthread.php?t=4968)

vetustas 04-11-2003 13:10:18

usar el tabset en un dbgrid
 
Hola!

Trabajo con Delphi5 y paradox. Tengo una tabla de alumnos. Y uno de sus campos es año. Lo que quiero es mostrar un listado (en un dbgrid) y por ejemplo usar un TabSet para ordenarlos por ese campo año. Es decir, tener varias pestañas debajo: 2001,2002,2003..etc. Cómo lo hago?

Muchas gracias

jachguate 04-11-2003 13:43:39

hey... hay mil formas.

En principio podes hacer un select distinct sobre el año, para saber cuantos tabs crear y como deben llamarse.

Luego, podes tener un Query por cada tab, con su propio datasource y regilla, y cuya propiedad SQL ya estará enlazada al año que representa.

También podes tener un Query genérico, con un parámetro año, y cada vez que el usuario seleccione un tab, cerrar el query, cambiar el valor del parámetro por el adecuado, y abrirlo de nuevo.

Hasta luego.

;)

vetustas 04-11-2003 13:53:57

Muchas gracias por tu respuesta

Y qué opinas de aplicar rangos o filtros? Toy un poco perdida. Podrías enseñarme un ejemplo con algo de codigo.

Graciasssssss

jachguate 04-11-2003 13:59:46

La desventaja de los filtros, es que al aplicarse del lado del cliente, pueden sobrecargarte la red innecesariamente, y volver lenta tu aplicación.

Yo me inclino por la solución con Queryes, donde el "fitro" se aplica de forma mucho mas óptima, y del lado del servidor.

mmm... codigo, por ahora lo siento, pero ya me voy. Vuelvo mas tarde, y con gusto te ayudo un poco.

Salu2.

;)

roman 04-11-2003 17:10:14

Cita:

vetustas comentó:
Trabajo con Delphi5 y paradox. Tengo una tabla de alumnos. Y uno de sus campos es año. Lo que quiero es mostrar un listado (en un dbgrid) y por ejemplo usar un TabSet para ordenarlos por ese campo año. Es decir, tener varias pestañas debajo: 2001,2002,2003..etc. Cómo lo hago?

Aquí va una idea:

Creas, en caso de que no la tengas ya, una tabla para almacenar los posibles años:

años = (semestre)

esto es, un sólo campo que a su vez es la llave primaria.

En la tabla de alumnos creas un índice para el campo año.

Ya en Delphi insertas dos componentes Table para tus tablas:

tblAños, tblAlumnos y dos DataSource que enlazas a éstas:

dsAños -> tblAños
dsAlumnos -> tblAlumnos

Estableces una relación maestro-detalle entre ambas tablas:

tblAlumnos.MasterSource -> dsAños
tblAlumnos.MasterFields -> 'Año'

Esto lo puedes hacer desde el inspector de objetos. Primero seleccionando el MasterSource y luego MasterFields en donde primero escoges el índice de la tabla alumnos que creaste para el campo'año ' y escogiendo en ambos lados, Detail y Master, el campo 'semestre'.

De esta forma, cada vez que selecciones un registro en la tabla de años automáticamente se filtrará la tabla de alumnos reflejándose en la rejilla que tengas dispuesta para ello.

Cómo seleccionas el registro deseado en la tabla de años puede hacerse en varias formas.

Una es la que quieres usando un TabSet y cambiando el registro en su evento OnChange:

tblAños.FindKey([TabSet.Tabs[NewTab]]);

Aunque conforme pasen los años habrá demasiados. Yo mejor utilizaría un DBLookupComboBox:

cboAños.ListSource -> dsSemestre
cboAños.ListField -> 'Semestre'
cboAños.KeyField -> 'Semestre'

Como comentario extra te digo que por mi parte yo no usaría componentes Query. Aunque normalmente puede resultar más eficiente, no es así en el caso de Paradox. Paradox parece hacer caso omiso de los índices cuando se utilizan consultas SQL y trabaja mucho mejor con relaciones maestro-detalle. Además, usando Queries debes reconsultar la base de datos cada vez que cambies de año, lo cual ocasiona-- haz la prueba para que veas la diferencia -- un parpadeo en la rejilla que no sucede con la relación maestro-detalle.

Finalmente, aclaro que todas las componentes, nombres de campo, etc. que en los ejemplos tienen ñ deberán cambiarse por algún nombre que no la tenga.

// Saludos

vetustas 04-11-2003 18:27:06

Muchas gracias Roman. Me funciona de maravilla. Pero ahora me encuentro con el siguiente problema. Tengo también una tabla de prácticas a la que también me gustaria separarlas por años (como hice con los alumnos) pero claro, no puedo usar la relación maestro/detalle porque las prácticas ya dependen de otra tabla que es empresas. Cómo lo puedo hacer? Espero haberme explicado medianamente bien.
Y otra vez muchisimas gracias

roman 04-11-2003 18:56:42

Cita:

vetustas comentó:
Tengo también una tabla de prácticas a la que también me gustaria separarlas por años (como hice con los alumnos) pero claro, no puedo usar la relación maestro/detalle porque las prácticas ya dependen de otra tabla que es empresas. Cómo lo puedo hacer?
Vamos a ver. No conozco la estructura de tus tablas pero supongamos que es algo así:

empresas = (id, otros campos)
practicas = (id, emp_id, año, otros campos)

de manera que empresas.id se relaciona con practicas.emp_id.

Lo que yo haría (y de hecho hago en un caso similar) es crear otra tabla auxiliar:

emp_años = (emp_id, año)

En lugar de usar empresas como tabla maestra de practicas usas emp_años:

practicas.master -> emp_años
practicas.masterfields -> 'emp_id;año'

La tabla practicas deberá tener un índice para el par de campos emp_id, año.

De esta forma, conforme te desplaces por la tabla emp_años, la tabla practicas reflejará únicamente los registros correspondientes a la empresa y al año identificados por (emp_id, año).

Ahora sólo tienes que ver cómo moverte por la tabla emp_años.

Yo usaría dos DBLooupComboBox enlazados a empresas y años:

cboEmpresas.ListSource -> dsEmpresas
cboEmpresas.ListField -> campo que desees mostrar
cboEmpresas.KeyField -> id

cboAños.ListSource -> dsAños
cboAños.ListField -> 'año'
cboAños.KeyField -> 'año'

Asignas el mismo evento al OnChange de cboEmpresas y de cboAños para moverte de registro cuando cambie cualquiera de ambos:

tblEmp_Años.FindKey([cboEmpresas.KeyValue, cboAños.KeyValue])

y ¡listo!, tu rejilla asociada a practicas mostrará sólo las prácticas de la empresa y año seleccionados.

// Saludos

vetustas 04-11-2003 20:06:06

Mmm...creo que haberte entendido pero lo que me gustaria tener es dos dbgrid y un combobox. En un dbgrid la lista de todas las empresas, en el combo la lista de todos los años disponibles y en el otro dbgrid mostrar las practicas asociadas a la empresa que tengo seleccionada en el primer dbgrid correspondientes al año seleccionado en el combo. Supongo que no tendrá mucha dificultad
Muchas muchas gracias

roman 04-11-2003 20:22:05

Cita:

vetustas comentó:
Supongo que no tendrá mucha dificultad
Claro que no. Lo único que hay que cambiar es la forma en que se obtiene el id de la empresa en el evento OnChange del (ahora único) combo para pasárselo a FindKey.

// Saludos

vetustas 04-11-2003 21:15:31

Lo de seleccionar alumnos segun año me funciona perfectamente aplicando lo de maestro/detalle (habiendo creado previamente la tabla auxiliar q me mandaste) pero me he puesto a hacer lo de crear una tabla auxiliar "emp_años" para lo de practicas, empresas y años y no me funciona. No se que estaré haciendo mal. De todos modos...no hay forma de hacerlo sin tener que crear una nueva tabla auxiliar? es que la creación de esta ultima tabla auxiliar no la entiendo mu bien.

muxas gasias

roman 04-11-2003 22:40:48

Velo de este modo:

Por un lado puedes poner a empresas como maestra de practicas de manera que al seleccionar una empresa sólo se muestran las prácticas de dicha empresa.

Por otro lado puedes poner a años como maestra de practicas de manera que al seleccionar un año sólo se muestran las prácticas de dicho año.

El problema es que tú necesitas ambos comportamientos al mismo tiempo, pero no puedes relacionar una tabla con dos maestras simultáneamente.

Supongamos por un momento que sí fuera posible. Lo que harías sería:

Código:

practicas.master1 -> empresas
practicas.masterfields1 -> 'id;emp_id'

practicas.master2 -> años
practicas.masterfields2 -> 'año;año';

De esta manera se mostrarían sólo las prácticas de las empresa seleccionada en la tabla empresas y del año seleccionado en la tabla años.

Pero esto, como dijimos, no es posible ya que los campos en la tabla detalle, emp_id y año tendrían que enlazarse con tablas distintas

La solución entonces es crear una tabla que reuna estos dos campos. Esta tabla es emp_años y no es más que una copia de la tabla practicas tomando sólo los campos en cuestión y eliminado los registros duplicados:

Código:

SELECT DISTINCT emp_id, año FROM practicas
Al ser una sola tabla, puedes ponerla como maestra de practicas. Al seleccionar un registro en emp_años, la relación provoca que practicas sólo muestre los registros correspondientes a la empresa y año del registro seleccionado en emp_años.

Así, como dijimos antes, lo único que hay que hacer es ver cómo seleccionar un registro de esta tabla maestra. Pero esto ya lo sabes: por un lado seleccionas la empresa de la rejilla y el año del combo y usas el evento OnChange del combo y el evento OnScroll del dataset asociado a empresas para, en ambos, utilizar el método FindKey de la tabla emp_años.

Claro que puede parecer que esta tabla sobre en el diseño de la base de datos pero es necesaria si deseas poder hacer el filtrado mediante el uso de relaciones maestro-detalle.

Como mencioné anteriormente, en una situación muy similar yo usaba Queries para hacer el filtrado pero cada cambio provocaba una nueva consulta a la base y por tanto el despliegue de la rejilla no es inmediato. Así hasta que decidí crear la tabla extra, innecesaria para el diseño de la base pero muy útil para la interfaz de usuario.

// Saludos

vetustas 08-11-2003 13:11:12

Hola de nuevo!

Otra dudilla respecto a esto de las tablas maestro/detalle. Se pueden tener dos tablas detalle apuntando a una misma tabla maestra? Lo digo porque quiero que la tabla "años" q mencionaste anteriormente me gustaria que fuese la tabla maestra de alumnos y de practicas. No se si recuerdas que antes te dije que la tabla practicas dependia de empresa, pero ahora ya no es asi. Por eso me gustaria que dependiese de la tabla años...pero como de esa depende tb la de alumnos...es q al ejecutar me sale "Circular datalinks are not allowed". Igual no es de eso pero sea lo que sea no me funciona
Graciasssssss

jachguate 10-11-2003 00:59:56

Hola vetustas.

Te recomiendo que leas la guía de estilo ya que es recomendable abrir un nuevo hilo cuando cambia tu pregunta. Como en este caso.

Hasta luego.

;)


La franja horaria es GMT +2. Ahora son las 15:44:47.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi