Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Recorrer Array de variables... (https://www.clubdelphi.com/foros/showthread.php?t=85070)

geolife 22-01-2014 23:01:39

Recorrer Array de variables...
 
Hola Amigos!

Estoy atascado con un asunto. ¿Es posible crear un Array de variables predefinidas de un tipo X?, lo intento ilustrar.

Por ejemplo tenemos 7 variables del mismo tipo:

Código:

Var
 
 a,b,c,d,e,f,g: Word;

¿Habría alguna forma de crear un vector que contenga las 7 variables? para posteriormente hacer asignaciones en masa a las mismas con un For .. To, en vez de llevarlo a cabo de forma separada: a:= 1; b:= 2; c:= 3; d := 4,....

Muchas gracias! :confused:

Caminante 22-01-2014 23:18:23

Algo asi???

Código Delphi [-]
Var
 i:integer;
 MyArray:Array[1..7]of word;
begin
 for i:=1 to 7 do
 MyArray[i]:=i;
end;

Espero te sirva.

Saludos

geolife 22-01-2014 23:27:31

Gracias Caminante!

Pero no era esto lo que quería ilustrar, quizás no lo explique demasiado bien... Se trataría de crear un vector o array que contenga a las variables (a,b,c,d,e,f,g) y luego mediante un bucle recorrerlas desde el inicio al final para asignarles un valor determinado.

No se trataría de crear una variable Miarray de 7 enteros, sino una variable de array que contenga 7 variables independientes y ya predefinidas...Imagina que tienes un programa con 50 variables de un mismo tipo con "nombres diferentes" y deseas iniciarlas de un tirón mediante un bucle...: Confused:

Cita:

Empezado por Caminante (Mensaje 472017)
Algo asi???

Código Delphi [-]
Var
 i:integer;
 MyArray:Array[1..7]of word;
begin
 for i:=1 to 7 do
 MyArray[i]:=i;
end;

Espero te sirva.

Saludos


ecfisa 22-01-2014 23:47:00

Cita:

Empezado por geolife (Mensaje 472018)
...
Se trataría de crear un vector o array que contenga a las variables (a,b,c,d,e,f,g) y luego mediante un bucle recorrerlas desde el inicio al final para asignarles un valor determinado.
...

Hola geolife.

Sin dudas lo que mencionas se soluciona usando un arreglo de punteros a Word, pero el trabajo de asignar a cada posición del arreglo la variable respectiva, se equipara al trabajo de inicializarlas una a una...

Una opción que podría reducir un poco la tarea podría ser:
Código Delphi [-]
procedure InitVar(VecWord: array of PWord; const Values: array of Word);
var
  i: Integer;
begin
  for i := Low(VecWord) to High(VecWord) do
    VecWord[i]^ := Values[i];
end;

Ejemplo de uso:
Código Delphi [-]
var
   a,b,c,d,e,f,g: Word;
begin
  InitVar([@a,@b,@c,@d,@e,@f,@g], [300, 101, 502, 203, 904, 705, 406]);
  ...

Saludos :)

ecfisa 23-01-2014 12:22:36

Hola geolife.
Cita:

Empezado por geolife (Mensaje 472023)
¿Se podría hacer esto creando una clase con objetos tipo variable y luego recorrer todos los objetos de la clase de inicio a fin?

Si claro. Se complica un poco debido a que el compilador convierte los nombres de variables en direcciones de memoria, por lo que no es posible acceder a ellas por su nombre en tiempo de ejecución.

Aunque se podría hacer con TList o [i]TObjectList] usando un puntero a record, pero me parece mas simple usar TStrings ya que podemos aprovechar sus propiedades vectoriales String y Objects para almacenar el nombre de variable y el valor respectivamente.

Como para darte una pauta, te pongo un ejemplo no muy pulido aunque operativo :
Código Delphi [-]
unit Unit2;

interface

uses Classes, SysUtils;

type
  TListDT = class(TStringList)
  public
    procedure InitList(VecArray: array of string; const InitValue: TDateTime);
    function GetVarValue(const VarName: string): TDateTime;
    procedure ChangeVarValue(const VarName: string; Value: TDateTime);
  end;

implementation

type
  TCDateTime = class(TObject)
    Value : TDateTime;
  end;

procedure TListDT.InitList(VecArray: array of string; const InitValue: TDateTime);
var
  i: Integer;
  dt: TCDateTime;
begin
  if not Assigned(Self) then
    raise Exception.Create('La lista aún no fue creada.');
  Clear;
  for i:= Low(VecArray) to High(VecArray) do
  begin
    dt := TCDateTime.Create;
    dt.Value := InitValue;
    AddObject(VecArray[i], TObject(dt));
  end;
end;

function TListDT.GetVarValue(const VarName: string): TDateTime;
var
  ix: Integer;
begin
  if not Assigned(Self) then
    raise Exception.Create('La lista aún no fue creada.');
  ix := IndexOf(VarName);
  if ix = -1 then
    raise Exception.Create('Nombre de variable inexistente.');
  Result := TCDateTime(Objects[ix]).Value;
end;

procedure TListDT.ChangeVarValue(const VarName: string; Value: TDateTime);
var
  ix: Integer;
  dt: TCDateTime;
begin
  if not Assigned(Self) then
    raise Exception.Create('La lista aún no fue creada.');
  ix := IndexOf(VarName);
  if ix = -1 then
    raise Exception.Create('Nombre de variable inexistente.');
  dt := TCDateTime.Create;
  dt.Value := Value;
  Objects[ix] := TObject(dt);
end;
end.

Ejemplo de uso:
Código Delphi [-]
...
type
  TForm1 = class(TForm)
    btnShowAll: TButton;
    ListBox1: TListBox;
    btnShowtByName: TButton;
    Edit1: TEdit;
    btnChangeValue: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnShowAllClick(Sender: TObject);
    procedure btnShowtByNameClick(Sender: TObject);
    procedure btnChangeValueClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation {$R *.dfm}

uses Unit2;

var
  List: TListDT;

procedure TForm1.FormCreate(Sender: TObject);
begin
  List:= TListDT.Create;
  List.InitList(['fec1','fec2','fec3','fec4','fec5'],  // ,'fec6',...'fecN'],
     StrToDate('01/01/2014'));
end;

procedure TForm1.btnShowAllClick(Sender: TObject);
var
  i: Integer;
begin
  ListBox1.Clear;
  for i:= 0 to List.Count-1 do
    ListBox1.Items.Add(Format('%s = %s',[List[i],DateTimeToStr(List.GetVarValue(List[i]))]));
end;

procedure TForm1.btnShowtByNameClick(Sender: TObject);
begin
  ShowMessage(Format('%s = %s',
      [Edit1.Text, DateTimeToStr(List.GetVarValue(Edit1.Text))]));
end;

procedure TForm1.btnChangeValueClick(Sender: TObject);
begin
   List.ChangeVarValue(Edit1.Text, StrToDate('31/12/2015'));
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  List.Free;
end;
end.

Saludos :)

geolife 23-01-2014 13:18:03

Nota: A la pregunta de si la implementación se podía llevar cabo mediante programación a través de objetos, de forma que recorriéramos una lista de variables en memoria para su inicialización y/o asignación, evitando hacerlo con un esquema "una a una". Se elimino por accidente la pregunta en el hilo anterior!

Apreciado ecfisa!

Que puedo decirte,...:eek: esto es una muestra de amor a la programación. Voy probar tu esquema.
Muchísimas gracias por tomarte la molestia de ofrecer esta gran porción de código y una solución al problema planteado.
Es un verdadero y encomiable regalo el tiempo que dedicáis en Clubdelphi a las personas que estamos aprendiendo.

Muchas gracias de nuevo! :):):)


Cita:

Empezado por ecfisa (Mensaje 472034)
Hola geolife.

Si claro. Se complica un poco debido a que el compilador convierte los nombres de variables en direcciones de memoria, por lo que no es posible acceder a ellas por su nombre en tiempo de ejecución.

Aunque se podría hacer con TList o [i]TObjectList] usando un puntero a record, pero me parece mas simple usar TStrings ya que podemos aprovechar sus propiedades vectoriales String y Objects para almacenar el nombre de variable y el valor respectivamente.

Como para darte una pauta, te pongo un ejemplo no muy pulido aunque operativo :

Saludos :)


nlsgarcia 24-01-2014 06:30:11

ecfisa,

^\||/ :)

Nelson.


La franja horaria es GMT +2. Ahora son las 12:18:43.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi