quinta-feira, 21 de março de 2013

Objeto TStringManager

Objeto TStringManager


Olá a todos

Nas próximas semanas estarei postando no dicas4lazarus alguns objetos/classes desenvolvidos por mim.

São objetos simples, que eu escrevi para automatizar algumas tarefas realizadas diariamente.

No exemplo de hoje, veremos o TStringManager.

Descrição


O TStringManager é apenas um TStringlist com algumas funções especiais que eventualmente utilizamos para facilitar certas tarefas como adicionar conteudo a um arquivo ja existente, contar as palavras, e salvar no formato unix.

O método SaveToFileEx faz a mesma coisa que o SaveToFile. Porém, em alguns casos, o SaveFile do TStringList não salva no disco e não retorna erro, como no caso em que não tem permissão de escrita no disco. Usando o
SaveToFileEx, se não tiver permissão, retornará um erro.

Utilização


Para usar o TStringManager, basta adicionar ao seu form e utiliza-lo como se fosse um Itens de um TListBox

Métodos


GetWordList(str: String)

Retorna um TStringList com a lista de palavras passada no parametro str.  Use esse método em conjunto com a propriedade WordList.

SavetoFileEx(strfilename: String)

Identico ao Savetofile, porem retorna erro em caso de falhas.

AppendToFile(strfilename: String)

Salva o texto em um arquivo já existente, adicionando no final do arquivo informado em strfilename.

ConvertToUnix(SourceFile, TargetFile: String)

Função para converter um arquivo do formato windows para o linux.


Propriedades


WordList

Contem a lista de palavras criada pelo método GetWordList.

Items

Manipulador do TStringList.



Exemplo de uso:


var
Str1:TStringManager;
npalavras:Integer;
nlinhas:Integer;
begin
Str1:TStringManager.Create(self);

Str1.Items.Add('Exemplo simples de como utilizar o TStringManager');
Str1.Items.Add('Veremos como salvar o texto em um arquivo');
Str1.Items.Add('E tambem como adicionar o texto em um arquivo ja existente');
 Str1.Items.Add('Quantas palavras tem o texto? chame GetWordList(seu texto) ');


npalavras:=0;
for nlinhas:=0 to Str1.Items.count-1 do
Begin
     GetWordList(Str1.Items[nlinhas]);
     npalavras:=npalavras+ WordList.count;
end;

ShowMessage('O texto contem '+inttostr(npalavras)+' palavras');


//Salvando em um novo arquivo
Str1.SavetoFileEx('exemplo.txt');

Str1.Items.Add('Texto adicionado em arquivo ja existente');

//Salvando em um arquivo ja existente (append)
//No exemplo, irá adicionar o mesmo texto 3 vezes no arquivo exemplo.txt
Str1.AppendtoFile('exemplo.txt');
Str1.AppendtoFile('exemplo.txt');
Str1.AppendtoFile('exemplo.txt');


Str1.free;


end;


Segue abaixo o codigo fonte. Espero que seja util.

Até a próxima.



Codigo fonte


type
  TStringManager = class(TComponent)
  private
    Fwordlist: TStrings;
    FItems: TStrings;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure GetWordList(str: String);
    procedure SavetoFileEx(strfilename: String);
    procedure AppendToFile(strfilename: String);
    procedure setItems(Value: TStrings);
    procedure ConvertToUnix(SourceFile, TargetFile: String);

  protected
  published
    property WordList: TStrings Read FWordlist;
    property Items: TStrings Read FItems Write setItems;
  end;

constructor TStringManager.Create(AOwner: TComponent);
begin
  inherited;
  FWordList := TStringList.Create;
  FItems := TStringList.Create;
end;

destructor TStringManager.Destroy;
begin
  inherited;
end;

procedure TStringManager.getwordlist(str: string);
var
  Count: integer;
  i: integer;
  len: integer;
  s1: string;
begin
  s1 := '';
  FWordList.Clear;
  len := length(str);
  Count := 0;
  i := 1;
  while i <= len do
  begin
    while ((i <= len) and ((str[i] = #32) or (str[i] = #9) or (Str[i] = ';'))) do
      Inc(i);
    if i <= len then
      Inc(Count);
    while ((i <= len) and ((str[i] <> #32) and (str[i] <> #9) and (Str[i] <> ';'))) do
    begin
      s1 := s1 + str[i];
      Inc(i);
    end;
    if s1 <> '' then
      FWordList.Add(s1);
    s1 := '';
  end;

end;

procedure TStringManager.ConvertToUnix(SourceFile, TargetFile: string);
var
  SAIDA: TFileStream;
  Buffer: array[0..1] of char;
  Entrada: TFileStream;
  Lidos: integer;
begin
  Entrada := TFileStream.Create(SourceFile, fmOpenRead);
  SAIDA := TFileStream.Create(TargetFile, fmCreate);
  repeat
    Lidos := Entrada.Read(Buffer, 1);
    if Buffer[0] = ''#13'' then
      Continue;
    SAIDA.Write(Buffer, Lidos);
  until Lidos = 0;
  Entrada.Free;
  SAIDA.Free;
end;

procedure TStringManager.AppendToFile(strfilename: String);
var
  FTextFile: TextFile;
  x: integer;
begin
  try
  AssignFile(FTextFile, strfilename);
  Append(FTextFile);
  for x := 0 to FItems.Count - 1 do writeln(FTextFile, FItems[x]);
  except
  Showmessage('Problemas ao escrever em '+strfilename);
  end;
  CloseFile(FTextFile);

end;

procedure TStringManager.SavetoFileEx(strfilename: string);
var
  FTextFile: TextFile;
  x: integer;
begin
  try
  AssignFile(FTextFile, strfilename);
  rewrite(FTextFile);
  for x := 0 to FItems.Count - 1 do
    writeln(FTextFile, FItems[x]);
  except
  Showmessage('Problemas ao escrever em '+strfilename);
  end;
  CloseFile(FTextFile);
end;

procedure TStringManager.setItems(Value: TStrings);
begin
  if Items.Text <> Value.Text then
  begin
    Items.BeginUpdate;
    try
      Items.Assign(Value);
    finally
      Items.EndUpdate;
    end;
  end;

end;





quarta-feira, 13 de fevereiro de 2013

Advantage Database 11.1


Foi lançado em dezembro de 2012 a versão 11.1 do banco de dados Advantage Database, de propriedade da Sybase Inc.


Eu, particularmente ainda uso a versão 8.10. Não façam isso!

Eu trabalho com esse componente desde 2006, devido a capacidade dele funcionar no windows e no linux.


TAdsStringField

Essa nova versão vem com uma correção a muito tempo esperada por mim, e imagino que muitos outros.

Ao portar um projeto do delphi, quem utiliza esse banco de dados tinha que manualmente alterar o tipo de campo TAdsStringField para TStringField.


Conclusão

Convido a todos a testar esse componente, que é um dos poucos que tem a caracteristica de ser cliente/servidor e tambem funcionar no modo local.

Para baixar o componente, click aqui.

Postem seus comentários sobre esse componente.


Até a proxima.





terça-feira, 12 de fevereiro de 2013

Dicas for lazarus - O retorno

Depois de 2 anos sem postar devido a vários contratempos, estou de volta.

As coisas não são faceis quando se trabalha sozinho, o que é o meu caso.

Pesquisar, escrever, postar, responder comentários, pode parecer tarefa simples pra alguns, mas pra mim nem sempre é possivel.

Muita coisa mudou de lá pra cá.

O lazarus avançou bastante, e agora funciona até no android.

Apesar de estar na versão 1.06, eu ainda uso a versão 0.9.30.4, por questão de compatibilidade com alguns componentes.

Estarei testando a partir de hoje a versão mais recente, postando nesse espaço minhas duvidas e soluções.

Espero com isso, colaborar com a comunidade lazarus e ajudar a melhorar ainda mais esta ferramenta de programação.

Abração a todos.

domingo, 26 de dezembro de 2010

Illegal unit name Calendar

Na postagem anterior sobre esse problema, eu recomendei renomear a unit Calendar e alterar todos os fontes que a utilizava.

Fazendo alguns testes para Windows Mobile, deu o mesmo problema com uma versão mais recente do lazarus.

Desta vez, ao invés de renomear a unit, eu fiz o seguinte:

Na unit Calendar.pp, exclui as seguintes linhas:

{
@abstract(Calendar component)
@author(Shane Miller)
@created(05 Dev 2001)
}

A partir dai, resolveu o problema de illegal unit name, mas deu outro erro:
"Search CalendarPopup, but found Calendar"

A unit Calendar.pp fica na pasta lazarus\lcl\ e a unit CalendarPopup na pasta -lazarus\lcl\forms

Então, alterei o arquivo fpc.cfg, acrescentei os path abaixo, na seção searchpath for units

-FuC:\lazarus\lcl
-FuC:\lazarus\lcl\forms

A partir dai, compilou normalmente.

Até a proxima.

domingo, 5 de setembro de 2010

illegal unit name Calendar

O lazarus é uma ferramenta em constante evolução, e por isso as vezes ocorre uns erros muito estranhos, bugs que parecem impossivel de resolver ou remediar.

Ontem baixei o snapshot revisão 27259 fpc 2.4.0. A instalação ocorreu normalmente.

O problema foi quando tentava instalar o pacote sqlite3dataset e deu o erro de illegal unit name Calendar.

Nunca tinha visto esse tipo de erro, então mudei o nome para calendar minusculo, tambem não resolveu.

Depois de muito pesquisar no google, não encontrei a solução para o problema. As vezes deve ser até coisa simples, mas eu não consegui resolver de forma elegante.

A solução que eu encontrei foi renomear a unit Calendar para Calendar2 (calendar2.pp).

Claro que tive que alterar todas as ocorrencias de Calendar para calendar2, mas o mais importante é que deu certo!

Se alguem está passando por esse problema, não desista, tenha paciencia e altere o nome da unit.

Se alguem tiver a solução correta para esse problema, por favor poste aqui para nosso conhecimento.

Até a próxima.

terça-feira, 20 de julho de 2010

Simulando um keybd_event

Nos meus programas em Delphi, algumas vezes, se fez necessário simular o pressionamento de uma tecla num TEdit que ainda não recebeu o foco.

Por exemplo:

procedure TFormPegaProdutos.DBGrid1KeyPress(Sender: TObject;
var Key: Char);
begin

//Testa se pressionou um tecla valida
if not (key in ['0'..'9','/',#13,#27,'A'..'z']) Then key:=#0;
if key=#27 then close;

//Testa se pressionou um letra
if (key in ['A'..'Z']) or (key in ['a'..'z']) Then
begin
//Abre um painel para digitacao do nome do item a pesquisar
. PanelPesquisa.Top:=80;
. PanelPesquisa.Left:=160;
. PanelPesquisa.visible:=True;
. Palavra1.setfocus;
. if (key in ['a'..'z']) Then Key:=chr(trunc(ord(Key))-32);
. keybd_event(trunc(Ord(Key)),0,0,0);
end;
if key in ['0'..'9'] Then
begin
. PanelVenda.Top:=80;
. PanelVenda.Left:=60;
. PanelVenda.visible:=True;
. ValorUni.Text:=FormatCurr('#0.00',ProTEMPP_VIS.AsCurrency);
. QTD.setfocus;
. keybd_event(trunc(Ord(Key)),0,0,0);
end;

...ou seja, na lista de itens (dbgrid1) o usuario pode abrir um painel de pesquisa de um novo item sem sair da lista, e ainda pode registrar uma venda do item, sem sair da lista, o que é, diga-se de passagem, muito prático.

Mas no lazarus não temos disponivel o keybd_event, então como resolver esse problema?

Criei uma simples procedure:

procedure keybd_event_on(EditControl:TEdit; var key: char);
begin
EditControl.Text:=key+' ';
EditControl.setfocus;
EditControl.SelStart:=1;
EditControl.SelLength:=1;
end;

Pronto!

Agora, posso continuar portando meus programas pro lazarus :-)
Não é por causa de um keybd_event que o projeto vai parar!

procedure TFormPegaProdutos.DBGrid1KeyPress(Sender: TObject;
var Key: Char);
begin

//Testa se pressionou um tecla valida
if not (key in ['0'..'9','/',#13,#27,'A'..'z']) Then key:=#0;
if key=#27 then close;

//Testa se pressionou um letra
if (key in ['A'..'Z']) or (key in ['a'..'z']) Then
begin
//Abre um painel para digitacao do nome do item a pesquisar
. PanelPesquisa.Top:=80;
. PanelPesquisa.Left:=160;
. PanelPesquisa.visible:=True;
. Palavra1.setfocus;
. if (key in ['a'..'z']) Then Key:=chr(trunc(ord(Key))-32);
. keybd_event(trunc(Ord(Key)),0,0,0);
. keybd_event_on(Palavra1,Key);
end;
if key in ['0'..'9'] Then
begin
. PanelVenda.Top:=80;
. PanelVenda.Left:=60;
. PanelVenda.visible:=True;
. ValorUni.Text:=FormatCurr('#0.00',ProTEMPP_VIS.AsCurrency);
. QTD.setfocus;
.//keybd_event(trunc(Ord(Key)),0,0,0);
. keybd_event_on(QTD,Key);
end;

O lazarus não é 100% compativel com o Delphi, mas ao depararmos com problemas como esse, não podemos desistir, sempre tem uma saida.

Seja livre!
Use lazarus/freepascal.

segunda-feira, 19 de julho de 2010

GERAOBJCODE - Simples gerador de codigo OOP

Pra quem esta começando na programação OOP, e não dispõem de nenhuma ferramenta auxiliar para geração de codigos, venho aqui disponibilizar uma ferramenta de minha autoria.

É um programa simples, mas que tem sido muito util pra mim.

GERAOBJCODE





Muito simples de usar, basta informar o nome da classe ou objeto, colocar as variaveis da classe/objeto na caixa codigo fonte do objeto e clicar em gerar propriedades e metodos.


Imagine que será necessário criar propriedades e metodos para os items abaixo:
Nome da classe: TObjetoTeste

Itens que compoem a nossa classe:




Codigo gerado pelo nosso GERAOBJCODE:








Criticas, elogios, deixem a sua mensagem.

Link para download dos fontes:
GERAOBJCODE

Até a próxima.