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.
sábado, 20 de outubro de 2007
Como retornar múltiplos resultados numa função?
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
Marcadores: SQL Server
sexta-feira, 19 de outubro de 2007
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.
Marcadores: API
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
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
Marcadores: API
Perfil
- Cristiano Martins Alves
- São Paulo, SP, Brazil
- Programador Delphi desde 2000, desenvolvendo aplicações Client/Server. Colunista da Revista ActiveDelphi Membro Fundador do DUG-SP ( www.dug-sp.com )
Blogs de Amigos
Exemplos
Search
Marcadores
- Actions (1)
- AJAX (1)
- API (2)
- Arquivos (1)
- ASP.NET (1)
- Blackfish SQL (1)
- Borcon (3)
- CodeGear (2)
- Datas (1)
- Datasnap (3)
- DBExpress (1)
- DBGrid (2)
- Delimitados (1)
- Delphi (1)
- Delphi2009 (3)
- DUG (1)
- ECO (1)
- Embarcadero (1)
- ExtractStrings (1)
- Firebird (1)
- Framework (1)
- Funcões (2)
- Herança Visual (1)
- IDE (1)
- Join (1)
- Lookup (1)
- POO (1)
- RAD Studio 2007 (1)
- RN's (1)
- SQL Server (1)
- StringList (2)
- Strings (2)
- TextFile (1)
- Tiburon (2)
- TypeLibrary (1)
- UML (1)