Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Asignacion a un Variant (https://www.clubdelphi.com/foros/showthread.php?t=74755)

gersonmaba 08-07-2011 23:21:00

Asignacion a un Variant
 
Buenos Tardes muchachos y gracias de antemano,

Tengo un pequeño problema con la asignacion de un campo a un TcxDBCurrencyEdit Resulta que en tiempo de Ejecucion yo voy creando varios TcxDBCurrencyEdit a los cuales les asigno propiedades tambien en tiempo de ejecucion, en medio de eso le asigno Datasource y un Field el datasource no tiene ningun tipo de problema pero el field me sale error, lo estoy haciendo de forma erronea y la verdad no se como es la correcta. lo estoy haciendo de esta forma:

TextDinamico:=TcxDBCurrencyEdit.create(self);
TextDinamico.Name:= 'txVB_' + fieldbyname('nombreconcep').AsString;
TextDinamico.DataBinding.DataSource:=DataModulo.DSItemsFactura;
TextDinamico.DataBinding.Field.Value:='valorBase'; // AQUI COMO ASIGNO EL CAMPO DE LA BD AQUI ES EL ERROR..

Les agradesco cualquier ayuda.

gersonmaba 08-07-2011 23:50:24

No que pena muchachos...Error mio me equivoque era l apropiedad DataField y yo estaba usando Field lo siento...

TextDinamico.DataBinding.DataField:='valorBase';


Graicas

Al González 08-07-2011 23:56:17

Hola gersonmaba. :)

Lo primero, decirte que siempre es importante poner el mensaje de error exacto que aparece en pantalla. Para errores de tiempo de ejecución, sólo tienes que presionar Ctrl+C cuando aparezca (de aparecer) y luego sencillamente lo colocas aquí con Ctrl+V.

El error, según puede verse en el código que has puesto —y que también es importante y agradezco (de agradecer)— es que con la sentencia:
Código Delphi [-]
TextDinamico.DataBinding.Field.Value:='valorBase';
se está intentando asignar un valor al campo que tenga asociado el control cx, objeto campo que en ese momento no es ninguno. Lo que me parece que quieres hacer (y hazlo) es asignar el nombre del campo que debe tener asociado. Es decir, la sentencia tendría que ser:
Código Delphi [-]
TextDinamico.DataBinding.DataField := NombreDeCampo;

Por último, sin pretender ser grosero, me gustaría decir que he puesto a propósito el texto que ves subrayado para hacer notar algo que puede ser útil ya sea a ti o a alguna de las demás personas que lo lean: Cuando un verbo en infinitivo termina en "cer", generalmente se cambia esa letra "c" por "z" (no por "s") en conjugaciones como "agradezco", "aparezca", "haz" (no de haber, sino de hacer), etc. :)

Espero quede solucionado el problema, e independientemente de ello tu retroalimentación.

Al González.
P.D. Ahora veo que ya has encontrado la solución.

gersonmaba 11-07-2011 15:56:44

Hola Al González,

Muchisimas Gracias, por tu respuesta tan completa.

Y mil Gracias por la correccion de ortografia, la verdad tengo serios problemas con eso, lo tendre muy encuenta.

Gracias.

gersonmaba 11-07-2011 16:09:04

Muchachos de nuevamente los saludo,

Debido a la forma en la que estoy creando objetos en tiempo de ejecución nacieron dos nuevas preguntas.
Como hago referencia a un objeto creado en tiempo de ejecución? , Es decir que cuando presionen un botón yo vaya y tome el valor que está en un objeto que cree en tiempo de ejecución..

Y la otra pregunta es, Como manejo o le asigno eventos a un objeto creado en tiempo de ejecicion, por ejemplo un onexit o un onchange.
Les agradezco cualquier tipo de colaboración.

Gracias

gersonmaba 11-07-2011 16:59:37

Hola Muchahos, ya e avanzado un poco un la segunda pregunta, cuando estoy creado el objeto le asigno el evento.


TextDinamico.OnExit:= ComponentesOnExit();


Y obviamente creo el procedimiento previamente


procedure ComponentesOnExit(Sender: TObject);


Pero mi gran pregunta ahora es, como hacer referencia a las propiedades, del objeto del que envie el evento por ejemplo al name..o alguna otra propiedad.

procedure TFrm1.ComponentesOnExit(Sender: TObject);
begin
// aquí como hago referencia a las propiedades..por ejemplo al name, o al text o a cualquer otro
end;


Gracias

ecfisa 11-07-2011 17:07:24

Hola.

Te pongo un ejemplo sencillo de como podés manejar los objetos creados en ejecución.
Código Delphi [-]
...
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Contnrs;

type
  TForm1 = class(TForm)
    btnLlama: TButton;
    procedure FormShow(Sender: TObject);
    procedure btnLlamaClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    FObjLst: TObjectList;
    function GetCmpt(AName: string): TComponent;
    procedure EditEnter(Sender: TObject);
    procedure EditExit(Sender: TObject);
  public
  end;

var
  Form1: TForm1;

implementation {$R *.dfm}

procedure TForm1.EditEnter(Sender: TObject);
begin
  ShowMessage('Edit Enter');
end;

procedure TForm1.EditExit(Sender: TObject);
begin
  ShowMessage('Edit Exit');
end;

{ Devuelve el componente dado el nombre }
function TForm1.GetCmpt(AName: string): TComponent; 
var
  i: Integer;
begin
  Result:= nil;
  for i:= 0 to FObjLst.Count -1 do
    if TEdit(FObjLst.Items[i]).Name = AName then
      Result:= TComponent(FObjLst.Items[i]);
end;

procedure TForm1.FormShow(Sender: TObject);
var
  TE: TEdit;
  i: Integer;
begin
  FObjLst:= TObjectList.Create;
  for i:= 1 to 5 do  // Crear 5 Edits
  begin
    TE:= TEdit.Create(Self);
    with TE do
    begin
      Name:= 'Edit'+IntToStr(i);
      Width:= 150;
      Height:= 25;
      Left:= 8;
      Top:= i*25+30;
      OnEnter:= EditEnter; // Asignar evento OnEnter
      OnExit:= EditExit;   // Asignar evento OnExit 
      Parent:= Self;
      FObjLst.Add(TE)
    end;
  end;
end;

procedure TForm1.btnLlamaClick(Sender: TObject);
var
  i: Integer;
begin
  // Poner Text = '' en los TEdits creados
  for i:= 0 to FobjLst.Count-1 do
   if Assigned(GetCmpt('Edit'+IntToStr(i+1))) then
     TEdit(GetCmpt('Edit'+IntToStr(i+1))).Text:= '';
  // Poner un texto en Edit1
  if Assigned(GetCmpt('Edit1')) then
    TEdit(GetCmpt('Edit1')).Text:= 'PRUEBA DE TEXTO';
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FObjLst.Free;  // Liberar memoria
end;
...

Saludos.

gersonmaba 11-07-2011 18:08:36

Hola, ecfisa

Muchas gracias, por tu colaboracion, Osea creo que entendi tu codigo, pero no veo la forma muy clara de adaptarlo a mi necesidad. para capturar una propiedad en un evento.
Código Delphi [-]
procedure TForm1.EditEnter(Sender: TObject);
 begin 

// como Capturo aqui por ejemplo el NAME o el TEXT del 
//objeto Edit en el cual se dio Enter. 

end;

ecfisa 11-07-2011 18:37:54

Hola.

Código Delphi [-]
procedure TForm1.EditEnter(Sender: TObject);
begin
  with TEdit(Sender) do
    ShowMessage(Name + #10#13 + Text + #10#13 + ClassName + #10#13 + IntToStr(Left) + #10#13 +  // ...
    );
end;

Saludos.

gersonmaba 11-07-2011 21:20:34

Hola

ecfisa, Muchas Gracias, por tu gran colaboracion, pero tengo una ultima pregunta, necesito tambien obtener las propiedades de otro objetos creados dinamicamente. de la forma en la que lo lo estoy haciendo es, muy larga y me gustaria saber si ahi una solucion mas puntual o mas inteligente. pues es mi primera vez trabajando de este modo. lo hago de la siguiente forma.

For i:=ComponentCount -1 downto 0 do // Recorro Todos Los Componentes del FORM
begin
if (Components[i].Name = 'cxDBLC_Base') or (Components[i].Name = 'cxDBLC_Fac') // Resulta que esto puede ser 1 o mucho de acuerdo a lo que el usuario escoja.
Components[i].text;
end;

Es que quiero explorar otra solucion, pues esta me parece un poco pesada ejecutar y armar los nombres(Traidos de la BD) cada vez que se ejecute el evento. no ahi alguna forma mas puntual. Muchas Gracias.

ecfisa 12-07-2011 02:09:53

Hola gersonmaba.

Si cxDBLC_Base, cxDBLC_Fac, ..., cxDBLC_ZZZ son del mismo tipo, podés evaluar la propiedad ClassType:
Código Delphi [-]
procedure TForm1.btnClassTypeClick(Sender: TObject);
var
  i: Integer;
begin
  for i:= ComponentCount - 1 downto 0 do
    if Components[i].ClassType = TEdit then
      TEdit(Components[i]).Text:= 'Nuevo Texto'; // Text = 'Nuevo Texto'
end;

Si son de diferentes tipos pero comparten una misma propiedad como por ejemplo Caption, podrías hacer:
Código Delphi [-]
uses TypInfo;
{pone la propiedad Caption = '' en todos los componentes que la posean }
procedure TForm1.btnRTTIClick(Sender: TObject);
var
  i: Integer;
  PropInfo: PPropInfo;
begin
  for i:= ComponentCount - 1 downto 0 do
  begin
    PropInfo:= GetPropInfo(Components[i], 'Caption');
    if PropInfo <> nil then
      SetStrProp(Components[i],PropInfo, ''); // Caption = ''
  end;
end;
Usando esta última forma (RTTI), podés ir bastante más lejos que lo que hace este simple ejemplo.

Saludos.

gersonmaba 13-07-2011 00:42:17

Si Tienes muchas Razon ecfisa me pondre a explorar y a aplicar esta forma, Mil Gracias por tu gran Colaboracion.

Gracias.

ecfisa 13-07-2011 04:44:40

Hola gersonmaba.

Si querés empezar a interiorizarte sobre RTTI te paso unos enlaces:

Run-Time Type Information In Delphi (artículo)

Blog de Neftalí (ejemplo muy completo)

Buscando vas a encontrar mucho mas material sobre el tema.

Un saludo.


La franja horaria es GMT +2. Ahora son las 04:02:09.

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