Ir al contenido


Foto

encontrar Campos de una tabla con Findcomponent


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

#1 makina

makina

    Member

  • Miembros
  • PipPip
  • 19 mensajes

Escrito 26 octubre 2011 - 11:23

Que tal foristas. les describo mi problematica.


En Mi proyecto construyo tablas,querys y campos de forma dinamica en tiempo real algo como




delphi
  1.     if xpTipoDato ='INTEGER'    then
  2.                   begin
  3.  
  4. //                    CampoMain :=TIntegerField(FindComponent(forma+Tabla+Campo));
  5.                     nCampoI:=TIntegerField(FindComponent(forma+Tabla+Campo));
  6.                     if ncampoI = nil then
  7.                     begin
  8.                       nCampoI      := TIntegerField.Create(Itabla);
  9.                       nCampoI.Name :=forma+Tabla+Campo;
  10.                     end;
  11.                     with ncampoi do
  12.                       begin
  13.                           nCampoI.FieldName              :=Campo;
  14.                           nCampoI.EditMask              :=xpMascara;
  15.                           nCampoI.required              :=xpbRequerido;
  16.                           nCampoI.ReadOnly              :=xpbReadOnly;
  17.                           nCampoI.OnValidate            :=xFormaValidate;
  18.                           nCampoI.DefaultExpression      :=xpValorDefault;
  19.                           nCampoI.OnChange              :=xFormaChange;
  20.                           nCampoI.ConstraintErrorMessage :=xpMensajeErrorValidacion;
  21.                           nCampoI.CustomConstraint      :=xpValidacion;
  22.                           nCampoI.MinValue              :=xpiValorMinimo;
  23.                           nCampoI.MaxValue              :=xpiValorMaximo;
  24.                           ncampoi.DataSet                :=Itabla;
  25.                           if xpbActualizaObjetos = true then
  26.                             begin
  27.                               nCampoI.OnChange:=xFormaChangeCampoAV;
  28.                               xpbActualizaOBjetos:=False;
  29.                             end;
  30.                       end;
  31.                   end




y en otro procedimiento trato de cambiarle las propiedades ya asignadas  utilizando el procedimiento FindComponent algo como




delphi
  1.                 if xpTipoDato ='INTEGER'    then
  2.                   begin
  3.                     nCampoI:=TIntegerField(FindComponent(forma+Tabla+Campo));
  4.                     if ncampoI = nil then
  5.                       begin
  6.                         ...
  7.                       end;
  8.                 end 



Sin embargo el problema es que  nCampoI:=TIntegerField(FindComponent(forma+Tabla+Campo)); me trae nil lo cual es falso ya que el campo si exisite, incluso si despues de que no lo encuentra lo trato de crear me manda un error diciendo que ya existe el componente.


alguna sugerencia??


es correcto usar el Findcomponent para encotrar  un campo de una tabla??


Gracias
Saludos.
  • 0

#2 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 26 octubre 2011 - 11:44

Buenas,

Has probado con FindField del TDataSet que contiene el campo??

Nos leemos
cadetill
  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 26 octubre 2011 - 11:48

Hola,
Si estás creando campos de forma dinámica, lo lógico sería que éstos se asociaran a un DataSet en concreto como un xQuery o un xTable por ejemplo.


De ser cierto esto, entonces para localizar un campo en cuestión bastaría con un simple:




delphi
  1. MiDataSet.FieldByName('NombreDelCampo');




Para obtener el Field correspondiente. O si se desea ubicarlos por su índice La propiedad vectorial Fields[].


Por otro lado no estaría mal que identaras apropiadamente tu código. He intentado editar tu mensaje para mejorar su escritura, que estaba lleno de etiquetas [ ] pero debido a algún formato que le pusiste mientras escribías hace que se siga viendo un [ font ] que no logro eliminar. Para utilizar etiquetas de Delphi sólo basta con escribir Delphi y /Delphi entre corchetes... y en lo posible evita poner una etiqueta dentro de las etiquetas diseñadas para código como las de Delphi, SQL. Éstas solitas se encargan de dar el formato.


Saludos,
  • 0

#4 makina

makina

    Member

  • Miembros
  • PipPip
  • 19 mensajes

Escrito 26 octubre 2011 - 11:49

Pero el Findfield es para encontrar el campo del select o query. lo que requiero es accesar al campo del Tquery


es decir el campo se llama 'Nombre' pero el componente campo se llama VentaClienteNombre


al que requiero modificarle las  propiedades es al Componente no al campo de la base de datos..




Si no es correcto lo que escribo su correccion es bien apreciada.
  • 0

#5 makina

makina

    Member

  • Miembros
  • PipPip
  • 19 mensajes

Escrito 26 octubre 2011 - 11:52

Que raro.. yo no coloque ningun formato de letra especial. y el codigo esta identado..
lo estoy visualizando con Crhome y se ve correcto.

hay algo que deba hacer para que no aparezca,, trate de editar el mensaje pero esas etiquetas no me aparecen, por lo que no las puedo quitar
  • 0

#6 makina

makina

    Member

  • Miembros
  • PipPip
  • 19 mensajes

Escrito 26 octubre 2011 - 11:53

Por cierto.. lo que quiero es accesar a las propiedades del objeto TField no al valor del campo en la base de datos.
  • 0

#7 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 26 octubre 2011 - 11:55

FindField devuelve un TField, que es precisamente lo que quieres para cambiar propiedades.

No obstante, también puedes hacerlo como comenta Delphius dado que FieldByName también devuelve un TField.

Nos leemos
cadetill
  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 26 octubre 2011 - 12:14

Ha... ya entiendo.


El problema con FindField y FieldByName es que esperan el nombre del campo, que está asociado y hace referencia a la propiedad FieldName del Field. Tu deseas buscar por el nombre del componente, y por tanto por su propiedad Name.


En ese caso lo que debes hacer es recorrer el vector fields[] buscando su coincidencia con el nombre. Como con Fields[] se tiene acceso a Field, luego simplemente basta con acceder a .Name. Por ejemplo:




delphi
  1. while (NOT encontrado) AND (j <= DataSet.Fields.Count - 1) do
  2. begin
  3.   encontrado := DataSet.Fields[j].Name = NombreABuscar;
  4.   if encontrado
  5.     then posicion := j;
  6. end; 




Saludos,
  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 26 octubre 2011 - 12:27

Ahora que lo pienso... es demasiado, no... muy raro que no te encuentre el componente con un simple:




delphi
  1. DataSet.FindComponent();




;)  Recuerda que FindComponent localiza a los componentes "hijos". Este funciona gracias a la propiedad Components[]. Supuestamente, con crear el Field y asignarle su "dueño" debería ser suficiente para encontrarlo.


¿No te arroja error alguno? ¿simplemente devuelve nil?


Saludos,
  • 0

#10 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 26 octubre 2011 - 01:03

Creo que diste en el clavo, delphius, los findcomponent que usa no indican desde que componente "padre" hacer esa busqueda, con lo que seguramente solo busque en los que estan directamente sobre el form (paneles, grids, etc.) pero no en sus sub-objetos.

Deberias ponerle delante a todos esos findcomponent el nombre de tu dataset, o bien hacerte una funcion que busque recursivamente, algo tipo recorrer los compenets si el find no encuentra nada, y repetir la busqueda partiendo de cada objeto, y asi recursivamente... no es dificl de programar, pero es innecesario aqui.




delphi
  1. function FindComponentRecursivo(Padre, MyName);
  2. var i: integer;
  3. begin
  4.   result:= Padre.FindComponent(MyName);
  5.   if Assigned(result) then exit;
  6.   for i:= 0 to Padre.Components.count-1 do begin
  7.     result:= FindComponentRecursivo(Padre.Components[i], MyName);
  8.     if Assigned(result) then exit;   
  9.   end;
  10.   ShowMessage('No encontre componente "'+MyName+'".');
  11. end;



Ojo, esta escrita "de memoria", asi que mira el manual si algo no encaja  *-)

Luego, en tu codigo, cambia los dos FindComponent(MyName) por FindComponentRecursivo(self, MyName) y deberia funcionarte (se supone que self sera el form, claro).
  • 0

#11 makina

makina

    Member

  • Miembros
  • PipPip
  • 19 mensajes

Escrito 26 octubre 2011 - 02:32

Delphius / Sergio.

Esa es la solucion. ya la he probado y funciona perfecto
es algo asi



delphi
  1. Procedure ChangeProperties(nombre:String)
  2. var
  3. zCampo:TField;
  4. begin
  5.   zCampo:=TField(Dataset.Findcomponent(nombre));
  6.   if zCampo <>nil then
  7.   with zCampo do
  8.     begin
  9.       ...
  10.     end;
  11.  
  12. end;



Muchas Gracias a todos por su ayuda y sugerencias

Atte. Makina
  • 0

#12 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 27 octubre 2011 - 01:11

Perdonar, pero yo sigo sin ver por qué no te sirve FieldByName o FindField.

Para hacer la búsqueda por nombre del componente necesitas saber (según el ejemplo primero) forma+Tabla+Campo. Es decir, sabes la tabla y el nombre del campo. Qué problema tienes en usar el FieldByName o FindField? Estos métodos te devuelven un TField, que es lo que necesitas.

Nos leemos
cadetill
  • 0

#13 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 27 octubre 2011 - 07:21

Perdonar, pero yo sigo sin ver por qué no te sirve FieldByName o FindField.

Para hacer la búsqueda por nombre del componente necesitas saber (según el ejemplo primero) forma+Tabla+Campo. Es decir, sabes la tabla y el nombre del campo. Qué problema tienes en usar el FieldByName o FindField? Estos métodos te devuelven un TField, que es lo que necesitas.

Nos leemos
cadetill


No es lo mismo, si tienes dos campos "nombre" en tu consulta, tendras dos fields del estilo nombre y nombre1, y no sabes a priori este nuevo nombre que se le asignara, y no podras diferenciar entre un nombre y otro, de hecho no podras localizar el segundo de ellos porque no sabes por que field buscar... en consultas simples con solo 1 tabla, vale, pero en general no te vale.
  • 0

#14 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 27 octubre 2011 - 10:50

Vale, eso lo entiendo, pero entonces está mal planteada la forma de dar nombre al TField, fíjate que hace forma+Tabla+Campo, con lo que si se da lo que tu dices (que se puede dar ciertamente, pero facilmente salvable con alias que para eso están) le dará un error por duplicidad de nombre.

Nos leemos
cadetill
  • 0

#15 makina

makina

    Member

  • Miembros
  • PipPip
  • 19 mensajes

Escrito 27 octubre 2011 - 11:18

Pues veras Cadetill.

Te cuento mi triste historia.. yo solia hacer eso precisamente para accesar a las propiedades de los campos y no tenia necesidad de construir el campo como componente

algo asi



delphi
  1. Tabla.FieldbyName('Campo').EditMask:='999-AAA';



estas propiedades las modifico despues de haber creado la tabla y asignarle su SQL.text.

funciona la primera vez, pero una vez que cierras y abres nuevamente la tabla estas propiedades desaparecen

por eso mi necesidad de crear el Tfield como componente asi ya creado el componente puedo acceder a sus propiedades y modificarlas sin el problema de que desaparezcan despues de cerrar, abrir, o refrescar la ttabla.


mi conclusion es que cuando no declaras o construyes los campos el ttabla los crea de forma dinamica y te regresa un tfield virtual (por nombrarle de una manera)
si le asignas propiedades las respeta mientras no cierres la tabla, porque al momento de cerrarla destruye estos tfield y al abirla vuelve a crearlos pero con sus propiedades default, por lo que las propiedades antes asignadas desaparecen.


Espero ser claro..
Saludos.


  • 0

#16 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 28 octubre 2011 - 05:10

Buenas makina,

Has sido claro no, lo siguiente jejejeje

Yo ahora te pregunto, ¿por qué no declarar campos persistentes y te ahorras de tener que crearlos por código? De esta manera estableces las propiedades en diseño a tu gusto, te ahorras código y tienes acceso a ellos siempre que quieras.

Sí, quizás eso te implique tener más de 1 TDataSet, pero te facilita y clarifica el código.

Son sólo opciones ;-)

Nos leemos
cadetill
  • 0




IP.Board spam blocked by CleanTalk.