quinta-feira, 20 de agosto de 2015

Adicionar o evento OnClick no DBGrid

Problema:

Meu programa precisa processar algo quando o usuário clicar no DBGrid em um determinado form. O problema é que o DBGrid não possui o evento OnClick. É possível adicionar este evento no DBGrid?

Solução:

É possível sim. Afinal é muito simples. Siga os passos abaixo para resolver seu problema:

- Monte seu form normalmente, colocando o DBGrid e demais componentes;

- Vá na seção "private" da unit e declare a procedure abaixo:

private
  procedure DBGridClick(Sender: TObject);
- Logo após a palavra "implementation", escreva a procedure:

implementation
{$R *.DFM}

procedure TForm1.DBGridClick(Sender: TObject);
begin
  ShowMessage('Clicou no DBGrid.');
end;
- Coloque as instruções abaixo no evento OnCreate do Form:

procedure TForm1.FormCreate(Sender: TObject);
begin
  DBGrid1.ControlStyle :=
  DBGrid1.ControlStyle + [csClickEvents];
  TForm(DBGrid1).OnClick := DBGridClick;
end;
- E pronto. Execute e teste.

Observações
O segredo principal desta dica está OnCreate do Form. A primeira instrução ativa o evento OnClick. A segunda instrução acessa o manipulador do evento OnClick. Para isto precisamos tratar o DBGrid como se fosse Form, pois o evento OnClick está declarado como protegido (protected) na classe TDBGrid. 

segunda-feira, 17 de agosto de 2015

Consultando entre datas utilizando SQL

Coloque no formulário dois componentes TDateTimePicker, um TDbgrid e um TButton. Ligue seu TDbgrid a tabela do teu banco que queres aplicar a consulta, e no  evento onclic do compoenente TButton adicione o código abaixo.

If DateTimePicker2.Date < DateTimePicker1.Date Then
begin
       ShowMessage('Intervalo de datas inválido, a data inicial é maior que a data final!');
       DateTimePicker2.Date := DateTimePicker1.Date;
end
Else
begin
     Inicio := DateToStr(DateTimePicker1.Date);
     Final := DateToStr(DateTimePicker2.Date);
     Query1.Close;
     Query1.SQL.Clear;
     //Campos utilizados somente para exemplo. Utilize os campos que achar necessário apresentação
     //em seu Dbgrid
     Query1.SQL.Text := 'SELECT Nome,Empresa,FoneRes,FoneCom,Mala FROM Contatos
     WHERE Data >=:pInicial and Data<=:pFinal ORDER BY Nome';
     Query1.ParamByName('pInicial').AsDateTime := StrToDate(Inicio);
     Query1.ParamByName('pFinal').AsDateTime := StrToDate(Final);
     Query1.Prepare;
     Query1.Open;
     DBGrid.SetFocus;
end;
Label3.Caption := 'Total de contatos: ' + IntToStr(Query1.RecordCount) ;
  

Consulta SQL que usa a data do sistema

Problema:

Preciso fazer uma consulta com SQL que me retorne todos os registros em que o valor de um campo do tipo data seja igual ou anterior à dada do sistema. Como fazer?

Solução:

Query.Close;
Query.SQL.Text := 'select * from Tabela where CampoData <= :Hoje';
Query.ParamByName('Hoje').AsDate := Date;
Query.Open;

Bloco PL/SQL para inserção de dados

Pergunta 
Criar um bloco pl/sql que insira um novo dep na tabela s_dept 

- use a sequencia s_dept_id para o campo id da tabela 

- solicite ao usuario o nome do dep 

- insira valores nulos p/ o campo region_id 

Resposta 
-> no banco de dados... 
create or replace 
procedure insere_departamento (v_nome char) is 
v_id number; 
begin 
  SELECT sequenciaID.NEXTVAL INTO v_id FROM DUAL; 
  insert into tabela (id,dep,region_id) 
  values (v_id,v_nome,null); 
end insere_departamento; 

-> no delphi..

- coloque o objeto TStoredProc dentro do formulario que ira disparar esta procedure; 
- no evento que voce quiser que dispare coloque o seguinte codigo: 
 var 
  v_nome : String[50]; 
  begin 
{caso vc queira informar o nome do departamento atraves de uma caixa de dialogo} 
  V_nome := inputbox('Informe o nome do departamento.','Depto:',''); 
  .Params[0].AsString := v_nome; 
{caso vc queira buscar o nome atraves de um TEdit já preenchido} 
  .Params[0].AsString := .Text; 
  .ExecProc; 
  end; 

Inserindo uma Imagem no Formulário

A dica abaixo apresenta o código para implementação da função para inserir uma imagem no fundo do formulário. 

A função permite que se especifique as coordenadas da imagem e qual o arquivo que contém a imagem.

Através do componente TBitMap é possível criar uma figura dinamicamente e especificar qual será a imagem, através do método LoadFromFile.

Para desenhar a imagem usa-se o componente Tcanvas, através do método Draw, que desenha um gráfico nas coordenadas especificadas.

Código Completo:

declara após o type junto aos outros procedimentos!

Procedure Desenha(figura:String;H,V:Integer);

Procedure TForm1.Desenha(figura:String;H,V:Integer);
Var 
Imagem :TBitMap;
begin 
Imagem := TBitMap.Create;
Try
Imagem.LoadFromFile(Figura); 
Canvas.Draw(H,V,Imagem); 
Except 
ShowMessage(' Arquivo não foi localizado !'); 
end;
end;
ExemploQuando o botão for clicado, uma imagem será inserida no formulário, nas coordenadas (10,20);

procedure TForm1.Button1Click(Sender: TObject);
begin 
Desenha('c:\windows\bolhas.bmp',10,20);
end;

Como desenhar um Bitmap num form

var
Form1: TForm1;
Bmp: TBitmap;
implementation
{$R *.DFM}
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  Bmp:=TBitmap.Create;
  Bmp.Loadfromfile('c:\windows\nuvens.bmp');
end;

procedure TForm1.TForm1.FormPaint(Sender: TObject);
begin
  Canvas.Draw(50,50,Bmp);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Bmp.Free;
end; 

segunda-feira, 3 de agosto de 2015

Formatação de Casas Decimais no TEdit

Esse comando formata para decimal os números do componente TEDIT.
Crie um novo projeto, coloque no TForm, um componente TEDIT e um componente TBUTTON. No evento onclick do componente TBUTTON adicione o código abaixo:

procedure TForm1.Button1Click(Sender: TObject); 
var
     num : integer; 
begin 
     num:=12450; 
     Edit1.text:=formatfloat('###,###,##0.00', num) 
end;

Como posso rolar um form com pgUp e pgDn

Questão. Como posso fazer funções de rolagem num componente TForm usando comandos de teclado? Por exemplo, rolar pra cima e pra baixo quando pressionar PgUp ou PgDown. Existe algum método simples de fazer isso?

Resposta. O rolamento do form é completo fazendo-se uma modificação na posição das propriedades VertScrollbar ou HorzScrollbar do form. Como mostrado no código a seguir:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
const
PageDelta = 10;
begin
  With VertScrollbar do
  if Key = VK_NEXT then
  Position := Position + PageDelta
  else if Key = VK_PRIOR then
  Position := Position - PageDelta;
end;
  

sábado, 1 de agosto de 2015

Capturar a data da BIOS ( Basic Input Output System ) do computador

Insira um objeto do tipo Button com a propriedade name definica como Button1 e um objeto do tipo Label com a propriedade definida como Label1.

procedure TForm1.Button1Click(Sender: TObject); 
begin
  Label1.Caption := 'Data da Bios: '+String(PChar(Ptr($FFFF5))); 
end; 

Como retornar a uma lista os campos indexados de um tabela

procedure TForm1.Button1Click(Sender: TObject);
var
      i : integer;
begin
     Table1.IndexDefs.Update;
     ListBox1.Items.add
    ('******** Índice Primário ********');
    for i:=0 to Table1.IndexDefs.Count-1 do
    begin
          if Table1.IndexDefs.Items[i].Options = [ixPrimary..ixUnique] then
          ListBox1.Items.add(Table1.IndexDefs.Items[I].Fields)
    else
         begin
              ListBox1.Items.add('');
              ListBox1.Items.add
              ('**** Índice Secundário ****');
              Listbox1.Items.Add(Table1.IndexDefs.Items[I].Name); 
          end;
     end; 
end;
  

Como filtrar registros de uma tabela pelo mês de um campo data

Você pode usar a função DecodeDate( ) no evento onFilterRecord de um componente TTable.

Ex.:

// não se esqueça de mudar a propriedade Filtered para True;
// isto fará com que o evento onFilterRecord seja disparado.

procedure TForm1.Table1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
  Dia, Mes, Ano: word;
begin
  Accept := false;
  DecodeDate(Table1['Competencia'],Ano,Mes,Dia);
  if Mes=MesFiltrado then
  Accept := True;
end;
Obs.: Você pode usar este mesmo código para filtrar por Ano ou por Dia, basta utilizar a comparação adequada no bloco if ... then

Como diminuir o tempo de abertura do TTable e TQuery

Operação feita quando é executado o método Open do componente TTable ou TQuery, que produz a compilação e execução do comando select. Quando esse método é executado através do componente TTable, o Delphi realiza uma série de outros comandos SQLs para buscar informações do catálogo da tabela necessárias para as operações de seleção e atualização. Essa busca pode ser otimizada através da opção ENABLE SCHEMA CACHE do BDE, fazendo com que essas informações sejam lidas apenas uma vez durante a execução da aplicação. Quando o primeiro acesso é feito, o BDE armazena as informações em um arquivo e qualquer nova necessidade de abertura da mesma tabela não necessita buscar novamente os elementos do catálogo.

Por outro lado, utilizando-se o componente TQuery, pode-se desviar dessa busca desde que não se utilize a propriedade Request Live que torna o "result set" da "query" atualizável automaticamente pelo Delphi. Se o valor da propriedade Request Live for TRUE e o SELECT utilizado obedecer as restrições para que o Delphi consiga atualizar o "result set", as mesmas buscas utilizadas para o componente TTable terão que ser feitas. 

Concluindo, para que a busca de elementos do catálogo não seja feita é necessário utilizar o componente TQuery e controlar as atualizações manualmente ou através de componentes do tipo TUpdateSQL.

sexta-feira, 31 de julho de 2015

Como formatar data para exibição por extenso

O Delphi permite formatar datas para apresentação por extenso de forma bastante simples. Vejamos os seguintes exemplos: 

Para formatar a data 18/03/1999, podemos utilizar: 

No create do form colocar

Shortdateformat :=

dddd, dd/mm/yyyy = Quinta, 18/03/1999 
dd/mmm/yyyy = 18/Mar/1999 
dddd, dd" de "mmmm" de "yyyy = Quinta, 18 de Março de 1999 
dd" de "mmmm" de "yyyy, dddd = 18 de Março de 1999, Quinta 

Função para acrescentar dias uteis a uma data

Retorna uma data acrescida de mais um certo número de dias  uteis descontando os fins de semana.

function Datafinal(dataini:tdatetime; dias_uteis:integer):tdatetime;
var dw:integer;
begin
  dw := DayOfWeek(dataini)-1;
  result := dataini+dias_uteis+((dias_uteis-1+dw) div 5)*2;
end;
  

Função para extrair o mês por extenso

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
function MesExtenso( Mes:Word ) : string;
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.MesExtenso( Mês:Word ) : string; const meses : array[0..11] of PChar = ('Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro','Outubro', 'Novembro', 'Dezembro');
begin
result := meses[mes-1];
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
label1.Caption := MesExtenso(3);
end;

end.

Como usar a cláusula UNION em um Query

O uso do componente TQuery gera muitas vantagens e economiza muitas linhas de programação. Mas muitas vezes nos deparamos com situações que parecem não ser resolvidas com sentenças SQL. Vejamos um exemplo:

Você possui 2 tabelas (VendasExternas e VendasInternas) e deseja fazer um resumo de todas as vendas de um vendedor chamado Marcos. Se você usar a sentença

SELECT Nome, Valor FROM VendasExternas, VendasInternas
WHERE Nome = 'Marcos'
você vai obter como resultado uma query com 4 campos (Nome, Valor, Nome_1 e Valor_1) e um resultado bem confuso para ser manipulado.

Para resolver o problema, você poderá usar a sentença

SELECT Nome, Valor FROM VendasExternas
WHERE Nome = 'Marcos'
UNION ALL
SELECT Nome, Valor FROM VendasInternas
WHERE Nome = 'Marcos'
A sentença acima pede para que sejam identificados as vendas de Marcos na tabela VendasExternas, as vendas de Marcos na tabela VendasInternas e que o resultado da primeira seja unido com o resultado da segunda produzindo uma query com apenas 2 colunas.

segunda-feira, 27 de julho de 2015

Enviando informações direto para a impressora

Muitas vezes torna-se necessário, ou até mesmo, imprescindível que você envie informações diretamente para a impressora, uma vez que a utilização da impressão típica do Windows é um pouco demorada e o uso do driver Genérico/Somente Texto não é muito confiável.

Uma boa solução para enviar informações diretamente para a impressora é usar o seguinte código:

Procedure TForm1.Button1Click(Sender: Object);
var
    Imp: TextFile;
begin
    AssignFile(Imp, 'LPT1');
    Rewrite(Imp);
    Write(Imp, 'Isto vai sair na impressora');
    CloseFile(Imp);
end;

COMO ARRASTAR UM FORM SEM CLICAR NO CAPTION?

Quando você pressiona o botão do mouse, o Windows identifica a posição da tela onde o cursor estava no momento do clique. Se a posição é igual a área do Caption do Form, o Windows ativa o modo de movimentação do Form permitindo que este seja arrastado. Portanto, a maneira mais fácil de solucionar esta questão é "enganar" o Windows.
Neste exemplo vamos considerar que o usuário poderá arrastar o Form ao cli-car na área cliente deste Form:

a) Crie uma nova aplicação;
b) Adicione a seguinte declaração na seção private do Form:
procedure WMNCHitTest(var M: TWMNCHitTest); message wm_NCHitTest;
c) Adicione o código deste procedimento na seção implementation do Form:

procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);
begin
inherited;                   { ativa a herança da mensagem }
if M.Result = htClient then { o clique foi na área cliente? }
            M.Result := htCaption;     { se sim, faz o Windows pensar que foi no Cap-tion. }
          end;

      Este exemplo tratou o clique na área cliente. Você pode alterar este código para suas necessidades. Eis os possíveis valores para o Result:

     VALOR - Local do clique
     HTBORDER - Borda da janela que não tem a borda de tamanho
     HTBOTTOM - Borda horizontal inferior da janela
     HTBOTTOMLEFT - Canto inferior esquerdo da janela
     HTBOTTOMRIGHT - Canto inferior direito da janela
     HTCAPTION - Barra de Título(Caption)
     HTCLIENT - Área cliente
     HTERROR - igual ao HTNOWHERE, a diferença é que produz um beep indicando erro
     HTGROWBOX - Caixa de tamanho (igual ao HTSIZE)
     HTHSCROLL - Barra de rolagem horizontal
     HTLEFT - Borda esquerda da janela
     HTMENU - Em um menu
     HTNOWHERE - Plano de fundo da janela ou linha de divisão entre janelas
     HTREDUCE - Botão minimizar
     HTRIGHT - Borda direita da janela
     HTSIZE - Caixa de tamanho (igual ao HTGROWBOX)
     HTSYSMENU - Botão de Sistema/Fechar da janela MDIChild
     HTTOP - Borda horizontal superior da janela
     HTTOPLEFT - Canto superior esquerdo da janela
     HTTOPRIGHT - Canto direito superior da janela
     HTTRANSPARENT - Janela em segundo plano
     HTVSCROLL - Barra de rolagem vertical
     HTZOOM - Botão maximizar

terça-feira, 14 de julho de 2015

Como tornar um servidor datasnap rest compatível com o cache off-line do HTML5


Por padrão, servidores DataSnap stand-alone WebBroker não permitem usar o "novo" HTML5 Aplicação manifesto de arquivo de cache.
Enquanto eu estava me preparando os conteúdos e as demonstrações do meu "HTML5 e aplicação web DataSnap desenvolvimento" eu configurei os componentes DataSnap para suportar esse recurso HTML5. Há apenas uma alteração a fazer ao "WebApplication REST" padrão gerado pelo assistente. No WebModuleUnit há o componente utilizado TWebFileDispatcher. Este componente tem as WebFileExtensions propriedade que é uma coleção de valores-chave contendo todas as extensões de arquivos permitidas relacionada com o mime-type.
A imagem abaixo mostra o que precisa ser configurado.

quarta-feira, 29 de abril de 2015

Função para gerar senhas aleatórias


Essa é uma dica simples e que para os que trabalham com redes sem fio pode ser muito útil. O que a função faz é gerar um string com caracteres hexadecimais, mas que podem ser adaptados para qualquer outro tipo. Esta função recebe como parâmetros o comprimento da senha como um integer, e outros três parametros do tipo boolean que indicam se estarão presentes letras minúsculas, maiúsculas e números.

Aqui vai o código e as explicações seguem logo abaixo.

function GeraSenhaHex(Digitos: Integer; Min: Boolean; Mai: Boolean; Num: Boolean): string;
const
   MinC = 'abcdef';
   MaiC = 'ABCDEF';
   NumC = '1234567890';
var
   p, q : Integer;
   Char, Senha: String;
begin
   Char := '';
   If Min then Char := Char + MinC;
   If Mai then Char := Char + MaiC;
   If Num then Char := Char + NumC;
   for p := 1 to Digitos do
   begin
      Randomize;
      q := Random(Length(Char)) + 1;
      Senha := Senha + Char[q];
   end;
   Result := Senha;
end;

Explicações:

Primeiro criamos as constantes que trarão os caracteres referentes a letras minúsculas, maiúsculas, e números, depois, iniciamos como vazia, só por desencargo de consciência já que o delphi faz isso por padrão, a variável "Char", que conterá todos os caracteres a serem usados para a geração da senha randômica.

Após isso, testamos os parâmetros para letras maiúsculas, minúsculas e números, acrescentando à "Char" cada um dos que forem verdadeiros segundo os parâmetros passados na chamada da função.

E depois, para finalizar, um laço com o número de repetições igual aos dígitos passados também como parâmetro na chamada, que usando a função Random do delphi gera números aleatórios dentro do limite estabelecido pelo cumprimento da variável "Char", lembrando que o fato de acrescentar o "+ 1" é por que as posições dos caracteres dentro de um string iniciam em 1, e a função Random gera números de 0 até o valor estipulado como limite. Por exemplo uma String = 'teste' temos os valores a seguir:

String[1] = 't'
String[2] = 'e'
String[3] = 's'
String[4] = 't'
String[5] = 'e'

segunda-feira, 9 de março de 2015

Como Identar código no Delphi

O comando para identar o código é: 

- CTRL + SHIFT + i (para avançar o código, ou seja, mover pra a direita) 
- CTRL + SHIFT + u (para retroceder o código ou mover para a esquerda). 

Lembrando de selecionar o código antes de utilizar as teclas de atalho. 

sexta-feira, 6 de março de 2015

dbExpress Suporte ao MySQL no Delphi 2010 e XE


Parece ser frequente as dúvidas relacionadas a utilização do driver dbExpress para MySQL, na grande maioria usuários das versões 2010 e XE do Delphi
O arquivo readme.html que está localizado no diretório onde o Delphi foi instalado, documenta as versões de MySQL e dos outros bancos suportados pelo dbExpress. No caso do MySQL o arquivo inclui as combinações de versões de server e bilbiotecas clientes suportadas, infelizmente o MySQL a cada nova versão traz inúmeras alterações nas API’s e acabe dificultando uma pouco nosso trabalho.

Abaixo informações que você deve saber.

Versões de servidores MySQL oficialmente suportadas e testadas.

MySQL 5.1, 5.0.27, 4.1 (Todas) (Driver dbxMYS.dll, Client libmysql.dll)

Combinação das versões de servidores e clientes MySQL que foram testadas

LibMySQL.dll (5.1.XX) Client - DBXMys.dll MySQL 4.0.XX Server
LibMySQL.dll (5.1.XX) Client - DBXMys.dll MySQL 5.0.XX Server
LibMySQL.dll (5.1.XX) Client - DBXMys.dll MySQL 5.1.XX Server
Em resumo, você tem que instalar a versão do cliente do MySQL 5.1.xx para que sua aplicação cliente funcione com servidores MySQL 4.0.XX, 5.0.XX e 5.1XX

O que fazer caso você tenha outras versões do Delphi na mesma máquina?

Caso isso aconteça o IDE poderá carregar uma das versões antigas do driver dbExpress para MySQL, isso acontece porque o diretório bin da versão anterior do Delphi está a frente na variável de sistema PATH, para resolver este problema, no menu Tools -> Options -> Environment Variables adicione o PATH da versão atual do Delphi a frente de todas as variáveis. Lembre-se que casa você use a versão anterior instalada na sua máquina, você deverá atualiza a variável de ambiente PATH novamente.

Espero que essas dicas tenham ajudado. 

Post Origial blog do Andreano.
http://www.andreanolanusse.com/pt/dbexpress-suporte-ao-mysql-no-delphi-2010-e-xe/

Usando Coalesce em Comandos SQL


Nessa dica, vou expor uma situação comum para nós desenvolvedores, que pode ser resolvida de várias formas, (como tudo em programação), mas sempre existe a forma correta ou a que vai garantir a integridade do sistema, e ainda, ser resolvida em pouquíssimo tempo.

Imaginem a seguinte situação, uma empresa possui uma entidade chamada TitulosPagar, nessa entidade estão gravados os titulos a pagar com as suas respectivas datas de vencimento. Nessa mesma entidade temos um campo chamado Prorrogado, que é preenchido quando o fornecedor concede uma prorrogação no título para que o mesmo seja pago após a data de vencimento sem juros etc.

Vocês ja devem ter imaginado que o sistema em questão possui um relatório de Titulos a Pagar em um determinado período. Certo?

Nesse caso o mesmo poderia usar o um Sql simples como o abaixo:

Select titulo, valor, vencimento
From titulosPagar
Where dataVcto between :dataIni and :dataFim

Tranquilo né. O Sql retorna todos os títulos a pagar com vencimento no período passado nos parâmetros dataIni e dataFim.

Vamos complicar, um belo dia o cliente liga para você pedindo para que nesse mesmo relatório de titulos a pagar considerasse a data de prorrogação também, ou seja deve ser listado todos os títulos analisando a data de vencimento, e também a data de prorrogação. 

Saída rápida, fazer duas querys, com dois Sql diferentes, um analisando o período pela data de vencimento e o outro analisando pela data de prorrogação, depois gravar tudo em um ClientDataSet e ligar o Client ao relatório. Beleza? Funciona com certeza, mas da um trabalhão, sem falar no tempo de processamento, dependendo o tamanho da entidade de TitulosPagar o processo será demorado.

Solução:
Criar o seguinte comando SQL.

Select titulo, valor, vencimento
From titulosPagar
Where Coalesce(Prorrogado, dataVcto) between :dataIni and :dataFim

Bingo! Temos uma query apenas, um processamento, e a solução com certeza não demorou mais que 1 minuto para alterar a query.

Sistema Fechando Sozinho


Amigos, acompanhando os grupos de discussão sobre programação e outros, percebi que muitas pessoas estão enfrentando um problema em comum.
Programas feitos em Delphi e ou VB, fechando sozinho, do nada o sistema fecha, como se alguém tivesse clicado em finalizar processo.

Também passei por isso, e depois de muitos testes descobri a causa.
O Bradesco, contratou uma empresa para desenvolver uma solução de segurança para eles, a mesma criou um processo que é inicializado quando o site do banco é aberto, e que verifica todos os outros processos que estão rodando. Caso considere o programa suspeito imediatamente encerra o processo.

Se você tem o costume de usar o compactador de exe chamado UPX, esse processo de segurança irá identificar o seu sistema como um programa malicioso ou suspeito, e irá finalizá-lo. 
Fato já comprovado! Para piorar o processo inicializado pelo site do Bradesco não é finalizado quando o browser é fechado, ou seja, para você conseguir usar o seu programa precisa reinicializar a máquina. 

sexta-feira, 15 de agosto de 2014

COMO RETIRAR SOMENTE OS NUMEROS DE UMA STRING

Segue uma função básica de como extrair de uma string somente números no formato currency.

function StrToCurr(Texto: String): Currency;
var
  nI: Integer;
  TextoLimpo: String;
begin
  TextoLimpo := '';
  For nI := 1 to Length(Texto) do begin
    if Texto[nI] in ['0'..'9',','] then
       TextoLimpo := TextoLimpo + Texto[nI];
  end;
  Result := StrToCurr(TextoLimpo);
end;

segunda-feira, 12 de agosto de 2013

ClientDataSet - Clicando no Título das Colunas do DBGrid para Ordenar


Veja nesta dica como é simples realizar a tarefa de ordenação dos dados de um DBGrid que está ligado a um ClientDataSet, criando e selecionando índices em memória.
O código abaixo mostra como realizar a ordenação clicando no titulo da coluna desejada. Clicando uma uma vez será utilizada a ordem crescente e na segunda, a ordem decrescente.

Primeiramente, no evento onCreate do Form, criaremos um índice Crescente e um Decrescente para cada campo do DBGrid, com o seguinte código:

procedure TForm1.FormCreate(Sender: TObject);
var
  i : integer;
begin
  for i := 0 to clientdataset1.FieldCount - 1 do
  begin
    CLIENTDATASET1.IndexDefs.Add('a' + CLIENTDATASET1.Fields[i].FieldName, 
      CLIENTDATASET1.Fields[i].FieldName, []);
    CLIENTDATASET1.IndexDefs.Add('d' + CLIENTDATASET1.Fields[i].FieldName,
      CLIENTDATASET1.Fields[i].FieldName, [ixDescending]);
  end;
end;
Em seguida, programaremos o evento onTitleClick do DBGrid:

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
  if 'a' + Column.FieldName = CLIENTDATASET1.IndexName then
    CLIENTDATASET1.IndexName := 'd' + column.FieldName
  else
    CLIENTDATASET1.IndexName := 'a' + column.FieldName;
end;
Pronto! Seu DBGrid em ordem Crescente e Decrescente de qualquer coluna, com apenas um click!

segunda-feira, 22 de julho de 2013

Enviando e-mails com Delphi 5

Este resumo não está disponível. Clique aqui para ver a postagem.

Repositório do Delphi


O repositório do Delphi é um local para armazenamento de objetos, como formulários e projetos, que facilita o compartilhamento desses objetos por vários projetos. Quando você clica em File|New... para criar um novo objeto, você pode escolher um dos itens do repositório.

Acrescentando um formulário ao repositório 

     Abra um projeto DPR, e dentro dele o formulário "Form" (Form1.pas). Esse formulário está sendo compartilhado dentro do mesmo projeto, mas se você quiser reutilizá-lo em outros projetos, pode acrescentá-lo ao repositório. 
     Para isso, clique com o botão direito e em Add to Repository. Você deve informar o título do item, uma descrição e qual a página onde ele será inserido (se você digitar um nome de página que não existe, uma nova será criada), além do seu nome para indicar qual o autor desse item. Opcionalmente você pode escolher um ícone que será usado para representar o item. Para o exemplo digite o seguinte: 

   Title: Formulário para uma tabela
   Description: Formulário de banco de dados para uma tabela
   Page: Forms (default)
   Author: seu nome 

     O botão "Browse" permite você procurar um ícone , para representar sua classe de formulário, caso não informe ele irá mostrar o seguinte ícone . Clique Ok. O novo item será adicionado ao repositório. Agora crie um novo projeto com File|New Application e veremos como o item pode ser reutilizado. 

     Formas de criar novos objetos 
     Se você clicar em File|New... e na página "Forms", você verá que o novo item ("Formulário para uma tabela") está dentro do repositório. Agora ele está disponível em qualquer projeto, permitindo criar novos formulários a partir dele. 

     Existem três opções para criar novos objetos a partir do repositório: copiar [copy] o item, herdar [inherit] do item (criar uma nova classe derivada) ou usar [use] o item diretamente. 

Se você marcar a opção "Copy" e clicar Ok, o Delphi cria uma cópia separada do objeto original que está no repositório. Qualquer alteração no original posteriormente não vai afetar essa cópia e qualquer alteração na cópia é independente do que está no repositório. Note que a unidade do formulário não foi salva e está em memória como "Unit2". Isso permite você salvar com um nome qualquer. 

     A opção "Inherit" (herdar) faz diferente: faz uma referência ao original (ou seja, acrescenta o formulário original dentro do projeto) e cria uma nova classe derivada da original, TForm1. O novo formulário será chamado de 'FormBase1', com a classe 'TFormBase1'. A unidade do formulário não foi salva ainda. Nesse caso, qualquer alteração no original, que está no repositório, será herdada pela classe derivada. 

     A opção "Use" não copia o objeto original, mas compartilha com o projeto atual. Nesse caso, alterações feitas no item dentro do projeto afetam o item no repositório e vice-versa. Se vários projetos usarem o mesmo item, todos eles compartilham o mesmo item. 

     Adicionando um projeto ao repositório 
     Para reutilizar um projeto inteiro, você pode acrescentá-lo ao repositório com o menu Project|Add to Repository... e informar a descrição do item como antes. 

     Gerenciando o repositório 
     Para gerenciar as páginas do repositório e os itens de cada página, você pode clicar em   Tools|Repository. Na caixa de diálogo você pode criar, renomear ou excluir uma página do repositório (você só pode excluir se ela estiver vazia). É possível também mudar a ordem das páginas. 

     Você pode mover os itens entre páginas arrastando o item da lista da esquerda e soltando sobre a página desejada. Também é possível renomear ou alterar características de um item ou excluir o item. 

     Compartilhando o repositório numa equipe 
     Quando uma equipe de desenvolvedores trabalha em conjunto, é importante que eles possam compartilhar o repositório, de forma que novos itens adicionados a ele estejam disponíveis para toda a equipe. 

     Para compartilhar o repositório, você deve usar um diretório na rede que seja acessível a todos os desenvolvedores. Por exemplo, se G: é uma letra de drive que aponta para a rede, você pode usar G:\REPOS. Você deve também copiar os arquivos do repositório do Delphi para esse diretório. 

     Os arquivos do repositório do Delphi são armazenados num subdiretório OBJREPOS, abaixo do diretório onde o Delphi foi instalado (geralmente C:\Arquivos de Programas\Borland\Delphi6). Além desses arquivos, o Delphi usa um arquivo de texto chamado DELPHI32.DRO, localizado no subdiretório BIN do Delphi. 

     Para compartilhar o repositório na rede, faça o seguinte: 
     • Crie um diretório compartilhado (e.g. G:\REPOS). Verifique que todos os desenvolvedores têm acesso a ele e usam a mesma letra de drive; 
     • Copie o repositório de um computador para o diretório compartilhado (G:\REPOS), ou seja, todos os arquivos do subdiretório OBJREPOS do Delphi, mais DELPHI32.DRO, do subdiretório BIN; 
     • Em cada um dos computadores, no Delphi, clique em Tools|Environment Options. Na página Preferences Em "Shared Repository", digite o caminho do diretório compartilhado. 

Agora lembre-se que qualquer alteração ou acréscimo feito por um desenvolvedor afeta todos os outros. É importante também notar que quando você quiser compartilhar um objeto, ele deve ser salvo num diretório compartilhado também, acessível a todos (por exemplo, G:\BIBLIOTECAS). 

Autor    : Celso Rodrigues

segunda-feira, 17 de junho de 2013

Mainmenu e popupmenu personalizados utilizando canvas (muito simples)


Olá Pessoal!!!

Bom estou aqui com mais uma dica que interessa a muitas pessoas! Personalizar 
uma aplicação sem utilizar componentes externos.
Estaremos Pesonalizando os Menus de Nossa aplicação.
  Mas antes quero esclarecer algumas coisas para quem esta procurando por isso:
  -A dica é para personalizar os Menus da aplicação, tanto MainMenu quanto popupMenu.
  -Para quem utiliza Delphi 7 (Exemplo) pode utilizar os Componentes ActionMainMenuBar e 
  ActionManager para fazer alguns MainMenus bacanas(em breve mostrarei passo-a-passo como 
  utilizar estes componentes que são muito legais de trabalhar).
  -Neste exemplo estarei trabalhando com Canvas!
  
 Então... Mãos à Obra!!!!

   Neste exemplo que faremos utilizarei o Componentes MainMenu mas o que vai ser aplicado nele
 pode ser sem problemas aplicado para um popupmenu.

 Vamos deixar os nossos menus com uma aparência bem legal!.

 Eventos Utilizados no componente: onDrawItem, onMeasureItem.

 1º- Crie uma nova aplicação.
 2º- Coloqueno formulario o componente MainMenu (Standard Palette).
 3º- Ative a propriedade OwnerDraw do componente MainMenu.
 3º- Abra o "Editor de Menus" dando 2 clique no componente e crie 1 menu.
        (insira Caption, Name...)

 4º- Acesse o Evento onDrawItem de deste item do Menu e vamos implementar o seguinte código:
}
procedure TForm1.Arquivo1DrawItem(Sender: TObject; ACanvas: TCanvas;
ARect: TRect; Selected: Boolean);
begin
  //Pinta a opção
  
  if Selected then  //verifica se o item está selecionado
    BEGIN
      ACanvas.Brush.Color :=  $00EFD3C6;        //cor de fundo do item (Lembrando que podemos printar um Imagem).
          //   Canv.Brush.Color :=  clAppWorkSpace;
      ACanvas.Rectangle(Arect);                         //Desenharemos uma retangulo em todo o Item selecionado.
      ACanvas.pen.Color:=$00C66931;             //seta a cor da borda do retangulo.
      InflateRect (ARect, -1,-1);
    end
    else
    ACanvas.Brush.Color:=clMenu;                        //se não estiver selecionado o item coloca a cor normal do item.
        //-->  dietrich 01/02/2007
        
        //coloca o texto
    ACanvas.pen.Color:=clBlack;  //cor
    ACanvas.TextRect(ARect,ARect.Left+5, ARect.Top+1,'Sair');//local onde sera escrito o texto ARect

end;

Curso de Delphi: 7.Consultas SQL