Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   consultas a medida utilizando TComboBox (https://www.clubdelphi.com/foros/showthread.php?t=77838)

naty_prog 29-02-2012 06:22:46

consultas a medida utilizando TComboBox
 
Hola compañeros.Necesito de su ayuda.tengo un formulario en el cual hago una consulta a medida por medio de un quickreport con los datos de docentes de una base de datos.esta consulta esta desarrollada utilizando combobox, para el filtrado de los datos:

consulta:
  • por sexo (todos/femenino/masculino)
  • por estado (todos/habilitados/deshabilitados)
  • por localidad (los datos se toman de otra tabla llamada localidades)
  • por tipo de documento (TODOS/D.N.I./L.C./L.E./D.N.I.F./M/PASS/C.I.)
  • por edad (todas/Igual a/Mayor a/Menor a/Desde utilizando tambien 2 edit's para establecer el numero)
  • por orden (Apellido Ascendente/Apellido Descendente)
Esto por una parte.luego existen otros 4 combobox, los cuales deberian funcionar en forma de cascada, es decir, selecciono el primero y de acuerdo a ello se va filtrando la informacion de los demas combobox.Ellos son:
  • por area (Todas las Areas/Cs. Económicas/Cs. Exactas/Cs. Humanas/Cs. Sociales)
  • por carrera
  • por plan de estudio
  • por materia
Estos 3 ultimos tambien utilizan datos de una tabla. Al ejecutar el programa, cuando quiero ver la consulta, sin cambiar algo en los combobox,me aparecen todos los datos bien, ahora cuando cambio alguno de los combobox, no aparece ningun dato.Este es el codigo que tenemos para hacer la consulta:
Código Delphi [-]
procedure TForm_docente.BitBtn_VistaPreviaClick(Sender: TObject);
var

 consulta: string;
 puse_where: Boolean;
begin
  inherited;
  cont:=cont+1;
puse_where:=false;

  consulta:='select * from docente';

  case ComboBox_tipodoc.ItemIndex of
    0:  //todos
      begin
      end;
    else
      begin
        if(puse_where)then
        consulta:=consulta + ' and tip_doc=:tipo'
        else
        consulta:=consulta + ' where tip_doc=:tipo';
        puse_where:=true;
      end;
   end;


   case ComboBox_materia.ItemIndex of
    0:
      begin
      end;
     else
        begin
         dm.IBDataSet_materia.Locate('nombre',ComboBox_materia.Text,[]);
         dm.IBDataSet_profesor.Locate('id_docente',dm.IBDataSet_materiaID_DOCENTE.Value,[]);

          if (puse_where)then
           consulta:=consulta +' and id_docente=:mat'
          else
           begin
             consulta:= consulta + ' where id_docente=:mat';
             puse_where:=true;
           end;
        end;
     end;



  case ComboBox_localidad.ItemIndex of
    0:
      begin
      end;
    else
      begin
        DM.IBDataSet_Localidad.Locate('nombre',ComboBox_localidad.Text,[]);
        if(puse_where)then
          consulta:= consulta + ' and id_localidad=:loc'
        else
          begin
            consulta:= consulta + ' where id_localidad=:loc';
            puse_where:=true;
          end;
      end;
  end;

  case ComboBox_sexo.ItemIndex of
    0:   //todas
      begin
      end;
    else
       if(puse_where)then
          consulta:= consulta + ' and SEXO=:sex'
        else
          begin
            consulta:= consulta + ' where SEXO=:sex';
            puse_where:=true;
          end;
  end;

   case ComboBox_estado.ItemIndex of
    0:   //todas
      begin
      end;
    1:
      begin
        if(puse_where)then
          consulta:= consulta + ' and ESTADO=1'
        else
          begin
            consulta:= consulta + ' where ESTADO=1';
            puse_where:=true;
          end;
      end;
    2:
      begin
        if(puse_where)then
          consulta:= consulta + ' and ESTADO=0'
        else
          begin
            consulta:= consulta + ' where ESTADO=0';
            puse_where:=true;
          end;
      end;
  end;



  {EL ORDER  BY DEBE IR LAL FINAL}


    case ComboBox_Con_Edad.ItemIndex of
     0:   //todas
      begin
      end;

     1:   //igual a
        begin
          if(puse_where)then
            consulta:= consulta + ' and EDAD=:eda'
          else
            begin
              consulta:= consulta + ' where EDAD=:eda';
              puse_where:=true;
            end;
        end;

     2:   //mayor a
        begin
          if(puse_where)then
            consulta:= consulta + ' and EDAD>:eda'
          else
            begin
              consulta:= consulta + ' where EDAD>:eda';
              puse_where:=true;
            end;
        end;

     3:    //menor a
        begin
          if(puse_where)then
            consulta:= consulta + ' and EDAD<:eda'
          else
            begin
              consulta:= consulta + ' where EDAD<:eda';
              puse_where:=true;
            end;
        end;

     4:    //desde
        begin
            if(puse_where)then
             consulta:= consulta + ' and ((EDAD>=:eda)and (EDAD<=:eda2))'
            else
              begin
               consulta:= consulta + ' where ((EDAD>=:eda)and (EDAD<=:eda2))';
               puse_where:=true;
              end;
        end;
  end;

  case ComboBox_Con_Orden.ItemIndex of
    0://apellido asc
      begin
        consulta:=consulta +' order by nombre_apellido asc';
      end;

    1://apellido DESCENDENTE
      begin
        consulta:=consulta +' order by nombre_apellido DESC';
      end;
   end;

  with(DM.IBQuery_profesor)do
    begin
      SQL.Clear;
      SQL.Add(consulta);
      if(ComboBox_tipodoc.ItemIndex<>0)then
        ParamByName('tipo').AsString:=ComboBox_tipodoc.Text;

      if(ComboBox_localidad.ItemIndex<>0)then
        ParamByName('loc').AsInteger:=DM.IBDataSet_LocalidadID_LOCALIDAD.Value;

      if(ComboBox_materia.ItemIndex<>0)then
         ParamByName('mat').AsInteger:=DM.IBDataSet_materiaID_DOCENTE.Value;

      if(ComboBox_sexo.ItemIndex<>0)then
        ParamByName('sex').AsString:=ComboBox_sexo.Text;

      if(ComboBox_Con_Edad.ItemIndex=1)then
        ParamByName('eda').AsString:=Edit_Con_n1.Text;

      if(ComboBox_Con_Edad.ItemIndex=2)then
        ParamByName('eda').AsString:=Edit_Con_n1.Text;

      if(ComboBox_Con_Edad.ItemIndex=3)then
        ParamByName('eda').AsString:=Edit_Con_n1.Text;

      if(ComboBox_Con_Edad.ItemIndex=4)then
        ParamByName('eda').AsString:=Edit_Con_n1.Text;

      if(ComboBox_Con_Edad.ItemIndex=4)then
       ParamByName('eda2').AsString:=Edit_Con_n2.Text;

      Open;

      QuickReport_Docentes.PreviewModal;
      if(cont<>0)then
       begin
         Form_docente.ComboBox_area.Text:='Todas las Areas';
         Form_docente.ComboBox_carrera.Clear;
         Form_docente.ComboBox_carrera.Text:='Todas las Carreras';
         Form_docente.ComboBox_plan.Clear;
         Form_docente.ComboBox_plan.Text:='Todas los Planes de Estudios';
         Form_docente.ComboBox_materia.Clear;
         Form_docente.ComboBox_materia.Text:='Todas las Materias';
       end;
    end;


end;

procedure TForm_docente.ComboBox_areaChange(Sender: TObject);
begin
  inherited;
 if(ComboBox_area.ItemIndex<>0)then
    begin
      with (DM.IBQuery_carrera)do
        begin
          ComboBox_carrera.Clear;
          SQL.Clear;
          SQL.Add('select * from carrera where area starting with :name AND ESTADO = 1 order by nombre');
          ParamByName('name').AsString:=ComboBox_area.Text;
          Open;
          first;
          while not eof do
            begin
              ComboBox_carrera.Items.Add(dm.IBQuery_carreraNOMBRE.Value);
              Next;
            end;
          ComboBox_carrera.ItemIndex:=0;
          with (DM.IBQuery_plan_estudio)do
            BEGIN
              dm.IBQuery_carrera.Locate('nombre',ComboBox_carrera.Text,[]);
              ComboBox_plan.Items.Clear;
              SQL.Clear;
              SQL.Add('select * from pe  where PE.CARRERA=:CARRERA  AND ESTADO = 1 order by nombre');
              ParamByName('CARRERA').AsInteger:=DM.IBQuery_carreraID_CARRERA.Value;
              dm.IBQuery_plan_estudio.Open;
              if not dm.IBQuery_plan_estudio.IsEmpty then
              dm.IBQuery_plan_estudio.first;
              while(dm.IBQuery_plan_estudio.Eof=false)do
                BEGIN
                  ComboBox_plan.Items.Add(DM.IBQuery_plan_estudioNOMBRE.Value);
                  dm.IBQuery_plan_estudio.Next;
                END;



               with (DM.IBQuery_materia)do
                BEGIN
               dm.IBQuery_plan_estudio.Locate('nombre',ComboBox_plan.Text,[]);
               ComboBox_materia.Items.Clear;
                 SQL.Clear;
                 SQL.Add('select * from materia  where materia.plan_estudio=:plan  AND ESTADO = 1 order by N_CUATRI');
                 ParamByName('plan').AsInteger:=DM.IBQuery_plan_estudioID_PE.Value;
                    DM.IBQuery_materia.Open;
                    if not dm.IBQuery_materia.IsEmpty then
                    DM.IBQuery_materia.First;
                  while(dm.IBQuery_materia.Eof=false)do
                   BEGIN
                     ComboBox_materia.Items.Add(DM.IBQuery_materiaNOMBRE.Value);
                     DM.IBQuery_materia.Next;
                   END;
                 end
            end;

        end;


    end;
     end;

procedure TForm_docente.ComboBox_carreraEnter(Sender: TObject);
begin
  inherited;

if(ComboBox_area.ItemIndex<>0)then
  begin

     with (DM.IBQuery_carrera)do
     BEGIN
      SQL.Clear;
      SQL.Add('select * from carrera where carrera.AREA starting with :name AND ESTADO = 1 order by nombre');
      ParamByName('name').AsString:=ComboBox_area.Text;
       Open;
       first;
      while(dm.IBQuery_carrera.Eof=false)do
       BEGIN

          ComboBox_carrera.Items.Add(DM.IBQuery_carreraNOMBRE.Value);
          NEXT;

        END;
     END
end
else
 begin
 poner_carreras;
end;
end;

procedure TForm_docente.ComboBox_planEnter(Sender: TObject);
begin
  inherited;
if(ComboBox_carrera.ItemIndex<>0)then
  begin

     with (DM.IBQuery_plan_estudio)do
     BEGIN
      SQL.Clear;
      SQL.Add('select * from pe  where PE.CARRERA starting with :CARRERA  AND ESTADO = 1 order by nombre');
        ParamByName('CARRERA').AsInteger:=DM.IBQuery_carreraID_CARRERA.Value;
         Open;
         First;
       while(dm.IBQuery_plan_estudio.Eof=false)do
        BEGIN
          ComboBox_plan.Items.Add(DM.IBQuery_plan_estudioNOMBRE.Value);
          NEXT;
        END;
     END
end
else
 begin
 poner_pe;
end;
end;



procedure TForm_docente.ComboBox_materiaEnter(Sender: TObject);
begin
  inherited;
if(ComboBox_plan.ItemIndex<>0)then
  begin

     with (DM.IBQuery_materia)do
     BEGIN
      SQL.Clear;
      SQL.Add('select * from materia  where materia.plan_estudio starting with :plan  AND ESTADO = 1 order by nombre');
        ParamByName('plan').AsInteger:=DM.IBQuery_plan_estudioID_PE.Value;
         Open;
         first;
       while(dm.IBQuery_materia.Eof=false)do
        BEGIN
          ComboBox_materia.Items.Add(DM.IBQuery_materiaNOMBRE.Value);
          NEXT;
        END;
     END
end
else
 begin
 poner_materia;
end;
end;



procedure TForm_docente.ComboBox_planChange(Sender: TObject);
begin
  inherited;
// ComboBox_materia.Clear;
ComboBox_materia.Clear;
   with (DM.IBQuery_materia)do
                BEGIN
               dm.IBQuery_plan_estudio.Locate('nombre',ComboBox_plan.Text,[]);
               ComboBox_materia.Items.Clear;
                 SQL.Clear;
                 SQL.Add('select * from materia  where materia.plan_estudio=:plan  AND ESTADO = 1 order by N_CUATRI');
                 ParamByName('plan').AsInteger:=DM.IBQuery_plan_estudioID_PE.Value;
                    DM.IBQuery_materia.Open;
                    if not dm.IBQuery_materia.IsEmpty then
                    DM.IBQuery_materia.First;
                  while(dm.IBQuery_materia.Eof=false)do
                   BEGIN
                     ComboBox_materia.Items.Add(DM.IBQuery_materiaNOMBRE.Value);
                     DM.IBQuery_materia.Next;
                   END;
                 end

end;


procedure TForm_docente.ComboBox_carreraChange(Sender: TObject);
begin
  inherited;
// ComboBox_plan.Clear;
 ComboBox_plan.Clear;
          with (DM.IBQuery_plan_estudio)do
            BEGIN
              dm.IBQuery_carrera.Locate('nombre',ComboBox_carrera.Text,[]);
              ComboBox_plan.Items.Clear;
              SQL.Clear;
              SQL.Add('select * from pe  where PE.CARRERA=:CARRERA  AND ESTADO = 1 order by nombre');
              ParamByName('CARRERA').AsInteger:=DM.IBQuery_carreraID_CARRERA.Value;
              dm.IBQuery_plan_estudio.Open;
              if not dm.IBQuery_plan_estudio.IsEmpty then
              dm.IBQuery_plan_estudio.first;
              while(dm.IBQuery_plan_estudio.Eof=false)do
                BEGIN
                  ComboBox_plan.Items.Add(DM.IBQuery_plan_estudioNOMBRE.Value);
                  dm.IBQuery_plan_estudio.Next;
                END;
            END

end;

espero puedan ayudarme y desde ya muchas gracias por sus respuestas.

ecfisa 29-02-2012 10:34:52

Hola naty_prog.

A primera vista te hago una sugerencia para el armado de la consulta SQL. Si estandarizas el primer campo de los combos (ItemIndex = 0) para ignorar la condición, se puede acortar bastante esa parte del código.

Por ejemplo:
Código Delphi [-]
function TForm_docente.MakeSQLString: string;
var
  TS: TStrings;
  i: Integer;
begin
  Result:= 'SELECT * FROM DOCENTE ';
  TS:= TStringList.Create;
  try
    if ComboBox1.ItemIndex > 0 then
      TS.Add('TIPODOC = :TIPO');
    if Combobox2.ItemIndex > 0 then
      TS.Add('ID_DOCENTE = :MAT');
    if ComboBox3.ItemIndex > 0 then
      TS.Add('ID_LOCALIDAD =:LOC');
    if ComboBox4.ItemIndex > 0 then
      TS.Add('SEXO = :SEX');
    case ComboBox5.ItemIndex of
      1: TS.Add('EDAD = :EDA'); // igual
      2: TS.Add('EDAD > :EDA'); // mayor
      3: TS.Add('EDAD < :EDA'); // menor
      4: TS.Add('EDAD BETWEEN :EDA AND :EDA2') // entre
    end;
    if TS.Count > 0 then
    begin
      Result:= Result + 'WHERE ';
      for i:= 0 to TS.Count-1 do
        if i < TS.Count-1 then
          Result:= Result + TS[i] + ' AND '
        else
          Result:= Result + TS[i];
    end;
    case ComboBox6.ItemIndex of
      1: Result:= Result + ' ORDER BY NOMBRE_APELLIDO ASC';
      2: Result:= Result + ' ORDER BY NOMBRE_APELLIDO DESC'
    end
  finally
    TS.Free
  end;
end;
En el ejemplo, para todos los combos el primer valor (índice 0) contiene el texto 'Ignorar'.

Saludos.

naty_prog 29-02-2012 18:36:30

agradecimientos
 
estoy muy agradecida por sus respuesta,no saben lo que me hace falta poder terminar con los errores del programa que estamos haciendo con un compañero ya que solo nos quedan 5 meses para poder presentarla y cada vez que hacemos testing encontramos mas y mas errores. muchas gracias compañeros,saludos.

naty_prog 05-03-2012 19:01:45

pregunta..
 
hola eficsa,queria consultarte por la sentencia que declaraste en la respuesta anterior:
Código Delphi [-]
function TForm_docente.MakeSQLString: string;
ya que no comprendo de la funcion MakeSQLstring.
gracias.

ecfisa 05-03-2012 19:57:19

Cita:

ya que no comprendo de la funcion MakeSQLstring
Hola naty_prog.

Voy a tratar de explicarla documentando el código de la función misma. (Que bién podría haberse llamado HacerCadenaSQL :) ).
Código Delphi [-]
function TForm_docente.MakeSQLString: string;
var
  TS: TStrings;
  i: Integer;
begin
  Result:= 'SELECT * FROM DOCENTE '; //Iniciar la sentencia SQL
  TS:= TStringList.Create;
  try
    (* Tipo documento *)
    if ComboBox1.ItemIndex > 0 then  // si es diferente a 'Ignorar'
      TS.Add('TIPODOC = :TIPO');     // se agregará parámetro ":TIPO" a WHERE
    (* Materia *)
    if Combobox2.ItemIndex > 0 then  // si es diferente a 'Ignorar'
      TS.Add('ID_DOCENTE = :MAT');   // se agregará parámetro ":MAT" a WHERE
    (* Localidad *)
    if ComboBox3.ItemIndex > 0 then  // si es diferente a 'Ignorar'
      TS.Add('ID_LOCALIDAD =:LOC');  // se agregará parámetro ":LOC" a WHERE
    (* Sexo *)
    if ComboBox4.ItemIndex > 0 then  // si es diferente a 'Ignorar'
      TS.Add('SEXO = :SEX');         // se agregará parámetro ":LOC" a WHERE
    (* Edad *)
    case ComboBox5.ItemIndex of      // ItemIndex = 0 => 'Ignorar'
      1: TS.Add('EDAD = :EDA'); // igual
      2: TS.Add('EDAD > :EDA'); // mayor
      3: TS.Add('EDAD < :EDA'); // menor
      4: TS.Add('EDAD BETWEEN :EDA AND :EDA2') // entre
    end;
    (* Comenzar armado de WHERE *)
    if TS.Count > 0 then         // Si hubo selección en algún ComboBox -> armar cadena
    begin
      Result:= Result + 'WHERE ';  // comienza con WHERE
      for i:= 0 to TS.Count-1 do
        if i < TS.Count-1 then   // ¿ Existen más comprobaciones delante ?
          Result:= Result + TS[i] + ' AND ' // si, agregar AND
        else
          Result:= Result + TS[i];          // no
    end;
    (* Orden  *)
    case ComboBox6.ItemIndex of   // ItemIndex = 0 => 'Ignorar'
      1: Result:= Result + ' ORDER BY NOMBRE_APELLIDO ASC';  // ascendente
      2: Result:= Result + ' ORDER BY NOMBRE_APELLIDO DESC' // descendente
    end
  finally
    TS.Free  // Liberar 
  end;
end;
Si no he sido suficientemente claro, hacemelo saber y gustoso trataré de explicarme de otro modo.

Un saludo.


Edito: Ya me olvidaba de ejemplificar el uso... :o
Código Delphi [-]
var
  CadenaSQL: string;
begin
   CadenaSQL:= MakeSQLString
end;

ecfisa 05-03-2012 20:26:10

Hola de nuevo.

Me quedé pensando que quizá un ejemplo te pueda ayudar a entender el funcionamiento. Traté de hacerlo lo más simple posible, consta de seis TComboBox para la elección de los parámetros y un TButton para mostrar la consulta SQL generada.

Saludos.

naty_prog 06-03-2012 18:24:43

respuesta
 
hola ecfisa, gracias por tu explicacion,ahora lo comprendo mejor ya que me habia mareado un poco jaja tu ayuda y la de muchas otras personas en este foro me viene al pelo para poder avanzar con mi tesis que debo rendirla en agosto,asi que seguire recurriendo a sus aportes.gracias nuevamente...naty_prog

naty_prog 21-03-2012 19:56:13

respuesta
 
hola amigos,utilizando el codigo anterior,se me presento un problema con un combobox,el cual selecciona a los docentes de una tabla clasificandolos por los que se encuentran habilitados y por los que estan deshabilitados.el codigo que habia creado es el siguiente:

Código Delphi [-]
 case ComboBox_estado.ItemIndex of
    0:   //todas
      begin
      end;
    1:
      begin
        if(puse_where)then
          consulta:= consulta + ' and ESTADO=1'
        else
          begin
            consulta:= consulta + ' where ESTADO=1';
            puse_where:=true;
          end;
      end;
    2:
      begin
        if(puse_where)then
          consulta:= consulta + ' and ESTADO=0'
        else
          begin
            consulta:= consulta + ' where ESTADO=0';
            puse_where:=true;
          end;
      end;
  end;

este codigo quisiera tranformarlo para que me coordine con el resto del codigo anterior,es decir, utilizando el ejemplo de ecfisa.desde ya muchas gracias

ecfisa 21-03-2012 20:49:42

Hola naty_prog.

Si no entiendo mal es otro ComboBox mas, cuyos items serían:
  • Todos
  • Habilitados
  • Inhabilitados
Entonces creo que podrías agregar al codigo anterior algo como:
Código Delphi [-]
  ...
  (* Edad *)
  ...
  (* Docentes habilitados o no *)
    case ComboBoxEstado.ItemIndex of
      //0 = todos
      1: TS.Add('ESTADO = 1');
      2: TS.Add('ESTADO = 0');
    end;
  (* Comenzar armado de WHERE *)
  ...

Saludos.

naty_prog 21-03-2012 20:59:00

respuesta
 
hola ecfisa,eso era lo que precisamente necesitaba.muchisimas gracias.saludines :)


La franja horaria es GMT +2. Ahora son las 15:27:25.

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