Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Simplificar el uso de if al usar RadioGroup (https://www.clubdelphi.com/foros/showthread.php?t=80137)

wull 06-09-2012 03:57:58

Simplificar el uso de if al usar RadioGroup
 
El problema que me esta poniendo los pelos de punta es este: Tengo un par de RadioGroup, que al evaluarlos me dan los parámetros para crear un informe... hasta ahi todo bien, gracias a la ayuda proporcionada por el foro. Pero ahora quiero lograr que si ninguno de los item de los RadioGroup ha sido marcado, entonces mandar un mensaje al usuario para pedirle que marque por lo menos una opción no importa de que RadioGroup sea.
Para lograr esto estoy usando el siguiente código:
Código Delphi [-]
 if (radiogroup1.ItemIndex > -1) then 
        begin
         if (radiogroup2.ItemIndex >-1) then 
             begin 
               with ADOQuery1 do
                  begin 
                   Close;
                   SQL.Text:= 'SELECT * FROM MITABLA WHERE AÑO = :PANIO AND MES=:PMES';
                   Parameters.ParamByName('PANIO').Value:=RadioGroup1.Items[RadioGroup1.ItemIndex];
                   Parameters.ParamByName('PMES').Value:=RadioGroup2.Items[RadioGroup2.ItemIndex];
                   Open;
                  end;
                Myreport.ShowReport(true);
                end;
                

         end  
      else
       showmessage('elija por lo menos un parametro para el reporte');
Con esto me surgen dos problemas, primero el orden de los RadioGroup, ya debo que repetir las comparaciones. Es decir primero estoy comparando el RadioGroup1, con una serie de condicones... pero si no es este el que se elige primero tengo que repetir el código ahora iniciando con el RadioGroup2. El otro problema es que al estar usando if anidados tengo que repetir la comparacion para ver si solo se ha usado un RadioGroup o si se han usado los dos.
Espero haber explicado bien mi problema... no tengo idea de como solucionarlo, se me olvida mencionarlo todo este codigo lo tengo en el evento onclick de un botón que llama al reporte. Espero me puedan ayudar

roman 06-09-2012 04:06:17

Cita:

Empezado por wull (Mensaje 442011)
pero si no es este el que se elige primero tengo que repetir el código ahora iniciando con el RadioGroup2.

Yo no entiendo. ¿Cómo vas a saber cuál se eligió primero? En general, no entiendo el planteamiento.

// Saludos

Caral 06-09-2012 04:10:07

Hola
Código Delphi [-]
var
  i: Integer;
  comp: TComponent;
begin
  for i := 1 to 2 do begin
  comp := FindComponent('radiogroup' + IntToStr(i)); 
 
 if Tradiogroup(comp).ItemIndex > -1 then 
 begin
  with ADOQuery1 do
  begin 
  Close;
  SQL.Text:= 'SELECT * FROM MITABLA WHERE AÑO = :PANIO AND MES=:PMES';
  Parameters.ParamByName('PANIO').Value:= RadioGroup1.Items[RadioGroup1.ItemIndex];
  Parameters.ParamByName('PMES').Value:= RadioGroup2.Items[RadioGroup2.ItemIndex];
  Open;
  end;
  Myreport.ShowReport(true);
 end  
 else
       showmessage('elija por lo menos un parametro para el reporte');
end;
Saludos

ecfisa 06-09-2012 05:17:14

Cita:

Empezado por wull (Mensaje 442011)
Pero ahora quiero lograr que si ninguno de los item de los RadioGroup ha sido marcado, entonces mandar un mensaje al usuario para pedirle que marque por lo menos una opción no importa de que RadioGroup sea.

Hola wull.

La lógica planteada arriba es:
Código Delphi [-]
  ...
  if (RadioGroup1.ItemIndex <> -1) or (RadioGroup2.ItemIndex <> -1) then // Si al menos un item fué seleccionado...
  begin
     // Todo bién, hacer lo que haya que hacer
  end
  else 
    // Error, seleccione al menos uno
  ...
Y funcionaría correctamente... de no ser por un detalle: Si hay selección solamente en un RadioGroup, vas a obtener una excepción que se producirá en la línea:
Código Delphi [-]
Parameters.ParamByName('PANIO').Value := RadioGroup1.Items[RadioGroup1.ItemIndex];
Cuando el usuario haya seleccionado un item de RadioGroup2 o en la línea:
Código Delphi [-]
Parameters.ParamByName('PMES').Value := RadioGroup2.Items[RadioGroup2.ItemIndex];
Cuando lo haya echo en el RadioGroup1.


¿ Por que digo esto ?, por que en algun punto estarías haciendo lo mismo que:
Código Delphi [-]
Parameters.ParamByName('PXXX').Value := RadioGroupN.Items[-1]; // Error!!! índice fuera de rango

Saludos.

ecfisa 06-09-2012 05:51:37

Hola de nuevo.

Para no dejarte así, sin nada te pongo una opción que dada la hora y el estado de mis neuronas, no creo sea la mejor. :)
Código Delphi [-]
...
  if (RadioGroup1.ItemIndex = -1)and(RadioGroup2.ItemIndex = -1) then
  begin
    MessageBox(Handle,'Al menos una opción debe estar seleccionada','',
      MB_ICONERROR+MB_OK);
    Exit;
  end;
  with ADOQuery1 do
  begin
    Close;
    SQL.Clear;
    SQL.Add('SELECT * FROM A_CATALOGO WHERE ');
    if (RadioGroup1.ItemIndex <> -1) and (RadioGroup2.ItemIndex <> -1) then
      SQL.Add('AÑO = ' + QuotedStr(RadioGroup1.Items[RadioGroup1.ItemIndex])+
              ' AND MES = '+ QuotedStr(RadioGroup2.Items[RadioGroup2.ItemIndex]));
    if (RadioGroup1.ItemIndex <> -1) and (RadioGroup2.ItemIndex  = -1) then
      SQL.Add('AÑO = ' +  QuotedStr(RadioGroup1.Items[RadioGroup1.ItemIndex]));
    if (RadioGroup1.ItemIndex = -1) and (RadioGroup2.ItemIndex  <> -1) then
      SQL.Add('MES = ' +  QuotedStr(RadioGroup2.Items[RadioGroup2.ItemIndex]));
    Open;
  end;
  ...
El código sería más simple si por ejemplo se usaran Combobox.

Saludos.

cloayza 06-09-2012 16:15:15

Otra alternativa
Código Delphi [-]
{
type
  TMiData=array of integer;

Función: GetValues(Senders:array of TObject; Var AValues:TMiData):Integer;
              Retorna la suma de los items del array AValues, si la suma es menor a cero, no hay selección
}

function TForm3.GetValues(Senders:array of TObject; Var AValues:TMiData):Integer;
var
   i:integer;
begin
     SetLength(AValues,High(Senders)+1);
     Result:=0;
     for i := Low(Senders) to High(Senders) do
     begin
          AValues[i]:=-1;
          if (TRadioGroup(Senders[i]).ItemIndex>-1)   then
             AValues[i]:=StrToInt(TRadioGroup(Senders[i]).Items[ TRadioGroup(Senders[i]).ItemIndex ]);
          Inc(Result,AValues[i]);
     end;
end;

procedure TForm3.BitBtn1Click(Sender: TObject);
var
  AValues:TMiData;
  i:Integer;
  Prefix:string;
begin
     {             AValues[0]   AValue[1]  }
     if GetValues([RadioGroup1, RadioGroup2],AValues)<0 then
     begin
          ShowMessage('Sin selección');
          Exit;
     end;

     With ADOQuery1 Do
     Begin
          Close;
          SQL.Clear;
          SQL.Add('SELECT * FROM A_CATALOGO WHERE ');

           Prefix:='';
           if AValues[0]>-1 then {Corresponde a RadioGroup1}
           begin
                Prefix:=' AND';
                SQL.Add(Format('(AÑO = %d)',[AValues[0]]));
           end;

           if AValues[1]>-1 then  {Corresponde a RadioGroup2}
           begin
               SQL.Add(Format('%s (MES = %d)',[Prefix, AValues[1]]));
               Prefix:=' AND';
           end;

          Open;
     End;
   
end;

Saludos cordiales

wull 06-09-2012 22:20:07

Hola de nuevo, antes que otra cosa quiero darles las gracias a todos por sus sugerencias... leí sus comentarios, ya he probado algunas de ellas, les comento lo siguiente:

Empezare por roman: Lo siento trate de explicarme lo mejor que pude, la verdad si estaba algo confuso... mil disculpas.

[Caral]: probe tu solución y me paso lo siguiente: cuando no estaba seleccionado ningun item me mandaba el mensaje pero
tenia que confirmar dos veces (segun yo esto se debe a que es un ciclo for y debe repetirse dos veces antes de terminar)
y tambien me mandaba el error que dice caral cuando solo seleccionaba el item de uno de los dos RadioGroup.

Cita:

Y funcionaría correctamente... de no ser por un detalle: Si hay selección solamente en un RadioGroup, vas a obtener una excepción que se producirá en la línea:
Código Delphi [-]
Parameters.ParamByName('PANIO').Value := RadioGroup1.Items[RadioGroup1.ItemIndex];
Cuando el usuario haya seleccionado un item de RadioGroup2 o en la línea:

Código Delphi [-]
Parameters.ParamByName('PMES').Value := RadioGroup2.Items[RadioGroup2.ItemIndex];
Cuando lo haya echo en el RadioGroup1.


¿ Por que digo esto ?, por que en algun punto estarías haciendo lo mismo que:

Código Delphi [-]
Parameters.ParamByName('PXXX').Value := RadioGroupN.Items[-1]; // Error!!! índice fuera de rango

cloayza: segun yo tu respuesta es muy buena, pero la verdad es demasiado para mi, me perdi en muchas partes del codigo, por lo cual no pude probar con tu propuesta

Asi que despues de leer detenidamente sus mensajes opte por seguir el consejo de ecfisa, (con una pequeña variación) con todo y su advertencia
Cita:

Hola de nuevo.

Para no dejarte así, sin nada te pongo una opción que dada la hora y el estado de mis neuronas, no creo sea la mejor.
Ya habia pensado en algo asi, pero sin duda sus consejos me aclararon mucho el panorama.
El siguiente es el codigo que me ha ayudado ya lo he probado y funciona, aunque como dice ecfisa no es lo mejor.

Código Delphi [-]
if (RadioGroup1.ItemIndex >-1) and (RadioGroup2.ItemIndex >-1) then
      begin
       with ADOQuery1 do
        begin
        Close;
        SQL.Text:= 'SELECT * FROM MITABLA WHERE AÑO = :PANIO AND MES=:PMES';
        Parameters.ParamByName('PANIO').Value:=RadioGroup1.Items[RadioGroup1.ItemIndex];
        Parameters.ParamByName('PMES').Value:=RadioGroup2.Items[RadioGroup2.ItemIndex];
        Open;
        end;// fin de with
       Myreport.ShowReport(true);
      end
   else
    if (RadioGroup1.ItemIndex > -1) then
       begin
        with ADOQuery1 do
        begin
        Close;
        SQL.Text:= 'SELECT * FROM MITABLA WHERE AÑO = :PANIO';
        Parameters.ParamByName('PANIO').Value:=RadioGroup1.Items[RadioGroup1.ItemIndex];
        //Parameters.ParamByName('PMES').Value:=RadioGroup2.Items[RadioGroup2.ItemIndex];
        Open;
        end;// fin de with
        Myreport.ShowReport(true);
       end
        else
         if (RadioGroup2.ItemIndex > -1) then
           begin
             with ADOQuery1 do
              begin
              Close;
              SQL.Text:= 'SELECT * FROM MITABLA WHERE MES =:PMES';
              //Parameters.ParamByName('PANIO').Value:=RadioGroup1.Items[RadioGroup1.ItemIndex];
              Parameters.ParamByName('PMES').Value:=RadioGroup2.Items[RadioGroup2.ItemIndex];
              Open;
              end;// fin de with
           Myreport.ShowReport(true);
           end
            else
            showmessage ('Debe elegir al menos un parametro para el reporte');
Con esto me ha funcionado muy bien, aunque no es muy presentable me va perfecto para lo que quiero lograr... gracias de nuevo a todos por su ayuda.

P.D.Después de tantas preguntas que he hecho, me surge una más ¿ habra algo que no puedan resolver? jjajaja ;):D

wull 07-09-2012 19:40:05

Hola ecfisa, oye note esto en tu comentario.
Cita:

Empezado por ecfisa (Mensaje 442027)
El código sería más simple si por ejemplo se usaran Combobox.

¿me podrías dar una idea idea de como hacerlo? es que el codigo que implemente funciona bien cuando uso dos RadioGroup, pero si incremento el número de RadioGroups pues por consiguiente el codigo se torna más dificil de seguir, así que voy a tratar de de usar ComboBox. Agradecere cualquier sugerencia... gracias de antemano

ecfisa 07-09-2012 20:35:09

Hola wull.

Me costó encontrar el hilo, pero al final apareció: Consultas a medida utilizando TComboBox, tal vez saques algunas ideas de allí.

Saludos. :)


La franja horaria es GMT +2. Ahora son las 16:06:29.

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