Há alguns dias escrevi um post mostrando o desenvolvimento de uma pequena aplicação para WinCE usando SQLite. Na época fiz os testes em um PDA, não usei emulador. Muitas pessoas tem entrado em contato comigo questionando sobre emuladores. Sempre tive dificuldades com os emuladores da Microsoft. Mas passei a procurar por um emulador que funcione e acabei por encontrar no site da PDAExpert. Lá encontrei as versões Standard e Professional do emulador para Windows Mobile 6. Por limitações de banda fiz o download da versão Standard que oferece três emuladores diferentes. Consegui executar o exemplo do artigo, como mostra a figura.
No entanto, o programa não consegue acesso ao banco SQLite. Minha forte suspeita é que a dll não é compatível com Windows Mobile 6. Ainda não tenho dados suficientes para afirmar isso. Por conta disso, pretendo criar uma nova aplicação que grava os dados em XML ou mesmo em arquivo texto usando TFixedFormatDataSet, como mostrei no post Lazarus - Tratamento de Arquivos Texto. De qualquer forma, se alguém tiver tido experiência com esse emulador rodando SQLite, gostaria de trocar idéias.
terça-feira, 27 de abril de 2010
Lazarus - Emulador WinCE/Windows Mobile
Marcadores:
emulador WinCE,
SQLite,
WinCE,
Windows Mobile
Posts Relacionados
segunda-feira, 26 de abril de 2010
Lazarus - Relógio para jogar Xadrez
Para os aficcionados do milenar jogo de Xadrez que não querem ou não podem pagar por um relógio, estou disponibilizando um programa bem simples que simula um relógio, cujo executável pode ser baixado aqui. O programa não requer instalação, podendo inclusive ser executado em um pendrive. Ele foi desenvolvido usando a fantástica ferramenta Lazarus/FreePascal e substitui com eficiência os relógios de mesa. Além disso, aqueles que estão dando os primeiros passos em Lazarus encontrarão um exmplo de programa que usa bastante componentes e código para seus exercícios.
Antes de mostrar o código vou mostrar a interface e explicar o funcionamento do relógio.
A interface
Na parte superior do relógio está a configuração do tempo que será usado na partida. Há três caixas de texto (TEdit). Uma para hora, a segunda para minutos e a terceira para segundos. À direita encontram-se três botões (TButton). O primeiro para iniciar o relógio, o segundo para reset e o terceiro para pausar.
Abaixo temos mais dois TButton que servirão para simular o pressionamento do botão do relógio de cada jogador. Mais abaixo tem-se dois TGroupBox com TLabel dentro deles. Os rótulos são usados para mostrar o tempo de reflexão de cada jogador. E, finalmente, dois TProgressBar para mostrar visualmente o progresso do tempo das brancas e das pretas. As barras de progresso também ficam dentro de TGroupBox.
Além dos componentes visuais são usados dois TTimer, usados para controlar o tempo de cada jogador.
O funcionamento
Para iniciar uma partida, inicialmente definimos o tempo da partida. Certamente o tempo é o mesmo, tanto para as brancas quanto para as pretas. Definido o tempo, pressiona-se o botão iniciar. Imediatamente o tempo das brancas começa a correr, habilitando-se o TTimer das brancas. As brancas fazem sua jogada e pressionam qualquer tecla do teclado que possa ser detectada pelo evento OnKeyPress. Nesse momento o TTimer das pretas é habilitado e o das brancas é desabilitado. O processo continua até que um dos jogadores estoure o tempo ou a partida seja encerrada. Se o botão Pausar for pressionado, os dois TTimer são desabilitados e o rótulo dele muda para Continuar. Pressionando-se o botão novamente a partida prossegue do ponto onde parou.
O componente TTimer dispara um evento a determinados intervalos definidos na propriedade Interval. O valor informado em Interval é em milissegundos. Deixamos a propriedade com o valor padrão 1000 milissegundos. Ou seja, o evento OnTimer irá acontecer a cada segundo.
O código
Grande parte do código é bem simples e não merece maiores explicações. Vou apresentar o método do evento OnClick do botão Pausar/Continuar. Para o funcionamento correto, declarei duas variáveis boolean globais: blPausa, que define se o relógio está em pausa ou em andamento, e blBrancas, que define de quem é o relógio que está em andamento.
De acordo com o estado de blPausa, habilita-se/desabilita-se o TTimer correspondente e ora o botão das brancas recebe o foco, ora o botão das pretas é quem recebe o foco. Nesse evento muda-se o rótulo do botão, alternando-se entre Pausar e Continuar.
Os eventos OnTimer tanto das brancas quanto das pretas são similares. Mostro apenas o método referente às brancas.
Nas linhas de 5 a 15, o tempo é incrementado. Observe que temos uma variável para hora, minutos e segundos. Em seguida o tempo é mostrado no rótulo correspondente ao display do relógio, na linha 16. Nas linhas de 17 a 19, é calculado o percentual de tempo decorrido e esse valor é mostrado no TProgressBar. Finalmente, é verificado se o tempo limite foi atingido. Caso positivo, o relógio é parado e a mensagem de estouro de tempo é mostrado.
A função StrZero() foi criada para preencher um número inteiro com zeros à esquerda. O código pode ser encontrado no download.
Baixe o programa completo aqui e divirta-se jogando Xadrez e aprendendo mais um pouco sobre Lazarus/FreePascal.
Antes de mostrar o código vou mostrar a interface e explicar o funcionamento do relógio.
A interface
Na parte superior do relógio está a configuração do tempo que será usado na partida. Há três caixas de texto (TEdit). Uma para hora, a segunda para minutos e a terceira para segundos. À direita encontram-se três botões (TButton). O primeiro para iniciar o relógio, o segundo para reset e o terceiro para pausar.
Abaixo temos mais dois TButton que servirão para simular o pressionamento do botão do relógio de cada jogador. Mais abaixo tem-se dois TGroupBox com TLabel dentro deles. Os rótulos são usados para mostrar o tempo de reflexão de cada jogador. E, finalmente, dois TProgressBar para mostrar visualmente o progresso do tempo das brancas e das pretas. As barras de progresso também ficam dentro de TGroupBox.
Além dos componentes visuais são usados dois TTimer, usados para controlar o tempo de cada jogador.
O funcionamento
Para iniciar uma partida, inicialmente definimos o tempo da partida. Certamente o tempo é o mesmo, tanto para as brancas quanto para as pretas. Definido o tempo, pressiona-se o botão iniciar. Imediatamente o tempo das brancas começa a correr, habilitando-se o TTimer das brancas. As brancas fazem sua jogada e pressionam qualquer tecla do teclado que possa ser detectada pelo evento OnKeyPress. Nesse momento o TTimer das pretas é habilitado e o das brancas é desabilitado. O processo continua até que um dos jogadores estoure o tempo ou a partida seja encerrada. Se o botão Pausar for pressionado, os dois TTimer são desabilitados e o rótulo dele muda para Continuar. Pressionando-se o botão novamente a partida prossegue do ponto onde parou.
O componente TTimer dispara um evento a determinados intervalos definidos na propriedade Interval. O valor informado em Interval é em milissegundos. Deixamos a propriedade com o valor padrão 1000 milissegundos. Ou seja, o evento OnTimer irá acontecer a cada segundo.
O código
Grande parte do código é bem simples e não merece maiores explicações. Vou apresentar o método do evento OnClick do botão Pausar/Continuar. Para o funcionamento correto, declarei duas variáveis boolean globais: blPausa, que define se o relógio está em pausa ou em andamento, e blBrancas, que define de quem é o relógio que está em andamento.
procedure TfrmRelogio.btPausarClick(Sender: TObject);
begin
if not blPausa then
begin
if blBrancas then
timBrancas.Enabled := false
else
timPretas.Enabled := false;
btParar.Enabled := false;
blPausa := true;
btPausar.Caption := 'Continuar';
end
else
begin
if blBrancas then
begin
timBrancas.Enabled := true;
btBrancas.SetFocus;
end
else
begin
timPretas.Enabled := true;
btPretas.SetFocus;
end;
blPausa := false;
btParar.Enabled := true;
btPausar.Caption := 'Pausar';
end
end;
De acordo com o estado de blPausa, habilita-se/desabilita-se o TTimer correspondente e ora o botão das brancas recebe o foco, ora o botão das pretas é quem recebe o foco. Nesse evento muda-se o rótulo do botão, alternando-se entre Pausar e Continuar.
Os eventos OnTimer tanto das brancas quanto das pretas são similares. Mostro apenas o método referente às brancas.
procedure TfrmRelogio.timBrancasTimer(Sender: TObject);
var
bTotal, bParcial: integer;
begin
bSeg := bSeg + 1;
if bSeg > 59 then
begin
bSeg := 0;
bMin := bMin + 1;
if bMin > 59 then
begin
bMin := 0;
bHor := bHor + 1;
end
end;
lbBrancas.Caption := StrZero(bHor, 2, 0) + ':' + StrZero(bMin, 2, 0)+':'+StrZero(bSeg, 2, 0);
bTotal := StrToInt(edHora.Text) * 3600 + StrToInt(edMinuto.Text) * 60 + StrToInt(edSegundo.Text);
bParcial := bHor * 3600 + bMin * 60 + bSeg;
pbBrancas.Position := (100 * bParcial div bTotal);
if (StrZero(bHor, 2, 0) >= edHora.Text) and (StrZero(bMin, 2, 0) >= edMinuto.Text) and (StrZero(bSeg, 2, 0) >= edSegundo.Text) then
begin
timBrancas.Enabled := false;
ShowMessage('As brancas estouraram o tempo');
end;
end;
Nas linhas de 5 a 15, o tempo é incrementado. Observe que temos uma variável para hora, minutos e segundos. Em seguida o tempo é mostrado no rótulo correspondente ao display do relógio, na linha 16. Nas linhas de 17 a 19, é calculado o percentual de tempo decorrido e esse valor é mostrado no TProgressBar. Finalmente, é verificado se o tempo limite foi atingido. Caso positivo, o relógio é parado e a mensagem de estouro de tempo é mostrado.
A função StrZero() foi criada para preencher um número inteiro com zeros à esquerda. O código pode ser encontrado no download.
Baixe o programa completo aqui e divirta-se jogando Xadrez e aprendendo mais um pouco sobre Lazarus/FreePascal.
Marcadores:
progressbar,
timer,
xadrez
Posts Relacionados
sexta-feira, 23 de abril de 2010
Lazarus - Funcoes de tratamento de Strings
Sysutils é uma unit do Free Pascal que implementa várias funções/procedimentos utilitários e tem a vantagem de ser multiplataforma. Esses utilitários são organizados em grupos e dentre eles podemos destacar: as rotinas de conversão de dados, as rotinas de data e hora, as rotinas de formatação de strings e as rotinas de manipulação de strings.
Destacamos neste post as funções/procedimentos de manipulação de strings:
LeftStr(const s: string; n: integer): string;
Retorna os n primeiros caracteres da string s. Por exemplo:
RightStr(const s: string; n: integer): string;
Retorna os n últimos caracteres da string s. Por exemplo:
Neste caso o exemplo pega o último caractere de uma string e imprime na tela.
Trim(const s: string): string;
Retira os espaços das extremidades da string s. Por exemplo:
TrimLeft(const s: string): string;
Retira os espaços no início da string s. Por exemplo:
TrimRight(const s: string): string;
Retira os espaços do final da string s. Por exemplo:
A função LowerCase(const s: string): string; converte s para caixa baixa. E a função UpperCase(const s: string): string; converte s para caixa alta. Existem muitas outras funções de tratamento de strings em sysutils. Inclusive funções para AnsiString e null-terminated. Num próximo post falaremos de outras funções dessa unit.
Destacamos neste post as funções/procedimentos de manipulação de strings:
LeftStr(const s: string; n: integer): string;
Retorna os n primeiros caracteres da string s. Por exemplo:
var s: string; begin s: 'Free Pascal'; writeln(LeftStr(s, 4)); // imprime Free end;
RightStr(const s: string; n: integer): string;
Retorna os n últimos caracteres da string s. Por exemplo:
var s: string; begin s: 'Free Pascal'; writeln(RightStr(s, 1)); // imprime "l" end;
Neste caso o exemplo pega o último caractere de uma string e imprime na tela.
Trim(const s: string): string;
Retira os espaços das extremidades da string s. Por exemplo:
var s: string; begin s: ' Free Pascal '; writeln(Trim(s)); // imprime "Free Pascal" end;
TrimLeft(const s: string): string;
Retira os espaços no início da string s. Por exemplo:
var s: string; begin s: ' Free Pascal '; writeln(TrimLeft(s)); // imprime "Free Pascal " end;
TrimRight(const s: string): string;
Retira os espaços do final da string s. Por exemplo:
var s: string; begin s: ' Free Pascal '; writeln(TrimRight(s)); // imprime " Free Pascal" end;
A função LowerCase(const s: string): string; converte s para caixa baixa. E a função UpperCase(const s: string): string; converte s para caixa alta. Existem muitas outras funções de tratamento de strings em sysutils. Inclusive funções para AnsiString e null-terminated. Num próximo post falaremos de outras funções dessa unit.
Posts Relacionados
quinta-feira, 15 de abril de 2010
Lazarus - Criando relatórios com FortesReport (Parte I)
Para a criação de relatórios, o Lazarus já trás o componente LazReport, no entanto ele precisa ser instalado no IDE. Para fazer a instalação do pacote, acesse o menu Package -> Open package file (.lpk). Localize o diretório de instalação do Lazarus e na pasta components abra lazreport e depois source. Abra o pacote lazreport.lpk, clique em Compile e depois em Install. Como já sabemos isso irá recompilar o IDE. Depois de inicializado novamente estará disponível a aba LazReport. Leia aqui um tutorial básico sobre o LazReport.
No entanto queremos mostrar uma alternativa ao LazReport. Por essa razão, vamos apresentar neste artigo o FortesReport. Para quem conhece o QuickReport, que fazia parte do Delphi, não terá dificuldade de desenvolver com esse componente. Baixe o pacote aqui e instale. Os procedimentos são semelhantes aos que mostramos acima. Você terá uma nova aba chamada Fortes Report.
Conectando o banco de dados
O primeiro passo para criar a aplicação é fazer a conexão com o banco de dados. Vamos usar o SQLite e o ZeosLib. O banco de dados será o mesmo já usado em exemplos anteriores. Selecione a aba Zeos Access e coloque um TZConnection no Data Module. Defina a propriedade Database com o caminho e o nome do arquivo do banco de dados. Na propriedade Protocol escolha sqlite-3.
Agora coloque um TZReadOnlyQuery da mesma aba. Na propriedade Connection escola o TZConnection anterior. Na propriedade SQL digite SELECT * FROM CIDADE ORDER BY NOME. Localize a aba Data Access e coloque um TDataSource no Data Module. Na propriedade DataSet selecione o TZReadOnlyQuery. Para que possamos visualizar uma prévia do relatório deixe o banco conectado e a Query aberta. Queremos criar um relatório com a seguinte aparência:
Ou seja, mostraremos as cidades em ordem alfabética e a cada letra inicial nova ela será impressa destacando um novo grupo de cidades.
A aplicação deverá ter dois forms. Um onde será criado o relatório, e outro que chamará o primeiro. Assim, se a aplicação já possui um form, adicione o segundo. Nosso trabalho será todo efetuado em cima do segundo form.
Selecione a aba Fortes Report e coloque um TRLReport no form. Esse componente é como se fosse a folha de papel e possui um quadriculado para facilitar o desenho. No Inspetor de Objetos expanda a propriedade AllowedBands e coloque em True as opções btColumnHeader, btDetail e btHeader. O componente trabalha com bandas e isso define quais as bandas que são permitidas no relatório. Definimos que nosso relatório terá um cabeçalho de página (btHeader), um cabeçalho de coluna (btColumnHeader) e uma banda de detalhe (btDetail). Na propriedade DataSource selecione o TDataSource colocado no Data Module anteriormente.
Agora coloque um TRLBand. Defina a propriedade BandType como btHeader. Aumente a altura da banda e coloque um TRLLabel sobre a TRLBand. Defina a propriedade Caption como Relatório de Cidades. Na propriedade Align selecione faCenter, para centralizar o rótulo na banda. Expanda a propriedade Font e defina Size como 14, por exemplo. Coloque um TRLSystemInfo no lado esquerdo da banda. Na propriedade Info selecione itDate. Isso mostrará a data atual na banda. Coloque outro TRLSystemInfo, este no lado direito da banda e defina a propriedade Info como itPageNumber. Isso mostra o número da página.
Coloque outro TRLBand e defina BandType como btColumnHeader. Coloque dois TRLLabel sobre esta e defina as propriedades Caption como ID e Nome respectivamente.
Como desejamos agrupar as cidades precisamos de um TRLGroup. Coloque um componente desses. Expanda AllowedBands e defina btDetail e btHeader como True. As propriedades DataField ou DataFormula são responsáveis por definir como se dará a quebra de grupos. Como queremos que a quebra ocorra pela primeira letra do nome da cidade, então informamos em DataFormula, copy(nome, 1, 1). Se a quebra fosse por um campo, este seria informado em DataField. Coloque um TRLBand sobre TRLGroup. Defina BandType como btHeader. Coloque um TRLDBText sobre o btHeader. Defina a propriedade DataSource com o TDataSource que foi inserido no DataModule. Podemos aqui imprimir um campo ou uma fórmula. Usaremos DataFormula para imprimir apenas a letra inicial do nome da cidade informando copy(nome, 1, 1). Coloque outro TRLBand sobre TRLGroup e dessa vez defina BandType como btDetail. Na banda detalhe é que são mostradas as linhas da tabela. Coloque dois TRLDBText sobre o btDetail de forma que fiquem abaixo dos rótulos ID e Nome inseridos no btColumnHeader. Defina a propriedade DataSource de ambos com o mesmo TDataSource usado desde o início do artigo. Na propriedade DataField do primeiro TRLDBText, informe ID_CIDADE. E no segundo informe NOME.
Podemos obter uma prévia do relatório clicando com o botão em TRLReport e selecionando Preview.
Para finalizar o exemplo coloque um botão no form que irá chamar o relatório. Abaixo de implementation acrescente no uses o nome da unit referente ao form do relatório. E no evento OnClick do botão escreva o código para chamar o método Preview() de RLReport.
No entanto queremos mostrar uma alternativa ao LazReport. Por essa razão, vamos apresentar neste artigo o FortesReport. Para quem conhece o QuickReport, que fazia parte do Delphi, não terá dificuldade de desenvolver com esse componente. Baixe o pacote aqui e instale. Os procedimentos são semelhantes aos que mostramos acima. Você terá uma nova aba chamada Fortes Report.
Conectando o banco de dados
O primeiro passo para criar a aplicação é fazer a conexão com o banco de dados. Vamos usar o SQLite e o ZeosLib. O banco de dados será o mesmo já usado em exemplos anteriores. Selecione a aba Zeos Access e coloque um TZConnection no Data Module. Defina a propriedade Database com o caminho e o nome do arquivo do banco de dados. Na propriedade Protocol escolha sqlite-3.
Agora coloque um TZReadOnlyQuery da mesma aba. Na propriedade Connection escola o TZConnection anterior. Na propriedade SQL digite SELECT * FROM CIDADE ORDER BY NOME. Localize a aba Data Access e coloque um TDataSource no Data Module. Na propriedade DataSet selecione o TZReadOnlyQuery. Para que possamos visualizar uma prévia do relatório deixe o banco conectado e a Query aberta. Queremos criar um relatório com a seguinte aparência:
Ou seja, mostraremos as cidades em ordem alfabética e a cada letra inicial nova ela será impressa destacando um novo grupo de cidades.
A aplicação deverá ter dois forms. Um onde será criado o relatório, e outro que chamará o primeiro. Assim, se a aplicação já possui um form, adicione o segundo. Nosso trabalho será todo efetuado em cima do segundo form.
Selecione a aba Fortes Report e coloque um TRLReport no form. Esse componente é como se fosse a folha de papel e possui um quadriculado para facilitar o desenho. No Inspetor de Objetos expanda a propriedade AllowedBands e coloque em True as opções btColumnHeader, btDetail e btHeader. O componente trabalha com bandas e isso define quais as bandas que são permitidas no relatório. Definimos que nosso relatório terá um cabeçalho de página (btHeader), um cabeçalho de coluna (btColumnHeader) e uma banda de detalhe (btDetail). Na propriedade DataSource selecione o TDataSource colocado no Data Module anteriormente.
Agora coloque um TRLBand. Defina a propriedade BandType como btHeader. Aumente a altura da banda e coloque um TRLLabel sobre a TRLBand. Defina a propriedade Caption como Relatório de Cidades. Na propriedade Align selecione faCenter, para centralizar o rótulo na banda. Expanda a propriedade Font e defina Size como 14, por exemplo. Coloque um TRLSystemInfo no lado esquerdo da banda. Na propriedade Info selecione itDate. Isso mostrará a data atual na banda. Coloque outro TRLSystemInfo, este no lado direito da banda e defina a propriedade Info como itPageNumber. Isso mostra o número da página.
Coloque outro TRLBand e defina BandType como btColumnHeader. Coloque dois TRLLabel sobre esta e defina as propriedades Caption como ID e Nome respectivamente.
Como desejamos agrupar as cidades precisamos de um TRLGroup. Coloque um componente desses. Expanda AllowedBands e defina btDetail e btHeader como True. As propriedades DataField ou DataFormula são responsáveis por definir como se dará a quebra de grupos. Como queremos que a quebra ocorra pela primeira letra do nome da cidade, então informamos em DataFormula, copy(nome, 1, 1). Se a quebra fosse por um campo, este seria informado em DataField. Coloque um TRLBand sobre TRLGroup. Defina BandType como btHeader. Coloque um TRLDBText sobre o btHeader. Defina a propriedade DataSource com o TDataSource que foi inserido no DataModule. Podemos aqui imprimir um campo ou uma fórmula. Usaremos DataFormula para imprimir apenas a letra inicial do nome da cidade informando copy(nome, 1, 1). Coloque outro TRLBand sobre TRLGroup e dessa vez defina BandType como btDetail. Na banda detalhe é que são mostradas as linhas da tabela. Coloque dois TRLDBText sobre o btDetail de forma que fiquem abaixo dos rótulos ID e Nome inseridos no btColumnHeader. Defina a propriedade DataSource de ambos com o mesmo TDataSource usado desde o início do artigo. Na propriedade DataField do primeiro TRLDBText, informe ID_CIDADE. E no segundo informe NOME.
Podemos obter uma prévia do relatório clicando com o botão em TRLReport e selecionando Preview.
Para finalizar o exemplo coloque um botão no form que irá chamar o relatório. Abaixo de implementation acrescente no uses o nome da unit referente ao form do relatório. E no evento OnClick do botão escreva o código para chamar o método Preview() de RLReport.
Marcadores:
fortesreport,
lazreport,
relatórios
Posts Relacionados
quarta-feira, 7 de abril de 2010
Lazarus - Criando XML a partir de um DataSet
Sabemos que um documento XML pode ser criado manipulando strings e arquivos texto. Esta opção não é aconselhável, pois é difícil garantir que o documento seja bem formado. A melhor forma de fazer isso é usar DOM (Modelo Objeto de Documento). Já usamos esse padrão para ler um documento XML no artigo anterior.
Para ilustrar a criação de um documento vamos implementar uma aplicação que gera um XML a partir dos registros de um DataSet. Para isso vamos usar nosso banco de dados SQLite de exemplos anteriores e vamos usar ZeosLib. Mas pode ser usado qualquer conjunto de componentes, inclusive SQLdb.
Coloque então um TZConnection no form, ou num Data Module. Defina a propriedade Database com o banco SQLite, ou qualquer outro. Defina a propriedade Protocol com sqlite-3.
Coloque também um TZReadOnlyQuery e defina Name como queCidade. Em Connection selecione o TZConnection. Na propriedade SQL digite SELECT * FROM CIDADE.
Insira um botão, que vai executar a criação do XML.
Na cláusula uses acrescente as units DOM e XMLWrite.
Agora vamos criar o código que efetivamente irá criar o XML. A idéia é criar um procedimento genérico, que servirá para qualquer tabela.
O procedimento Tabela2DOM() recebe como argumentos o nome do nó raiz, o nome do nó pai, o próprio documento XML e o DataSet. Observe o código abaixo:
Nas linhas 8 e 9 criamos o nó raiz e o adicionamos ao documento. O método AppendChild() adiciona um nó ao documento.
A partir da linha 11 iniciamos a varredura da tabela. Para cada registro da tabela adicionamos um nó pai com o nome passado como parâmetro, que é feito nas linhas 14 e 15.
O for da linha 16 irá precorrer os campos de cada registro da tabela. Para cada registro criamos um nó pai com o nome do campo (linha 20) e um nó filho com o conteúdo do campo. A linha 18 evita a inclusão de campos vazios no documento.
No evento OnClick do botão criamos o objeto DOM, o procedimento acima é chamado, o documento é gravado usando o método writeXMLFile() e o objeto é destruido.
Para executar lembre de conectar o banco e abrir a tabela, conforme visto em artigos anteriores.
Baixe aqui o código completo do exemplo.
Para ilustrar a criação de um documento vamos implementar uma aplicação que gera um XML a partir dos registros de um DataSet. Para isso vamos usar nosso banco de dados SQLite de exemplos anteriores e vamos usar ZeosLib. Mas pode ser usado qualquer conjunto de componentes, inclusive SQLdb.
Coloque então um TZConnection no form, ou num Data Module. Defina a propriedade Database com o banco SQLite, ou qualquer outro. Defina a propriedade Protocol com sqlite-3.
Coloque também um TZReadOnlyQuery e defina Name como queCidade. Em Connection selecione o TZConnection. Na propriedade SQL digite SELECT * FROM CIDADE.
Insira um botão, que vai executar a criação do XML.
Na cláusula uses acrescente as units DOM e XMLWrite.
Agora vamos criar o código que efetivamente irá criar o XML. A idéia é criar um procedimento genérico, que servirá para qualquer tabela.
O procedimento Tabela2DOM() recebe como argumentos o nome do nó raiz, o nome do nó pai, o próprio documento XML e o DataSet. Observe o código abaixo:
procedure TfrmDataXml.Tabela2DOM(Raiz, Registro: string; XMLDoc: TXmlDocument; DataSet: TDataSet);
var
iRaiz, iPai, iFilho: TDOMNode;
i, j: Integer;
begin
DataSet.Open;
DataSet.First;
iRaiz := XMLDoc.CreateElement(Raiz);
XMLDoc.AppendChild(iRaiz);
j := 0;
while not DataSet.EOF do
begin
iRaiz := XMLDoc.DocumentElement;
iPai := XMLDoc.CreateElement(Registro);
iRaiz.AppendChild(iPai);
for I := 0 to DataSet.FieldCount - 1 do
begin
if not (DataSet.Fields[i].IsNull) then
begin
iPai := XMLDoc.CreateElement(DataSet.Fields[i].FieldName);
iFilho := XMLDoc.CreateTextNode(DataSet.Fields[i].AsString);
iPai.AppendChild(iFilho);
iRaiz.ChildNodes.Item[j].AppendChild(iPai);
end;
end;
DataSet.Next;
j := j + 1;
end;
DataSet.Close;
end;
Nas linhas 8 e 9 criamos o nó raiz e o adicionamos ao documento. O método AppendChild() adiciona um nó ao documento.
A partir da linha 11 iniciamos a varredura da tabela. Para cada registro da tabela adicionamos um nó pai com o nome passado como parâmetro, que é feito nas linhas 14 e 15.
O for da linha 16 irá precorrer os campos de cada registro da tabela. Para cada registro criamos um nó pai com o nome do campo (linha 20) e um nó filho com o conteúdo do campo. A linha 18 evita a inclusão de campos vazios no documento.
No evento OnClick do botão criamos o objeto DOM, o procedimento acima é chamado, o documento é gravado usando o método writeXMLFile() e o objeto é destruido.
procedure TfrmDataXml.btnCriarClick(Sender: TObject);
begin
XMLDoc := TXMLDocument.Create;
Tabela2DOM ('cidades', 'cidade', XMLDoc, queCidade);
writeXMLFile(XMLDoc,'cidade.xml');
XMLdoc.free;
end;
Para executar lembre de conectar o banco e abrir a tabela, conforme visto em artigos anteriores.
Baixe aqui o código completo do exemplo.
Posts Relacionados
quinta-feira, 1 de abril de 2010
Lazarus - Lendo XML em um TreeView
XML (Extensible Markup Language) é uma linguagem de marcação, baseada em texto, recomendada pela W3C para troca de informações entre diferentes sistemas e plataformas. Linguagens usadas para troca de dados, como XHTML, a maioria dos WebServices, se baseiam em XML. Aqui está o exemplo de um arquivo XML:
Em Lazarus/Free Pascal existem três units que dão suporte a XML. São chamadas XMLRead, XMLWrite e DOM. Fazem parte da FCL (Biblioteca de Componentes Livres). Só precisamos adicionar as units na cláusula uses para ter suporte a XML.
DOM (Modelo Objeto de Documento) define uma interface padrão. Quando você escreve código que usa essa interface, você pode mudar para outras implementações de DOM sem precisar mudar seu código fonte.
Lendo XML em um TreeView
Como XML tem uma estrutura de árvore, carregar um documento XML em um TTreeView parece bem natural. No nosso exemplo nós carregamos um documento XML em um DOM e depois mostramos a estrutura em um TTreeView. Para mostrar o documento em uma árvore usamos um método recursivo que navega pelos nós e subnós do XML.
Vamos iniciar uma nova aplicação e na cláusula uses da unit vamos adicionar DOM e XMLRead. No form coloque um TEdit, defina Name como edArquivo e delete o conteúdo de Text. Coloque um botão e defina Name como btnAbrir e Caption como Abrir. Insira mais um botão e em Name informe btnLer e em Caption informe Ler. A propriedade Enabled desse botão deve ficar em False. Agora coloque um TTreeView - da aba Common Controls - e em Name digite tvwXML. Coloque também um TOpenDialog da aba Dialogs e mude Name para dlgAbrir. Sua interface irá ficar assim:
No método do evento OnClick do botão btnAbrir escreva o seguinte código:
if dlgAbrir.Execute then
begin
edArquivo.Text := dlgAbrir.FileName;
btnLer.Enabled := True;
end;
Esse código abre a caixa de diálogo para selecionar o arquivo XML, atribui o nome do arquivo ao TEdit e habilita o botão btnLer. No botão btnLer vamos executar o código que povoa o TTreeView com os dados do documento XML. O método recursivo será construido separado:
Este método utiliza várias operações que podemos fazer com DOM. Cada nó tem uma propriedade denominada NodeType, para determinar se é um elemento, atributo, nó texto, etc (linha 09). Nas linhas 13 e 14 podemos observar que NodeValue - a representação textual - só pode ser acessado se o nó tiver um elemento textual. Após mostrar o nome do item e o valor textual - se houver - o método mostra o conteúdo de cada atributo. Em seguida chamamos o método recursivamente para mostrar cada subnó.
A interface do método deve ser informada na seção type. O método do evento OnClick do botão btnLer deve ser assim:
procedure TfrmXml.btnLerClick(Sender: TObject);
var
Documento: TXMLDocument;
begin
tvwXML.Items.Clear;
ReadXMLFile(Documento, edArquivo.Text);
DomToTree(Documento.DocumentElement, nil);
tvwXML.FullExpand;
Documento.Free;
end;
Ele cria um DOM a partir do arquivo XML e depois chama o método que povoa o TTreeView.
Faça o download do código fonte do exemplo aqui.
Joao da Silva (93)3522-0001 Jose Sousa (93)3522-0002 jose@email.com.br Maria da Silva (93)3522-0003 (93)9122-0001 Raimunda de Sousa rsousa@email.com.br
Em Lazarus/Free Pascal existem três units que dão suporte a XML. São chamadas XMLRead, XMLWrite e DOM. Fazem parte da FCL (Biblioteca de Componentes Livres). Só precisamos adicionar as units na cláusula uses para ter suporte a XML.
DOM (Modelo Objeto de Documento) define uma interface padrão. Quando você escreve código que usa essa interface, você pode mudar para outras implementações de DOM sem precisar mudar seu código fonte.
Lendo XML em um TreeView
Como XML tem uma estrutura de árvore, carregar um documento XML em um TTreeView parece bem natural. No nosso exemplo nós carregamos um documento XML em um DOM e depois mostramos a estrutura em um TTreeView. Para mostrar o documento em uma árvore usamos um método recursivo que navega pelos nós e subnós do XML.
Vamos iniciar uma nova aplicação e na cláusula uses da unit vamos adicionar DOM e XMLRead. No form coloque um TEdit, defina Name como edArquivo e delete o conteúdo de Text. Coloque um botão e defina Name como btnAbrir e Caption como Abrir. Insira mais um botão e em Name informe btnLer e em Caption informe Ler. A propriedade Enabled desse botão deve ficar em False. Agora coloque um TTreeView - da aba Common Controls - e em Name digite tvwXML. Coloque também um TOpenDialog da aba Dialogs e mude Name para dlgAbrir. Sua interface irá ficar assim:
No método do evento OnClick do botão btnAbrir escreva o seguinte código:
if dlgAbrir.Execute then
begin
edArquivo.Text := dlgAbrir.FileName;
btnLer.Enabled := True;
end;
Esse código abre a caixa de diálogo para selecionar o arquivo XML, atribui o nome do arquivo ao TEdit e habilita o botão btnLer. No botão btnLer vamos executar o código que povoa o TTreeView com os dados do documento XML. O método recursivo será construido separado:
procedure TfrmXml.DomToTree(XmlNode: TDOMNode; TreeNode: TTreeNode);
var
I: integer;
NewTreeNode: TTreeNode;
NodeText: string;
AttrNode: TDOMNode;
begin
// considera apenas nós elementos
if XmlNode.NodeType <> ELEMENT_NODE then
Exit;
// inclui o nó
NodeText := XmlNode.NodeName;
if (XmlNode.ChildNodes.Count = 1) and (XmlNode.ChildNodes[0].NodeValue <> '') then
NodeText := NodeText + ' = ' + XmlNode.ChildNodes[0].NodeValue;
NewTreeNode := tvwXML.Items.AddChild(TreeNode, NodeText);
// inclui atributos, se existirem
for I := 0 to xmlNode.Attributes.Length - 1 do
begin
AttrNode := xmlNode.Attributes.Item[I];
tvwXML.Items.AddChild(NewTreeNode,
'[' + AttrNode.NodeName + ' = "' + AttrNode.NodeValue + '"]');
end;
// inclui cada nó filho
if XmlNode.HasChildNodes then
for I := 0 to xmlNode.ChildNodes.Count - 1 do
DomToTree(xmlNode.ChildNodes.Item[I], NewTreeNode);
end;
Este método utiliza várias operações que podemos fazer com DOM. Cada nó tem uma propriedade denominada NodeType, para determinar se é um elemento, atributo, nó texto, etc (linha 09). Nas linhas 13 e 14 podemos observar que NodeValue - a representação textual - só pode ser acessado se o nó tiver um elemento textual. Após mostrar o nome do item e o valor textual - se houver - o método mostra o conteúdo de cada atributo. Em seguida chamamos o método recursivamente para mostrar cada subnó.
A interface do método deve ser informada na seção type. O método do evento OnClick do botão btnLer deve ser assim:
procedure TfrmXml.btnLerClick(Sender: TObject);
var
Documento: TXMLDocument;
begin
tvwXML.Items.Clear;
ReadXMLFile(Documento, edArquivo.Text);
DomToTree(Documento.DocumentElement, nil);
tvwXML.FullExpand;
Documento.Free;
end;
Ele cria um DOM a partir do arquivo XML e depois chama o método que povoa o TTreeView.
Faça o download do código fonte do exemplo aqui.
Atualizado em 08/04/2010.
quinta-feira, 25 de março de 2010
Lazarus - Criando um Splash e um Hint com várias linhas
Splash
Splash é uma janela de abertura de um programa. Vamos aprender como criar uma dessas em Lazarus. Para isso crie uma nova aplicação. Podemos dar o nome de frmPrincipal a esse form e salvar tudo. Para a unit dê o nome u_principal e ao projeto dê o nome Splash. Agora inclua mais um form na aplicação. Esse será o splash. Na propriedade Name digite frmSplash. Salve e digite u_splash no nome da unit. Na propriedade FormStyle desse form selecione fsSplash. Selecione a opção de menu Project -> Project Options. Localize a aba Forms, selecione frmSplash e, usando a seta, passe-o para a caixa da direita. Isso define que o form não será criado automaticamente.
Coloque um TImage em frmSplash e selecione uma imagem adequada ao seu projeto. É bom mudar Align para alClient e Stretch para True.
Agora clique no botão View Units na barra de ferramentas. Isso abrirá uma janela com todas as units da aplicação. Selecione o arquivo do projeto: splash.lpr.
Na seção uses acrescente Crt. Isso é necessário para invocar o procedimento Delay() na linha 21, que provoca um retardo para que o splash seja mostrado por um certo tempo. Explicando o código apenas para as linhas que serão acrescentadas:
Linha 18 - cria o form frmSplash.
Linha 19 - mostra o splash.
Linha 20 - funciona como Repaint, atualizando a janela, senão não será mostrada.
Linha 21 - causa um retardo na execução do programa.
Linha 23 - oculta o splash.
Linha 24 - libera a memória ocupada pelo splash.
Hint com várias linhas
Hints são aquelas dicas que aparecem quando paramos o mouse sobre um componente. Normalmente essas dicas são informadas na propriedade Hint e habilitadas na propriedade ShowHint. No entanto através do Object Inspector só conseguimos colocar uma linha. Para mostrar como podemos ter um Hint com múltiplas linhas coloque um botão do tipo TBitBtn - pode ser qualquer outro tipo de botão - em frmPrincipal. Em Name informe btnSair. Na propriedade Kind selecione bkClose. Dê um duplo clique no form para criar um método para o evento OnCreate. Digite no Editor de código:
O #13 insere um Enter na string e causa um salto de linha. Pode inserir quantos #13 você precise. Execute a aplicação e pare o mouse sobre o botão.
Splash é uma janela de abertura de um programa. Vamos aprender como criar uma dessas em Lazarus. Para isso crie uma nova aplicação. Podemos dar o nome de frmPrincipal a esse form e salvar tudo. Para a unit dê o nome u_principal e ao projeto dê o nome Splash. Agora inclua mais um form na aplicação. Esse será o splash. Na propriedade Name digite frmSplash. Salve e digite u_splash no nome da unit. Na propriedade FormStyle desse form selecione fsSplash. Selecione a opção de menu Project -> Project Options. Localize a aba Forms, selecione frmSplash e, usando a seta, passe-o para a caixa da direita. Isso define que o form não será criado automaticamente.
Coloque um TImage em frmSplash e selecione uma imagem adequada ao seu projeto. É bom mudar Align para alClient e Stretch para True.
Agora clique no botão View Units na barra de ferramentas. Isso abrirá uma janela com todas as units da aplicação. Selecione o arquivo do projeto: splash.lpr.
program splash;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, crt, u_principal, LResources, u_splash
{ you can add units after this };
{$IFDEF WINDOWS}{$R splash.rc}{$ENDIF}
begin
{$I splash.lrs}
Application.Initialize;
frmSplash := TfrmSplash.Create(nil);
frmSplash.Show;
frmSplash.Update;
Delay(1000);
Application.CreateForm(TfrmPrincipal, frmPrincipal);
frmSplash.Hide;
frmSplash.Free;
Application.Run;
end.
Na seção uses acrescente Crt. Isso é necessário para invocar o procedimento Delay() na linha 21, que provoca um retardo para que o splash seja mostrado por um certo tempo. Explicando o código apenas para as linhas que serão acrescentadas:
Linha 18 - cria o form frmSplash.
Linha 19 - mostra o splash.
Linha 20 - funciona como Repaint, atualizando a janela, senão não será mostrada.
Linha 21 - causa um retardo na execução do programa.
Linha 23 - oculta o splash.
Linha 24 - libera a memória ocupada pelo splash.
Hint com várias linhas
Hints são aquelas dicas que aparecem quando paramos o mouse sobre um componente. Normalmente essas dicas são informadas na propriedade Hint e habilitadas na propriedade ShowHint. No entanto através do Object Inspector só conseguimos colocar uma linha. Para mostrar como podemos ter um Hint com múltiplas linhas coloque um botão do tipo TBitBtn - pode ser qualquer outro tipo de botão - em frmPrincipal. Em Name informe btnSair. Na propriedade Kind selecione bkClose. Dê um duplo clique no form para criar um método para o evento OnCreate. Digite no Editor de código:
btnSair.Hint := 'Para sair desse form' + #13 +
'clique neste botão';
btnSair.ShowHint:= True;
btnSair.ShowHint:= True;
O #13 insere um Enter na string e causa um salto de linha. Pode inserir quantos #13 você precise. Execute a aplicação e pare o mouse sobre o botão.
Atualizado em 15/04/2010.
segunda-feira, 22 de março de 2010
Lazarus - Conectando Firebird com SQLdb ou ZeosLib
Vamos mostrar duas maneiras de acessar Firebird no Lazarus. Uma usando os componentes nativos SQLdb e outra usando ZeosLib. Já fizemos aqui alguns exemplos e a construção da interface não será mais tratada. Apresentaremos apenas os passos necessários no Data Module. Usaremos a versão 0.9.29 do Lazarus.
Antes de iniciar é importante ter conhecimento da versão do Firebird, principalmente para o caso de usar ZeosLib. Crie o banco dados. Vamos usar o mesmo banco usado em artigos anteriores.
create table cidade (id_cidade integer not null primary key, nome varchar(30));
create table cliente (id_cliente integer not null primary key, nome varchar(40), endereco varchar(40), id_cidade integer references cidade(id_cidade), telefone varchar(14), tipo char(1));
Diferente do PG, no Firebird você pode ter um arquivo de banco em qualquer diretório que você queira, desde que seja na máquina local onde está instalado o servidor FB.
Usando SQLdb
Selecione a aba SQLdb e coloque no Data Module um TIBConnection. Ele que fará a conexão com o banco. Defina então as seguintes propriedades:
DatabaseName - informe o arquivo do banco de dados com o caminho completo.
HostName - informe o nome ou o IP do servidor de banco de dados.
Name - informe um nome para a conexão. Por exemplo: dbCliente.
Password - informe a senha do usuário. Normalmente é masterkey.
UserName - informe o nome do usuário. Normalmente é sysdba.
Coloque agora um TSQLTransaction e selecione dbCliente na propriedade Database, e na propriedade Name digite trGeral, por exemplo.
Volte ao TIBConnection e informe trGeral na propriedade Transaction. Coloque a propriedade Connected em True para verificar se a conexão é feita. Depois volte para False.
Coloque um TSQLQuery no Data Module e defina suas propriedades:
Database - selecione dbCliente.
Name - defina queCidade.
SQL - informe SELECT * FROM CIDADE.
Transaction - selecione trGeral.
Coloque agora um TDataSource da aba Data Access e mude Name para dsCidade e em DataSet selecione queCidade.
No evento AfterPost de queCidade digite o código:
queCidade.ApplyUpdates;
trGeral.CommitRetaining;
No evento AfterDelete selecione o mesmo método para não repetir código.
Pronto. Está feita a configuração de acesso, tanto para leitura quanto para escrita, em uma tabela FB. Assim como nos exemplos anteriores lembre-se de conectar e desconectar o banco de dados através de código.
Usando ZeosLib
Usaremos a versão 7.0 do ZeosLib disponível no grupo Lazarus-BR. Coloque um TZConnection no Data Module. Defina as propriedades:
Database - informe o arquivo do banco com o caminho completo.
HostName - informe o nome ou IP do servidor do banco. Para máquina local informe localhost.
Name - digite dbCliente.
Password - informe a senha do usuário. Geralmente masterkey.
Protocol - informe firebird-xx. Observe a versão do FB que você está usando.
User - informe sysdba.
Mude Connected para True. No Windows se ocorrer um erro de dll, localize a mesma na pasta do FB e copie-a para system32 do Windows. Depois de conectar com sucesso volte Connected para False.
Coloque um TZQuery e um TZUpdateSQL e configure-os como foi feito no artigo Lazarus - Conectando PostegreSQL com ZeosLib.
Coloque um TDataSource da aba Data Access e defina Name como dsCidade e em DataSet selecione a TZQuery anterior. Ai está. Agora crie a interface com nos posts anteriores.
Antes de iniciar é importante ter conhecimento da versão do Firebird, principalmente para o caso de usar ZeosLib. Crie o banco dados. Vamos usar o mesmo banco usado em artigos anteriores.
create table cidade (id_cidade integer not null primary key, nome varchar(30));
create table cliente (id_cliente integer not null primary key, nome varchar(40), endereco varchar(40), id_cidade integer references cidade(id_cidade), telefone varchar(14), tipo char(1));
Diferente do PG, no Firebird você pode ter um arquivo de banco em qualquer diretório que você queira, desde que seja na máquina local onde está instalado o servidor FB.
Usando SQLdb
Selecione a aba SQLdb e coloque no Data Module um TIBConnection. Ele que fará a conexão com o banco. Defina então as seguintes propriedades:
DatabaseName - informe o arquivo do banco de dados com o caminho completo.
HostName - informe o nome ou o IP do servidor de banco de dados.
Name - informe um nome para a conexão. Por exemplo: dbCliente.
Password - informe a senha do usuário. Normalmente é masterkey.
UserName - informe o nome do usuário. Normalmente é sysdba.
Coloque agora um TSQLTransaction e selecione dbCliente na propriedade Database, e na propriedade Name digite trGeral, por exemplo.
Volte ao TIBConnection e informe trGeral na propriedade Transaction. Coloque a propriedade Connected em True para verificar se a conexão é feita. Depois volte para False.
Coloque um TSQLQuery no Data Module e defina suas propriedades:
Database - selecione dbCliente.
Name - defina queCidade.
SQL - informe SELECT * FROM CIDADE.
Transaction - selecione trGeral.
Coloque agora um TDataSource da aba Data Access e mude Name para dsCidade e em DataSet selecione queCidade.
No evento AfterPost de queCidade digite o código:
queCidade.ApplyUpdates;
trGeral.CommitRetaining;
No evento AfterDelete selecione o mesmo método para não repetir código.
Pronto. Está feita a configuração de acesso, tanto para leitura quanto para escrita, em uma tabela FB. Assim como nos exemplos anteriores lembre-se de conectar e desconectar o banco de dados através de código.
Usando ZeosLib
Usaremos a versão 7.0 do ZeosLib disponível no grupo Lazarus-BR. Coloque um TZConnection no Data Module. Defina as propriedades:
Database - informe o arquivo do banco com o caminho completo.
HostName - informe o nome ou IP do servidor do banco. Para máquina local informe localhost.
Name - digite dbCliente.
Password - informe a senha do usuário. Geralmente masterkey.
Protocol - informe firebird-xx. Observe a versão do FB que você está usando.
User - informe sysdba.
Mude Connected para True. No Windows se ocorrer um erro de dll, localize a mesma na pasta do FB e copie-a para system32 do Windows. Depois de conectar com sucesso volte Connected para False.
Coloque um TZQuery e um TZUpdateSQL e configure-os como foi feito no artigo Lazarus - Conectando PostegreSQL com ZeosLib.
Coloque um TDataSource da aba Data Access e defina Name como dsCidade e em DataSet selecione a TZQuery anterior. Ai está. Agora crie a interface com nos posts anteriores.
Posts Relacionados
quinta-feira, 18 de março de 2010
Lazarus - Conectando MSAccess com ODBC
Atualizei o Lazarus para a versão Lazarus-0.9.29-24055-fpc-2.4.1-20100317-win32. E foi usando esse snapshot que criei o exemplo usado neste post. Pode-se baixar o mais recente snapshot em http://www.hu.freepascal.org/lazarus/
Nem todas as fontes de dados estão contempladas pelo SQLdb ou pelo ZeosLib. Algumas vezes é necessário migrar ou mesmo atualizar fontes de dados como Paradox, Access e outros. Para essa nobre tarefa o Lazarus disponibiliza o componente TODBCConnection, encontrado na aba SQLdb. Ou seja, podemos acessar qualquer banco de dados (mesmo aqueles que não merecem essa denominação) através de ODBC, desde que tenhamos o driver específico. Devo observar que fiz esse exemplo no Windows.
Então o primeiro passo é criar uma fonte de dados ODBC e isso é feito no sistema operacional. Usei uma fonte MSAccess - o dbdemos.mdb que vem com o Delphi. Após isso vamos ao Lazarus.
No Data Module coloque um TODBCConnection. Mude a propriedade Name para dbAccess, por exemplo. Em DatabaseName digite o nome da fonte de dados criada no sistema anteriormente. Mude Connected para True para testar a conexão. Depois volte para False.
Coloque um TSQLTransaction, mude Name para trAccess e em Database selecione dbAccess. Feito isso coloque um TSQLQuery e mude Name para queEmployee, em Database selecione dbAccess. Na propriedade SQL informe SELECT * FROM EMPLOYEE e em Transaction selecione trAccess. Se você mudar a propriedade Active de queEmployee para True, ela deveria abrir sem erro. No meu caso não funcionou e, depois de muito apanhar, mudei a propriedade UsePrimaryKeyAsKey de queEmployee para False e deu certo. Não sei explicar porque. Na propriedade InsertSQL digite:
INSERT INTO EMPLOYEE VALUES (:EMPNO, :LASTNAME, :FIRSTNAME, :PHONEEXT, :HIREDATE, :SALARY);
Em UpdateSQL:
UPDATE EMPLOYEE SET LASTNAME = :LASTNAME, FIRSTNAME = :FIRSTNAME, PHONEEXT = :PHONEEXT, HIREDATE = :HIREDATE, SALARY = :SALARY WHERE EMPNO = :EMPNO;
E em DeleteSQL:
DELETE FROM EMPLOYEE WHERE EMPNO = :EMPNO;
Agora coloque um TDataSource da aba Data Access. Defina Name como dsEmployee e DataSet como tbEmployee.
Crie uma interface. Se tiver dúvida de como fazer isso, dê uma olhada nos posts Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II.
Lembre de abrir e fechar a conexão do TODBCConnection. Pode fazer isso nos eventos OnShow e OnClose de form, usando os métodos Open e Close. Abra e feche tbEmployee nos mesmos eventos. Para finalizar, no evento AfterPost de tbEmployee escreva o seguinte código:
tbEmployee.ApplyUpdates;
E ligue o evento AfterDelete a esse mesmo método. Clique aqui para fazer o download do exemplo. Qualquer dúvida ou sugestão comente.
Nem todas as fontes de dados estão contempladas pelo SQLdb ou pelo ZeosLib. Algumas vezes é necessário migrar ou mesmo atualizar fontes de dados como Paradox, Access e outros. Para essa nobre tarefa o Lazarus disponibiliza o componente TODBCConnection, encontrado na aba SQLdb. Ou seja, podemos acessar qualquer banco de dados (mesmo aqueles que não merecem essa denominação) através de ODBC, desde que tenhamos o driver específico. Devo observar que fiz esse exemplo no Windows.
Então o primeiro passo é criar uma fonte de dados ODBC e isso é feito no sistema operacional. Usei uma fonte MSAccess - o dbdemos.mdb que vem com o Delphi. Após isso vamos ao Lazarus.
No Data Module coloque um TODBCConnection. Mude a propriedade Name para dbAccess, por exemplo. Em DatabaseName digite o nome da fonte de dados criada no sistema anteriormente. Mude Connected para True para testar a conexão. Depois volte para False.
Coloque um TSQLTransaction, mude Name para trAccess e em Database selecione dbAccess. Feito isso coloque um TSQLQuery e mude Name para queEmployee, em Database selecione dbAccess. Na propriedade SQL informe SELECT * FROM EMPLOYEE e em Transaction selecione trAccess. Se você mudar a propriedade Active de queEmployee para True, ela deveria abrir sem erro. No meu caso não funcionou e, depois de muito apanhar, mudei a propriedade UsePrimaryKeyAsKey de queEmployee para False e deu certo. Não sei explicar porque. Na propriedade InsertSQL digite:
INSERT INTO EMPLOYEE VALUES (:EMPNO, :LASTNAME, :FIRSTNAME, :PHONEEXT, :HIREDATE, :SALARY);
Em UpdateSQL:
UPDATE EMPLOYEE SET LASTNAME = :LASTNAME, FIRSTNAME = :FIRSTNAME, PHONEEXT = :PHONEEXT, HIREDATE = :HIREDATE, SALARY = :SALARY WHERE EMPNO = :EMPNO;
E em DeleteSQL:
DELETE FROM EMPLOYEE WHERE EMPNO = :EMPNO;
Agora coloque um TDataSource da aba Data Access. Defina Name como dsEmployee e DataSet como tbEmployee.
Crie uma interface. Se tiver dúvida de como fazer isso, dê uma olhada nos posts Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II.
Lembre de abrir e fechar a conexão do TODBCConnection. Pode fazer isso nos eventos OnShow e OnClose de form, usando os métodos Open e Close. Abra e feche tbEmployee nos mesmos eventos. Para finalizar, no evento AfterPost de tbEmployee escreva o seguinte código:
tbEmployee.ApplyUpdates;
E ligue o evento AfterDelete a esse mesmo método. Clique aqui para fazer o download do exemplo. Qualquer dúvida ou sugestão comente.
Posts Relacionados
terça-feira, 16 de março de 2010
Lazarus - Tratamento de Arquivos Texto
Em determinadas situações tratar arquivos textos é necessário. Arquivos nesse formato são usados com frequência para troca de dados entre sistemas. Mesmo com a força de XML, esse formato ainda tem seu espaço.
Em Lazarus existem componentes que possibilitam o tratamento desse tipo de fontes de dados. Na aba de componentes Data Access encontramos o TSdfDataSet e o TFixedFormatDataSet. A seguir vamos abordar cada um deles e mostrar exemplos.
TSdfDataSet
Este componente permite tratar um arquivo texto que usa um delimitador entre os campos, como um arquivo csv. O arquivo já deve existir para ser utilizado. Pode ser criado facilmente usando um editor comum. Crie um arquivo e digite uma linha com três campos separados por vírgula, por exemplo:
1,JOÃO DA SILVA,joao@meuemail.com.br
Chame o arquivo de cliente.txt. Ele terá três campos: ID, NOME e EMAIL.
Crie uma nova aplicação no Lazarus. Vamos fazer tudo no próprio form, mas mantenha o hábito de colocar seus componentes de banco de dados em um Data Module, como costumamos fazer nos artigos anteriores.
Localize a aba Data Access e coloque um TSdfDataSet. Altere a propriedade Name para tbContato e, em FileName informe o nome do arquivo criado acima com o caminho completo. Na propriedade Delimiter é possível especificar um delimitador, que por padrão é (,).
Da mesma aba selecione um TDataSource e coloque no form. Altere Name para dsContato e selecione tbContato na propriedade DataSet.
Coloque três TDBEdits no form e identifique-os apropriadamente com TLabels. Defina a propriedade DataSource de cada um deles com dsContato. Defina DataField como Field1, Field2 e Field3, respectivamente. Deve ocorrer um erro em cada atribuição mas não se preocupe com isso. Se preferir, pode mudar a propriedade Active de tbContato para True e os nomes dos campos - Field1, Field2 e Field3 - devem aparecer automaticamente. Se ocorrer um erro ou os nomes dos campos não aparecerem verifique se o nome do arquivo está corretamente definido. Agora coloque um TDBNavigator da aba Data Controls e defina a propriedade DataSource como dsContato.
Agora vamos escrever o código para abrir e fechar a tabela. Faça como antes já fizemos. No evento OnShow do form escreva:
tbContato.Open;
E no evento OnClose, escreva:
tbContato.Close;
Execute o programa. Ele deve funcionar normalmente. Permite inserir, excluir, alterar e navegar nos registros.
TFixedFormatDataSet
Este componente é usado para manipular arquivos de texto onde cada campo tem um tamanho fixo. Quando o valor do campo não preenche totalmente o tamanho dele, o restante é completado com espaços. Assim como no componente anteior, neste também é necessário criar o arquivo antes. Simplesmente vamos criar um novo arquivo texto vazio. Fica definido que o campo Id terá 5 caracteres, Nome e Email terão 30 caracteres, cada um. Diferente de TSdfDataSet, a programação de exige um pouco de código, como veremos mais a frente.
Crie uma nova aplicação no Lazarus. Coloque um TFixedFormatDataSet no form e defina a propriedade Name como tbContato e na propriedade FileName informe o nome do arquivo texto criado com o caminho completo.
Coloque também um TDataSource. Mude Name para dsContato e selecione tbContato em DataSet.
Bem, este componente precisa de algum código para funcionar. Ele só reconhece um campo - Line. Line representa uma linha do arquivo. Então coloque três TEdits e mude as propriedades Names para edId, edNome e edEmail, respectivamente. Coloque três TLabels para identificar esses campos. Coloque um TDBNavigator e defina a propriedade DataSource como dsContato.
Localize o evento AfterScroll de tbContato e escreva o seguinte código para ele:
edId.Text := copy(tbContato.FieldByName('Line').Value, 1, 5);
edNome.Text := copy(tbContato.FieldByName('Line').Value, 6, 30);
edEmail.Text := copy(tbContato.FieldByName('Line').Value, 36, 30);
Com isso, a cada vez que navegamos em um registro, este código extrai cada parte e a atribui ao TEdit correspondente. No evento BeforePost de tbContato escreva:
tbContato.FieldByName('Line').Value := Espacos(edId.Text,5) + Espacos(edNome.Text,30) + Espacos(edEmail.Text,30);
A função Espacos() preenche cada campo com espaços até completar o tamanho do campo:
function TfrmTexto.Espacos(s: string; t: integer): string;
var
i: integer;
begin
result := s;
for i := length(s) + 1 to t do
result := result + ' ';
end;
O cabeçalho dessa função deve ser declarado na seção type junto aos outros métodos da unit. Agora escreva o código para abrir a tabela em OnShow e para fechar em OnClose.
Pronto. Compile e execute o programa. Neste exemplo, a tabela não entra em modo de edição automaticamente quando alteramos algum campo nos TEdits. É necessário ativar o modo de edição pressionando o botão correspondente no TDBNavigator.
Em Lazarus existem componentes que possibilitam o tratamento desse tipo de fontes de dados. Na aba de componentes Data Access encontramos o TSdfDataSet e o TFixedFormatDataSet. A seguir vamos abordar cada um deles e mostrar exemplos.
TSdfDataSet
Este componente permite tratar um arquivo texto que usa um delimitador entre os campos, como um arquivo csv. O arquivo já deve existir para ser utilizado. Pode ser criado facilmente usando um editor comum. Crie um arquivo e digite uma linha com três campos separados por vírgula, por exemplo:
1,JOÃO DA SILVA,joao@meuemail.com.br
Chame o arquivo de cliente.txt. Ele terá três campos: ID, NOME e EMAIL.
Crie uma nova aplicação no Lazarus. Vamos fazer tudo no próprio form, mas mantenha o hábito de colocar seus componentes de banco de dados em um Data Module, como costumamos fazer nos artigos anteriores.
Localize a aba Data Access e coloque um TSdfDataSet. Altere a propriedade Name para tbContato e, em FileName informe o nome do arquivo criado acima com o caminho completo. Na propriedade Delimiter é possível especificar um delimitador, que por padrão é (,).
Da mesma aba selecione um TDataSource e coloque no form. Altere Name para dsContato e selecione tbContato na propriedade DataSet.
Coloque três TDBEdits no form e identifique-os apropriadamente com TLabels. Defina a propriedade DataSource de cada um deles com dsContato. Defina DataField como Field1, Field2 e Field3, respectivamente. Deve ocorrer um erro em cada atribuição mas não se preocupe com isso. Se preferir, pode mudar a propriedade Active de tbContato para True e os nomes dos campos - Field1, Field2 e Field3 - devem aparecer automaticamente. Se ocorrer um erro ou os nomes dos campos não aparecerem verifique se o nome do arquivo está corretamente definido. Agora coloque um TDBNavigator da aba Data Controls e defina a propriedade DataSource como dsContato.
Agora vamos escrever o código para abrir e fechar a tabela. Faça como antes já fizemos. No evento OnShow do form escreva:
tbContato.Open;
E no evento OnClose, escreva:
tbContato.Close;
Execute o programa. Ele deve funcionar normalmente. Permite inserir, excluir, alterar e navegar nos registros.
TFixedFormatDataSet
Este componente é usado para manipular arquivos de texto onde cada campo tem um tamanho fixo. Quando o valor do campo não preenche totalmente o tamanho dele, o restante é completado com espaços. Assim como no componente anteior, neste também é necessário criar o arquivo antes. Simplesmente vamos criar um novo arquivo texto vazio. Fica definido que o campo Id terá 5 caracteres, Nome e Email terão 30 caracteres, cada um. Diferente de TSdfDataSet, a programação de exige um pouco de código, como veremos mais a frente.
Crie uma nova aplicação no Lazarus. Coloque um TFixedFormatDataSet no form e defina a propriedade Name como tbContato e na propriedade FileName informe o nome do arquivo texto criado com o caminho completo.
Coloque também um TDataSource. Mude Name para dsContato e selecione tbContato em DataSet.
Bem, este componente precisa de algum código para funcionar. Ele só reconhece um campo - Line. Line representa uma linha do arquivo. Então coloque três TEdits e mude as propriedades Names para edId, edNome e edEmail, respectivamente. Coloque três TLabels para identificar esses campos. Coloque um TDBNavigator e defina a propriedade DataSource como dsContato.
Localize o evento AfterScroll de tbContato e escreva o seguinte código para ele:
edId.Text := copy(tbContato.FieldByName('Line').Value, 1, 5);
edNome.Text := copy(tbContato.FieldByName('Line').Value, 6, 30);
edEmail.Text := copy(tbContato.FieldByName('Line').Value, 36, 30);
Com isso, a cada vez que navegamos em um registro, este código extrai cada parte e a atribui ao TEdit correspondente. No evento BeforePost de tbContato escreva:
tbContato.FieldByName('Line').Value := Espacos(edId.Text,5) + Espacos(edNome.Text,30) + Espacos(edEmail.Text,30);
A função Espacos() preenche cada campo com espaços até completar o tamanho do campo:
function TfrmTexto.Espacos(s: string; t: integer): string;
var
i: integer;
begin
result := s;
for i := length(s) + 1 to t do
result := result + ' ';
end;
O cabeçalho dessa função deve ser declarado na seção type junto aos outros métodos da unit. Agora escreva o código para abrir a tabela em OnShow e para fechar em OnClose.
Pronto. Compile e execute o programa. Neste exemplo, a tabela não entra em modo de edição automaticamente quando alteramos algum campo nos TEdits. É necessário ativar o modo de edição pressionando o botão correspondente no TDBNavigator.
Marcadores:
arquivos texto,
TFixedFormatDataSet,
TSdfDataSet
Posts Relacionados
domingo, 14 de março de 2010
Pausa para uma xícara de café
Em Java usamos a classe Scanner para separar uma fonte de dados em partes delimitadas por um delimitador específico. Quem é responsável pela entrada de dados é System.in e não Scanner. Por exemplo, vamos observar esse trecho de código:
Scanner sc = new Scanner(System.in); // declara um objeto
// Scanner
String nome;
String endereco;
System.out.println("Digite o nome:");
nome = sc.next(); // lê nome do teclado
System.out.println("Digite o endereço:");
endereco = sc.next(); // lê endereço do teclado
System.out.println(nome + ", " + endereco);
Se você, quando for pedido o nome, entrar por exemplo: "Joao da Silva", vai observar que nome irá receber "Joao" e endereco, "da". O programa nem irá solicitar a digitação do endereço. Isso acontece porque o delimitador padrão da classe Scanner é o espaço. Scanner é um tokenizador, ou seja, divide uma string em pedaços, e quem delimita esses pedaços, por padrão, é o espaço. Dessa forma quando digitamos "Joao da Silva", Scanner o divide em três pedaços. O primeiro ("João") é atribuido a nome, o segundo ("da") é atribuido a endereço e o terceiro fica perdido. Então, como solucionar isso? A boa notícia é que Scanner tem um método que permite alterar o delimitador. Inclua a seguinte linha após a declaração do objeto Scanner:
System.getProperty("line.separator") retorna o separador de linhas definido no sistema e passa para o método useDelimiter(), que o define como um novo delimitador para Scanner. Normalmente o separador de linhas é o "\n". No Windows é "\r\n". Dessa forma quando for solicitado o nome, tudo que for digitado até o "\n", será considerado parte da variável nome. Podemos definir qualquer string como delimitador ou mesmo uma expressão regular (regex). Scanner pode tokenizar quaisquer strings, não apenas o que é lido do teclado.
Scanner sc = new Scanner(System.in); // declara um objeto
// Scanner
String nome;
String endereco;
System.out.println("Digite o nome:");
nome = sc.next(); // lê nome do teclado
System.out.println("Digite o endereço:");
endereco = sc.next(); // lê endereço do teclado
System.out.println(nome + ", " + endereco);
Se você, quando for pedido o nome, entrar por exemplo: "Joao da Silva", vai observar que nome irá receber "Joao" e endereco, "da". O programa nem irá solicitar a digitação do endereço. Isso acontece porque o delimitador padrão da classe Scanner é o espaço. Scanner é um tokenizador, ou seja, divide uma string em pedaços, e quem delimita esses pedaços, por padrão, é o espaço. Dessa forma quando digitamos "Joao da Silva", Scanner o divide em três pedaços. O primeiro ("João") é atribuido a nome, o segundo ("da") é atribuido a endereço e o terceiro fica perdido. Então, como solucionar isso? A boa notícia é que Scanner tem um método que permite alterar o delimitador. Inclua a seguinte linha após a declaração do objeto Scanner:
sc.useDelimiter(System.getProperty("line.separator"));
System.getProperty("line.separator") retorna o separador de linhas definido no sistema e passa para o método useDelimiter(), que o define como um novo delimitador para Scanner. Normalmente o separador de linhas é o "\n". No Windows é "\r\n". Dessa forma quando for solicitado o nome, tudo que for digitado até o "\n", será considerado parte da variável nome. Podemos definir qualquer string como delimitador ou mesmo uma expressão regular (regex). Scanner pode tokenizar quaisquer strings, não apenas o que é lido do teclado.
Marcadores:
classe Scanner,
Java
Posts Relacionados
sábado, 13 de março de 2010
Lazarus - Conectando PostgreSQL com ZeosLib
Neste artigo mostraremos como criar uma aplicação simples usando o conjunto de componentes ZeosLib e o banco de dados PostgreSQL (PG). ZeosLib precisar ser baixado e instalado. Depois de extrair os arquivos, inicie o Lazarus. Selecione no menu Package -> Open package file (.lpk). Localize o diretório onde você extraiu o componente e selecione o pacote zcomponent.lpk em \packages\lazarus. Na janela que abrir clique em Compile. Aguarde finalizar e então clique em Install. Esse procedimento irá recompilar o Lazarus e depois ele será reinicializado. Confira que uma nova aba foi adicionada na paleta de componentes - Zeos Access.
Com relação ao banco de dados, você pode baixá-lo no site oficial. A instalação é muito simples, inclusive no Ubuntu. No Windows localize libpq.dll no diretório de instalação do PG e copie-a para o diretório System32 - procedimento necessário para o funcionamento do Zeos com PG.
Agora que está tudo instalado, no PG, crie um novo banco de dados - chame-o de clientes - e as tabelas necessárias para o nosso exemplo:
create table cidade (id_cidade integer primary key, nome varchar(30));
create table cliente (id_cliente integer primary key, nome varchar(40), endereco varchar(40), id_cidade integer references cidade(id_cidade), telefone varchar(14), tipo char(1), status boolean);
Vamos criar uma aplicação semelhante àquela que criamos nos posts em Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II. Como a interface é a mesma, vamos descrever apenas a criação do Data Module.
Inicie o Lazaus, crie uma nova aplicação e adicione um Data Module ao programa. Defina Name como dmDados. É no Data Module que tudo irá acontecer daqui em diante.
TZConnection
Esse componente é reponsável por criar uma conexão com o banco de dados e controlar as transações. Veremos que ele possui propriedades que permitem que seja configurado para se conectar a vários bancos de dados: PostgreSQL, Firebird, Oracle, SQLite e outros. Coloque um desses no Data Module. As seguintes propriedades merecem um melhor entendimento:
AutoCommit - determina de que forma as alterações são confirmadas no banco de dados. Se deixar em True as alterações são confirmadas implicitamente. Caso se deseje confirmar explicitamente devemos mudar para False. No nosso caso deixemos em True.
Connected - estabelece uma conexão com o banco. Durante o desenvolvimento, se for necessário, coloque em True. Mas lembre de voltar para False antes de finalizar o projeto.
Database - define o nome do banco de dados. Digite clientes. Se estiver usando o Firebird ou SQLite você deve informar o caminho completo do arquivo do banco de dados.
HostName - informa o nome ou IP do servidor de banco de dados. Se for a máquina local atribua o nome localhost.
Name - informe dbCliente.
Password - informar a senha do servidor de banco de dados. Informe a senha do usuário definida durante a instalação do PG.
Protocol - define qual o banco de dados que será conectado. Informe postgresql-8 ou o que for adequado ao banco usado.
TransactionIsolation - define o nível de isolamento da transação. No nosso caso vamos usar tiReadCommitted.
User - define o nome do usuário do banco de dados. Informe o usuário criado durante a instalação do PG.
Para fazer um teste da conexão, mude a propriedade Connected para True. Se estiver tudo certo não deve acontecer erro.
TZUpdateSQL
Especifica os comandos SQL de atualização - INSERT, UPDATE e DELETE. Atua em conjunto com um TZQuery. Inclua um componente desse no Data Module e defina suas propriedades assim:
DeleteSQL - DELETE FROM CIDADE WHERE ID_CIDADE = :OLD_ID_CIDADE;
InsertSQL - INSERT INTO CIDADE VALUES (:ID_CIDADE, :NOME);
ModifySQL - UPDATE CIDADE SET NOME = :NOME WHERE ID_CIDADE = :OLD_ID_CIDADE;
Para informar os comandos clique na propriedade correspondente do Inspetor de Objetos. Digite o comando no editor e tecle OK.
Name - defina como upCidade.
Qualquer identificador precedido por dois pontos (:) é um parâmetro que será definido quando o comando for executado. O prefixo OLD possibilita o acesso ao valor do campo antes dele ser modificado.
TZQuery
Query que deve ser usada para atualizar dados em tabelas. É usada em conjunto TZUpdateSQL para que execute as operações de INSERT, UPDATE ou DELETE. Para cada tabela do banco deveremos ter um desses componentes no Data Module. Inclua uma TZQuery no Data Module e vamos alterar suas propriedades:
Connection - especifica o objeto TZConnection. Selecione dbCliente.
Name - queCidade.
SQL - especifica um comando SELECT para mostrar os dados da tabela. Informe: SELECT * FROM CIDADE.
UpdateObject - define o objeto TZUpdateSQL que será usado em conjunto com TZQuery. Selecione upCidade.
Para finalizar o desenho do acesso à tabela Cidade, coloque um TDataSource da aba Data Access. Defina Name como dsCidade e DataSet como queCidade.
Com exceção de TZConnection - que deve ser apenas um - repita o processo para definir o acesso à tabela Cliente. O Data Module deverá ter esse aspecto:
Não é necessário incluir todo aquele código no evento AfterPost das TZQueries. Isso é feito automaticamente pois a propriedade AutoCommit de TZConnection está definida como True. A partir de agora o programa é exatamente igual ao que foi criado em Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II. Siga os mesmos passos desses posts. Bem, uma pequena modificação se faz necessária. Nos eventos OnShow e OnClose de frmPrincipal na aplicação anterior nós incluimos códigos para abrir e fechar a conexão. Diferente do SQLdb, no Zeos, o comando para abrir a conexão será:
e para encerrar:
Qualquer dúvida na criação dessa aplicação, podem me escrever ou deixar um comentário. Terei o maior prazer em ajudar.
Com relação ao banco de dados, você pode baixá-lo no site oficial. A instalação é muito simples, inclusive no Ubuntu. No Windows localize libpq.dll no diretório de instalação do PG e copie-a para o diretório System32 - procedimento necessário para o funcionamento do Zeos com PG.
Agora que está tudo instalado, no PG, crie um novo banco de dados - chame-o de clientes - e as tabelas necessárias para o nosso exemplo:
create table cidade (id_cidade integer primary key, nome varchar(30));
create table cliente (id_cliente integer primary key, nome varchar(40), endereco varchar(40), id_cidade integer references cidade(id_cidade), telefone varchar(14), tipo char(1), status boolean);
Vamos criar uma aplicação semelhante àquela que criamos nos posts em Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II. Como a interface é a mesma, vamos descrever apenas a criação do Data Module.
Inicie o Lazaus, crie uma nova aplicação e adicione um Data Module ao programa. Defina Name como dmDados. É no Data Module que tudo irá acontecer daqui em diante.
TZConnection
Esse componente é reponsável por criar uma conexão com o banco de dados e controlar as transações. Veremos que ele possui propriedades que permitem que seja configurado para se conectar a vários bancos de dados: PostgreSQL, Firebird, Oracle, SQLite e outros. Coloque um desses no Data Module. As seguintes propriedades merecem um melhor entendimento:
AutoCommit - determina de que forma as alterações são confirmadas no banco de dados. Se deixar em True as alterações são confirmadas implicitamente. Caso se deseje confirmar explicitamente devemos mudar para False. No nosso caso deixemos em True.
Connected - estabelece uma conexão com o banco. Durante o desenvolvimento, se for necessário, coloque em True. Mas lembre de voltar para False antes de finalizar o projeto.
Database - define o nome do banco de dados. Digite clientes. Se estiver usando o Firebird ou SQLite você deve informar o caminho completo do arquivo do banco de dados.
HostName - informa o nome ou IP do servidor de banco de dados. Se for a máquina local atribua o nome localhost.
Name - informe dbCliente.
Password - informar a senha do servidor de banco de dados. Informe a senha do usuário definida durante a instalação do PG.
Protocol - define qual o banco de dados que será conectado. Informe postgresql-8 ou o que for adequado ao banco usado.
TransactionIsolation - define o nível de isolamento da transação. No nosso caso vamos usar tiReadCommitted.
User - define o nome do usuário do banco de dados. Informe o usuário criado durante a instalação do PG.
Para fazer um teste da conexão, mude a propriedade Connected para True. Se estiver tudo certo não deve acontecer erro.
TZUpdateSQL
Especifica os comandos SQL de atualização - INSERT, UPDATE e DELETE. Atua em conjunto com um TZQuery. Inclua um componente desse no Data Module e defina suas propriedades assim:
DeleteSQL - DELETE FROM CIDADE WHERE ID_CIDADE = :OLD_ID_CIDADE;
InsertSQL - INSERT INTO CIDADE VALUES (:ID_CIDADE, :NOME);
ModifySQL - UPDATE CIDADE SET NOME = :NOME WHERE ID_CIDADE = :OLD_ID_CIDADE;
Para informar os comandos clique na propriedade correspondente do Inspetor de Objetos. Digite o comando no editor e tecle OK.
Name - defina como upCidade.
Qualquer identificador precedido por dois pontos (:) é um parâmetro que será definido quando o comando for executado. O prefixo OLD possibilita o acesso ao valor do campo antes dele ser modificado.
TZQuery
Query que deve ser usada para atualizar dados em tabelas. É usada em conjunto TZUpdateSQL para que execute as operações de INSERT, UPDATE ou DELETE. Para cada tabela do banco deveremos ter um desses componentes no Data Module. Inclua uma TZQuery no Data Module e vamos alterar suas propriedades:
Connection - especifica o objeto TZConnection. Selecione dbCliente.
Name - queCidade.
SQL - especifica um comando SELECT para mostrar os dados da tabela. Informe: SELECT * FROM CIDADE.
UpdateObject - define o objeto TZUpdateSQL que será usado em conjunto com TZQuery. Selecione upCidade.
Para finalizar o desenho do acesso à tabela Cidade, coloque um TDataSource da aba Data Access. Defina Name como dsCidade e DataSet como queCidade.
Com exceção de TZConnection - que deve ser apenas um - repita o processo para definir o acesso à tabela Cliente. O Data Module deverá ter esse aspecto:
Não é necessário incluir todo aquele código no evento AfterPost das TZQueries. Isso é feito automaticamente pois a propriedade AutoCommit de TZConnection está definida como True. A partir de agora o programa é exatamente igual ao que foi criado em Lazarus - Acessando banco de dados com SQLdb - Parte I e Parte II. Siga os mesmos passos desses posts. Bem, uma pequena modificação se faz necessária. Nos eventos OnShow e OnClose de frmPrincipal na aplicação anterior nós incluimos códigos para abrir e fechar a conexão. Diferente do SQLdb, no Zeos, o comando para abrir a conexão será:
dmDados.dbCliente.Connect;
e para encerrar:
dmDados.dbCliente.Disconnect;
Qualquer dúvida na criação dessa aplicação, podem me escrever ou deixar um comentário. Terei o maior prazer em ajudar.
Marcadores:
PostgreSQL,
ZeosLib
Posts Relacionados
sexta-feira, 5 de março de 2010
Lazarus - Criando uma aplicação para WinCE
Preparando o ambiente
Para criar aplicações que executem em dispositivos móveis com SO Windows Mobile ou WinCE é necessário instalar o cross-arm-wince, que tem apenas versão para Win32. Se já existir o Lazarus instalado, baixe e instale o Lazarus-0.9.28.2-fpc-2.2.4-cross-arm-wince-win32.exe no mesmo diretório do Lazarus.
A partir de agora sua instalação continuará compilando para o ambiente Windows, mas terá a opção de compilar para o WinCE. Sempre que você iniciar um projeto WinCE é necessário fazer algumas configurações em Project -> Compiler options. Na aba Paths selecione wince em LCL Widget Type (various). Na aba Code escolha WinCE em Target OS (-T) e arm em Target CPU family (-P). Pronto. O compilador irá gerar um executável que executa apenas no PDA. Dessa forma para compilar use sempre CTRL + F9.
Banco de dados
A opção pelo SQLite é quase forçada. Só precisamos de uma dll e tudo funciona. Bem de acordo com as limitações impostas pelos PDAs. Prefiro sempre baixar alguma coisa já pronta, compilar os fontes gera um certo incômodo. Se você prefere compilar pode baixar os fontes aqui. Mas pode obter algo pronto aqui, inclusive com um visualizador de tabelas para WinCE. A dll deverá ser instalada na mesma pasta do PDA onde estará o banco de dados SQLite e o executável.
Escolha dos componentes
Essa foi a parte mais difícil. Muitas opções mas não tive muito sucesso. Para banco de dados tive problemas com SQLdb e Zeos. Com SQLdb não reconhecia o banco no PDA. Com Zeos deram alguns erros durante a compilação. Então optei por usar o TSQLite3Dataset da unit sqlite3ds. Mesmo existindo um pacote com o componente eu usei código FreePascal direto.
Para a interface existe o pacote KOL-CE. No entanto nos meus testes eu não consegui integrar esses componentes com banco de dados. Vou continuar tentando e apresento o resultado mais tarde.
Assim, usei os próprios componentes nativos do Lazarus. A grande dificuldade é adequar a interface ao modelo de PDA onde a aplicação irá executar. Fiz testes em um HP iPAQ com Windows Mobile 5.0.
Criação da interface
Crie uma nova aplicação no Lazarus. Altere a propriedade Name do form para frmCidade, Caption para Cidades. Salve tudo. Para a unit dê o nome u_cidade e para o projeto digite Cidade. Faça as alterações em Project -> Compiler options conforme falamos anteriormente.
Desenhe o form de acordo com a figura abaixo: coloque dois TEdits, dois TLabels, cinco TButtons da aba Standard, e um TStringGrid da aba Additional.
Note que não estamos usando controles da aba Data Controls. Defina as propriedades dos componentes - da esquerda para a direita e de cima para baixo - da seguinte forma:
TLabel - Caption defina como ID.
TLabel - Caption defina como Nome.
TEdit - Name defina com edId e apague o conteúdo de Text.
TEdit - Name defina com edNome e apague o conteúdo de Text.
TButton - Caption defina como Inserir e Name defina como btnInserir.
TButton - Caption defina como Excluir e Name defina como btnExcluir.
TButton - Caption defina como Alterar e Name defina como btnAlterar.
TButton - Caption defina como Consultar e Name defina como btnConsultar.
TButton - Caption defina como Sair e Name defina como btnSair.
TStringGrid - Name defina como grdDados e FixedCols como 0. Clique no botão à direita na propriedade Columns. Clique no botão Add para adicionar duas colunas. Selecione a primeira e expanda a propriedade Title. Digite ID na propriedade Caption. Faça o mesmo na segunda coluna e digite NOME na propriedade Caption. Feche a janela.
Você deve ajustar as dimensões do form de acordo com o PDA onde a aplicação será executada. O form do exemplo tem 243 x 300.
O código
Para nosso exemplo usarei o mesmo banco de dados criados nos post anteriores. Inicialmente as declarações de variáveis. Inclua sqlite3ds na cláusula uses:
No evento OnShow do form o objeto tbCidade é criado e inicializado com os dados do banco de dados e da tabela Cidade:
No evento OnSelectCell da TStringGrid definimos que a os dados na linha selecionada na StringGrid são copiados para os TEdits:
No evento OnClick de btnConsultar a tabela é consultada e seus dados mostrados na StringGrid:
No evento OnClick de btnAlterar o comando UPDATE é construído e executado:
sSql := 'update cidade set nome = ''%s'' where id_cidade = %d';
tbCidade.SQL := Format(sSql, [edNome.Text, StrToInt(edId.Text)]);
tbCidade.ExecSQL;
No evento OnClick de btnInserir fazemos o mesmo com o comando INSERT:
O comando DELETE é construído e executado no evento OnClick de btnExcluir:
Este programa é apenas um exemplo e muita coisa precisa ser feita para que ele funcione bem. Por exemplo, os botões btnAlterar e btnExcluir só podem ser habilitados se houver um ID a ser pesquisado, entre outras melhorias que devem ser implementadas.
Para criar aplicações que executem em dispositivos móveis com SO Windows Mobile ou WinCE é necessário instalar o cross-arm-wince, que tem apenas versão para Win32. Se já existir o Lazarus instalado, baixe e instale o Lazarus-0.9.28.2-fpc-2.2.4-cross-arm-wince-win32.exe no mesmo diretório do Lazarus.
A partir de agora sua instalação continuará compilando para o ambiente Windows, mas terá a opção de compilar para o WinCE. Sempre que você iniciar um projeto WinCE é necessário fazer algumas configurações em Project -> Compiler options. Na aba Paths selecione wince em LCL Widget Type (various). Na aba Code escolha WinCE em Target OS (-T) e arm em Target CPU family (-P). Pronto. O compilador irá gerar um executável que executa apenas no PDA. Dessa forma para compilar use sempre CTRL + F9.
Banco de dados
A opção pelo SQLite é quase forçada. Só precisamos de uma dll e tudo funciona. Bem de acordo com as limitações impostas pelos PDAs. Prefiro sempre baixar alguma coisa já pronta, compilar os fontes gera um certo incômodo. Se você prefere compilar pode baixar os fontes aqui. Mas pode obter algo pronto aqui, inclusive com um visualizador de tabelas para WinCE. A dll deverá ser instalada na mesma pasta do PDA onde estará o banco de dados SQLite e o executável.
Escolha dos componentes
Essa foi a parte mais difícil. Muitas opções mas não tive muito sucesso. Para banco de dados tive problemas com SQLdb e Zeos. Com SQLdb não reconhecia o banco no PDA. Com Zeos deram alguns erros durante a compilação. Então optei por usar o TSQLite3Dataset da unit sqlite3ds. Mesmo existindo um pacote com o componente eu usei código FreePascal direto.
Para a interface existe o pacote KOL-CE. No entanto nos meus testes eu não consegui integrar esses componentes com banco de dados. Vou continuar tentando e apresento o resultado mais tarde.
Assim, usei os próprios componentes nativos do Lazarus. A grande dificuldade é adequar a interface ao modelo de PDA onde a aplicação irá executar. Fiz testes em um HP iPAQ com Windows Mobile 5.0.
Criação da interface
Crie uma nova aplicação no Lazarus. Altere a propriedade Name do form para frmCidade, Caption para Cidades. Salve tudo. Para a unit dê o nome u_cidade e para o projeto digite Cidade. Faça as alterações em Project -> Compiler options conforme falamos anteriormente.
Desenhe o form de acordo com a figura abaixo: coloque dois TEdits, dois TLabels, cinco TButtons da aba Standard, e um TStringGrid da aba Additional.
Note que não estamos usando controles da aba Data Controls. Defina as propriedades dos componentes - da esquerda para a direita e de cima para baixo - da seguinte forma:
TLabel - Caption defina como ID.
TLabel - Caption defina como Nome.
TEdit - Name defina com edId e apague o conteúdo de Text.
TEdit - Name defina com edNome e apague o conteúdo de Text.
TButton - Caption defina como Inserir e Name defina como btnInserir.
TButton - Caption defina como Excluir e Name defina como btnExcluir.
TButton - Caption defina como Alterar e Name defina como btnAlterar.
TButton - Caption defina como Consultar e Name defina como btnConsultar.
TButton - Caption defina como Sair e Name defina como btnSair.
TStringGrid - Name defina como grdDados e FixedCols como 0. Clique no botão à direita na propriedade Columns. Clique no botão Add para adicionar duas colunas. Selecione a primeira e expanda a propriedade Title. Digite ID na propriedade Caption. Faça o mesmo na segunda coluna e digite NOME na propriedade Caption. Feche a janela.
Você deve ajustar as dimensões do form de acordo com o PDA onde a aplicação será executada. O form do exemplo tem 243 x 300.
O código
Para nosso exemplo usarei o mesmo banco de dados criados nos post anteriores. Inicialmente as declarações de variáveis. Inclua sqlite3ds na cláusula uses:
var
frmCidade: TfrmCidade;
tbCidade: TSQLite3Dataset;
sSql: string;
No evento OnShow do form o objeto tbCidade é criado e inicializado com os dados do banco de dados e da tabela Cidade:
tbCidade := TSqlite3Dataset.Create(nil);
tbCidade.FileName := 'clientes.db';
tbCidade.TableName := 'cidade';
tbCidade.PrimaryKey := 'Id_Cidade';
No evento OnSelectCell da TStringGrid definimos que a os dados na linha selecionada na StringGrid são copiados para os TEdits:
edId.Text := grdDados.Cells[0, aRow];
edNome.Text := grdDados.Cells[1, aRow];
No evento OnClick de btnConsultar a tabela é consultada e seus dados mostrados na StringGrid:
tbCidade.Close;
tbCidade.SQL := 'select * from cidade';
tbCidade.Open;
grdDados.Clear;
while not tbCidade.EOF do
begin
grdDados.Row := grdDados.RowCount - 1;
grdDados.RowCount := grdDados.RowCount + 1;
grdDados.Cells[0, grdDados.Row] := tbCidade.Fields[0].AsString;
grdDados.Cells[1, grdDados.Row] := tbCidade.Fields[1].AsString;
tbCidade.Next;
end;
tbCidade.Close;
No evento OnClick de btnAlterar o comando UPDATE é construído e executado:
sSql := 'update cidade set nome = ''%s'' where id_cidade = %d';
tbCidade.SQL := Format(sSql, [edNome.Text, StrToInt(edId.Text)]);
tbCidade.ExecSQL;
No evento OnClick de btnInserir fazemos o mesmo com o comando INSERT:
sSql := 'insert into cidade(id_cidade, nome) ' +
'values(%d, ''%s'')';
tbCidade.SQL := Format(sSql, [StrToInt(edId.Text), edNome.Text]);
tbCidade.ExecSql;
O comando DELETE é construído e executado no evento OnClick de btnExcluir:
if MessageDlg('Confirmação','Deseja excluir o registro?', mtConfirmation, [mbYes, mbNo],0) = mrYes then
begin
sSql := 'delete from cidade where id_cidade = %d';
tbCidade.SQL := Format(sSql, [StrToInt(edId.Text)]);
tbCidade.ExecSQL;
end;
Este programa é apenas um exemplo e muita coisa precisa ser feita para que ele funcione bem. Por exemplo, os botões btnAlterar e btnExcluir só podem ser habilitados se houver um ID a ser pesquisado, entre outras melhorias que devem ser implementadas.
Marcadores:
WinCE,
Windows Mobile
Posts Relacionados
quarta-feira, 24 de fevereiro de 2010
Lazarus - Acessando banco de dados com SQLdb - Parte II
Form de Cliente
No DataModule já deve ter uma TSQLQuery e um TDataSource devidamente configurados para acesso à tabela Cliente. Vamos então inserir um novo form no programa definindo Name como frmCliente, Caption como Clientes. Mande salvar e informe u_cliente no nome da unit. Acesse o editor de código referente a esse form e abaixo de Implementation, para permitir que a unit u_cliente tenha acesso aos objetos do DataModule, digite:
uses u_dmdados;
Volte ao form e inclua um TPanel da mesma forma que foi feito para o form de Cidade. Selecione um TDBNavigator da aba Data Controls e coloque sobre o painel. Defina a propriedade DataSource como dsCliente. Insira um TSpeedButton da aba Additional no painel e o configure semelhante ao que fizemos no form de Cidade, inclusive definindo o código do evento OnClick para fechar o form. O form de Cliente deverá ter essa aparência:
Coloque dois TDBedit no form, o primeiro deve ter Name definido como edIdCliente, DataSource como dsCliente e DataField como ID_CLIENTE. No segundo defina Name como edNome, DataSource como dsCliente e DataField como NOME. Coloque dois TLabel para identificar esse campos e defina os Caption de acordo com a figura anterior.
O componente TDBLookupComboBox é usado para que, no caso de uma chave estrangeira (ID_CIDADE na tabela Cliente), o usuário possa escolher o registro na tabela referenciada (Cidade). Neste componente os dados da tabela referenciada são mostrados em uma lista. Pegue então um componente desses na aba Data Controls e coloque no form abaixo do segundo TDBEdit. Defina Name como dblIdCidade, DataSource como dsCliente e DataField como ID_CIDADE. Para definir a lista primeiramente defina a propriedade ListSource como dsCidade, na propriedade ListField (campo que será visualizado na lista) defina NOME e KeyField (campo chave) defina como ID_CIDADE. Existe ainda a propriedade Sorted que define se a lista estará ordenada e Style que define o comportamento do controle. Deixe Sorted como True e Style como dsDropDownList (o usuário não poderá digitar no controle, apenas selecionar da lista). Coloque um TLabel para identificar este campo.
Coloque mais um TDBEdit abaixo do LookupComboBox. Defina Name como edTelefone, DataSource como dsCliente e DataField como TELEFONE. Coloque um TLabel para fazer a identificação do campo.
O campo TIPO da tabela Cliente é usado para informar se o cliente é pessoa física - representado pela letra F - ou pessoa jurídica - representado pela letra J. Para este controle vamos usar um TDBRadioGroup, que permite que sejam definidas opções para serem selecionadas. Pegue um componente desses e o coloque no form. Defina a propriedade Caption como Tipo e Name como rgTipo. DataSource será dsCliente e DataField será TIPO. Clique no botão da propriedade Items. Será aberta uma janela com o editor de strings. Digite Pessoa física na primeira linha e Pessoa jurídica na segunda e pressione OK. Na propriedade Columns digite 2 para que as opções apareçam em linha. Clique no botão da propriedade Values - onde estão os valores correspondentes às opções definidas em Items. Digite F na primeria linha e J na segunda. Desta forma quando for selecionada a opção Pessoa física será gravado F no banco de dados, e J caso contrário. Redimensione o componente adequadamente.
Finalmente coloque um TDBCheckBox no form. Defina Caption como Ativo e Name como chxStatus. DataSource é definido como dsCliente e em DataField digite STATUS. As propriedades ValueChecked e ValueUnchecked são usadas para definir o que será gravado no campo quando o componente estiver marcado ou não marcado. Como nosso campo no banco de dados é boolean, não é necessário alterar nada.
Para programar a abertura e o fechamento da Query faça de forma análoga ao que foi feito no form de Cidade. Escreva os códigos correspondentes nos eventos OnShow e OnClose de frmCliente.
Mude para o DataModule e selecione queCliente. Selecione a aba Eventos do Inspetor de objetos e dê um duplo clique ao lado do evento AfterPost. Digite o código como na figura:
Note que esse código é ligeiramente diferente do que fizemos para queCidade. Em vez de usarmos CommitRetaining, agora usamos Commit. Commit fecha todas as tabelas abertas, por isso a Query é aberta na linha 68. Na linha 63 guardamos as chave primária do registro atual na variável chave. E depois que a Query é aberta, usamos Locate para localizar o registro correspondente à variável chave. Esta é outra forma de fazer o COMMIT na transação.
Localize o evento AfterDelete da Query. Clique no botão da caixa à direita para selecionar um método existente. Selecione queClienteAfterPost para que a transação seja encerrada da mesma forma quando um registro for excluído.
Agora vamos ao form principal. Na linha uses abaixo de Implementation acrescente u_cliente para que ela fique assim:
Clique no menu Cadastros -> Clientes e no código do evento OnClick digite:
Execute o programa e chame o form de Cliente para fazer os testes.
Consultas
O próximo passo do desenvolvimento será criar as telas de consulta às tabelas Cidade e Cliente. Neste artigo mostraremos a criação da consulta de cidades. Supomos que a consulta de clientes é análoga e não haverá dificuldade em criá-la.
Para iniciar vamos ao DataModule inserir dois componentes necessários: um TSQLQuery e um TDataSource. Na Query mude Name para queConsCidade. Na propriedade Database selecione dbCliente. Certifique-se que a propriedade Transaction está corretamente definida como trGeral. No TDataSource mude Name para dsConsCidade e DataSet para queConsCidade.
Uma interface de consulta é necessária, portanto deve-se inserir um novo form. Defina Name como frmConsCidade e Caption como Consulta de cidades. Salve e digite u_conscidade no nome da unit.
A consulta irá oferecer duas opções de consulta - pela chave primária ou por parte do nome. Então insira um TRadioGroup da aba Standard. Defina Caption como Campo. Na propriedade Items inclua as linhas Código e Nome. Na propriedade Name digite rgCampo. Redimensione o componente adequadamente.
Observe a figura acima para orientar o seu desenho. Inclua um TEdit da aba Standard. Defina Name como edDado e delete o conteúdo da propriedade Text.
Coloque um TLabel para identificar o campo. Defina Caption como Dado a consultar.
Insira um TButton. Defina Name btnConsultar. Localize o componente TDBGrid na aba Data Controls. Insira um no form. Defina sua propriedade Name com dbgDados. Abra o editor de código e digite abaixo de Implementation:
Volte ao form e na propriedade DataSource da TDBGrid selecione dsConsCidade. Dê um duplo clique no botão btnConsultar e digite o código:
Execute o programa e faça testes de consulta. Falta validar edDado para que aceite apenas dígitos numéricos quando a consulta for direcionada para o campo chave. Deixamos essa tarefa e a criação da consulta de clientes como um exercício.
Baixe aqui o código completo do programa.
Algumas considerações
Durante a criação dessa pequena aplicação encontramos dificuldade em achar relatos de experiências usando os componentes SQLdb. Já utilizamos outros componentes tanto em Lazarus quando no Delphi e sentimos algumas dificuldades principalmente no que diz respeito ao controle de transações. SQLdb só permite um objeto SQLTransaction na aplicação. Isso torna-se um obstáculo quando é necessário abrir mais de um form simultaneamente, pois quando fechamos uma transação todas as tabelas são fechadas. Outra dificuldade refere-se ao ponteiro TBookmark. Antes de encerrar uma transação guardamos o ponteiro do registro atual. Após encerrar a transação, quando o método GotoBookmark() é chamado para posicionar o registro no ponteiro salvo anteriormente ocorre uma exceção. Vale observar que chamar o GotoBookmark() antes de encerrar a transação funciona normalmente. Por esses motivos nos próximos artigos usaremos os componentes ZeosLib.
No DataModule já deve ter uma TSQLQuery e um TDataSource devidamente configurados para acesso à tabela Cliente. Vamos então inserir um novo form no programa definindo Name como frmCliente, Caption como Clientes. Mande salvar e informe u_cliente no nome da unit. Acesse o editor de código referente a esse form e abaixo de Implementation, para permitir que a unit u_cliente tenha acesso aos objetos do DataModule, digite:
uses u_dmdados;
Volte ao form e inclua um TPanel da mesma forma que foi feito para o form de Cidade. Selecione um TDBNavigator da aba Data Controls e coloque sobre o painel. Defina a propriedade DataSource como dsCliente. Insira um TSpeedButton da aba Additional no painel e o configure semelhante ao que fizemos no form de Cidade, inclusive definindo o código do evento OnClick para fechar o form. O form de Cliente deverá ter essa aparência:
Coloque dois TDBedit no form, o primeiro deve ter Name definido como edIdCliente, DataSource como dsCliente e DataField como ID_CLIENTE. No segundo defina Name como edNome, DataSource como dsCliente e DataField como NOME. Coloque dois TLabel para identificar esse campos e defina os Caption de acordo com a figura anterior.
O componente TDBLookupComboBox é usado para que, no caso de uma chave estrangeira (ID_CIDADE na tabela Cliente), o usuário possa escolher o registro na tabela referenciada (Cidade). Neste componente os dados da tabela referenciada são mostrados em uma lista. Pegue então um componente desses na aba Data Controls e coloque no form abaixo do segundo TDBEdit. Defina Name como dblIdCidade, DataSource como dsCliente e DataField como ID_CIDADE. Para definir a lista primeiramente defina a propriedade ListSource como dsCidade, na propriedade ListField (campo que será visualizado na lista) defina NOME e KeyField (campo chave) defina como ID_CIDADE. Existe ainda a propriedade Sorted que define se a lista estará ordenada e Style que define o comportamento do controle. Deixe Sorted como True e Style como dsDropDownList (o usuário não poderá digitar no controle, apenas selecionar da lista). Coloque um TLabel para identificar este campo.
Coloque mais um TDBEdit abaixo do LookupComboBox. Defina Name como edTelefone, DataSource como dsCliente e DataField como TELEFONE. Coloque um TLabel para fazer a identificação do campo.
O campo TIPO da tabela Cliente é usado para informar se o cliente é pessoa física - representado pela letra F - ou pessoa jurídica - representado pela letra J. Para este controle vamos usar um TDBRadioGroup, que permite que sejam definidas opções para serem selecionadas. Pegue um componente desses e o coloque no form. Defina a propriedade Caption como Tipo e Name como rgTipo. DataSource será dsCliente e DataField será TIPO. Clique no botão da propriedade Items. Será aberta uma janela com o editor de strings. Digite Pessoa física na primeira linha e Pessoa jurídica na segunda e pressione OK. Na propriedade Columns digite 2 para que as opções apareçam em linha. Clique no botão da propriedade Values - onde estão os valores correspondentes às opções definidas em Items. Digite F na primeria linha e J na segunda. Desta forma quando for selecionada a opção Pessoa física será gravado F no banco de dados, e J caso contrário. Redimensione o componente adequadamente.
Finalmente coloque um TDBCheckBox no form. Defina Caption como Ativo e Name como chxStatus. DataSource é definido como dsCliente e em DataField digite STATUS. As propriedades ValueChecked e ValueUnchecked são usadas para definir o que será gravado no campo quando o componente estiver marcado ou não marcado. Como nosso campo no banco de dados é boolean, não é necessário alterar nada.
Para programar a abertura e o fechamento da Query faça de forma análoga ao que foi feito no form de Cidade. Escreva os códigos correspondentes nos eventos OnShow e OnClose de frmCliente.
Mude para o DataModule e selecione queCliente. Selecione a aba Eventos do Inspetor de objetos e dê um duplo clique ao lado do evento AfterPost. Digite o código como na figura:
Note que esse código é ligeiramente diferente do que fizemos para queCidade. Em vez de usarmos CommitRetaining, agora usamos Commit. Commit fecha todas as tabelas abertas, por isso a Query é aberta na linha 68. Na linha 63 guardamos as chave primária do registro atual na variável chave. E depois que a Query é aberta, usamos Locate para localizar o registro correspondente à variável chave. Esta é outra forma de fazer o COMMIT na transação.
Localize o evento AfterDelete da Query. Clique no botão da caixa à direita para selecionar um método existente. Selecione queClienteAfterPost para que a transação seja encerrada da mesma forma quando um registro for excluído.
Agora vamos ao form principal. Na linha uses abaixo de Implementation acrescente u_cliente para que ela fique assim:
uses u_cidade, u_cliente;
Clique no menu Cadastros -> Clientes e no código do evento OnClick digite:
frmCliente.Show;
Execute o programa e chame o form de Cliente para fazer os testes.
Consultas
O próximo passo do desenvolvimento será criar as telas de consulta às tabelas Cidade e Cliente. Neste artigo mostraremos a criação da consulta de cidades. Supomos que a consulta de clientes é análoga e não haverá dificuldade em criá-la.
Para iniciar vamos ao DataModule inserir dois componentes necessários: um TSQLQuery e um TDataSource. Na Query mude Name para queConsCidade. Na propriedade Database selecione dbCliente. Certifique-se que a propriedade Transaction está corretamente definida como trGeral. No TDataSource mude Name para dsConsCidade e DataSet para queConsCidade.
Uma interface de consulta é necessária, portanto deve-se inserir um novo form. Defina Name como frmConsCidade e Caption como Consulta de cidades. Salve e digite u_conscidade no nome da unit.
A consulta irá oferecer duas opções de consulta - pela chave primária ou por parte do nome. Então insira um TRadioGroup da aba Standard. Defina Caption como Campo. Na propriedade Items inclua as linhas Código e Nome. Na propriedade Name digite rgCampo. Redimensione o componente adequadamente.
Observe a figura acima para orientar o seu desenho. Inclua um TEdit da aba Standard. Defina Name como edDado e delete o conteúdo da propriedade Text.
Coloque um TLabel para identificar o campo. Defina Caption como Dado a consultar.
Insira um TButton. Defina Name btnConsultar. Localize o componente TDBGrid na aba Data Controls. Insira um no form. Defina sua propriedade Name com dbgDados. Abra o editor de código e digite abaixo de Implementation:
uses u_dmdados;
Volte ao form e na propriedade DataSource da TDBGrid selecione dsConsCidade. Dê um duplo clique no botão btnConsultar e digite o código:
Analisando o código:
linha 39 - define que propriedades e métodos sem referência a um objeto são considerados como sendo de queConsCidade.
linha 41 - fecha a Query.
linha 42 - limpa o conteúdo da propriedade SQL.
linha 43 - verifica que campo foi selecionado no RadioGroup.
linhas 45 e 46 - definem um comando SELECT para buscar linhas na tabela pela chave primária. pIdCidade é um parâmetro definido na linha 46.
linhas 50 e 51 - definem um comando SELECT para buscar linhas na tabela por parte do nome da cidade.
linha 53 - abre a Query.
Mude para o form principal. No editor de código inclua a unit u_conscidade na linha uses abaixo de Implementation. Clique na opção Consultas -> Cidades. Digite o código:
frmConsCidade.Show;
Execute o programa e faça testes de consulta. Falta validar edDado para que aceite apenas dígitos numéricos quando a consulta for direcionada para o campo chave. Deixamos essa tarefa e a criação da consulta de clientes como um exercício.
Baixe aqui o código completo do programa.
Algumas considerações
Durante a criação dessa pequena aplicação encontramos dificuldade em achar relatos de experiências usando os componentes SQLdb. Já utilizamos outros componentes tanto em Lazarus quando no Delphi e sentimos algumas dificuldades principalmente no que diz respeito ao controle de transações. SQLdb só permite um objeto SQLTransaction na aplicação. Isso torna-se um obstáculo quando é necessário abrir mais de um form simultaneamente, pois quando fechamos uma transação todas as tabelas são fechadas. Outra dificuldade refere-se ao ponteiro TBookmark. Antes de encerrar uma transação guardamos o ponteiro do registro atual. Após encerrar a transação, quando o método GotoBookmark() é chamado para posicionar o registro no ponteiro salvo anteriormente ocorre uma exceção. Vale observar que chamar o GotoBookmark() antes de encerrar a transação funciona normalmente. Por esses motivos nos próximos artigos usaremos os componentes ZeosLib.
Marcadores:
Data Module,
SQLdb,
SQLite
Posts Relacionados
terça-feira, 23 de fevereiro de 2010
Lazarus - Acessando banco de dados com SQLdb - Parte I
Para fazer nossa primeira aplicação usando banco de dados no Lazarus vamos usar o SQLite e o conjunto de componentes nativo SQLdb. Inicialmente vamos apresentar passo como essa aplicação foi criada. Essa foi a maneira que eu fiz, e eu agradeço sugestões e questionamentos que pessoas que já passaram por essa experiência. Depois irei fazer algumas considerações sobre o uso do SQLdb.
SQLite
SQLite é uma biblioteca que implementa um motor de banco de dados SQL. É livre para qualquer finalidade, seja uso particular ou comercial. Lê e escreve em um único arquivo que pode ter além de tabelas, índices, gatilhos e visões. Executa em várias plataformas e é indicado para aplicações embarcadas. Maiores detalhes podem ser encontrados no site oficial. Para usá-lo, baixe-o do site e faça a instalação adequada para o seu sistema operacional. No Windows isso é muito simples, apenas copie sqlite3.dll para o system32 da pasta do sistema operacional.
Existe uma ferramenta de linha de comando chamada sqlite3 que podemos usar para criar o banco de dados e as tabelas. Pode ser baixada no próprio site oficial do SQLite. Depois de instaladas a dll e a ferramenta de criação do banco execute-a digitando o seguinte comando no console do sistema operacional:
sqlite3 banco.db
Se o banco já existir ele será aberto para operações como criar/alterar tabelas e consultar/inserir/atualizar/deletar dados nas tabelas existentes. Depois disso digite os comandos SQL para a criação de duas tabelas necessárias para nossa aplicação:
create table cidade (id_cidade integer primary key, nome varchar(30));
create table cliente (id_cliente integer primary key, nome varchar(40), endereco varchar(40), id_cidade integer, telefone varchar(14), tipo char(1), status boolean);
Feito isso digite .quit para sair e voltemos ao nosso IDE.
SQLdb
Esse é o pacote para acessar bancos de dados no Lazarus. Você o encontra na aba SQLdb. Algumas informações estão em http://wiki.freepascal.org/SQLdb_Package. Com esse pacote podemos conectar ao PostgreSQL, Oracle, MySQL, Firebird, SQLite e ODBC. Para cada um desses existe um componente TXXXConnection. Para conectar ao Firebird, por exemplo, existe o componente TIBConnection. Para executar as operações sobre tabelas temos o TSQLQuery e o TSQLTransaction. A seguir iremos criar a aplicação e mostraremos como utilizar esses componentes.
A aplicação exemplo
Vamos então iniciar o Lazarus e criar uma nova aplicação. No primeiro form crie um menu com a seguinte estrutura. Se for necessário leia o artigo sobre criação de menus em http://professorcarlos.blogspot.com/2010/01/lazarus-criando-menus.html:
Arquivo
Sair
Cadastros
Cidade
Cliente
Consultas
Cidade
Cliente
Mude a propriedade Name desse form para frmPrincipal. Mande salvar tudo. Escolha u_principal para nome da unit e Clientes para nome do projeto.
É fortemente aconselhado que os componentes de conexão e acesso ao banco de dados estejam agrupados em um repositório denominado DataModule. Para criar um DataModule no Lazarus selecione o menu Arquivo -> Novo. Selecione Data Module abaixo do grupo Módulo e pressione o botão OK. Mude a propriedade Name para dmDados, mande salvar e dê o nome u_dmdados para esta unit.
Agora selecione a aba de componentes SQLdb e coloque um TSQLite3Connection no DataModule. Na propriedade DatabaseName informe o nome do arquivo do banco de dados com o caminho. Mude a propriedade Name para dbCliente. Neste momento podemos mudar a propriedade Connected para True. Se nenhum erro acontecer o componente de conexão está corretamente configurado. Volte a propriedade Connected para False. Coloque um componente TSQLTransaction no DataModule. Na propriedade Database selecione dbCliente e em Name digite trGeral. Retorne ao SQLite3Connection e selecione trGeral na propriedade Transaction. TSQLTransaction é o componente que controla as transações no banco de dados. Em um banco de dados as operações ocorrem no contexto de uma transação. Uma transação finaliza com sucesso através de um COMMIT e ROLLBACK desfaz as operações realizadas anteriormente.
Selecione um TSQLQuery e coloque no DataModule. Na propriedade Database selecione dbCliente. Na propriedade Name digite queCidade e em SQL informe select * from cidade. Na propriedade Transaction defina trGeral. Agora localize a aba Data Access. Selecione um componente TDataSource e coloque no DataModule. Defina Name como dsCidade e em DataSet selecione queCidade. Resumindo, fizemos a conexão com o banco de dados usando SQLite3Connection, em seguida definimos um componente para controlar as transações, definimos uma conexão com uma tabela do banco usando TSQLQuery, e criamos uma ligação entre a tabela e os componentes que terão a função de ler os campos dessa tabela usando TDataSource. Esse é um procedimento repetitivo para novas tabelas nessa aplicação e mesmo quando usarmos outros conjuntos de componentes. O DataModule terá essa aparência, já com os componentes para acesso à tabela Cliente.
Repita os mesmos passos para a tabela Cliente, inserindo mais um TSQLQuery e um TDataSource. Selecione o form principal e, no editor de código, digite abaixo de Implementation:
Localize o evento OnShow na aba Eventos do Inspetor de objetos. Dê um duplo clique à direita e digite:
Assim, sempre que o programa for iniciado a conexão com o banco de dados será aberta.
Form de Cidade
Insira um novo form na aplicação. Ele será desenhado para fazer as atualizações na tabela Cidade. Defina o Name do form como frmCidade e o Caption como Cidades. Salve a unit e defina seu nome como u_cidade. O desenho deste form deve ter a seguinte aparência.
Antes de começar a desenhar a janela, acesse o código da unit e insira o seguinte código abaixo de Implementation:
uses u_dmdados;
Isso permite que esta unit acesse os objetos do DataModule.
Pegue um componente TPanel na aba Standard e coloque no form. Defina a propriedade Align como alTop. Exclua o conteúdo de Caption. As propriedades BevelInner e BevelOuter são usadas para definir contornos para o painel. Deixe, por exemplo, como bvLowered e bvRaised respectivamente.
Agora selecione um TDBNavigator na aba Data Controls e o coloque no form sobre o painel. Na propriedade DataSource do navegador selecione dsCidade.
Dessa mesma aba selecione TDBEdit e coloque dois deles no form. No primeiro defina Name como edIdCidade, em DataSource selecione dsCidade e em DataField digite ID_CIDADE. Essa última atribuição irá provocar um erro, mas isso não vai interferir no resultado. No segundo TDBEdit defina Name como edNome, DataSource como dsCidade e em DataField digite NOME. Selecione TLabel na aba Standard e coloque um à esquerda de cada TDBEdit para identificá-los. Defina suas propriedades Caption como ID e Nome, respectivamente. Para finalizar o desenho coloque um TSpeedButton da aba Additional sobre o painel. Defina Name como btnSair e escolha um ícone apropriado para ele usando a propriedade Glyph. No evento OnClick deste botão digite:
É necessário programar a abertura e o fechamento da Query no form. A abertura será programada no evento OnShow e o fechamento será programado no evento OnClose, ambos de form. Com o form selecionado selecione da aba Eventos no Inspetor de Objetos. Localize o evento OnShow, dê um duplo clique na caixa à direita e digite o seguinte:
Faça o mesmo para o evento OnClose e digite:
Agora precisamos programar a chamada do form frmCidade a partir no form principal. Selecione o form principal, mude para o editor de código e digite abaixo de Implementation:
Volte para o form e clique no menu Cadastros -> Cidades. No editor de código digite:
Se você compilar e executar o programa verificará que não consegue ainda inserir dados na tabela Cidade. Todos os dados que são inseridos ficam em cache. É necessário enviar os dados para o banco e finalizar a transação.
Isso será feito no evento AfterPost da Query. Este evento ocorre após um registro ser gravado no banco. Selecione o DataModule e em seguida queCidade. Clique na aba Eventos do Inspetor de Objetos. Localize o evento AfterPost, dê um duplo clique à direita dele e digite o seguinte:
Vamos esclarecer o código:
linha 42 - declara um TBookMark, que é um ponteiro para um registro.
linha 45 - try, juntamente com except consiste em um tratamento de exceção. Se algo falhar no bloco try, o código em except é executado.
linha 46 - guarda o ponteiro do registro atual.
linha 47 - envia para o banco de dados o que estiver no cache.
linha 48 - verifica se existe uma transação ativa.
linha 50 - executa um COMMIT no banco, mas mantém a transação aberta.
linha 51 - desvia para o ponteiro salvo na linha 46.
linha 54 - executa um ROLLBACK se algo sair errado no bloco try.
Localize o evento AfterDelete da Query. Clique no botão da caixa à direita para selecionar um método existente. Selecione queCidadeAfterPost. Assim reaproveitamos o código que executa a mesma operação necessária no AfterDelete.
Compile e execute o programa. No post seguinte daremos seguimento ao desenvolvimento dessa aplicação.
SQLite
SQLite é uma biblioteca que implementa um motor de banco de dados SQL. É livre para qualquer finalidade, seja uso particular ou comercial. Lê e escreve em um único arquivo que pode ter além de tabelas, índices, gatilhos e visões. Executa em várias plataformas e é indicado para aplicações embarcadas. Maiores detalhes podem ser encontrados no site oficial. Para usá-lo, baixe-o do site e faça a instalação adequada para o seu sistema operacional. No Windows isso é muito simples, apenas copie sqlite3.dll para o system32 da pasta do sistema operacional.
Existe uma ferramenta de linha de comando chamada sqlite3 que podemos usar para criar o banco de dados e as tabelas. Pode ser baixada no próprio site oficial do SQLite. Depois de instaladas a dll e a ferramenta de criação do banco execute-a digitando o seguinte comando no console do sistema operacional:
sqlite3 banco.db
Se o banco já existir ele será aberto para operações como criar/alterar tabelas e consultar/inserir/atualizar/deletar dados nas tabelas existentes. Depois disso digite os comandos SQL para a criação de duas tabelas necessárias para nossa aplicação:
create table cidade (id_cidade integer primary key, nome varchar(30));
create table cliente (id_cliente integer primary key, nome varchar(40), endereco varchar(40), id_cidade integer, telefone varchar(14), tipo char(1), status boolean);
Feito isso digite .quit para sair e voltemos ao nosso IDE.
SQLdb
Esse é o pacote para acessar bancos de dados no Lazarus. Você o encontra na aba SQLdb. Algumas informações estão em http://wiki.freepascal.org/SQLdb_Package. Com esse pacote podemos conectar ao PostgreSQL, Oracle, MySQL, Firebird, SQLite e ODBC. Para cada um desses existe um componente TXXXConnection. Para conectar ao Firebird, por exemplo, existe o componente TIBConnection. Para executar as operações sobre tabelas temos o TSQLQuery e o TSQLTransaction. A seguir iremos criar a aplicação e mostraremos como utilizar esses componentes.
A aplicação exemplo
Vamos então iniciar o Lazarus e criar uma nova aplicação. No primeiro form crie um menu com a seguinte estrutura. Se for necessário leia o artigo sobre criação de menus em http://professorcarlos.blogspot.com/2010/01/lazarus-criando-menus.html:
Arquivo
Sair
Cadastros
Cidade
Cliente
Consultas
Cidade
Cliente
Mude a propriedade Name desse form para frmPrincipal. Mande salvar tudo. Escolha u_principal para nome da unit e Clientes para nome do projeto.
É fortemente aconselhado que os componentes de conexão e acesso ao banco de dados estejam agrupados em um repositório denominado DataModule. Para criar um DataModule no Lazarus selecione o menu Arquivo -> Novo. Selecione Data Module abaixo do grupo Módulo e pressione o botão OK. Mude a propriedade Name para dmDados, mande salvar e dê o nome u_dmdados para esta unit.
Agora selecione a aba de componentes SQLdb e coloque um TSQLite3Connection no DataModule. Na propriedade DatabaseName informe o nome do arquivo do banco de dados com o caminho. Mude a propriedade Name para dbCliente. Neste momento podemos mudar a propriedade Connected para True. Se nenhum erro acontecer o componente de conexão está corretamente configurado. Volte a propriedade Connected para False. Coloque um componente TSQLTransaction no DataModule. Na propriedade Database selecione dbCliente e em Name digite trGeral. Retorne ao SQLite3Connection e selecione trGeral na propriedade Transaction. TSQLTransaction é o componente que controla as transações no banco de dados. Em um banco de dados as operações ocorrem no contexto de uma transação. Uma transação finaliza com sucesso através de um COMMIT e ROLLBACK desfaz as operações realizadas anteriormente.
Selecione um TSQLQuery e coloque no DataModule. Na propriedade Database selecione dbCliente. Na propriedade Name digite queCidade e em SQL informe select * from cidade. Na propriedade Transaction defina trGeral. Agora localize a aba Data Access. Selecione um componente TDataSource e coloque no DataModule. Defina Name como dsCidade e em DataSet selecione queCidade. Resumindo, fizemos a conexão com o banco de dados usando SQLite3Connection, em seguida definimos um componente para controlar as transações, definimos uma conexão com uma tabela do banco usando TSQLQuery, e criamos uma ligação entre a tabela e os componentes que terão a função de ler os campos dessa tabela usando TDataSource. Esse é um procedimento repetitivo para novas tabelas nessa aplicação e mesmo quando usarmos outros conjuntos de componentes. O DataModule terá essa aparência, já com os componentes para acesso à tabela Cliente.
Repita os mesmos passos para a tabela Cliente, inserindo mais um TSQLQuery e um TDataSource. Selecione o form principal e, no editor de código, digite abaixo de Implementation:
uses u_dmdados;
Localize o evento OnShow na aba Eventos do Inspetor de objetos. Dê um duplo clique à direita e digite:
dmDados.dbCliente.Open;
Assim, sempre que o programa for iniciado a conexão com o banco de dados será aberta.
Form de Cidade
Insira um novo form na aplicação. Ele será desenhado para fazer as atualizações na tabela Cidade. Defina o Name do form como frmCidade e o Caption como Cidades. Salve a unit e defina seu nome como u_cidade. O desenho deste form deve ter a seguinte aparência.
Antes de começar a desenhar a janela, acesse o código da unit e insira o seguinte código abaixo de Implementation:
uses u_dmdados;
Isso permite que esta unit acesse os objetos do DataModule.
Pegue um componente TPanel na aba Standard e coloque no form. Defina a propriedade Align como alTop. Exclua o conteúdo de Caption. As propriedades BevelInner e BevelOuter são usadas para definir contornos para o painel. Deixe, por exemplo, como bvLowered e bvRaised respectivamente.
Agora selecione um TDBNavigator na aba Data Controls e o coloque no form sobre o painel. Na propriedade DataSource do navegador selecione dsCidade.
Dessa mesma aba selecione TDBEdit e coloque dois deles no form. No primeiro defina Name como edIdCidade, em DataSource selecione dsCidade e em DataField digite ID_CIDADE. Essa última atribuição irá provocar um erro, mas isso não vai interferir no resultado. No segundo TDBEdit defina Name como edNome, DataSource como dsCidade e em DataField digite NOME. Selecione TLabel na aba Standard e coloque um à esquerda de cada TDBEdit para identificá-los. Defina suas propriedades Caption como ID e Nome, respectivamente. Para finalizar o desenho coloque um TSpeedButton da aba Additional sobre o painel. Defina Name como btnSair e escolha um ícone apropriado para ele usando a propriedade Glyph. No evento OnClick deste botão digite:
Close;
É necessário programar a abertura e o fechamento da Query no form. A abertura será programada no evento OnShow e o fechamento será programado no evento OnClose, ambos de form. Com o form selecionado selecione da aba Eventos no Inspetor de Objetos. Localize o evento OnShow, dê um duplo clique na caixa à direita e digite o seguinte:
dmDados.queCidade.Open;
Faça o mesmo para o evento OnClose e digite:
dmDados.queCidade.Close;
Agora precisamos programar a chamada do form frmCidade a partir no form principal. Selecione o form principal, mude para o editor de código e digite abaixo de Implementation:
uses u_cidade;
Volte para o form e clique no menu Cadastros -> Cidades. No editor de código digite:
frmCidade.Show;
Se você compilar e executar o programa verificará que não consegue ainda inserir dados na tabela Cidade. Todos os dados que são inseridos ficam em cache. É necessário enviar os dados para o banco e finalizar a transação.
Isso será feito no evento AfterPost da Query. Este evento ocorre após um registro ser gravado no banco. Selecione o DataModule e em seguida queCidade. Clique na aba Eventos do Inspetor de Objetos. Localize o evento AfterPost, dê um duplo clique à direita dele e digite o seguinte:
Vamos esclarecer o código:
linha 42 - declara um TBookMark, que é um ponteiro para um registro.
linha 45 - try, juntamente com except consiste em um tratamento de exceção. Se algo falhar no bloco try, o código em except é executado.
linha 46 - guarda o ponteiro do registro atual.
linha 47 - envia para o banco de dados o que estiver no cache.
linha 48 - verifica se existe uma transação ativa.
linha 50 - executa um COMMIT no banco, mas mantém a transação aberta.
linha 51 - desvia para o ponteiro salvo na linha 46.
linha 54 - executa um ROLLBACK se algo sair errado no bloco try.
Localize o evento AfterDelete da Query. Clique no botão da caixa à direita para selecionar um método existente. Selecione queCidadeAfterPost. Assim reaproveitamos o código que executa a mesma operação necessária no AfterDelete.
Compile e execute o programa. No post seguinte daremos seguimento ao desenvolvimento dessa aplicação.
Marcadores:
Data Module,
SQLdb,
SQLite
Posts Relacionados
segunda-feira, 15 de fevereiro de 2010
Aventurando-se no Linux - VirtualBox
Sou um remanescente do bom e velho sistema operacional (SO) MS-DOS. Tudo era feito através de linha de comando semelhante ao que é feito no Linux, mas devo confessar que a cada vez que eu vejo os procedimentos para instalar um programa no Linux eu fico cansado e desisto até de continuar lendo o tutorial. Eu uso o Windows, mesmo com todos os problemas, devido a facilidade com que eu consigo instalar um programa. É só clicar em Instalar, Próximo, Próximo ... e Finalizar. Para um sujeito preguiçoso como eu não tem coisa melhor.
Bem, o que eu queria mesmo era utilizar os recursos do Cross Compiler do Lazarus. Recurso muito interessante que permite que você gere um executável para Windows a partir de uma instalação Linux, por exemplo. Em tese é possível gerar para qualquer sistema estando em qualquer um outro. Gostaria de pode criar executáveis Linux estando no Windows, mas não encontrei informação clara que me ajudasse. Em http://wiki.freepascal.org/Cross_compiling/pt#De_Windows existe algo um pouco confuso, e não tentei nada seguindo essas informações. Decidi então encarar uma instalação Ubuntu e depois o Lazarus. Para poder continuar usando o Windows e alternar entre um e outro SO, eu optei por instalar um software de virtualização. Após alguma pesquisa me decidi pela VirtualBox da Sun, que hoje é Oracle. Distribuida sob licença GPL, roda em Windows, Linux, Macintosh e OpenSolaris. Depois de instalar o VirtualBox, criei uma máquina virtual (VM). Podemos criar mais de uma e instalar vários SOs num mesmo micro. Em seguida instalei o Ubuntu a partir de um CD. Não é necessário instalar nenhum driver, o que é um alívio. Quando você instala a VM, ela instala um cartão de rede virtual e seleciona o modo NAT (Network Address Translation). Dessa forma o sistema guest (Linux no meu caso) pode acessar a Internet através de uma conexão do sistema host (Windows no meu caso). Instalei o VirtualBox Guest Additions. Isso possibilita alguma melhoria em vídeo, pastas compartilhadas entre host e guest, etc. Bem, até agora não consegui compartilhar uma pasta entre os dois SOs. Vejam na figura abaixo a VM executando na área de trabalho do Windows.
Agora eu já tinha um Linux rodando e precisava instalar o Lazarus. Não foi difícil encontrar dicas de como fazer isso. Em http://sites.google.com/site/silvioprogbs/documentos tem algumas coisas interessantes. Até que não deu muito trabalho. E dá-lhe baixar pacotes e mais pacotes dos quais o Lazarus e o FreePascal dependem para rodar. Confesso que fiquei bem animado quando terminou tudo, executei o Lazarus e ele compilou e executou um programinha simples. Bem, dai eu fui para um teste mais rigoroso. Copiei o programa Editor que criei nos posts anteriores para dentro da VM, abri o Lazarus e o compilei. Executou sem problema. Vejam ai a tela do programa rodando na VM.
Este post não é um tutorial de como instalar uma VM, dada a sua simplicidade. É mais para compartilhar minha experiência. No entanto se alguém se interessar pelo assunto gostaria de trocar idéias. Preciso compartilhar uma pasta entre os dois SOs e ainda não consegui e, claro, explorar mais recursos disponíveis.
Bem, o que eu queria mesmo era utilizar os recursos do Cross Compiler do Lazarus. Recurso muito interessante que permite que você gere um executável para Windows a partir de uma instalação Linux, por exemplo. Em tese é possível gerar para qualquer sistema estando em qualquer um outro. Gostaria de pode criar executáveis Linux estando no Windows, mas não encontrei informação clara que me ajudasse. Em http://wiki.freepascal.org/Cross_compiling/pt#De_Windows existe algo um pouco confuso, e não tentei nada seguindo essas informações. Decidi então encarar uma instalação Ubuntu e depois o Lazarus. Para poder continuar usando o Windows e alternar entre um e outro SO, eu optei por instalar um software de virtualização. Após alguma pesquisa me decidi pela VirtualBox da Sun, que hoje é Oracle. Distribuida sob licença GPL, roda em Windows, Linux, Macintosh e OpenSolaris. Depois de instalar o VirtualBox, criei uma máquina virtual (VM). Podemos criar mais de uma e instalar vários SOs num mesmo micro. Em seguida instalei o Ubuntu a partir de um CD. Não é necessário instalar nenhum driver, o que é um alívio. Quando você instala a VM, ela instala um cartão de rede virtual e seleciona o modo NAT (Network Address Translation). Dessa forma o sistema guest (Linux no meu caso) pode acessar a Internet através de uma conexão do sistema host (Windows no meu caso). Instalei o VirtualBox Guest Additions. Isso possibilita alguma melhoria em vídeo, pastas compartilhadas entre host e guest, etc. Bem, até agora não consegui compartilhar uma pasta entre os dois SOs. Vejam na figura abaixo a VM executando na área de trabalho do Windows.
Agora eu já tinha um Linux rodando e precisava instalar o Lazarus. Não foi difícil encontrar dicas de como fazer isso. Em http://sites.google.com/site/silvioprogbs/documentos tem algumas coisas interessantes. Até que não deu muito trabalho. E dá-lhe baixar pacotes e mais pacotes dos quais o Lazarus e o FreePascal dependem para rodar. Confesso que fiquei bem animado quando terminou tudo, executei o Lazarus e ele compilou e executou um programinha simples. Bem, dai eu fui para um teste mais rigoroso. Copiei o programa Editor que criei nos posts anteriores para dentro da VM, abri o Lazarus e o compilei. Executou sem problema. Vejam ai a tela do programa rodando na VM.
Este post não é um tutorial de como instalar uma VM, dada a sua simplicidade. É mais para compartilhar minha experiência. No entanto se alguém se interessar pelo assunto gostaria de trocar idéias. Preciso compartilhar uma pasta entre os dois SOs e ainda não consegui e, claro, explorar mais recursos disponíveis.
Marcadores:
Linux,
VirtualBox,
virtualização
Posts Relacionados
Assinar:
Postagens (Atom)

































