Share Button

Para aqueles momentos que quero varrer todos os componetes que estão no FORM para pegar quem são e aplicar um operador   AS que tal usar um metódo anônimo para isto….

Forma tradicional

A forma tradicional de se varrer todos os componentes que estão sobre responsabilidade do FORM é fazer um loop com FOR e avaliar um-a-um até encontrar o que se deseja.


var  i:integer;
begin
     for i := 0 to FormX.ComponentCount-1 do
     begin
           if FormX.Components[i] is TQuery then   // quero pegar so as TQuery
           with FormX.Components[i] as TQuery do
           begin   
               close;   // fechar a TQuery
           end;
     end;
 
end;

 

Loop de Componentes com Anonimous Methods

Utilizando “Anonimous Methods” é um modelo não tradicional de olhar a mesma questão. Entender a estrutura de um “Anonimous Method” pode simplificar muitas operações de codifição do dia-a-dia e como exemplo de fundo vamos varrer os componentes dos formulários…

  • Criando um HELPER para separar a lógica (o LOOP)
    type
      TComponentHelper = class Helper for TComponent
    
      public
        procedure ComponentsLoop(AProc: TProc<TComponent>; AChild: boolean = false);
      end;
    
    procedure TComponentHelper.ComponentsLoop(AProc: TProc<TComponent>; AChild: boolean = false);
    var
      i: integer;
    begin
      if assigned(AProc) then
        for i := 0 to ComponentCount - 1 do
        begin
          AProc(Components[i]);
          if AChild and (Components[i].ComponentCount > 0) then
            Components[i].ComponentsLoop(AProc, AChild);
        end;
    end;
    
  • Executando o LOOP utilizando o método anônimo do HELPER
    
    procedure TForm39.Button1Click(Sender: TObject);
    begin
      Memo1.Lines.Clear;
      ComponentsLoop(
        Procedure(AComp: TComponent)
        begin
          // fecha todos os TDataset  (TQuery)
          if AComp is TDataset then
            with AComp as TDataset do
                close;
    
        end, false);
    
    end;
    
    

 

Usando  Anonimous LOOP para um TList (genérico)

Quando vezes precisou fazer um loop em um TList….

  • Implementando um LOOP “anonimous” para o TList na classe HELPER
    procedure TComponentHelper.ListLoop(AList: TList; AProc: TProc<TObject>);
    var
      i: integer;
    begin
      for i := 0 to AList.Count - 1 do
        AProc(AList[i]);
    end;
    
    
  • Aplicando o LOOP “anonimous” em um TList
    procedure TForm39.Button3Click(Sender: TObject);
    var
      FList: TList;
    begin
      memo1.Lines.Clear;
      FList := TList.create;
      try
        PopularALista(FList);
    
        // fazer um LOOP usando Anonimous
        ListLoop(FList,
          procedure(AObj: TObject)
          begin
            memo1.Lines.Add( AObj.ClassName );
          end);
    
      finally
        FList.Free;
      end;
    end;
    
    

Parece Simples !!! Quantas vezes precisou escrever um LOOP em um TDataset (aka TQuery, TClientDataset)???

Código Exemplo  Helper para TDataset

 

 

Share Button

Sabe todos aquelas linhas de código para incluir um item no menu “by code”…

  • inicializa o item de menu;
  • adiciona os parametros;
  • cria o método para o evento OnClick…
  • atribui o evento;
  • adiciona o item à lista;

Exemplo VCL para incluir um item de menu usando código:

procedure TForm40.ClickMenuItem(sender:TObject);
  begin
          showMessage('menu sem anonimous');
  end;
procedure TForm40.FormCreate(Sender: TObject);
  var it:TMenuItem;
begin
  it := TMenuItem.Create(MainMenu1);
  it.caption := 'Teste de um menu sem anonimous';
  it.OnClick := ClickMenuItem;
  MainMenu1.Items.Add(it);
end;

Métodos “anonimous” é uma poderosa ferramenta presente no Delphi na era XE, que encurta caminhos complexos. Ao reduzir código ao mesmo tempo aumentamos qualidade (com menor ocorrência de bugs) bem como menor tempo de implementação. Se considerar que o maior tempo se gasta em testes e correções de defeitos, então o ganho é exponencial.

Exemplo usando “Anonimous Method”:

uses VCL.Menus.Helpers;
procedure TForm40.FormCreate(Sender: TObject);
begin
  MainMenu1.Items.CreateAnonimous('Teste menu com anonimous',
     procedure begin
          showmessage('ok...');
     end);
end;

Fontes: https://github.com/amarildolacerda/helpers

Share Button

Lembra quantas vezes você precisou fazer um Loop em um Dataset para fazer uma soma, uma
contagem ou qualquer outra coisa…
Não gosto de fazer de novo algo que já fiz antes… Pensando nisto passei a usar “anonimous
method” do delphi para executar para mim os trechos repetitivos dos loops…
Veja como ficou.

type
TDatasetHelper = class helper for TDataset
public
   procedure DoLoopEvent(AEvent: TProc<TDataset>); overload;
end;

procedure TForm34.execute;
var total:Double;
begin
   // abere o Dataset com os dados.
   alQuery1.sql.Text := 'select codigo, total valor from sigcaut1 where data>=:data';
   alQuery1.ParamByName('data').AsDateTime := strTodate('01/01/2016');
   alQuery1.Open;
   // fazer um loop para somar o total, usando metodos anonimos;
   total := 0;
   alQuery1.DoLoopEvent( procedure( ds:TDataset)
   begin
     total := total + ds.FieldByName('valor').AsFloat; // executa o loop
     end);
   showMessage( FloatTOStr(total) ); // mostra o total da soma obtida no loop
end;


procedure TDatasetHelper.DoLoopEvent(AEvent: TProc;TDataset;);
var
book: TBookMark;
begin
    book := GetBookmark;
    try
      DisableControls;
      first;
      while eof = false do
      begin
         AEvent(self);
         next;
      end;
    finally
    GotoBookmark(book);
    FreeBookmark(book);
    EnableControls;
  end;
end;

Código Original

Share Button

A introdução de Class Helper no delphi ajudou o desenvolvedor a incluir novas
funcionalidades nas classes nativas do delphi – você tem uma idéia de um
recursos dos sonhos e gostaria de implementar lá na classe base, use Class
Helper.

Extendendo o TDataset:

TDatasetHelper = class helper for TDataset
public
   procedure Run(AProc:TProc<TDataset>);
end;

procedure TDatasetHelper.Run(AProc: TProc<TDataset>);
begin // executa em um thread separada
     TThread.CreateAnonymousThread(
         procedure begin
            if assigned(AProc) then
               AProc(self);
         end
     ).Start;
end;

O exemplo implementa a capacidade de uso da “procedure” RUN(…) por
qualquer classe com herança de TDataset.

Trabalhando com o novo procedimento:

O procedimento RUN por finalidade executar em um processo paralelo (uma
nova TThread) a rotina que estiver implementando no TProc.

var total:double;
begin
        query1.run(
                   procedure (ds:TDataset) // rotina a executar em paralelo.
                     begin
                       ds.first;
                       while ds.eof=false do
                       begin
                          total := total + xxxxx;
                          ds.next;
                       end;
                  end);
end;