PDA

Ver la Versión Completa : validar checkbox en un FOR


GonzaloDias
12-04-2012, 20:17:40
Hola amigos del foro,
Bueno mi problema es que quiero validar varios checkbox dentro de un FOR, mi duda es si es posible que en vez de que se lea checkbox1.checked se pudiera leer como checkbox[i].checked, por ejemplo:

for i:=1 to 10 do
begin

total:=a*b;
if total >10 then
checkbox[i].checked = false;
end;


y asi ir validando los checkbox, les comento que tengo 10 checkbox pero antes al iniciar el form donde se encuentran estos checkbox lo squiero validar habilitandolos y deshabilitandolos y para no hacer varios if, se me ocurrio realizar un FOR es decir un for q valla de 1 a 10, el tema es ver si se puede de esta manera o cual sugieren? se que ahi varias maneras pero esta no se si es posible.
Muchas Gracias amigos.

roman
12-04-2012, 20:20:10
Podrías hacer algo como:


for I := 0 to ControlCount -1 do
if Controls[I] is TCheckBox then
TCheckBox(Controls[I]).Checked := true;


// Saludos

marcoszorrilla
12-04-2012, 21:43:03
Yo estaba intentando con éste código, pero es mucho más simple el de Román.

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

var
aChk:Array[1..9] of ^TCheckbox;
i:Integer;

type
TForm1 = class(TForm)
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
CheckBox4: TCheckBox;
CheckBox5: TCheckBox;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin
aChk[1]:= @CheckBox1;
aChk[2]:= @CheckBox2;
aChk[3]:= @CheckBox3;
aChk[4]:= @CheckBox4;
aChk[5]:= @CheckBox5;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
For i:=1 to 5 do
begin
aChk[i].Checked:=True;
end;

end;

end.
Un Saludo.

roman
12-04-2012, 22:02:59
El método que apuntas, Marcos, es el que yo usaría en los casos en que es necesario acceder a los controles en múltiples ocasiones. De hecho, si algo tenía de bueno VB, era que podías insertar arreglos de controles en automático.

Por otra parte, puedes obviar esos @ y ^ ;).

// Saludos

marcoszorrilla
12-04-2012, 22:14:08
Yo tengo un programa en el que una competición dura entre 1 y 10 días y hay que capturar 3 datos distintos por cada día y hasta que el usuario introduce el número de días no se sabe cuantos controles hay que mostrar, yo tengo los 30 controles, 3 columnas de datos con la propiedad Visible = False, y al introducir los días automáticamente se hacen visibles los correspondientes al número de días tecleados y por eso utilicé esta forma de trabajo.

Un Saludo.

GonzaloDias
12-04-2012, 22:39:21
Gracias amigos me sirvio de mucho, lo modifique un poco y me quedo asi.

c:=0;
for i := 8 to 20 do
begin

if Controls[i] is TCheckBox then
begin
c:=c+1;
//CostoC:=strtoint(form8.DBEdit3.Text);
CostoC:=600;
Resultado:=CostoC mod c;

if Resultado<>0 then
TCheckBox(Controls[i]).Enabled := false;

end;
end;


pero me quedo un problema que en el control 10 no ingresa al if que lo valida si es Tcheckbox, saben como es para asignarle al checkbox4 (en mi caso) el control 10?

GonzaloDias
12-04-2012, 22:47:25
al parecer se asigna el control cunado se crea i luego no se puede modificar, no logro modificarlo o asignarle el control 10

maeyanes
12-04-2012, 22:47:42
Hola...

Otro pequeño "shortcut":


TChecBox(Controls[I]).Enabled := Resultado = 0



Saludos...

maeyanes
12-04-2012, 22:51:13
Hola...

Otro detalle; cuando vayas a recorrer todos los controles en busca de controles de cierto tipo, tu ciclo debes hacerlo desde 0 hasta el número de controles menos uno (for I := 0 to Pred(ControlCount) do), esto es, no puedes estar seguro que en tiempo de ejecución todos los CheckBoxs van a tener un Index entre 8 y 20.


Saludos...

AzidRain
13-04-2012, 02:02:16
El resultado de este poste debiera irse a una sección "Buenas prácticas" o algo así ya que a pesar de ser soluciones muy sencillas, a mas de uno se nos olvidan de vez en cuando (Me acuerdo del concepto del Bibliotecario de Código de Al Gonzalez) y siempre son muy útiles. A ver si alguien o algunos nos tomamos un poco de tiempo de francachelas para ir compilando el "Pequeño ClubDelphi Ilustrado" jejeje.

Delphius
13-04-2012, 04:21:12
Hola amigos del foro,
Bueno mi problema es que quiero validar varios checkbox dentro de un FOR, mi duda es si es posible que en vez de que se lea checkbox1.checked se pudiera leer como checkbox[i].checked, por ejemplo:

for i:=1 to 10 do
begin

total:=a*b;
if total >10 then
checkbox[i].checked = false;
end;


y asi ir validando los checkbox, les comento que tengo 10 checkbox pero antes al iniciar el form donde se encuentran estos checkbox lo squiero validar habilitandolos y deshabilitandolos y para no hacer varios if, se me ocurrio realizar un FOR es decir un for q valla de 1 a 10, el tema es ver si se puede de esta manera o cual sugieren? se que ahi varias maneras pero esta no se si es posible.
Muchas Gracias amigos.

Bueno, es posible hacer algo "parecido" a eso. Yo en vez de proponerte las alternativas que te han dado, quisiera darle un pequeño giro de cuerda. Existe un control que justamente simplifica mucho el trabajo sobre un "grupo" o lista de CheckBoxs... el componente se llama TCheckListBox o algo así, no recuerdo bien y mi máquina con Delphi está dañada.
Este componente es simplemente un TListbox con checkboxs dentro, con lo que basta con recorrer la propiedad vectorial y los items para acceder a cada checkbox.

Saludos,

MartinS
13-04-2012, 15:08:09
Hola:

y si cambias
for i := 8 to 20 do
a
for I := 0 to ControlCount -1 do
como expresa Roman?

Saludos.-

roman
13-04-2012, 18:19:26
Existe un control que justamente simplifica mucho el trabajo sobre un "grupo" o lista de CheckBoxs... el componente se llama TCheckListBox [...]
Este componente es simplemente un TListbox con checkboxs dentro, con lo que basta con recorrer la propiedad vectorial y los items para acceder a cada checkbox.


Buena opción, pero con la limitante de que no puedes acomodar tus checkbox a tu gusto. Sin embargo, pensando en esta opción, se me ocurre que puede crearse un componente sencillo derivado de TGroupBox:


unit CheckGroup;

interface

uses Classes, StdCtrls, Contnrs;

type
TCheckGroup = class(TGroupBox)
private
FItems: TObjectList;

function GetItem(Index: Integer): TCheckBox;
function GetItemCount: Integer;

protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;

public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

property Items[Index: Integer]: TCheckBox read GetItem;
property ItemCount: Integer read GetItemCount;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('ClubDelphi', [TCheckGroup]);
end;

{ TCheckGroup }

constructor TCheckGroup.Create(AOwner: TComponent);
begin
inherited;
FItems := TObjectList.Create(false);
end;

destructor TCheckGroup.Destroy;
begin
FItems.Free;
inherited;
end;

function TCheckGroup.GetItem(Index: Integer): TCheckBox;
begin
Result := TCheckBox(FItems[Index]);
end;

function TCheckGroup.GetItemCount: Integer;
begin
Result := FItems.Count;
end;

procedure TCheckGroup.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;

case Operation of
opInsert:
if AComponent is TCheckBox then
FItems.Add(AComponent);

opRemove:
if AComponent is TCheckBox then
FItems.Remove(AComponent);
end;
end;

end.


Con este componente tendrías en Items el arreglo de CheckBox real. En un TCheckListBox lo que tienes son propiedades vectoriales para cada propiedad de un CheckBox: ItemEnabled, Checked, State. La ventaja sería, además de colocar los controles como gustes, que puedes insertar otro tipo de controles y la propiedad vectorial reflejaría sólo los checkbox.

// Saludos