Páginas

sexta-feira, 12 de agosto de 2011

Lazarus - Recursos do Editor de Código

Neste post vamos apresentar alguns dos inúmeros recursos que o Editor de Código oferece aos desenvolvedores. O Editor pode ser configurado via menu em Tools | Options | Editor. Estas opções também podem ser acessadas através do menu de contexto.

O detalhamento das opções e configuração do Editor exige um post específico, portanto não iremos nos ater a isso no momento. Queremos falar de recursos que a ferramenta oferece para facilitar o trabalho do programador.

Syncron

Esta é uma opção onde podemos rapidamente modificar o nome de um identificador em um trecho de código  selecionado.

Quando você seleciona um trecho do código (ou o código inteiro), no lado esquerdo do Editor aparece um ícone com uma caneta. Clique nesse ícone ou tecle CTRL + J. A área selecionada muda de cor e o cursor é movido para uma instância do identificador, destacando cada uma de suas ocorrências naquela área. Modifique o identificador e cada ocorrência dele será alterada automaticamente.
Volte a clicar no ícone ou tecle ESC para sair do modo syncron.

O Code Completion é um dos recursos que pode poupar muito tempo de digitação. Dependendo da posição do cursor no Editor, várias funções podem ser chamadas.

Complementação de classe

Se você escreveu uma classe incluindo propriedades e métodos, este recurso irá adicionar o corpo do método, variáveis e métodos de acesso às propriedades, etc. Suponha que você tenha criado a seguinte classe:

TPessoa = class(TObject)
    constructor Create;
    destructor Destroy; override;
    property nome: string;
end;

Posicione o cursor no interior da classe e pressione CTRL + SHIFT + C. O código seguinte será gerado, e o cursor será movido para que o corpo do primeiro método seja digitado.

type

  { TPessoa }

  TPessoa = class(TObject)
  private
    Fnome: string;
    procedure Setnome(AValue: string);
  published
    constructor Create;
    destructor Destroy; override;
    property nome: string read Fnome write Setnome;
  end;

implementation

{ TPessoa }

procedure TPessoa.Setnome(AValue: string);
begin
  if Fnome=AValue then exit;
  Fnome:=AValue;
end;

constructor TPessoa.Create;
begin

end;

destructor TPessoa.Destroy;
begin
  inherited Destroy;
end;

Complementação de declaração de variável

Se o cursor é posicionado em um identificador e for pressionado CTRL + SHIFT + C, é adicionado ao código uma declaração de variável local. Por exemplo, imagine o seguinte código fonte:

procedure TForm1.FormClick(Sender: TObject);
begin
  i := 5;
end;

Posicione o cursor na variável i (antes ou depois) e pressione CTRL + SHIFT + C. O código será modificado e ficará assim:

procedure TForm1.FormClick(Sender: TObject);
var
  i: Integer;
begin
  i := 5;
end;

O tipo da variável é deduzida a partir da expressão.

Message Composer

O Message Composer é uma ferramenta que auxilia na criação de caixas de diálogos,  tais ShowMessage, MessageDlg e InputBox. Para isso é necessário instalar o pacote messagecomposerpkg. Vá em Package | Install/Uninstall packages. Na lista Do not install localize e selecione messagecomposerpkg. Clique em Install selection e depois em Save and rebuild IDE. Em seguida clique no botão Continue para confirmar. Após o IDE ser reiniciado uma nova opção será adicionada ao menu Source. Você também pode usar o atalho CTRL + M. Esta opção irá abrir a seguinte janela:
Após escolher o tipo de mensagem, os parâmetros demais opções, confirme em OK e o diálogo selecionado será adicionado no seu código na posição do cursor.

Dicas para funções e procedimentos

Se você não lembra dos parâmetros, ordem, tipos de dados de uma função ou procedimento, digite a mesma e dentro dos parênteses tecle CTRL + SHIFT + ESPAÇO. Irá aparecer uma janela de dica com os argumentos:
À medida que um argumentos é digitado, o próximo fica em destaque na janela. Um botão à direita permite colar os parâmetros no código fonte.

Templates

Templates são modelos que podem ser inseridos no código. Por exemplo, suponha que você deseja inserir um comando case no seu código. Digite casee no ponto onde deseja inserir e tecle CRTL + J. Será inserido o seguinte código, e o cursor será posicionado no local onde deve ser inserida a variável do comando.
Existem vários modelos prontos, mas você pode criar os seus próprios templates usando a opção Tools | Code Templates. Na janela que será aberta você usará o botão Add para adicionar novo modelo.
Clique aqui para ver um rápido tutorial de como criar novos modelos. Por enquanto é isso que temos. Aproveite os recursos e explore mais possibilidades com o Lazarus

sábado, 23 de julho de 2011

Lazarus - Usando Dicionários de Dados

Nos dois posts anteriores:
Lazarus - O Lazarus Data Desktop e
Lazarus - Dicionário de Dados
estudamos a ferramenta Lazarus Data Desktop e como criar dicionários de dados. Neste artigo iremos mostrar como usar os dicionários nas aplicações desenvolvidas usando Lazarus.
Como já falamos, um dicionário de dados descreve entre outras coisas os atributos dos campos das tabelas de um esquema de banco de dados. E essa descrição, também chamada de metadados, pode ser usada nas aplicações para evitar que tenhamos que repetir essas definições em cada DataSet. Assim, vamos supor que já exista um dicionário de dados criado para um tabela chamada PRODUTO. E vamos mostrar como usar o dicionário de dados em tempo de execução e como aplicá-lo em tempo de desenvolvimento.
O primeiro passo é o mesmo necessário para acessar qualquer tabela sem usar o recurso do dicionário de dados. Supondo que estejamos usando ZeosLib, coloque todos os componentes que são precisos, no Data Module: ZConnection, ZQuery e um DataSource. Faça todas as configurações exigidas. Agora crie os campos persistentes TFields para a ZQuery - este é um procedimento obrigatório para o funcionamento do dicionário de dados. Dê um duplo clique na ZQuery e você verá uma pequena janela como na figura abaixo:
Clique no botão com o sinal de + ou pressione CTRL + INS para inserir os campos. Uma nova janela mostrando todos os campos da tabela correspondente será mostrada, como a figura a seguir:
Selecione todos os campos e pressione o botão Create.

Usando dicionário de dados em run-time

Uma maneira de usar o dicionário de dados em tempo de execução é inserir o código, por exemplo, no evento OnCreate do Data Module. A classe TFPDataDictionary está localizada na unit fpdatadict. Portanto, é necessário declarar esta unit na cláusula uses no módulo onde será instanciada TFPDataDictionary. Assim, nosso código poderá ficar assim:

procedure TdmData.DataModuleCreate(Sender: TObject);
var
  Dict : TFPDataDictionary;
begin
  Dict := TFPDataDictionary.Create;
  // carrega o arquivo do dicionário de dados
  Dict.LoadFromFile('produto.fpd');
  // aplica o dicionário ao DataSet
  Dict.ApplyToDataset(queProduto);
  // libera a memória usada pelo dicionário de dados
  Dict.Free;
end;

Num form você pode inserir um TDBGrid, onde serão mais facilmente visualizados os efeitos que desejamos.  Associe essa grade ao DataSource que está ligado ao DataSet onde foi aplicado o dicionário.
Agora execute o programa e você poderá constatar que todas as definições feitas no dicionário de dados serão assumidas pelos TFields que foram criados.

Usando dicionário de dados em tempo de projeto

Neste caso, o primeiro passo é registrar no projeto o dicionário desejado. Isso é feito usando a opção de menu Project > Data Dictionary > Set ... Quando selecionar este item de menu um diálogo será aberto:
Marque a caixa Use Data dictionary for this project. E selecione o dicionário de dados desejado. Confirme pressionando OK.
Agora localize o DataSet e clique com o botão direito sobre ele. Selecione o item Data dictionary e depois em Apply.
Isso irá aplicar o dicionário ao DataSet, da mesma forma que fizemos usando código. Agora podemos executar o programa e aproveitar o recurso.
Post escrito tendo como referência o livro Lazarus - the Complete Guide, publicado pela Blaise Pascal Magazine.

domingo, 10 de julho de 2011

Lazarus - Dicionários de Dados

Dicionários de dados são repositórios com metadados sobre bancos de dados, que descrevem a estrutura básica de um esquema de banco de dados. Num dicionário de dados as seguintes informações são armazenadas: as tabelas e os campos correspondentes, e os índices existentes nas tabelas. Além disso, os dicionários de dados contém atributos que definem como o conteúdo dos campos devem ser visualizados: número de casas decimais, o rótulo, a dica (hint) mostrada, tamanho do campo, entre outros.
Um dicionário de dados pode ser usado por uma aplicação Lazarus para definir as propriedades dos objetos TField; pode ser usado para criar comandos SQL, por exemplo, para criar o banco de dados descrito; e, a partir da comparação entre dois dicionários, as diferenças entre eles podem ser usadas para criar um script de atualização.
Os dicionários de dados podem ser mantidos usando o Lazarus Data Desktop, que começamos a descrever no post Lazarus - o Lazarus Data Desktop. Usando esta ferramenta podemos criar um dicionário novinho em folha ou importá-lo a partir de um banco de dados existente.

Criando um Dicionário de Dados

Para criar um novo dicionário clique no botão correspondente na barra de ferramentas conforme mostra a figura, ou tecle CTRL + N.
Isso irá criar uma nova aba. Clique com o botão direito no interior da aba e em seguida na opção New Table, ou tecle CTRL + T, para criar uma nova tabela. Digite o nome da tabela na caixa de diálogo e confirme.
Agora clique com o botão direito sobre o nome da tabela recém-criada e escolha a opção New Field. Digite o nome do campo e confirme. Um novo campo será criado e um formulário para definir as propriedades do campo será aberto no lado direito da interface, como podemos ver na figura abaixo.
Algumas propriedades que podem ser definidas, entre outras:
DisplayName - rótulo do campo que poderá ser visualizado em uma TDBGrid, por exemplo;
DisplayWidth - tamanho com que o campo será exibido;
FieldType - tipo de dado do campo;

Após criar todas as tabelas e campos, tecle CTRL + S para salvar.

Gerando comandos SQL a partir do Dicionário

Para gerar os comandos SQL pressione o botão correspondente conforme mostra a figura abaixo ou tecle CTRL + G.
Essa ação irá abrir um novo formulário. Escolha a tabela para a qual deseja gerar os comandos SQL. Na lista Key fields selecione o(s) campo(s) que será chave primária. Na lista Select/Update/Insert fields selecione o(s) campo(s) que serão usados nos comandos SELECT, UPDATE e INSERT. Pressione o botão Generate SQL. Clique em cada uma das abas para ver os comandos gerados. Na figura seguinte mostramos o comando CREATE TABLE que foi gerado.

Importando o Dicionário de Dados

Se já tivermos um banco de dados criado, podemos criar o dicionário a partir dele - processo que é chamado engenharia reversa.
Inicialmente crie uma conexão para o banco de dados existente conforme mostramos em Lazarus - o Lazarus Data Desktop. Em seguida selecione no menu Dictionary > Import > From connection. As conexões criadas na ferramenta estarão disponíveis nessa opção. Escolha aquela para a qual você precisa criar o dicionário.
Uma caixa de diálogo será aberta mostrando as tabelas do esquema. Selecione as tabelas desejadas, deixe marcada a caixa Update existing tables para atualizar tabelas que já existem e confirme.
Se houver um dicionário ativo na ferramenta, você será questionado se deseja atualizar ou criar um novo. Clique CTRL + S para salvar o dicionário. Os dicionários de dados são salvos com a extensão .fpd. Você pode visualizar o arquivo de dicionário de dados usando qualquer programa que abre arquivos texto.
Fica para o próximo post a utilização de dicionários de dados em aplicações Lazarus.
Post escrito tendo como referência o livro Lazarus - the Complete Guide, publicado pela Blaise Pascal Magazine.

segunda-feira, 4 de julho de 2011

Lazarus - O Lazarus Data Desktop

Se em suas aplicações você utiliza diversos bancos de dados, é provável que também precise de uma ferramenta específica para cada SGBD, com a finalidade de criar tabelas, criar comandos DML e DDL, entre outros. A fim de centralizar todas as tarefas do desenvolvedor no Ambiente de Desenvolvimento, o Lazarus oferece o Lazarus Data Desktop. Também chamado Database Desktop, esta ferramenta dispõe de vários recursos, dentre os quais destacamos:
  • Acesso a todos os bancos de dados suportados pelo Lazarus;
  • Criação de um dicionário de dados onde as propriedades de TFields podem ser armazenadas;
  • Criação de comandos DDL e DML a partir do dicionário de dados;
  • Consulta à tabelas;
  • Exportação de dados de tabelas para diversos formatos: XML, JSON, CSV, entre outros.
Para usar esta ferramenta. primeiramente é necessário compilá-la. Ela está localizada em tools/lazdatadesktop, no diretório home do Lazarus. Abra então o projeto lazdatadesktop e compile-o.
Para integrar a ferramenta ao IDE, abra e instale o pacote lazDataDict, localizado no diretório components/datadict. Após isso o IDE será estendido em três novas opções:
  1. Um novo item de menu será registrado no menu Project - com o nome Data Dictionary. Esta opção irá permitir que escolhamos um dicionário de dados para o projeto;
  2. No menu Tools será acrescentado o item de menu Database Desktop, que executa o Lazarus Data Desktop;
  3. Finalmente no Form Designer, um novo item é registrado no menu local que pode ser usado para aplicar o dicionário de dados a um TDataset - o item de menu Data Dictionary.
Vejamos então como utilizar o Lazarus Data Desktop.

Conectando-se a bancos de dados

Para fazer uma conexão use a opção de menu Connections > New connection, como mostra a figura abaixo:
Esta ação abrirá uma caixa de diálogo onde você irá escolher o banco de dados:
Selecione o banco de dados e você será levado a um novo diálogo para informar os dados da conexão:
Após informar os dados e confirmar será solicitado um nome para a conexão. Confirme também, após informar o nome e será adicionada uma nova aba ao ambiente com as informações da conexão. No lado direito da tela existe a aba Run Query,  que possibilita executar uma consulta e exportar o resultado da consulta, entre outros recursos.

Exportando dados de uma tabela

Para exportar os dados resultantes de uma consulta, use o botão Export this data que será habilitado após a execução bem sucedida de uma Query. Em seguida escolha o tipo de arquivo, por exemplo CSV, e confirme. Então será mostrado um diálogo onde se pode escolher os campos da tabela a serem exportados, o caminho e o nome do arquivo destino e opções de formatação, conforme pode ser visto na figura a seguir.
Depois de confirmar o arquivo exportado será criado.

Gerando código Free Pascal

Outro recurso importante do Lazarus Data Desktop é a criação de código em Free Pascal. Pode-se gerar código quando estamos visualizando o resultado de uma Query ou quando estamos examinando a definição de uma tabla no dicionário de dados.
Os códigos que podem ser gerados são:
  • Uma constante string a partir do comando SQL quando se está visualizando o resultado de uma consulta;
  • O código para criar uma tabela DBF a partir dos dados que estão sendo mostrados;
  • Uma classe Object Pascal e suas propriedades baseados em um Dataset e seus campos;
  • Uma declaração de classe tiOPF para usar com Object Persistence Framework.
Por exemplo, na aba Run Query, após executar uma consulta, clique no botão Create pascal code for this data. Escolha em seguida a opção Simple object/collection for the data. Será aberto o seguinte diálogo:
Nessa tela você define o caminho e nome do arquivo onde deseja salvar o código e os campos da tabela que serão propriedades da classe. Para cada campo da tabela é possível definir propriedades, bem como definir algumas propriedades da própria classe na aba Options. Confirme e uma tela com o código gerado será aberta, conforme mostra a figura seguinte:
Apesar de ter um botão Save, isso não será mais necessário, pois o código já está salvo no arquivo informado na tela anterior.
No próximo post veremos os procedimentos para criar dicionários de dados no Lazarus Data Desktop e como utilizá-los em nossas aplicações de banco de dados.
Post escrito tendo como referência o livro Lazarus - the Complete Guide, publicado pela Blaise Pascal Magazine.

domingo, 3 de julho de 2011

Lazarus - Livro sobre Lazarus em Português

"Desenvolvendo Aplicativos com Lazarus" (agbook, 2011, 344 páginas), produzido pelo paraense Jean Patrick, reúne um conjunto de informações valiosas sobre o IDE Lazarus, que chegam em boa hora para suprir uma necessidade urgente daqueles que, ou pretendem adotar uma nova ferramenta de desenvolvimento ou gostariam de melhorar seu conhecimento sobre o IDE.
O livro está organizado em 14 capítulos e 5 apêndices. Sendo que os nove primeiros capítulos passam por vários tópicos, alguns bem superficialmente tal como as paletas de componentes, e dá mais destaque à configuração no IDE no Capítulo 6.
Para os que preferem ação, ela começa mesmo no Capítulo 10. Nesse capítulo são desenvolvidos três projetos, o que dá uma boa noção do poder de fogo do Lazarus. Os projetos usam componentes básicos e há farta utilização de eventos e código. Desta forma o leitor terá um bom suporte para o que vem pela frente, que é o desenvolvimento usando banco de dados.
Uma introdução a banco de dados é feita no Capítulo 11. No Capítulo 12 são usados os componentes nativos do Lazarus para conexão a bancos de dados - a paleta SQLdb. Aqui é criada uma aplicação para controle de cheques usando o banco de dados sqlite.
Um cadastro de produtos usando banco de dados Firebird é criado no Capítulo 13. Neste caso o livro apresenta o conjunto de componentes ZeosLib, ZeosLib é uma biblioteca de terceiros e considerada melhor que SQLdb para aplicações de maior porte.
A criação de relatórios é abordada no Capítulo 14, onde se destaca o conjunto LazReport, nativo do Lazarus. Documentação sobre LazReport é muito raro. Esse é capítulo que vai ajudar muito aos desenvolvedores.
Nos apêndices destacamos os recursos do IDE para tratamento de arquivos texto e algumas dicas para programar aplicações multiplataforma. Inclusive é criada uma pequena aplicação para demonstrar o uso dos componentes oferecidos pelo Lazarus para acessar arquivos texto.
É uma obra que precisa do incentivo da comunidade para crescer ainda mais. Costumo dizer que só com a divulgação de conteúdo de valor é que será possível a disseminação do uso deste poderoso IDE.
Os interessados em adquirir um exemplar acessem o site da agbook.

terça-feira, 14 de junho de 2011

Curso de Introdução ao Free Pascal/Lazarus - Gratuito

Desenvolver aplicações usando um IDE como o Lazarus, pressupõe conhecimento da linguagem de programação subjacente. Pois a criação de um programa sempre irá precisar que se escreva algum código, principalmente para os eventos. No caso do Lazarus estamos falando do Free Pascal. Este é um curso introdutório ao Free Pascal oferecido na modalidade à distância e está organizado em oito módulos:

1. Princípios básicos, tipos, variáveis, constantes e comando de atribuição
2. Comandos condicionais (if)
3. Comandos de repetição (while, repeat e for)
4. Tipos definidos pelo usuário (subrange, set, enumerados, arrays, registros)
5. Ponteiros
6. Procedimentos e funções
7. Manipulação de strings
8. Classes e objetos

O curso será ministrado no ambiente virtual de aprendizagem Moodle. É uma ferramenta voltada para ensino à distância com todos os recursos de um ambiente dessa natureza: chat, fórum, exercícios, questionários, etc.
Caso você tenha interesse em fazer o curso, faça sua pré-inscrição aqui. Assim que completarmos a turma enviaremos um e-mail a você informando a data de início do curso e seu login e senha de acesso ao ambiente de aprendizagem.
Pré-inscrições encerradas.

Atualizado em 03/07/2011.

quarta-feira, 1 de junho de 2011

Free Pascal - Usando TList

A classe TList é usada para gerenciar uma coleção de ponteiros, com a grande vantagem de ser dinâmica. Ela dispõe de métodos para fazer busca na lista e ordenar os elementos, entre outros. No exemplo abaixo fazemos uso de alguns desses métodos.


unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;

type
  TContato = class
    private
      NomeContato     : String;
      TelefoneContato : String;

    public
      property Nome : String
          read NomeContato;
      property Telefone : String
          read TelefoneContato;

      constructor Create(const pNomeContato       : String;
                         const pTelefoneContato   : String);
  end;

  { TfrmTlist }

  TfrmTlist = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
    Agenda : TList;

    procedure MostraAgenda;
  public
    { public declarations }
  end;

var
  frmTlist: TfrmTlist;

implementation

{$R *.lfm}

constructor TContato.Create(const pNomeContato      : String;
                             const pTelefoneContato : String);
begin
  self.NomeContato     := pNomeContato;
  self.TelefoneContato := pTelefoneContato;
end;

function comparaPorNome(Item1 : Pointer; Item2 : Pointer) : Integer;
var
  contato1, contato2 : TContato;
begin
  contato1 := TContato(Item1);
  contato2 := TContato(Item2);

  if      contato1.Nome > contato2.Nome
  then Result := 1
  else if contato1.Nome = contato2.Nome
  then Result := 0
  else Result := -1;
end;

procedure TfrmTlist.Button1Click(Sender: TObject);
var
  contato : TContato;

begin
  Agenda := TList.Create;

  contato := TContato.Create('Nádia Alves', '3523-0001');
  Agenda.Add(contato);
  contato := TContato.Create('Célio Silva', '3524-0000');
  Agenda.Add(contato);

  Agenda.Add(TContato.Create('Hélio Costa', '3320-1000'));
  Agenda.Add(TContato.Create('Aldo Sousa', '3321-0001'));

  MostraAgenda;
  ShowMessage('Ordenando pelo nome. Pressione OK');
  Agenda.Sort(@comparaPorNome);

  MostraAgenda;
  ShowMessage('Inserindo novo contato. Pressione OK');
  Agenda.Insert(2, TContato.Create('Luis Gonzaga', '3325-4000'));
  MostraAgenda;
  ShowMessage('Excluindo um contato. Pressione OK');
  Agenda.Delete(4);
  ShowMessage('Pressione OK');
  Agenda.free;
end;

procedure TfrmTlist.MostraAgenda;
var
  i : Integer;
begin
  ListBox1.Items.Clear;
  for i := 0 to Agenda.Count-1 do
  begin
    ListBox1.Items.Add(TContato(Agenda[i]).Nome+' - '+
                      (TContato(Agenda[i]).Telefone));
  end;
end;

end.


No exemplo criamos uma classe Contato que será usada para povoar um TList que denominamos Agenda. Um TListBox é usado para apresentar os dados do TList.
Nas linhas que vão de 74 a 95 é onde acontece tudo que pretendemos mostrar. Inicialmente o TList é criado. Em seguida, são criados vários objetos Contato, que são adicionados à Agenda utilizando o método Add(). Este método sempre adiciona um objeto no fim da lista.
Após isso chamamos o método MostraAgenda, que foi criado para visualizar os dados da Agenda no TListBox. Na linha 86 há uma chamada ao método Sort(), que recebe como argumento o método comparaPorNome(). Aqui cabe uma explicação mais detalhada.
A ordenação de uma lista de objetos não é uma coisa tão natural como ordenar números inteiros ou strings. Como sabemos um objeto tem vários campos e por isso precisamos definir qual o critério que será usado para decidir que um objeto A é maior, menor ou igual a um outro objeto B. Por este motivo o método Sort() deve receber como parâmetro uma variável procedural, ou seja, um método que estabelece o critério de ordenação.
Dessa forma, foi criado o método comparaPorNome(), que recebe os ponteiros dos dois objetos a serem comparados. Tal método deve retornar -1 se o primeiro objeto for menor que o segundo, 1 se for maior e 0 se forem iguais. No nosso exemplo definimos que dois Contatos são iguais quando tem nomes iguais. Leia mais sobre variáveis procedurais no post Free Pascal - Variáveis Procedurais. Deve-se ressaltar que o Free Pascal define apenas como deve ser a assinatura do método que ele espera receber em Sort(). A implementação cabe ao desenvolvedor.
Na linha 90 um novo objeto é inserido na posição 2 do TList. Note que a primeira posição é 0.
Usamos o método Delete() para deletar um objeto em uma determinada posição. Na linha 93 excluímos o objeto da posição 4.
Quando a TList não é mais necessária, liberamos a memória usada chamando Free. Para criar uma lista de strings prefira usar TStrings ou sua descendente TStringList.
 
Creative Commons License
This work by Carlos Alberto P. Araújo is licensed under a Creative Commons Atribuição-Uso não-comercial-Compartilhamento pela mesma licença 3.0 Brasil License.