Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Utilización de Generics.Collections (https://www.clubdelphi.com/foros/showthread.php?t=82944)

Jere_84 26-04-2013 00:43:06

Utilización de Generics.Collections
 
Hola hoy modifique una rutina que tiene como objetivo tomar el Nº de Tag de los edit visibles que tengo puestos dentro de un pagecontrol los guarda en un Array de enteros, luego se ordenan (Sort).... después se asigna estos valores a la propiedad Tag de los campos persistentes de Clientdataset que están en un datamodule y por ultimo se asigna los valores de los campos persistentes a los edit visibles de los page control de la ventana que tienen el asignado el mismo Nº de tag que los campos persistentes... Para el array utilice la la unit Generics.Collections que por los ejemplos que eh visto en internet solo se usa para aplicaciones de consola... el tema es que esto andada de maravilla, a no ser por un Access Violation que me esta dando al cerrar la aplicación.. creo que el motivo de esta violación debe ser la implementacion de esta Unit ya que antes de la modificación no salia este error y sale el este error solo cuando abro esta ventana, en las otras no utilizo esta rutina.

Cita:

---------------------------
Application Error
---------------------------
Exception EAccessViolation in module '@#&%'.exe at 00005DBE.

Access violation at address 00405DBE in module '@#&%.exe'. Read of address 8D726142.

---------------------------
Aceptar
---------------------------
Esta es mi rutina:

Código Delphi [-]
procedure TvfInforNoved.AsignaMinMax2(vDataModulo: TDataModule; vTag: integer);
var
  vI, vJ, vK: integer;
  ListaDeTags: TList;
begin
  vK := 0;
  ListaDeTags:= TList.Create;
  try

    for vI := 0 to JfPageControlOrdenRango.Tabs.Count - 1 do
      if JfPageControlOrdenRango.Tabs[vI].Visible then
        for vJ := 0 to JfPageControlOrdenRango.Tabs[vI].Page.ControlCount - 1 do
          if JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] is TJfEdit then
            if (JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] as TJfEdit).Visible then
              if (JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] as TJfEdit).Tag >= vTag then
                ListaDeTags.Add((JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] as TJfEdit).Tag);

    ListaDeTags.Sort;

    for vI := 0 to vDataModulo.ComponentCount - 1 do
      if vDataModulo.Components[vI] is TClientDataSet then
        if (vDataModulo.Components[vI] as TClientDataSet).Tag <> 0 then
          for vJ := 0 to (vDataModulo.Components[vI] as TClientDataSet).FieldCount - 1 do
          begin
            (vDataModulo.Components[vI] as TClientDataSet).Open;
            (vDataModulo.Components[vI] as TClientDataSet).Fields.Fields[vJ].Tag := ListaDeTags.Items[vK];
            Inc(vTag);
            Inc(vK);
          end;

    for vI := 0 to JfPageControlOrdenRango.Tabs.Count - 1 do
      if JfPageControlOrdenRango.Tabs[vI].Visible then
        for vJ := 0 to JfPageControlOrdenRango.Tabs[vI].Page.ControlCount - 1 do
          if JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] is TJfEdit then
            if (JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] as TJfEdit).Visible then
              for vK := 0 to vDataModulo.ComponentCount - 1 do
                if (vDataModulo.Components[vK] is TField) and (vDataModulo.Components[vK].tag = JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ].Tag) then
                begin
                 (JfPageControlOrdenRango.Tabs[vI].Page.Controls[vJ] as TJfEdit).Value := (vDataModulo.Components[vK] as TField).AsVariant;
                  Break;
                end;
  finally
    ListaDeTags.Free;
  end;
end;


Esta correcto utilizar Generics.Collections en una aplicación digamos de 'win' ya que esto tiene que se lo que me provoca el Acces Violation.
Gracias.

ecfisa 26-04-2013 05:42:49

Hola Jere_84.

No sé en que parte estas utilizando Generics, pero en la parte de código que puedo alcanzar a ver estas utilizando TList (aunque me parece mas simple usar TObjectList).

De acuerdo a lo que entendí, con TList creo que podrías hacer similar a esto:
Código Delphi [-]
...
var
  List: TList;

function CompareTags(Item1,Item2: Pointer): Integer;
begin
  if TEdit(Item1).Tag > TEdit(Item2).Tag then
    Result := 1
  else if TEdit(Item1).Tag = TEdit(Item2).Tag then
    Result := 0
  else
    Result := -1;
end;

{ Crear instancia List, buscar Edits visibles en PageControl,
  agregarlos a la lista y ordenarla por sus propiedades Tag }
procedure TForm1.FormCreate(Sender: TObject);
var
  i,j: Integer;
begin
  List := TList.Create;
  with PageControl1 do
    for i:= 0 to PageCount-1 do
      for j:= 0 to Pages[i].ControlCount-1 do
        if (Pages[i].Controls[j] is TEdit) and Pages[i].Controls[j].Visible then
          List.Add(TEdit(Pages[i].Controls[j]));
  List.Sort(CompareTags);
end;

{ Agregar Tags a los TField, 
  pasar contenido de los campos a Edits }
procedure TForm1.btnAddFieldsClick(Sender: TObject);
var
  i,j: Integer;
begin
  with DataModule2 do
  begin
    i:= 0;
    // Por si no existen la misma cantidad de campos que Edits
    while (i < CDS1.FieldCount)and(i < List.Count) do
    begin
      CDS1.Fields[i].Tag := TEdit(List[i]).Tag;
      Inc(i);
    end;
    // Pasar contenidos de campos a Edits
    for i:= 0 to List.Count-1 do
      for j:= 0 to CDS1.FieldCount-1 do
        if TEdit(List[i]).Tag = CDS1.Fields[j].Tag then
          TEdit(List[i]).Text := CDS1.Fields[j].AsString;
  end;
end;

// Liberar Lista
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i:= List.Count-1 downto 0 do TEdit(List[i]).Free;
  List.Free;
end;

Saludos. :)

Jere_84 26-04-2013 05:59:43

Muchas gracias ecfisa voy a probar este código mañana a primera hora, esta mas ordenado que el mio. gracias por responder a mis consultas para que recién estoy comenzando a utilizar los arrays en Delphi. Anteriormente los había visto hace unos años en C++

Saludos.:)

Jere_84 26-04-2013 14:44:04

El problema es que el componente no esta mas en la ventana es como si lo sacara y lo guardara en el TList.. se muestra la ventana sin los componentes Edit que estaban en visible, lo que debería guardar en el array es el nº de tag. Si cambio este array por algún array de integer, delphi te brinda alguna manera de ordenar los arrays de enteros o tenemos que desarrollar nuestro propio algoritmo?

Código Delphi [-]
    with JfPageControlOrdenRango do
      for vI := 0 to Tabs.Count - 1 do
        if Tabs[vI].Visible then
          for vJ := 0 to Tabs[vI].Page.ControlCount - 1 do
            if Tabs[vI].Page.Controls[vJ] is TJfEdit then
              if (Tabs[vI].Page.Controls[vJ] as TJfEdit).Visible then
                ListaDeTags.Add(TJfEdit(Tabs[vI].Page.Controls[vJ])); <----- AQUI

Gracias, saludos.

Jere_84 26-04-2013 18:49:54

Ya fue solucionado en un rato subo el código para quiera implementar algo similiar...

Saludos.

ecfisa 26-04-2013 19:01:39

1 Archivos Adjunto(s)
Hola Jere_84.

No sé si entiendo lo que me comentas... Los componentes son removidos en el evento OnDestroy del form, pero durante la vida del form son mostrados de forma correcta. (Te adjunto la prueba que realizé para que puedas revisarla).

En cuanto a ordenar un arreglo, además de los métodos tradicionales que podrías usar, revisa en este enlace Best way to sort an array.

Saludos.


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

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