Páginas

terça-feira, 21 de maio de 2013

Tutorial de desenvolvimento para iOS com Delphi XE4

Olá Delpheiros, super dica na área!
Como a grande sensação do Delphi XE4 é o desenvolvimento para iOS a Embarcadero publicou um manual detalhado (em inglês) sobre desenvolvimento para iOS. 
O documento abrange configuração do Mac, instalação do certificado de desenvolvedor Apple, configuração de profile no Delphi para comunicação com o Mac, componentes e estilos, banco de dados e mais uma monte de coisa muito interessante.
O Tutorial está excelente, parabéns para equipe Embarcadero.

Link para donwload:

segunda-feira, 20 de maio de 2013

Portal de Treinamento Embarcadero


Olá Pessoal,
Nesse post quero falar um pouco do Portal de Treinamento Embarcadero. Já no ar a algum tempo mas ainda pouco divulgado.
Se você anda meio desanimado, não vendo a carreira deslanchar, sem vontade de cantar uma bela canção...
Como diz aquela canção do Raul e Marcelo Nova, "Chegou a luz no fim do seu túnel meu filho...", hehehe.
E essa luz nada mais é que o Portal de Treinamento Embarcadero,
www.embarcaderobr.com.br/treinamentos/
Nele você pode ter informações sobre os Centros de Treinamentos Oficiais Embarcadero, ondo você conta com toda assistência para se tornar um Jedi no desenvolvimento de Sistemas em Delphi. Também é possível cadastrar seu currículo ou no caso esteja procurando um desenvolvedor, pesquisar por profissionais de todo Brasil. O Site ainda traz informações sobre certificação e treinamentos oficiais.

Evento DUG-RS
Desenvolvimento para iOS

Salve Delpheiros!
Dia 21-05-13 apartir das 19h, teremos 4 dos MVPs Embarcaderos, Newton Oliveira, Carlos "Tatu" Agnes, Luciano Pimenta e Eu reunidos na  Faculdade Dom Bosco para colocar as novas ferramentas de desenvolvimento para iOS e o recém adquirido FireDAC a toda prova.
Vamos discutir, desenvolver, testar e rever a galera!

Incrições: http://www.sucesurs.org.br/evento/novidades-do-mobile-stduio-dugrs

Vejo vocês la.

quinta-feira, 16 de maio de 2013

Criando campos data e calculado em tempo de execução

Essa semana tive que implementar uma tela que mostrasse um grid com a listagem de produtos, e ao lado uma coluna para cada tabela de preço com seu respectivo preço, além de uma coluna que tivesse um campo InternalCalc booleano para que fosse possível selecionar os produtos através de um checkbox no meu grid (utilizo o cxGrid da DevExpress, então os campos booleanos podem ser exibidos com um checkbox na coluna). 
O drama começa na geração do Sql. Como eu posso ter quantas tabelas de preço eu quiser, logo as colunas deverão ser dinâmicas, cada tabela deverá gerar um campo novo no meu select. Eu estou utilizando Firebird, então não tenho nenhum recurso de Olap ou Pivot, então meu Sql teve que ser gerado por um método no Delphi, onde eu faço um loop para cada uma das tabelas de preço gerar uma coluna coluna correspondente, isso ficou mais ou menos assim (mudei a nomenclatura dos meus campos para ficar mais didático):

procedure TdmdCadAlteraPreco.MontarConsulta;
var
  lSql : TStringList;
  lCod, lCampo : String;
  lField : TField;
begin
  lSql := TStringList.Create;
  try
    lSql.Add('SELECT P.PROD_ID, P.PROD_CODIGO, P.PROD_DESC ');

    cdsTabPreco.Close;
    cdsTabPreco.Open;
    cdsTabPreco.First;
    while not cdsTabPreco.Eof do
    begin
      lCod := IntToStr(cdsTabPreco.FieldByName('TPRE_ID').AsInteger);
      lCampo := 'TABELAPRECO_'+lCod;
      lSql.Add(',(SELECT F.PRECO FROM PRECOPRODUTO F ');
      lSql.Add('   WHERE F.PROD_ID = P.PROD_ID ');
      lSql.Add(    AND F.TPRE_ID = '+lCod+') as 'lCampo);
  
      cdsTabPreco.Next;
    end;
    cdsTabPreco.Close;

    lSql.Add('FROM PRODUTO P');
    sqlPesquisa.CommandText := lSql.Text;
    finally
      lSql.Free;
    end;
end;

Como meu velho pai costumava dizer, "para bom programador meio código basta". Então, a unica coisa que não está visível aqui é o Sql do cdsTabPreco, que tem a lista das tabelas de preço cadastradas no sistema. Gerar Sql geralmente não é mistério pra ninguém, o problema está em colocar estes campos no CDS de pesquisa, para que possamos usar por exemplo o DisplayFormat, o DisplayName e também adicionar  campos InteralCal.

Confesso que até o momento nunca tinha passado por tal situação, minhas Sqls são todas colocadas diretamente nos datasets, e tenho um framework de pesquisa que apenas trabalha o where das Sqls, as colunas nunca são alteradas.
Na primeira tentativa fui direto para o FieldDefs do CdsPesquisa, já que estou acostumado a criar CDSs temporários utilizando esses comandos:

cdsPesquisa.FieldDefs.Add('PROD_ID',ftInteger);
cdsPesquisa.FieldDefs.Add('PROD_CODIGO',ftString,15);
...

Essa técnica foi frustrante, por que eu não tenho aqui como dizer se meu campo é calculado ou não. 

A próxima lógica ao meu ver seria criar um objeto do tipo TField e adiciona-lo ao CDS. Algo dessa forma:

lField := TIntegerField.Create(Self);
lField.FieldName := 'PROD_ID';
lField.FieldKind := fkData;
cdsPesquisa.Fields.Add(lField);

Aqui eu consigo definir o tipo do campo, se é data, calculado ou InternalCal, mas na hora de abrir o CDS...
Não é que o "chato do pato", ou melhor do CDS ficou reclamando que o campo não existia no dataset!
Ai fiquei matutando, qual será a mandinga para adicionar meu campo no CDS?
Foi então que dando um pesquisada por ai descubro que não devemos adicionar o TField a lista de TFields do CDS, e sim atribuir para a propriedade DataSet do TField o DataSet onde ele será adicionado. Dessa forma:

lField := TIntegerField.Create(Self);
lField.FieldName := 'PROD_ID';
lField.FieldKind := fkData;
lField.DataSet   := cdsPesquisa;

Facil né?
Claro, depois que sabemos o que fazer.

Nosso código completo fica assim:

procedure TdmdCadAlteraPreco.MontarConsulta;
var
  lSql : TStringList;
  lCod, lCampo : String;
  lField : TField;
begin
  lSql := TStringList.Create;
  try
    lSql.Add('SELECT P.PROD_ID, P.PROD_CODIGO, P.PROD_DESC ');


    lField := TBooleanField.Create(Self);

    lField.FieldName := 'SELECAO';
    lField.FieldKind := fkInternalCalc;
    lField.DisplayLabel := 'Sel';
    lField.DataSet   := cdsPesquisa;

    lField := TIntegerField.Create(Self);
    lField.FieldName := 'PROD_ID';
    lField.FieldKind := fkData;
    lField.Visible   := False;
    lField.DataSet   := cdsPesquisa;

    lField := TStringField.Create(Self);
    lField.FieldName := 'PROD_CODIGO';
    lField.FieldKind := fkData;
    lField.Size      := 15;
    lField.DisplayLabel := 'Código';
    lField.DataSet   := cdsPesquisa;

    lField := TStringField.Create(Self);
    lField.FieldName := 'PROD_DESC';
    lField.FieldKind := fkData;
    lField.Size := 50;
    lField.DisplayLabel := 'Descrição';
    lField.DataSet   := cdsPesquisa;

    cdsTabPreco.Close;
    cdsTabPreco.Open;
    cdsTabPreco.First;
    while not cdsTabPreco.Eof do
    begin
      lCod := IntToStr(cdsTabPreco.FieldByName('TPRE_ID').AsInteger);
      lCampo := 'TABELAPRECO_'+lCod;
      lSql.Add(',(SELECT F.PRECO FROM PRECOPRODUTO F ');
      lSql.Add('   WHERE F.PROD_ID = P.PROD_ID ');
      lSql.Add(    AND F.TPRE_ID = '+lCod+') as 'lCampo);
  

      lField := TFMTBCDField.Create(Self);

      lField.FieldName := lCampo;

      lField.FieldKind := fkData;

      lField.DataSet   := cdsPesquisa;

      TFMTBCDField(lField).DisplayFormat := '0.,00';

      lField.DisplayLabel :=
        cdsTabPreco.FieldByName('TPRE_DESC').AsString;    

      cdsTabPreco.Next;
    end;
    cdsTabPreco.Close;

    lSql.Add('FROM PRODUTO P');
    sqlPesquisa.CommandText := lSql.Text;
  finally
    lSql.Free;
  end;
end;

Observe que cada Field e instanciado usando a classe correspondente ao seu tipo no banco, TIntegerField, TFMTBCDField, TStringField ...

Galerinha, fica a dica e até a próxima!

Salve Delheiros!

Após algum tempo trabalhando com a comunidade Delphi apenas de forma presencial, através dos eventos do DUG-RS por todo Rio Grande do Sul, agora me faço presente no dia-dia de todos através da minha nova pagina.
Estarei postando de forma regular dicas de programação, agenda de eventos, novidades da ferramenta e tudo que for interessante e possa contribuir com a comunidade para melhorar nossa performance no mundo da programação.

Um grande abraço a todos e muito sucesso no desenvolvimento de seus sistemas.
Samuel "Muka" David.