Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   ayuda combobox anidado (https://www.clubdelphi.com/foros/showthread.php?t=70532)

Rofocale 26-10-2010 17:25:31

ayuda combobox anidado
 
hola a todos.. espero que esten bien... tengo una nueva pregunta jeje
tengo dos combobox:
Código Delphi [-]
combobox1         combobox2
bebidas              jugos
licores                cervezas
                         gaseosa
                         vino

lo que quiero hacer es que si en el combobox esta puesto bebidas solo me muestre en el 2do combobox cervezas, jugos y no toda la lista y si es licores: cervezas, vino

la info la saco de una BD hecha en firebird

gracias espero me puedan ayudar otra vez
cuidense

ecfisa 26-10-2010 18:04:10

Hola Rofocale.

Una forma podría ser:
Código Delphi [-]
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  if ComboBox1.ItemIndex = 0 then
  begin
    if ComboBox2.Items.IndexOf('JUGOS')= -1 then
      ComboBox2.Items.Add('JUGOS');
    if ComboBox2.Items.IndexOf('GASEOSAS')= -1 then
      ComboBox2.Items.Add('GASEOSAS');
    ComboBox2.Items.Delete(ComboBox2.Items.IndexOf('CERVEZA'));
    ComboBox2.Items.Delete(ComboBox2.Items.IndexOf('VINO'));
  end
  else
  begin
    if ComboBox2.Items.IndexOf('CERVEZA')= -1 then
      ComboBox2.Items.Add('CERVEZA');
    if ComboBox2.Items.IndexOf('VINO')= -1 then
      ComboBox2.Items.Add('VINO');
    ComboBox2.Items.Delete(ComboBox2.Items.IndexOf('JUGOS'));
    ComboBox2.Items.Delete(ComboBox2.Items.IndexOf('GASEOSAS'));
  end;
end;

Saludos. :)

Caral 26-10-2010 18:04:22

Hola
Necesitas un campo tipo asi con solo definir el tipo saldra lo que necesitas.
Saludos

Rofocale 26-10-2010 18:23:52

si las categorias en los combobox crecen osea les inserto mas, el codigo seria enorme.. otra forma de hacerlo si es que en cada combobox hubiera unas 60 categorias ?

gracias

ecfisa 26-10-2010 19:26:11

Cita:

Empezado por Rofocale (Mensaje 380488)
si las categorias en los combobox crecen osea les inserto mas, el codigo seria enorme.. otra forma de hacerlo si es que en cada combobox hubiera unas 60 categorias ?

gracias

Bueno, yo sólo me limité a responder a tu consulta, no sabía si era para un ejercicio... ;)
¡ No quiero ni imaginar 60 items en cada ComboBox con ese código... cinco días tecleando!!! :D

Me parece que si la lista puede crecer de forma indefinida, es más fácil hacer las inserciones, relaciones y mantenimiento
usando dos TDataSet.

Saludos. :)

Rofocale 27-10-2010 17:40:21

lo se.. solo que estoy practicando y queria una forma de anidar 2 combobox con codigo pero de una mejor manera de la que se muestra arriba porque el codigo se agrandaria demasiado si en un combobox se listara items

ElDioni 27-10-2010 18:35:20

Pues como te dice ecfisa,tendrás que hacerte dos tablas, maestro y otra detalle, en la primera pondrás las familias de bebidas y en la segunda rellenaras la bebida con la familia a la que pertenece, entonces enlazas estas tablas con un adoquery1 a un dblookcombobox, por ejemplo, y cuando selecciones la familia en el primero que te filtre en el segundo las bebidas que pertenecen a esa familia.

Un saludo.

Rofocale 28-10-2010 05:12:16

de esta manera utilizo el codigo para cargar leer los datos desde la base de datos y cargarlos a los combobox.. ahora quiero filtrar de la tabla categoria que hay bebidas y licores y en la tabla unidades hay cervezas,jugos,vinos,gaseosas

se que es una manera facil como me han dicho haciendo un maestro/detalle.. pero estoy practicando y lo estoy haciendo con codigo.. utilizo combobox en vez de dbcombobox y bueno no se como poder hacer el anidamiento mediante codigo

alguna idea ? gracias

Código Delphi [-]
    with dmDatos.qryConsulta do begin
        Close;
        SQL.Clear;
        SQL.Add('SELECT nombre FROM categorias WHERE tipo = ''A'' ORDER BY nombre');
        Open;
        cmbCategorias.Properties.Items.Clear;
        cmbCategBusq.Properties.Items.Clear;
        while (not Eof) do begin
            cmbCategorias.Properties.Items.Add(Trim(FieldByName('nombre').AsString));
            cmbCategBusq.Properties.Items.Add(Trim(FieldByName('nombre').AsString));
            Next;
        end;
        Close;
    end;
    with dmDatos.qryConsulta do begin
        Close;
        SQL.Clear;
        SQL.Add('SELECT nombre FROM unidades WHERE tipo = ''A'' ORDER BY nombre');
        Open;
        cmbTipo.Properties.Items.Clear;
        cmbTipoBusq.Properties.Items.Clear;
        while (not Eof) do begin
            cmbTipo.Properties.Items.Add(Trim(FieldByName('nombre').AsString));
            cmbTipoBusq.Properties.Items.Add(Trim(FieldByName('nombre').AsString));
            Next;
        end;
        Close;
    end;

ecfisa 28-10-2010 08:47:20

Hola Rofocale.

No pusiste la estructura de los datos, así que voy a tratar de inferir ...
Supongamos que declaraste:
Código SQL [-]
CREATE DOMAIN IN_AB CHAR(1) CHECK(VALUE IN('A','B')) NOT NULL;
CREATE DOMAIN VARCHAR20 VARCHAR(20) NOT NULL;

CREATE TABLE TBCATEGORIAS(
  Categoria IN_AB,
  Nombre VARCHAR20
);

CREATE TABLE TBUNIDADES(
  Categoria IN_AB,
  Nombre VARCHAR20
);

Y tenes ingresado:
TBCATEGORIAS
------------
A BEBIDAS
B LICORES

TBUNIDADES
----------
A GASEOSAS
A JUGOS
B VINOS
B LICORES
A LICUADOS
B AGUARDIENTES

Siendo cbCategorias y cbUnidades de tipo TComboBox, una forma de hacerlo puede ser:
Código Delphi [-]
procedure TForm1.FiltrarComboBox;
begin
  with IBQuery1 do
  begin
    Close;
    SQL.Text:= 'SELECT CATEGORIA, NOMBRE FROM TBCATEGORIAS C1, TBUNIDADES C2 '+
     'WHERE (C1.CATEGORIA = C2.CATEGORIA) AND '+
     'C2.CATEGORIA = (SELECT CATEGORIA FROM TBCATEGORIAS WHERE NOMBRE = '+
     QuotedStr(cbCategorias.Text)+')';
    Open;
    cbUnidades.Clear;
    while not Eof do
    begin
      cbUnidades.Items.Add(FieldByName('NOMBRE').AsString);
      Next;
    end;
    cbUnidades.ItemIndex:= 0;
    Close
  end;
end;

Código Delphi [-]
procedure TForm1.FormShow(Sender: TObject);
begin
 with IBQuery1 do
  begin
    Close;
    SQL.Text:= 'SELECT * FROM TBCATEGORIAS ORDER BY NOMBRE';
    Open;
    while not Eof do
    begin
      cbCategorias.Items.Add(FieldByName('NOMBRE').AsString);
      Next;
    end;
    cbCategorias.ItemIndex:= 0;
    Close;
    SQL.Text:= 'SELECT * FROM TBUNIDADES ORDER BY NOMBRE';
    Open;
    while not Eof do
    begin
      cbUnidades.Items.Add(FieldByName('NOMBRE').AsString);
      Next;
    end;
    cbUnidades.ItemIndex:= 0;
    Close;
  end;
  FiltrarComboBox
end;

Código Delphi [-]
procedure TForm1.cbCategoriasChange(Sender: TObject);
begin
  FiltrarComboBox;
end;

Saludos. :)

Rofocale 12-05-2011 23:33:46

Filtro

Código Delphi [-]
procedure TfrmArticulos.FiltrarComboBox;
begin
  with dmDatos.qryConsulta do
  begin
    Close;
    SQL.Text:= 'SELECT nombre, nombre2 FROM categorias c1, unidades c2 '+
     'WHERE (c1.nombre = c2.nombre2) AND '+
     'c2.nombre2 = (SELECT nombre FROM categorias WHERE nombre = '+
     QuotedStr(cmbCategorias.Text)+')';
    Open;
     cmbUnidadTipo.Clear;
    while not Eof do
    begin
      cmbUnidadTipo.Properties.Items.Add(FieldByName('nombre').AsString);
      Next;
    end;
    cmbUnidadTipo.ItemIndex:= 0;
    Close
  end;
end;


Código Delphi [-]

procedure TfrmArticulos.FormShow(Sender: TObject);
begin
 
   with dmDatos.qryConsulta do
   begin
    Close;
    SQL.Add('SELECT nombre FROM categorias ORDER BY nombre');
    Open;
    while not Eof do
    begin
      cmbCategorias.Properties.Items.Add(FieldByName('nombre').AsString);
      cmbCategBusq.Properties.Items.Add(Trim(FieldByName('nombre').AsString));
      Next;
    end;
    cmbCategorias.ItemIndex:= 0;
    Close;
    SQL.Text:= 'SELECT nombre FROM unidades ORDER BY nombre';
    Open;
    while not Eof do
    begin
      cmbUnidadTipo.Properties.Items.Add(FieldByName('nombre').AsString);
      cmbUnidadTipoBusq.Properties.Items.Add(Trim(FieldByName('nombre').AsString));
      Next;
    end;
    cmbUnidadTipo.ItemIndex:= 0;
    Close;
  end;
  FiltrarComboBox;


end;


Código Delphi [-]
procedure TfrmArticulos.cmbCategoriasPropertiesChange(Sender: TObject);
begin
FiltrarCombobox;
end;

Hola estoy retomando el ejemplo de hace tiempo.. debido a que estuve ocupado trabajando
ahora lo he probado y no filtra el combobox sigue apareciendome todo en el segundo combobox
espero puedas ayudarme

Rofocale 12-05-2011 23:50:29

siendo
]
Código Delphi [-]
categorias       unidades
clave              clave
nombre           nombre
fecha             fecha
                    nombre2


combobox1-categorias                     combobox2-unidades
nombre                             nombre               nombre2
----------                      -------------      ---------
bebidas                           gaseosa             bebidas
licores                            gaseosa             bebidas
                                    cerveza              licores

Rofocale 13-05-2011 01:12:13

alguien que pueda saber por ahi como puedo filtrar los datos de 2 combobox ? mediante codigo tal como menciono arriba ?
gracias de antemano

ecfisa 13-05-2011 04:02:27

Hola Rofocale.
Cita:

Hola estoy retomando el ejemplo de hace tiempo.. debido a que estuve ocupado trabajando
ahora lo he probado y no filtra el combobox sigue apareciendome todo en el segundo combobox
espero puedas ayudarme
Y tenés razón, no hacía el filtrado. :(

Cambié los nombres de los campos de las tablas anteriores, quedaron así:
TABLA CATEGORIAS
CCATEGORIA CHAR(1)
CNOMBRE VARCHAR(20)

TABLA UNIDADES
UCATEGORIA CHAR(1)
UNOMBRE VARCHAR(20)


En mi prueba usé estos datos:
TABLA CATEGORIAS
CAT - NOMB.
-----------------------
A - BEBIDAS
B - LICORES

TABLA UNIDADES
CAT - NOMB.
--------------------
A - GASEOSAS
A - JUGOS
B - VINOS
A - LICUADOS
B - LICORES
B - CHAMPAGNES
A - AGUA MINERAL
B - CERVEZAS


El código Delphi:
Código Delphi [-]
...
procedure TForm1.FiltrarComboBox;
begin
  IBQuery1.Close;
  IBQuery1.SQL.Clear;
  IBQuery1.SQL.Add('SELECT UNOMBRE FROM UNIDADES, CATEGORIAS');
  IBQuery1.SQL.Add('WHERE UCATEGORIA = CCATEGORIA AND UCATEGORIA =');
  IBQuery1.SQL.Add('(SELECT CCATEGORIA FROM CATEGORIAS WHERE CNOMBRE =:NOMB)');
  IBQuery1.ParamByName('NOMB').AsString:= cbCategorias.Text;
  IBQuery1.Open;
  cbUnidades.Clear;
  while not IBQuery1.Eof do
  begin
    cbUnidades.Items.Add(IBQuery1.FieldByName('UNOMBRE').AsString);
    IBQuery1.Next;
  end;
  cbUnidades.ItemIndex:= 0;
  IBQuery1.Close
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  IBQuery1.Close;
  IBQuery1.SQL.Text:= 'SELECT * FROM CATEGORIAS ORDER BY CNOMBRE';
  IBQuery1.Open;
  while not IBQuery1.Eof do
  begin
    cbCategorias.Items.Add(IBQuery1.FieldByName('CNOMBRE').AsString);
    IBQuery1.Next;
  end;
  cbCategorias.ItemIndex:= 0;
  IBQuery1.Close;
  IBQuery1.SQL.Text:= 'SELECT * FROM UNIDADES ORDER BY UNOMBRE';
  IBQuery1.Open;
  while not IBQuery1.Eof do
  begin
    cbUnidades.Items.Add(IBQuery1.FieldByName('UNOMBRE').AsString);
    IBQuery1.Next;
  end;
  cbUnidades.ItemIndex:= 0;
  IBQuery1.Close;
  FiltrarComboBox
end;

procedure TForm1.cbCategoriasChange(Sender: TObject);
begin
  FiltrarComboBox;
end;

Al seleccionar la categoria en cbCategorias filtra el combo cbUnidades acorde a la categoría seleccionada.

Saludos.

Rofocale 14-05-2011 08:23:07

no me filtra :( me siguen apareciendo en el combobox unidades.. los datos de forma triplicada

necesito ayuda :(

ecfisa 14-05-2011 16:12:30

Hola Rofocale.

Acabo de probarlo de nuevo y funciona perfectamente.

¿ Estas seguro que asignaste el evento OnChange a cbCategorias y dentro de él llamas a FiltrarComboBox ?

Por otro lado, ¿Reproduciste la totalidad del ejemplo (incluídas las tablas) o sólo copiaste/pegaste sobre tus datos ? por que si es del último modo y los datos difieren bíen podría no funcionar.

Saludos.

ecfisa 14-05-2011 16:42:07

Hola de nuevo.

Para disipar toda duda y ante la imposibilidad de enviarte la base de datos te adjunto imágenes del funcionamiento:
BEBIDAS:


LICORES:


Nota: Puse la propiedad del segundo combo a csSimple y lo estiré para una mejor visualización.

Saludos.

Rofocale 14-05-2011 17:12:47

hola mira en mi table categorias y unidades tengo lo sgte

categorias
----------

clave
nombre
fecha
ccategorias


unidades
-----------
clave
nombre
fecha
nombre2 ( este ultimo es como si fuera en el tuyo ucategorias)



Código Delphi [-]
procedure TfrmArticulos.FiltrarComboBox;
begin
  with dmDatos.qryConsulta do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT u.nombre AS unombre FROM unidades u ,categorias c');
    SQL.Add('WHERE u.nombre2 = c.ccategorias AND u.nombre2 =');
    SQL.Add('(SELECT c.ccategorias FROM categorias c WHERE c.nombre = :nomb)');
    ParamByName('nomb').AsString := cmbCategorias.Text;
    Open;
    cmbUnidadTipo.Clear;
    while not dmDatos.qryConsulta.Eof do
    begin
      cmbUnidadTipo.Properties.Items.Add(FieldByName('unombre').AsString);
      Next;
    end;
    cmbUnidadTipo.ItemIndex:= 0;
    Close
  end;
end;

ah y uso combobox de devexpress seria en el evento propertieschange
Código Delphi [-]
procedure TfrmArticulos.cmbCategoriasPropertiesChange(Sender: TObject);
begin
FiltrarCombobox;
end;
y en el formshow

Código Delphi [-]
begin
   with dmDatos.qryConsulta do
   begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT * FROM categorias ' ORDER BY nombre');
    Open;
    while not Eof do
    begin
      cmbCategorias.Properties.Items.Add(FieldByName('nombre').AsString);
   
      Next;
    end;
    cmbCategorias.ItemIndex:= 0;
    Close;
    end;
    with dmDatos.qryConsulta do
    begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT * FROM unidades  ORDER BY nombre');
    Open;
    while not Eof do
    begin
      cmbUnidadTipo.Properties.Items.Add(FieldByName('nombre').AsString);
      
      Next;
    end;
    cmbUnidadTipo.ItemIndex:= 0;
    Close;
  end;
  FiltrarComboBox;
end;

algo debo estar haciendo mal porque porque al seleccionar licores no me filtra y mas bien ya aparecen triplicados todos en el segundo combobox :(

ecfisa 14-05-2011 20:11:10

Hola.

Mirá, vamos a simplificar la cosa, renombrá los campos de tus tablas (o crealas nuevamente) para que queden así:

CATEGORIAS
CLAVE_CA
NOMBRE_CA
FECHA_CA
CATEGORIA_CA

UNIDADES
CLAVE_UN
NOMBRE_UN
FECHA_UN
CATEGORIA_UN


Con esos nombres el código Delphi es:
Código Delphi [-]
procedure TForm1.FiltrarComboBox;
begin
  IBQuery1.Close;
  IBQuery1.SQL.Clear;
  IBQuery1.SQL.Add('SELECT NOMBRE_UN FROM UNIDADES, CATEGORIAS ');
  IBQuery1.SQL.Add('WHERE CATEGORIA_UN = CATEGORIA_CA AND CATEGORIA_UN = ');
  IBQuery1.SQL.Add('(SELECT CATEGORIA_CA FROM CATEGORIAS WHERE NOMBRE_CA = :NOMB)');
  IBQuery1.ParamByName('NOMB').AsString:= cbCategorias.Text;
  IBQuery1.Open;
  cbUnidades.Clear;
  while not IBQuery1.Eof do
  begin
    cbUnidades.Items.Add(IBQuery1.FieldByName('NOMBRE_UN').AsString);
    IBQuery1.Next;
  end;
  cbUnidades.ItemIndex:= 0;
  IBQuery1.Close
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  IBQuery1.Close;
  IBQuery1.SQL.Text:= 'SELECT * FROM CATEGORIAS ORDER BY NOMBRE_CA';
  IBQuery1.Open;
  while not IBQuery1.Eof do
  begin
    cbCategorias.Items.Add(IBQuery1.FieldByName('NOMBRE_CA').AsString);
    IBQuery1.Next;
  end;
  cbCategorias.ItemIndex:= 0;
  IBQuery1.Close;
  IBQuery1.SQL.Text:= 'SELECT * FROM UNIDADES ORDER BY NOMBRE_UN';
  IBQuery1.Open;
  while not IBQuery1.Eof do
  begin
    cbUnidades.Items.Add(IBQuery1.FieldByName('NOMBRE_UN').AsString);
    IBQuery1.Next;
  end;
  cbUnidades.ItemIndex:= 0;
  IBQuery1.Close;
  FiltrarComboBox
end;

procedure TForm1.cbCategoriasChange(Sender: TObject);
begin
  FiltrarComboBox
end;

Está probado y al igual que el código anterior funciona correctamente. Siempre que los datos sean coherentes, es decir, si las bebidas sin alcohol son categoría A y las que tienen alcohol B, no guardes 'GASEOSAS' poniendo en el campo CATEGORIA_UN una 'B'.

Fijate que remarque en negrita los campos de la consulta en el código Delphi, debes ponerlos textualmente así. Ya que así están definidos en la declaración de la tabla. (No califiques los campos con C1 y C2, tampoco es necesario el uso de AS)

Resumiendo, si copias textualmente este ejemplo desde la creación de las tablas, te tiene que funcionar.


Saludos.

Rofocale 14-05-2011 20:24:18

mis categorias no son A Y B son asi
Código Delphi [-]
categorias                                  unidades

nombre   ccategorias                    nombre             nombre2
bebidas   bebidas                         gaseosa            bebidas
licores     licores                          cerveza             licores
                                                agua mineral      bebidas

ahora el codigo que tu me has puesto que funciona bien en el tuyo no me funciona implementandola a mi base de datos... no puedo renombrar los campos
ya que algunos son utilizados en otras partes del programa para poder seguir creando mas categorias y unidades etc.. pero en resumidas cuentas los campos asi tengan el mismo nombre u otro deberia de funcionar
no se que este mal en mi casa hay problema con lo mio :( y no se como solucionarlo ya que efectivamente si solo me hago un programa chikito con 2 combobox y la base de datos como me lo has puesto si funciona, no se que hacer :(

ecfisa 14-05-2011 22:04:36

Hola Rofocale.

Modifique los nombres de campos en las tablas que utilicé en la prueba por los que pusiste en tu mensaje.

Esta consulta funciona correctamente:
Código Delphi [-]
procedure TForm1.FiltrarComboBox;
begin
  IBQuery1.Close;
  IBQuery1.SQL.Clear;
  IBQuery1.SQL.Add('SELECT C1.NOMBRE FROM UNIDADES C1, CATEGORIAS C2');
  IBQuery1.SQL.Add('WHERE NOMBRE2 = CCATEGORIAS AND NOMBRE2 =');
  IBQuery1.SQL.Add('(SELECT CCATEGORIAS FROM CATEGORIAS C2 WHERE C2.NOMBRE =:NOMB)');
  IBQuery1.ParamByName('NOMB').AsString:= cbCategorias.Text;
  IBQuery1.Open;
  cbUnidades.Clear;
  while not IBQuery1.Eof do
  begin
    cbUnidades.Items.Add(IBQuery1.FieldByName('NOMBRE').AsString);
    IBQuery1.Next;
  end;
  cbUnidades.ItemIndex:= 0;
  IBQuery1.Close
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  IBQuery1.Close;
  IBQuery1.SQL.Text:= 'SELECT * FROM CATEGORIAS ORDER BY NOMBRE';
  IBQuery1.Open;
  while not IBQuery1.Eof do
  begin
    cbCategorias.Items.Add(IBQuery1.FieldByName('NOMBRE').AsString);
    IBQuery1.Next;
  end;
  cbCategorias.ItemIndex:= 0;
  IBQuery1.Close;
  IBQuery1.SQL.Text:= 'SELECT * FROM UNIDADES ORDER BY NOMBRE';
  IBQuery1.Open;
  while not IBQuery1.Eof do
  begin
    cbUnidades.Items.Add(IBQuery1.FieldByName('NOMBRE').AsString);
    IBQuery1.Next;
  end;
  cbUnidades.ItemIndex:= 0;
  IBQuery1.Close;
  FiltrarComboBox
end;

procedure TForm1.cbCategoriasChange(Sender: TObject);
begin
  FiltrarComboBox
end;

Saludos.


La franja horaria es GMT +2. Ahora son las 15:43:03.

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