Ir al contenido


Foto

[RESUELTO] Buscar todos los componentes por su nombre parcialmente


  • Por favor identifícate para responder
15 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 29 septiembre 2010 - 10:58

Pues eso, estoy haciendo un simple procedimiento que su única función es buscar todos los CheckBox del formulario por su nombre de manera parcial, me explico, tengo 14 checkboxes, 7 empiezan con el prefijo "cbA" y los otros 7 con "cbE", ahora, quiero buscar y contar todos los checkbox que empiecen con "cbA" o "cbE" para verficicar si al menos uno de ellos está acotejado, aquí dejo el code:



delphi
  1. Procedure SetDiasHabiles(Prefijo: string; Form: TForm);
  2. var i: integer;
  3. begin
  4.   for i := 0 to Form.ComponentCount -1 do
  5.       if (Form.FindComponent(Prefijo) as TCheckBox).Checked = False then
  6.         begin
  7.           ShowMessage('No has seleccionado ningún día hábil para este Horario!');
  8.           Abort;
  9.         end;
  10. end;



El resultado?, un bonito Access Violation:



delphi
  1. ---------------------------
  2. Debugger Exception Notification
  3. ---------------------------
  4. Project TimerPunch.exe raised exception class EAccessViolation with message 'Access violation at address 005E37E5 in module 'TimerPunch.exe'. Read of address 00000000'. Process stopped. Use Step or Run to continue.
  5. ---------------------------
  6. OK  Help 
  7. ---------------------------



:( :(

  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 septiembre 2010 - 11:36

Hola amigo,

¿No has pensado en este escenario en utilizar el TCheckListBox? Es como un TListBox pero con CheckBoxes. Está en la paleta Additional.

En tu caso yo pondría dos TCheckListBox, uno con para los cbA y otro para los cbE.

De ese modo sólo deberías verificar en cada lista y te evitas el FindComponent.

Por cierto, es redundante hacer un for de ComponentCount y dentro de éste hacer un FindComponent. Internamente FindComponent hace un For de ComponentCount.  ;)
  • 0

#3 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 29 septiembre 2010 - 12:06

Yo la cambiaria por esta función boolena :



delphi
  1. function Chequeados(Prefijo: string; Form: TForm): Boolean;
  2. var
  3.   i: integer;
  4. begin
  5.   Result := False;
  6.   for i := 0 to Form.ComponentCount - 1 do
  7.   begin
  8.     if (Form.Components[i].ClassType = TCheckBox) then
  9.       Result := (TCheckBox(Form.Components[i]).checked) and
  10.         (TCheckBox(Form.Components[i]).Name = Prefijo);
  11.     if Result then
  12.       break;
  13.   end;
  14. end;



y la usaría así:



delphi
  1. if not Cheauqueados('prefijo', form) then
  2. .......


  • 0

#4 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 29 septiembre 2010 - 12:19

O tambien podrías poner 1 al tag de los checkbox que quieres controlar y quedaría así:



delphi
  1. function Chequeados(ATag: Integer; Form: TForm): Boolean;
  2. var  i: integer;
  3. begin 
  4. Result := False; 
  5. for i := 0 to Form.ComponentCount - 1 do
  6. begin   
  7. if (Form.Components[i].ClassType = TCheckBox) then 
  8.   Result := (TCheckBox(Form.Components[i]).checked) and 
  9.     (TCheckBox(Form.Components[i]).Tag = ATag); 
  10.   if Result then   
  11.   break; 
  12. end;
  13. end;


  • 0

#5 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 29 septiembre 2010 - 01:47

Buenas

Y así?



delphi
  1. Procedure SetDiasHabiles(Prefijo: string; Form: TForm);
  2. var i: integer;
  3. begin
  4.   for i := 0 to Form.ComponentCount -1 do
  5.       if (Form.Components[i] as TCheckBox).Checked = False then
  6.         begin
  7.           ShowMessage('No has seleccionado ningún día hábil para este Horario!');
  8.           Abort;
  9.         end;
  10. end;



Nos leemos

  • 0

#6 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 29 septiembre 2010 - 06:53

Saludos.

Aparte de lo mencionado por Delphius, creo que el error consiste en que estas castiando todos los componentes sin importar su naturaleza, debes de tomar en cuenta también que FindComponent devuelve Nil cuando no encuentra nada y al realizar el casteo pues PUM.

La pregunta en la rutina de Wilson con el ClassType debería funcionar, puedes usar en cambio el operador Is y luego As.
  • 0

#7 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 septiembre 2010 - 07:27

Hola,
Yo sigo pensando que es mejor emplear el TCheckListBox. De ese modo se evita el estar recorriendo entre todos los componentes y buscar por nombre, se utiliza de forma similar a un TListBox. El CheckListBox tiene un método Checked que recibe como parámetro el índice del CheckBox a verificar.
Se puede asociar a los n-primeros checkboxs que identifique a un tipo y los n-siguientes los restantes.

Saludos,
  • 0

#8 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 29 septiembre 2010 - 07:35

A mi me parece que el uso de los Tag es lo más fácil, por ejemplo asignamos 1 a los que comienzan con cbA y 2 a los de cbE.

Utilizando el código de Wilson podemos modificarlo de esta manera.



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   i: integer;
  4.   cbe,cba: integer;
  5. begin
  6.   cba := 0;
  7.   cbe := 0;
  8.   for i := 0 to ComponentCount -1 do
  9.   begin
  10.     if Components[i].ClassType = TCheckBox then
  11.     begin
  12.       if TCheckBox(Components[i]).checked then
  13.       begin
  14.         Case TCheckBox(Components[i]).Tag of
  15.           1: cba := cba+1;
  16.           2: cbe := cbe+1;
  17.         end;
  18.       end;
  19.     end;
  20.   end;
  21.   ShowMessage(format('Hay %d cbA y %d cbE seleccionados',[cba,cbe]));
  22. end;



Salud OS
  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 septiembre 2010 - 07:44

Ejem:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   MAX_CHECKS = 7;
  4. var i, cA, cE: Integer;
  5. begin
  6.   cA := 0;
  7.   cE := 0;
  8.   for i := 0 to CheckListBox1.Count - 1 do
  9.     if CheckListBox1.Checked[i]
  10.       then if i < MAX_CHECKS
  11.               then Inc(cA)
  12.               else Inc(cE);
  13.   ShowMessage(intToStr(cA) + '/' + IntToStr(cE));
  14. end;


Esto se convirtió en una guerra de código. Fíjense. Nada de Finds, nada de cast, simple y directo. Tener una lista de CheckBoxs y explorarlos.

Y si es necesario recuperar el nombre basta con recurrir a la propiedad Items.

Saludos,
  • 0

#10 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 29 septiembre 2010 - 07:52

Hola amigo Delphius

Tu solución es muy buena suponiendo que los checkbox están agrupados y en un solo lugar, pero....... que pasa si no están agrupados en un mismo bloque, digo, nomás por molestar :D :D :D

Salud OS
  • 0

#11 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 29 septiembre 2010 - 08:06

Hola amigo Delphius

Tu solución es muy buena suponiendo que los checkbox están agrupados y en un solo lugar, pero....... que pasa si no están agrupados en un mismo bloque, digo, nomás por molestar :D :D :D

Salud OS

Bueno, allí si puede que falle mi idea.  :p
Pero si el objetivo es disponer de muchos chexbox, y si están nombrados bajo cierta denominación... es porque da a entender que se trata de agrupamiento. Por ello es que es muchísimo más ventajoso el CheckListBox.

Pero bueno, son ideas. Fernando dirá si le sirve...

Ha, por cierto... Fernando, ya he subido el monto... hoy cuando estuve en el centro vi la cotización del dolar y empezó a subir de 4  :
Los servicios de hoy suben a 350 dlr.  :D A este ritmo me compro Delphi XE Enterprise  :p  :D

Saludos,
  • 0

#12 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 30 septiembre 2010 - 08:16

Gracias a todos amigos, me he quedado con la segunda solución de Wilson, me funciona de pelos. Gracias a todos :).

Saludos.
  • 0

#13 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 30 septiembre 2010 - 09:11

Ah bueno, ya salio un ganador, cual era el premio ? :D :D :D

Salud OS
  • 0

#14 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 30 septiembre 2010 - 09:15

Ah bueno, ya salio un ganador, cual era el premio ? :D :D :D

Salud OS


Premio!!

;)
  • 0

#15 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 30 septiembre 2010 - 01:17

^o| Se me hace que no gané porque le pasé una factura muy pesada a Fernando. Tal vez si le hago una rebaja...  :D

Saludos,
  • 0

#16 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 01 octubre 2010 - 07:25


Ah bueno, ya salio un ganador, cual era el premio ? :D :D :D

Salud OS


Premio!!

;)


Hasta ahora me entero del premio, gracias enecumene,  me comeré un buen plato de mariscos, para disfrutar el regalo.

saludos
  • 0




IP.Board spam blocked by CleanTalk.