![]() |
![]() |
![]() |
![]() |
![]() |
FTP | ![]() |
![]() |
CCD | ![]() |
![]() |
Buscar | ![]() |
![]() |
Trucos | ![]() |
![]() |
Trabajo | ![]() |
![]() |
Foros | ![]() |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
![]() |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Buscar componentes
Hola,
Quisiera que me ayudaran en lo siguiente: Quiero colocarle color a los componentes que dependiendo de su fuente de datos verificar si son requeridos y colocarle un color diferente. Estoy haciendo un ciclo donde busco en el datasource y verificando su propiedad required lo asigno a un memo para hacer pruebas y selecciona los que son, pero al asignarle el color es donde me lio. Quisiera hacer lo siguiente, si es factible, cuando encuentre el primer campo que sea requerido, inmediatamente buscar en el formulario el componente que este asociado al campo pero no se como hacerlo, la funcion de findcomponente no sabría como implementarla para esto. No se si me puedan ayudar. De todas formas dejo la inquietud para ver si sale alguna idea. Gracias de antemano. El codigo que utilizo es este, claro es una idea Cita:
|
#2
|
||||
|
||||
Prueba con este ejemplo que acabo de preparar y verás como funciona.
procedure TForm1.Button1Click(Sender: TObject); var I,J:Integer; begin for i := 0 to DataSource1.DataSet.Fields.Count - 1 do begin if DataSource1.DataSet.FieldDefs.Items[i].Required then begin ShowMessage(DataSource1.DataSet.FieldDefs.Items[i].Name +'Requerido'); for j := 0 to ComponentCount - 1 do begin if Components[j].ClassNameIs('TDBEdit') then begin If DataSource1.DataSet.FieldDefs.Items[i].Name =(Components[j] as TDBEdit).DataField then (Components[j] as TDBEdit).Color := clLime; end; end; end; end; end; Un Saludo. |
#3
|
|||
|
|||
Hola marcos,
He copiado el codigo que me has enviado, y al intentar ejecutarlo me da un error de fuera de indice, no se si esto esta ocurriendo por que tengo un campo calculado en el editor de campos del cds que creo que es lo más certado, tendría que mirar como evitar o eludir este tipo de campos, alguna propiedad especifica que indique que es calculado o de busqueda que es el que tengo. Gracias |
#4
|
||||
|
||||
De momento no le encuentro solución, porque accede a una matriz formada por los campos persistentes.
Ahora bien, si no añadimos ningún campo real y por ejemplo 3 calculados, accederá a los 3 primeros campos reales del Dataset si los hubiera. Luego el problema surge cuando añadimos todos los campos reales y un calculado entonces resulta que tenemos una matriz con por ejemplo 21 campos de los cuales solamente existen 20, ya que el calculado no existe en la tabla. Aquí viene el error al llegar al elmento 21 que no tiene correspondencia. El error se produce por acceder al elemento 21, que no existe en el DataSet. Nota: Cuando digo real, quiero decir que el campo existe en la tabla, no me estoy refiriendo a un tipo de datos. Un Saludo. |
#5
|
||||
|
||||
Bueno despues de algunas pruebas he logrado circumvenir al DataSet, lo que he hecho es ver la manera de conocer el número real de campos que hay en la tabla, la única manera que he econtrado y que funciona, es cargar la lista de campos en una StringList y abordarlos desde el número de campos cargados.
procedure TForm1.Button1Click(Sender: TObject); var I,J,nCampos:Integer; Sl:TstringList; begin sl:=Table1.FieldDefList; nCampos:=sl.Count -1; for i := 0 to nCampos do begin ShowMessage(Table1.FieldDefList[i].Name); //showMessage(DataSource1.DataSet.FieldDefs.Items[i].FieldClass.ClassName ); //ShowMessage(DataSource1.DataSet.FieldDefs.Items[i].Name); if DataSource1.DataSet.FieldDefs.Items[i].Required then begin ShowMessage(DataSource1.DataSet.FieldDefs.Items[i].Name +'Requerido'); for j := 0 to ComponentCount - 1 do begin if Components[j].ClassNameIs('TDBEdit') then begin If DataSource1.DataSet.FieldDefs.Items[i].Name =(Components[j] as TDBEdit).DataField then (Components[j] as TDBEdit).Color := clLime; end; end; end; end; Un Saludo. |
#6
|
|||
|
|||
Hola:
Otra solución para lo que plantea Mosorio en el primer mensaje es recorriendo los componentes, averiguar cuáles son DBAware y asignar la propiedad Color, si la tienen. Pare ello nos velamos de la unit TypInfo para averiguar si cierta propiedad existe y para asignarla en tal caso. Tengo un código que hace algo parecido. Adaptado a este caso sería lo siguiente: Código:
uses TypInfo; {$R *.DFM} procedure TForm1.Button1Click(Sender: TObject); const ColorCampoRequerido = clYellow; var PropInfo : PPropInfo; ADataSet : TDataSet; AField : TField; s : String; i : Integer; begin for i:=0 to ComponentCount - 1 do begin // Primero comprobamos que el control es DBAware PropInfo := GetPropInfo (Components[i].ClassInfo, 'DataSource'); if (PropInfo <> nil) AND (PropInfo^.PropType^.Kind = tkClass) then begin // Nos aseguramos que está realmente enlazado a un TDataset ADataSet := TDataSource(GetOrdProp (Components[i], PropInfo)).DataSet; if ADataSet <> nil then begin // Obtenemos el nombre del campo al que está ligado PropInfo := GetPropInfo (Components[i].ClassInfo, 'DataField'); if (PropInfo <> nil) then begin // Obtenemos el campo al que está ligado y miramos si Required = TRUE s := GetStrProp(Components[i], PropInfo); AField := ADataSet.FindField (s); if (AField <> nil) AND (AField.Required) then begin // Comprobamos si el control tiene una propiedad Color y la asignamos PropInfo := GetPropInfo (Components[i].ClassInfo, 'Color'); if PropInfo <> nil then SetOrdProp(Components[i], PropInfo, ColorCampoRequerido); end; end; end; end; end; end; |
#7
|
|||
|
|||
Hola delphoros!
Agradesco toda la ayuda que me han dado, en especial a quellos que han aportado sus ideas. Andres ha funcionado perfectamente, claro que creo que la rutia es un poco larga, mirare si se puede optimizar más adelante. |
![]() |
|
|
![]() |
|