sexta-feira, 4 de março de 2011

Use o Format, por favor!

Olá!

A tempos queria postar sobre uma função muito interessante, que é o Format.

Uma das coisas que eu detesto em um código Delphi é a concatenação de string.

Olha este exemplo horrível (sim, estou lhe induzindo a achar horrível):

procedure TForm2.Button1Click(Sender: TObject);
var
sMessage : string;
begin
  sMessage := 'Aluno: ' + Self.FNome + ' Endereço: ' + Self.FEndereco + ' Nota: ' + Self.FNota;
  ShowMessage(sMessage)
end;

Compare com o código abaixo:

procedure TForm2.Button2Click(Sender: TObject);
var
sMessage : string;
begin
  sMessage := Format('Aluno: %s Endereço: %s Nota: %d',[Self.FNome,Self.FEndereco,Self.FNota]);
  ShowMessage(sMessage);
end;

Perceba que no segundo exemplo o código ficou mais legível. Qualquer um vai entender o resultado da concatenação sem muito esforço mental. Já no primeiro exemplo...

Então a idéia básica é passar uma string com marcações especiais (identificadas com o símbolo %) e em seguida os argumentos.

As marcações que eu considero mais úteis no dia a dia são:

%s - String
%d - Número decimal
%f - Float

Mas existem outras! Veja no Help no Delphi.

Uma característica que valorizo no Format é a possibilidade de alinharmos os valores, ajudando a formatar um bom arquivo de log por exemplo.

Para isso basta informar o número de caracteres que você deseja. %s pode vira um %15s por exemplo, onde o 15 é o tamanho. Ainda neste aspecto, vale salientar que a palavra será jogada para a direita e na maioria das vezes é mais adequado à esquerda. Para isso usamos um traço, ficando: %-15s.

Bom, é isso. Tem outros aspectos mas acho que iria tornar o assunto mais chato do que o necessário. Eu sempre incentivo o uso do Format. Na minha opinião é mais profissional. Quando você se acostumar irá ter a mesma opinião que tenho sobre o primeiro exemplo lá em cima deste post: horrível. :)

Exemplo completo (aplicação console):

program Console;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;


procedure ExemploSimples;
var
sResult : string;
begin
  sResult := Format('Nome: %s Endereco: %s Idade: %d',['Fulano','Terra do Nunca',10]);

  Writeln('Codigo.....: Format(''Nome: %s Endereco: %s Idade: %d'',[''Fulano'',''Terra do Nunca'',10])');
  Writeln('Resultado..:' + sResult);
end;

procedure ExemploListagemSemIdentacao;
var
i      : Integer;
sNome  : string;
iIdade : Integer;
begin
  Writeln('Codigo.....: Format(''Nome....: %s  Indade...: %d'',[sNome,iIdade])');
  Writeln('Resultado..:');
  for i := 1 to 5 do
  begin
    case i of
      1 :
      begin
        sNome  := 'Maria';
        iIdade := 34;
      end;
      2 :
      begin
        sNome  := 'Kleberson';
        iIdade := 18;
      end;
      3 :
      begin
        sNome  := 'Dona Florinda';
        iIdade := 60;
      end;
      4 :
      begin
        sNome  := 'Bazzinga';
        iIdade := 28;
      end;
      5 :
      begin
        sNome  := 'Fatima';
        iIdade := 40;
      end;
    end;

    WriteLn(Format('Nome: %s  Idade: %d',[sNome,iIdade]));
  end;
end;

procedure ExemploListagemComIdentacao;
var
i      : Integer;
sNome  : string;
iIdade : Integer;
begin
  Writeln('Codigo.....: Format(''Nome....: %15s  Indade...: %d'',[sNome,iIdade])');
  Writeln('Resultado..:');
  for i := 1 to 5 do
  begin
    case i of
      1 :
      begin
        sNome  := 'Maria';
        iIdade := 34;
      end;
      2 :
      begin
        sNome  := 'Kleberson';
        iIdade := 18;
      end;
      3 :
      begin
        sNome  := 'Dona Florinda';
        iIdade := 60;
      end;
      4 :
      begin
        sNome  := 'Bazzinga';
        iIdade := 28;
      end;
      5 :
      begin
        sNome  := 'Fatima';
        iIdade := 40;
      end;
    end;

    WriteLn(Format('Nome: %-15s  Idade: %d',[sNome,iIdade]));
  end;
end;

var
bContinue : Boolean;
sEntrada  : string;
begin
  try
    bContinue := True;

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN OR  BACKGROUND_BLUE);
    repeat
      Writeln('                                                                 ');
      Writeln('/===============================================================\');
      Writeln('| Escolha a opcao:                                              |');
      Writeln('|                                                               |');
      Writeln('| 1) Exemplo simples;                                           |');
      Writeln('| 2) Exemplo de listagem SEM identacao                          |');
      Writeln('| 3) Exemplo de listagem COM identacao                          |');
      Writeln('\===============================================================/');
      Writeln('                                                                 ');
      Write('Digite: ');
      Readln(sEntrada);
      Writeln('                                                                 ');

      if (sEntrada = '1') then
      begin
        ExemploSimples;
        Continue;
      end;

      if (sEntrada = '2') then
      begin
        ExemploListagemSemIdentacao;
        Continue;
      end;

      if (sEntrada = '3') then
      begin
        ExemploListagemComIdentacao;
        Continue;
      end;

      bContinue := False;
    until not (bContinue);
    Write('Fim da execucao!');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Forte abraço!

2 comentários:

Adecio Cavalheiro Junior disse...

Legal Mário, um exemplo claro que gosto de usar e também com o método de concatenação mais antigo é a montagem de comando Sql para passar para o componente, fica facil de debugar e um código bem claro e preciso.

Adecio Cavalheiro Junior disse...

Legal Mário, um exemplo claro que gosto de usar e também com o método de concatenação mais antigo é a montagem de comando Sql para passar para o componente, fica facil de debugar e um código bem claro e preciso.

Minha lista de blogs