sexta-feira, 14 de dezembro de 2007

0

Delphi Day onLine – Palestras disponíveis

No último dia 7 aconteceu o CodeGear Delphi Day em Português, um dia inteiro de palestras, onde foram abordados os seguintes temas:


  • As principais razões para migrar de Delphi 7 para RAD Studio 2007 (Andreano Lanusse)
  • Generics em RAD Studio 2007 (Manoel Edésio)
  • Utilizando dbExpress 4 Framework (Bruno Lichot)
  • Blackfish SQL sem limites para stored procedures e triggers em Delphi (Leonel Togniolli)
  • Desenvolvendo Aplicações WEB com ASP.NET, AJAX e RAD Studio 2007 (Andreano Lanusse )
  • Melhorando a qualidade de suas aplicações em Delphi (Ricardo Barbieri)
  • ECO IV e RAD Studio 2007 (Adilson Jr.)
Quem não teve oportunidade (assim como eu (-;) pode baixar as palestras no link http://dn.codegear.com/article/37460

Bom proveito a todos!

quinta-feira, 13 de dezembro de 2007

0

Exemplo para iniciantes

Pessoal, coloquei disponível para download um exemplo simples para inciante, onde abordei técnicas como Herança Visual, Actions, Pesquisa Incremental, etc.

Clique Aqui para fazer o Download


Não deixem de comentar o exemplo.

Abraço a todos.

sábado, 24 de novembro de 2007

2

Cobertura da Borland Conference Revolutions

Pessoal a cobertura completa do que aconteceu na Borcon 2007 pode ser vista no link http://info.borland.com.br/borcon07/cobertura_borcon.html, lá você pode baixar o material das palestras, visualizar a fotos além de depoimentos de quem participou. Boa leitura!

terça-feira, 20 de novembro de 2007

2

Função para retornar os dias úteis

Pessoal, a medida em que eu tiver tempo (-:, vou postar aqui funções que considero interessantes para o nosso dia-a-dia. A primeira que vou postar aqui é uma para contar os dias úteis em um intervalo de datas. Temos várias funções desse tipo na interne, mas eu achava os algoritimos muito complicados, então resolvi fazer a minha. Chegei a publicar ela no ActiveNews da ActiveDelphi, pra que não viu ai está.

function Dias_Uteis(DataI, DataF:TDateTime):Integer;
var
contador:Integer;
begin
if DataI > DataF then
begin
result := 0;
exit
end;
Contador := 0;
while (DataI <= DataF) do
begin
if ((DayOfWeek(DataI) <> 1) and (DayOfWeek(DataI) <> 7)) then
Inc(Contador);
DataI := DataI + 1

end;
result := Contador;
end;

São apenas dois argumentos, Data Inicial e Data Final, a idéia é fazer um looping enquanto a data inicial for menor que a data final, a partir dai vamos incrementando a data inicial e verificamos se é um sábado ou domingo com a função DayOfWeek, se não for, contamos 1 dia. Simples não?

Depois vamos melhorar essa função permitindo que ele suporte feriados. Até lá!

segunda-feira, 19 de novembro de 2007

0

Developer Conference (BorCon 2007) - Apresentações disponíveis para download

Para aqueles que estavam ansiosos, já está disponível para download, todo o material da Borcon. Como eu não perco tempo, já estou desfrutando de toda essa massa de conhecimento!.
Aproveitem! http://dn.codegear.com/br/article/37375

sexta-feira, 9 de novembro de 2007

1

StringOfChar, replicando caracteres.

Pessoal, essa é mais um funçãozinha muito interssante e muitos não conhecem. A sua utilidade é replicar um determinando caracter e sua sintaxe é muito simples, contendo apenas dois argumentos.

function StringOfChar(ch: AnsiChar; Count: Integer): AnsiString; overload;

  • ch - Caracter a ser replicado.
  • Count - Número de ocorrências

Exemplo:

procedure TForm1.Button1Click(Sender:TObject);
begin
ShowMessage(StringOfChar('*',20)+#13+'Atenção ocorreu um erro'+#13+StringOfChar('*',20));
end;

Abraços, e até a próxima!

quinta-feira, 8 de novembro de 2007

5

Polimorfismo não é bicho de sete cabeças!

É interessante como a POO em geral é um paradigma para muitos. Depois de muitos anos já se falando sobre o assunto, muitos ainda a tratam como um "TABÚ".
Normalmente, aqueles que "nasceram" na programação estruturada tem uma dificuldade maior para entender o conceito (ou filosofia, como alguns gostam de chamar).

Mas o fato é que não existe nenhum mistério, e posso garantir que os benefícios são muitos. E das possibilidades apresentadas pela POO, sem dúvida a que mais me fascina é o POLIMORFISMO.

A descrição mais usada para ele é a possibilidade que determinado objeto tem para assumir comportamentos diferentes dependendo da necessidade.

Eu vou exemplificar aqui os benefícios e ao mesmo tempo mostrar que não existe nenhum bicho de sete cabeças no polimorfismo.

Abra um novo projeto no delphi, salve com o nome de Polimorfismo.dpr, o form com o nome de uFrmMain.

Vamos incluir uma nova unit para criar a nossa classe. Para isso vá em File/New/Unit salve com o nome de uCalculadora e implemente a unit como a listagem abaixo:

unit uCalculadora;

interface

uses SysUtils;

type
TCalculadora = class
public

function Calcular (ValueA, ValueB:Real): Real; virtual; abstract;
end;

TMultiplicar = class(TCalculadora)
public
function Calcular (ValueA, ValueB:Real): Real; override;
end;

TSomar = class(TCalculadora)
public
function Calcular (ValueA, ValueB:Real): Real; override;
end;

TSubtrair = class(TCalculadora)
public
function Calcular (ValueA, ValueB:Real): Real; override;
end;

TDividir = class(TCalculadora)
public
function Calcular (ValueA, ValueB:Real): Real; override;
end;

implementation

{ TMultiplicar }

function TMultiplicar.Calcular(ValueA, ValueB: Real): Real;
begin
Result := ValueA * ValueB;
end;

{ TSomar }

function TSomar.Calcular(ValueA, ValueB: Real): Real;
begin
Result := ValueA + ValueB;
end;

{ TSubtrair }

function TSubtrair.Calcular(ValueA, ValueB: Real): Real;
begin
Result := ValueA - ValueB;
end;

{ TDividir }

function TDividir.Calcular(ValueA, ValueB: Real): Real;
begin
try
Result := ValueA / ValueB;
except on E: Exception do
begin
if Pos('BY ZERO', UpperCase(E.Message)) > 0 then
Raise Exception.Create('Não é permitido divisão por zero.');
end;
end;
end;

end.


Primeiro criamos uma classe com o nome de TCalculadora com um método chamado Calcular, observe a que definimos o método com o tipo virtual e com a diretiva abstract indicando que o método não será implementado na classe em que foi declarado.

Em seguida criamos 4 classes (TMultiplicar, TSomar, TSubtrair, TDividir) , todos elas descendem de TCalculadora e tem o método calcular (exatamente igual ao método da classe TCalculadora) com a diretiva override (sebrecarga) garantindo que o método tenha apenas a implementação da classe descendente sobrepondo a implementação da classe base.

Depois implementamos o método de cada classe conforme a operação. Agora vamos criar o exemplo de utilização dessas classes.

No FrmMain coloque os seguintes componentes: 3 Edits; 1 Button e um RadioGroup.
Adicione ao RadioGroup 3 itens (Somar, Multiplicar, Subtrair,Dividir), altere a propriedade ItemIndex para 0 (Zero).

Posicione os componentes conforme a figura abaixo:


Implemente o botão calcular conforme a listagem abaixo:

procedure TFrmMain.Button1Click(Sender: TObject);
var
Calculadora: TCalculadora;
begin
case RadioGroup1.ItemIndex of
0: Calculadora := TSomar.Create;
1: Calculadora := TMultiplicar.Create;
2: Calculadora := TSubtrair.Create;
3: Calculadora := TDividir.Create;
end;
Edit3.Text := FloatToStr(Calculadora.Calcular(StrToFloatDef(Edit1.text,0),StrToFloatDef(Edit2.text,0)));
end;


Criamos uma variável com o tipo da nossa classe base (TCalculadora) depois CRIAMOS com o tipo da classe descendente correspondente a operação que desejamos. Percebam que chamamos o método Calcula do nosso objeto sem nos preocupar com a implementação.

Download do exemplo


Como vocês podem ver não existem mistérios! não deixem de comentar esse post! até a próxima!




quarta-feira, 7 de novembro de 2007

6

ExtractStrings: Você conhece?

Pessoal, resolvi começar a postar aqui, funções do delphi que normalmente quebram muitos galhos, e, por desconhece-las, acabamos "rebolando" pra criar algo "parecido". E não pensem que não estou falando de mim! :)

Uma função muito interessante e que tem uma enorme utilidade é a função ExtracStrings. Essa função preenche uma lista (StringList), com substrings de uma string.

Imagine que você precise ler um arquivo CSV (separado por ponto-e-vírgula). Dai você pergunta: "Como vou separar as colunas?"; a primeira idéia é criar uma função para localizar (Pos) o primeiro ponto-e-vírgula e extrair o fragmento da string (Copy), e assim sucessivamente, atire a primeira pedra que nunca fez assim!

Pois é! Perdemos nosso precioso tempo reinventando a roda.

Veja a sintaxe da função ExtractString:

function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer;

  • Separator - É um array onde você pode definir vários separadores
  • WhiteSpace - É um Array onde você define os caracteres que devem ser Ignorados quando ocorrerem no inicio da String.
  • Content - É a String de onde se deseja extrais as substrings
A Função retorna o número de Substrings extraídas.

Veja um pequeno exemplo de utilização:

procedure TForm1.Button1Click(Sender: TObject);
const

SDados = 'Cristiano Martins Alves; 28 Anos; Casado; São Paulo; SP';
var
Lista: TStringList;
iRetorno:Integer;

begin

Lista := TStringList.Create;

try

iRetorno :=
ExtractStrings([';'],[' '],PChar(sDados),Lista);
if
iRetorno > 0 then
ShowMessage(Lista.Text);

finally

FreeAndNil(Lista);

end
;

end
;

Veja o resultado:













Repare que na nossa constante existe um espaço entre o nome e a idade, mas ele foi ignorado conforme definido no segundo parâmetro.


É isso ai pessoal! Não deixem de comentar o blog!

terça-feira, 6 de novembro de 2007

2

Controlar a exibição do ScrollBar do DBGrid

Muitas vezes ficamos incomodados com aquele ScrollBar que teima em aparecer mesmo que o DBGrid tenha apenas 1 ou 2 linhas.

Por causa desse incômodo que resolvi pesquisar até chegar a seguinte solução.

Coloque no evento onDrawColumnCell do seu DBGrid

procedure TForm2.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
if (TStringGrid(DBGrid1).RowCount-1) then
//Se tiver menos de 10 linha
ShowScrollBar(DBGrid1.Handle,SB_VERT,False);
//Remove barra Vertical
end;

É claro que você deve melhorar a lógica, como por exemplo achar o número de linhas (exibidos sem ScrollBar) dependo da altura do DBGrid.

Fonte: ActiveDelphi

sábado, 20 de outubro de 2007

6

Como retornar múltiplos resultados numa função?

Você já teve a necessidade de retornar múltiplos valores numa função? normalmente a primeira idéia é criar uma procedure com parâmetros passados por referência como abaixo:

procedure GetCalculo(const Valor1, Valor2:Double; var Soma, Media:Double);
begin
Soma := Valor1 + Valor2;
Media := Soma / 2;
end;

//Testando
procedure TForm1.Button1Click(Sender: TObject);
var
Soma, Media:Double;
begin
GetCalculo(100,50,Soma,Media);
ShowMessage('Soma: '+FloatToStr(Soma)+#13+'Media: '+FloatToStr(Media));
end;

Isso funciona perfeitamente, mas veja que precisei declarar as funções que vou receber. Agora imagina se fosse 10 valores no retorno! além da procedure ficar imensa você ainda teria que declarar as variáveis que seriam passadas como referência. Uma técnica mais elegante de fazer isso é criar um record e usar esse tipo na nossa função. Veja o exemplo acima alterado.

//definindo o tipo
type
TCalculo = record
Soma,
Media:Double;
end;

Form1 = Class(TForm)
...


implemetation

function
TForm1.GetCalculo(const Valor1, Valor2:Double):TCalculo;
begin
//Repare que o result agora pode receber vários resutados
Result.Soma := Valor1 + Valor2;
Result.Media :=
Result.Soma / 2;
end;

//Testando
procedure TForm1.Button1Click(Sender: TObject);
var
Calculo: TCalculo;
begin
Calculo := GetCalculo(100,50);
ShowMessage('Soma: '+FloatToStr(Calculo.Soma)+#13+'Media: '+FloatToStr(Calculo.Media));
end;

Com eu falei, não existe muita diferença nessa técnica com a passagem por parâmetros se considerarmos o número de parâmetros, mas com certeza numa função que retorna vários resultados, a segunda opção tornará o seu código muito mais legível e elegante. Até a próxima.


0

Função para validar CPF no SQL Server

/*
Cristiano Martins Alves
Para testar: SELECT DBO.CPF_VALIDO('16195473247')
*/
CREATE FUNCTION CPF_VALIDO(@CPF VARCHAR(11))
RETURNS CHAR(1)
AS
BEGIN
DECLARE @INDICE INT,
@SOMA INT,
@DIG1 INT,
@DIG2 INT,
@CPF_TEMP VARCHAR(11),
@DIGITOS_IGUAIS CHAR(1),
@RESULTADO CHAR(1)

SET @RESULTADO = 'N'

/*
Verificando se os digitos são iguais
A Principio CPF com todos o números iguais são Inválidos
apesar de validar o Calculo do digito verificado
EX: O CPF 00000000000 é inválido, mas pelo calculo
Validaria
*/

SET @CPF_TEMP = SUBSTRING(@CPF,1,1)

SET @INDICE = 1
SET @DIGITOS_IGUAIS = 'S'

WHILE (@INDICE <= 11)
BEGIN
IF SUBSTRING(@CPF,@INDICE,1) <> @CPF_TEMP
SET @DIGITOS_IGUAIS = 'N'
SET @INDICE = @INDICE + 1
END;

--Caso os digitos não sejão todos iguais Começo o calculo do digitos
IF @DIGITOS_IGUAIS = 'N'
BEGIN
--Cálculo do 1º dígito
SET @SOMA = 0
SET @INDICE = 1
WHILE (@INDICE <= 9)
BEGIN
SET @Soma = @Soma + CONVERT(INT,SUBSTRING(@CPF,@INDICE,1)) * (11 - @INDICE);
SET @INDICE = @INDICE + 1
END

SET @DIG1 = 11 - (@SOMA % 11)

IF @DIG1 > 9
SET @DIG1 = 0;

-- Cálculo do 2º dígito }
SET @SOMA = 0
SET @INDICE = 1
WHILE (@INDICE <= 10)
BEGIN
SET @Soma = @Soma + CONVERT(INT,SUBSTRING(@CPF,@INDICE,1)) * (12 - @INDICE);
SET @INDICE = @INDICE + 1
END

SET @DIG2 = 11 - (@SOMA % 11)

IF @DIG2 > 9
SET @DIG2 = 0;

-- Validando
IF (@DIG1 = SUBSTRING(@CPF,LEN(@CPF)-1,1)) AND (@DIG2 = SUBSTRING(@CPF,LEN(@CPF),1))
SET @RESULTADO = 'S'
ELSE
SET @RESULTADO = 'N'
END
RETURN @RESULTADO
END

sexta-feira, 19 de outubro de 2007

2

Dica: Permitir apenas uma instância da aplicação.

As vezes necessitamos limitar a abertura de apenas uma instância da nossa aplicação. O objetivo aqui é demonstrar como fazer isso:

Abra o fonte do seu arquivo DPR e adicione na uses as seguintes units:

uses
System, Windows,
...


E codifique como o exemplo abaixo

var
Instancia: THandle;
begin
Instancia:= CreateMutex(nil, false, 'InstanciaIniciada');
if WaitForSingleObject(
Instancia, 0) = wait_Timeout then
begin
Application.MessageBox('Atenção o programa já está aberto!.','Atenção',MB_ICONINFORMATION);;
Exit;
end;

Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

Nesse exemplo criamos um objeto do tipo THandle chamado
instancia, em seguida instanciamos o objeto com o nome da nossa janela (InstanciaIniciada), a apartir dai verificamos se já existe uma instância rodando com WaitForSingleObject, caso exista exibimos a mensagem para o usuários e fechamos a aplicação.

1

Dica: Utilizar formatos diferentes no FormatFloat

Muitas vezes temos a necessidade de formatos diferentes para números POSITIVOS e NEGATIVOS. O que pouca gente sabe é que o FormatFloat faz isso pra nós! Podemos passar no parâmetro format, uma string com os dois formatos separados por ; (ponto e vírgula)
veja:

ShowMessage(FormatFloat('R$ 0.00,;"("R$ 0.00,")"',-1500)); //Número negativo entre parênteses
ShowMessage(FormatFloat('R$ 0.00,;R$ 0.00,-',-1500)); //Número negativo com sinal a direita
ShowMessage(FormatFloat('R$ 0.00,;R$ 0.00,-',1500)); //Número positivo

1

Dica: Form sem barra de títulos. Utilizando API

Muitas vezes precisamos de um form sem barra de títulos quando a idéia é apenas exibir uma informação ao usuário. Sabemos que se alterarmos a propriedade BorderStyle para none conseguimos esse efeito, no entanto o visual não é muito bom, o form fica com uma aparência FLAT e nem sempre é o que queremos (a menos que seja um Splash).

Crie um novo projeto no delphi, coloque o Label e defina as seguintes propriedades:
Align: alClient
Alingment: taCenter
Layout: tlCenter

Seu form deve se parecer com este




Deixe o form com o tamanho que desejar. E no evento onCreate coloque.


procedure TForm1.FormCreate(Sender: TObject);
begin
{Removendo Barra de tírulos}
SetWindowLong(Handle,GWL_STYLE, GetWindowLong(Handle, GWL_STYLE ) and not WS_CAPTION);
end;


Veja a diferença entre as duas técnicas



Utilizando a API

Utilizando BorderStyle = bsNone



Para mais informações sobre a API acesse: http://msdn2.microsoft.com/en-us/library/ms633591.aspx