function AddBarra(S: string): string; 
var 
Temp: string; 
begin 
Temp := S; 
if S[Length(Temp)] <> '\' then 
Temp := Temp + '\'; 
Result := Temp; 
end;
terça-feira, 10 de agosto de 2010
Abrir arquivos com aplicativo associado
Inclua a unit SHELLAPI na clausula uses do seu form.
procedure TForm1.ExecFile(F: String);
var
r: String;
begin
case ShellExecute(Handle, nil, PChar(F), nil, nil, SW_SHOWNORMAL) of
ERROR_FILE_NOT_FOUND: r := 'The specified file was not found.';
ERROR_PATH_NOT_FOUND: r := 'The specified path was not found.';
ERROR_BAD_FORMAT: r := 'The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).';
SE_ERR_ACCESSDENIED: r := 'Windows 95 only: The operating system denied access to the specified file.';
SE_ERR_ASSOCINCOMPLETE: r := 'The filename association is incomplete or invalid.';
SE_ERR_DDEBUSY: r := 'The DDE transaction could not be completed because other DDE transactions were being processed.';
SE_ERR_DDEFAIL: r := 'The DDE transaction failed.';
SE_ERR_DDETIMEOUT: r := 'The DDE transaction could not be completed because the request timed out.';
SE_ERR_DLLNOTFOUND: r := 'Windows 95 only: The specified dynamic-link library was not found.';
SE_ERR_NOASSOC: r := 'There is no application associated with the given filename extension.';
SE_ERR_OOM: r := 'Windows 95 only: There was not enough memory to complete the operation.';
SE_ERR_SHARE: r := 'A sharing violation occurred.';
else
Exit;
end;
ShowMessage(r);
end;
Utilize a função assim:
procedure TForm1.ExecFile(F: String);
var
r: String;
begin
case ShellExecute(Handle, nil, PChar(F), nil, nil, SW_SHOWNORMAL) of
ERROR_FILE_NOT_FOUND: r := 'The specified file was not found.';
ERROR_PATH_NOT_FOUND: r := 'The specified path was not found.';
ERROR_BAD_FORMAT: r := 'The .EXE file is invalid (non-Win32 .EXE or error in .EXE image).';
SE_ERR_ACCESSDENIED: r := 'Windows 95 only: The operating system denied access to the specified file.';
SE_ERR_ASSOCINCOMPLETE: r := 'The filename association is incomplete or invalid.';
SE_ERR_DDEBUSY: r := 'The DDE transaction could not be completed because other DDE transactions were being processed.';
SE_ERR_DDEFAIL: r := 'The DDE transaction failed.';
SE_ERR_DDETIMEOUT: r := 'The DDE transaction could not be completed because the request timed out.';
SE_ERR_DLLNOTFOUND: r := 'Windows 95 only: The specified dynamic-link library was not found.';
SE_ERR_NOASSOC: r := 'There is no application associated with the given filename extension.';
SE_ERR_OOM: r := 'Windows 95 only: There was not enough memory to complete the operation.';
SE_ERR_SHARE: r := 'A sharing violation occurred.';
else
Exit;
end;
ShowMessage(r);
end;
Utilize a função assim:
procedure TForm1.Button1Click(Sender: TObject);
begin
ExecFile('c:\windows\ladrilhos.bmp');
end;
  
begin
ExecFile('c:\windows\ladrilhos.bmp');
end;
segunda-feira, 9 de agosto de 2010
Apagando todos os registros da tabela
Para apagar os registros de uma tabela utiliza-se a função delete.
Através de um comando de repetição (While) é possível excluir todos os registros da tabela, usando como flag a quantidade de registros existentes na tabela (RecordCount > 0).
Código Completo:
Procedure ApagarTodosReg(Origem:TDataSet);
Begin
With Origem do
While RecordCount > 0 do
Delete;
End;
Como Usar:
ApagarTodosReg(Table1);
Através de um comando de repetição (While) é possível excluir todos os registros da tabela, usando como flag a quantidade de registros existentes na tabela (RecordCount > 0).
Código Completo:
Procedure ApagarTodosReg(Origem:TDataSet);
Begin
With Origem do
While RecordCount > 0 do
Delete;
End;
Como Usar:
ApagarTodosReg(Table1);
Arquivos AVI e WAV em tabelas
O Exemplo Abaixo Demonstra Como Gravar Um Arquivo .Avi Ou .Wav Dentro De Um Arquivo Paradox. Mostra Também Como Reproduzir Estes Arquivos.
Para Que O Código Abaixo Funcione Inclua Em Um Form 02 Componentes Button, 01 Componente Panel, 01 Componente Dbgrid, 01 Componente Table, 01 Componente Datasource E 01 Componente Opendialog.
Crie Um Arquivo Paradox Com A Seguinte Estrutura:
Nome Tipo Tamanho
Codigo +
Nome A 100
Avi B
Unit Unit1;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs,
Stdctrls, Db, Dbtables, Extctrls, Mplayer, Dbctrls, Grids, Dbgrids;
Type
Tform1 = Class(Tform)
Button1: Tbutton;
Button2: Tbutton;
Table1: Ttable;
Datasource1: Tdatasource;
Dbgrid1: Tdbgrid;
Panel1: Tpanel;
Opendialog1: Topendialog;
Table1codigo: Tautoincfield;
Table1nome: Tstringfield;
Table1avi: Tblobfield;
Procedure Button1click(Sender: Tobject);
Procedure Button2click(Sender: Tobject);
Procedure Formdestroy(Sender: Tobject);
Procedure Formshow(Sender: Tobject);
Procedure Formclose(Sender: Tobject; Var Action: Tcloseaction);
Private
{ Private Declarations }
Public
{ Public Declarations }
End;
Var Form1: Tform1;
Filename : String;
Mediaplayer1 : Tmediaplayer;
Implementation
{$R *.Dfm}
{Esta Função Cria Um Arquivo Temporário Para O Sistema}
Function Gettemporaryfilename : String;
{$Ifndef Win32}
Const Max_path = 144;
{$Endif}
Var
{$Ifdef Win32}
Lppathbuffer : Pchar;
{$Endif}
Lpbuffer : Pchar;
Begin
{Get The File Name Buffer}
Getmem(Lpbuffer, Max_path);
{$Ifdef Win32}
{Get The Temp Path Buffer}
Getmem(Lppathbuffer, Max_path); {Get The Temp Path}
Gettemppath(Max_path, Lppathbuffer); {Get The Temp File Name}
Gettempfilename(Lppathbuffer,'Tmp',0,Lpbuffer);
Freemem(Lppathbuffer, Max_path);
{$Else} {Get The Temp File Name}
Gettempfilename(Gettempdrive('C'),'Tmp',0,Lpbuffer);
{$Endif} {Create A Pascal String Containg}
{The Temp File Name And Return It}
Result := Strpas(Lpbuffer);
{Free The File Name Buffer}
Freemem(Lpbuffer, Max_path);
End;
{Grava Avi Ou Wav No Arquivo Paradox}
Procedure Tform1.Button1click(Sender: Tobject);
Var Filestream: Tfilestream; {Para Ler O Arquivo Avi}
Blobstream: Tblobstream; {Para Salvar No Campo Blob}
Begin
Application.Processmessages;
Button1.Enabled := False;
Button2.Enabled := False;
If Opendialog1.Execute Then
Filestream := Tfilestream.Create(Opendialog1.Filename,Fmopenread);
Table1.Append;
Table1nome.Value := Opendialog1.Filename;
Blobstream := Tblobstream.Create(Table1avi, Bmreadwrite);
Blobstream.Seek(0, Sofrombeginning);
Blobstream.Truncate;
Blobstream.Copyfrom(Filestream, Filestream.Size);
Filestream.Free;
Blobstream.Free;
Table1.Post;
Button1.Enabled := True;
Button2.Enabled := True;
End;
{Reproduz O Que Está Gravado No Campo Blob}
Procedure Tform1.Button2click(Sender: Tobject);
Var Filestream: Tfilestream; {A Temp File}
Blobstream: Tblobstream; {The Avi Blob}
Begin
Blobstream := Tblobstream.Create(Table1avi, Bmread);
If Blobstream.Size = 0 Then
Begin
Blobstream.Free;
Exit;
End;
Mediaplayer1.Close; {Reset The File Name}
Mediaplayer1.Filename := ''; {Refresh The Play Window}
Mediaplayer1.Display := Panel1;
Panel1.Refresh;
If Filename <> '' Then
Deletefile(Filename); {Get A Temp File Name}
Filename := Gettemporaryfilename; {Create A Temp File Stream}
Filestream := Tfilestream.Create(Filename,Fmcreate Or Fmopenwrite);
Filestream.Copyfrom(Blobstream, Blobstream.Size); {Free The Streams}
Filestream.Free; Blobstream.Free;
Mediaplayer1.Filename := Filename;
Mediaplayer1.Devicetype := Dtavivideo;
Mediaplayer1.Open;
Mediaplayer1.Play;
End;
// Evento Ondestroy Do Form
Procedure Tform1.Formdestroy(Sender: Tobject);
Begin
Mediaplayer1.Close;
Mediaplayer1.Filename := '';
If Filename <> '' Then
Deletefile(Filename);
End;
// Evento Onshow Do Form
Procedure Tform1.Formshow(Sender: Tobject);
Begin
Mediaplayer1 := Tmediaplayer.Create(Self);
With Mediaplayer1 Do
Begin
Parent := Self ;
Visible := False;
End;
Table1.Open;
End;
// Evento Onclose Do Form
Procedure Tform1.Formclose(Sender: Tobject; Var Action: Tcloseaction);
Begin
Table1.Close;
End;
End.
Para Que O Código Abaixo Funcione Inclua Em Um Form 02 Componentes Button, 01 Componente Panel, 01 Componente Dbgrid, 01 Componente Table, 01 Componente Datasource E 01 Componente Opendialog.
Crie Um Arquivo Paradox Com A Seguinte Estrutura:
Nome Tipo Tamanho
Codigo +
Nome A 100
Avi B
Unit Unit1;
Interface
Uses
Windows, Messages, Sysutils, Classes, Graphics, Controls, Forms, Dialogs,
Stdctrls, Db, Dbtables, Extctrls, Mplayer, Dbctrls, Grids, Dbgrids;
Type
Tform1 = Class(Tform)
Button1: Tbutton;
Button2: Tbutton;
Table1: Ttable;
Datasource1: Tdatasource;
Dbgrid1: Tdbgrid;
Panel1: Tpanel;
Opendialog1: Topendialog;
Table1codigo: Tautoincfield;
Table1nome: Tstringfield;
Table1avi: Tblobfield;
Procedure Button1click(Sender: Tobject);
Procedure Button2click(Sender: Tobject);
Procedure Formdestroy(Sender: Tobject);
Procedure Formshow(Sender: Tobject);
Procedure Formclose(Sender: Tobject; Var Action: Tcloseaction);
Private
{ Private Declarations }
Public
{ Public Declarations }
End;
Var Form1: Tform1;
Filename : String;
Mediaplayer1 : Tmediaplayer;
Implementation
{$R *.Dfm}
{Esta Função Cria Um Arquivo Temporário Para O Sistema}
Function Gettemporaryfilename : String;
{$Ifndef Win32}
Const Max_path = 144;
{$Endif}
Var
{$Ifdef Win32}
Lppathbuffer : Pchar;
{$Endif}
Lpbuffer : Pchar;
Begin
{Get The File Name Buffer}
Getmem(Lpbuffer, Max_path);
{$Ifdef Win32}
{Get The Temp Path Buffer}
Getmem(Lppathbuffer, Max_path); {Get The Temp Path}
Gettemppath(Max_path, Lppathbuffer); {Get The Temp File Name}
Gettempfilename(Lppathbuffer,'Tmp',0,Lpbuffer);
Freemem(Lppathbuffer, Max_path);
{$Else} {Get The Temp File Name}
Gettempfilename(Gettempdrive('C'),'Tmp',0,Lpbuffer);
{$Endif} {Create A Pascal String Containg}
{The Temp File Name And Return It}
Result := Strpas(Lpbuffer);
{Free The File Name Buffer}
Freemem(Lpbuffer, Max_path);
End;
{Grava Avi Ou Wav No Arquivo Paradox}
Procedure Tform1.Button1click(Sender: Tobject);
Var Filestream: Tfilestream; {Para Ler O Arquivo Avi}
Blobstream: Tblobstream; {Para Salvar No Campo Blob}
Begin
Application.Processmessages;
Button1.Enabled := False;
Button2.Enabled := False;
If Opendialog1.Execute Then
Filestream := Tfilestream.Create(Opendialog1.Filename,Fmopenread);
Table1.Append;
Table1nome.Value := Opendialog1.Filename;
Blobstream := Tblobstream.Create(Table1avi, Bmreadwrite);
Blobstream.Seek(0, Sofrombeginning);
Blobstream.Truncate;
Blobstream.Copyfrom(Filestream, Filestream.Size);
Filestream.Free;
Blobstream.Free;
Table1.Post;
Button1.Enabled := True;
Button2.Enabled := True;
End;
{Reproduz O Que Está Gravado No Campo Blob}
Procedure Tform1.Button2click(Sender: Tobject);
Var Filestream: Tfilestream; {A Temp File}
Blobstream: Tblobstream; {The Avi Blob}
Begin
Blobstream := Tblobstream.Create(Table1avi, Bmread);
If Blobstream.Size = 0 Then
Begin
Blobstream.Free;
Exit;
End;
Mediaplayer1.Close; {Reset The File Name}
Mediaplayer1.Filename := ''; {Refresh The Play Window}
Mediaplayer1.Display := Panel1;
Panel1.Refresh;
If Filename <> '' Then
Deletefile(Filename); {Get A Temp File Name}
Filename := Gettemporaryfilename; {Create A Temp File Stream}
Filestream := Tfilestream.Create(Filename,Fmcreate Or Fmopenwrite);
Filestream.Copyfrom(Blobstream, Blobstream.Size); {Free The Streams}
Filestream.Free; Blobstream.Free;
Mediaplayer1.Filename := Filename;
Mediaplayer1.Devicetype := Dtavivideo;
Mediaplayer1.Open;
Mediaplayer1.Play;
End;
// Evento Ondestroy Do Form
Procedure Tform1.Formdestroy(Sender: Tobject);
Begin
Mediaplayer1.Close;
Mediaplayer1.Filename := '';
If Filename <> '' Then
Deletefile(Filename);
End;
// Evento Onshow Do Form
Procedure Tform1.Formshow(Sender: Tobject);
Begin
Mediaplayer1 := Tmediaplayer.Create(Self);
With Mediaplayer1 Do
Begin
Parent := Self ;
Visible := False;
End;
Table1.Open;
End;
// Evento Onclose Do Form
Procedure Tform1.Formclose(Sender: Tobject; Var Action: Tcloseaction);
Begin
Table1.Close;
End;
End.
Cuidados ao usar o OnExit
É comum fazermos uso do evento OnExit quando  queremos validar o conteúdo de um Edit. E essa pode ser uma boa prática quando  necessitamos verificar o que foi digitado apenas quando o usuário terminar de  fazer a entrada de dados, como, por exemplo, um Edit que vai receber o CPF ou  CNPJ.
Ao colocarmos um código qualquer no evento  OnExit ele sempre será executado quando o usuário sair do Edit, o que acontece  quando ele pressiona a tecla TAB, clica com o mouse em um outro Edit ou  pressiona um botão OK, por exemplo.
No entanto, existem algumas situações especiais  em que o evento OnExit não é gerado. Quer um exemplo? Você está no Edit e, ao  invés de clicar no botão OK, você pressiona as teclas ALT + O (considerando que  o botão OK tem a tecla O como atalho). É como se você tivesse pressionado o  botão OK, porém, sem perder o foco que está no Edit. Só mais um exemplo: Os  botões do tipo SpeedButton não recebem foco, então, mesmo que clique com o mouse  sobre um SpeedButton, o foco continuará no Edit e, conseqüentemente, o evento  OnExit não será gerado.
E a solução?
A solução para esse pequeno inconveniente é  simples. Basta você colocar o seguinte código no evento OnClick do  botão.
procedure TForm1.Button1Click(Sender:  TObject);
begin
ActiveControl := nil;
...
end;
Suponhamos que você possua 2 Edits em um  formulário. Supondo também que você queira dar alguma informação ao usuário da  aplicação logo depois que ele sair do Edit1 você faz:
procedure TForm1.Edit1Exit(Sender:  TObject);
begin
MessageDlg('Mensagem...', mtInformation, [mbOk],  0);
end;
A princípio está tudo ok, ou melhor, parece  estar tudo ok.
Se você altera o foco para o outro Edit através  do pressionamento da tecla TAB, tudo bem. Mas experimente alterar o foco  clicando com o mouse sobre o Edit2. Neste segundo caso a mensagem será exibida  normalmente. Mas ao fechar o dialogo onde aparece a mensagem, o foco  simplesmente se perde. Para setar o foco no Edit2 é necessário clicar novamente  sobre ele.
Isso poderia não problema nenhum até que seu  usuário experimente esta situação. Nada que ele digitar será acatado.
Mas existe uma maneira fácil de resolver o  problema. Basta você cancelar o foco e forçar uma reentrada no componente Edit2.  Como fazer isso? Veja o código:
procedure TForm1.Edit1Exit(Sender:  TObject);
begin
MessageDlg('Mensagem...', mtInformation, [mbOk],  0);
// cancela o foco e força novamente a  entrada
ActiveControl := nil;
PostMessage(Edit2.Handle, WM_SETFOCUS, 0,  0);
Edit2.SetFocus;
end;
Porém, você nunca terá certeza se o usuário  clicou foi no Edit2. Então temos que criar uma rotina genérica que leva o foco  para qualquer outro controle:
procedure TForm1.Edit1Exit(Sender:  TObject);
var
Ctrl: TWinControl;
begin
MessageDlg('Mensagem...', mtInformation, [mbOk],  0);
// cancela o foco e força novamente a  entrada
Ctrl := ActiveControl;
ActiveControl := nil;
PostMessage(TWinControl(Ctrl).Handle,  WM_SETFOCUS, 0, 0);
TWinControl(Ctrl).SetFocus;
end;
Observe que antes de cancelar o foco com  ActiveControl := nil, salvamos qual é o controle que detém o foco fazendo Ctrl  := ActiveControl.
Depois enviamos uma mensagem ao controle que  detinha o foco, forçando-o a receber o foco novamente.
Rave - Imprimindo Gráficos (Chart)
Uma coisa muito comum  nos sistemas, são os relatórios com gráficos estatísticos, os famosos  Charts.
Antigamente eu usava o  QuickReport e o ReportBuilder, porém relatórios com gráficos só precisei fazer  no QuickReport e não tive muitas dificuldade, pois ele já tem um componente que  facilita a vida.
Mas, como agora larguei o  QuickReport e estou usando somente o Rave, houve então a necessidade de saber  como fazer relatórios nele com gráficos. 
Comecei então a fuçar no Rave e  percebi que não existia nenhum componente que facilitasse a vida. Então fiz  algumas pesquisas na internet para saber se não existiam componentes de  terceiros, mas infelizmente não achei nenhum, porém nessas pesquisas, achei duas  soluções para o caso :
1 – Salvar o conteúdo de um  TCustomChart em um BMP e imprimir esse BMP no Rave
2 – Usar o método WriteChartData disponível na unit RPTChart
2 – Usar o método WriteChartData disponível na unit RPTChart
Esta última solução é a indicada  pela Nevrona.
Fiz o teste com as duas soluções  e as duas foram satisfatórias, porém gostei mais da última solução, pois como  disse, é indicada pela própria Nevrona e não aparenta ser uma "gambiarra" :-)  como a primeira solução.
Depois desta pesquisa, resolvi  escrever este artigo para demonstrar como não é um bicho de sete cabeças fazer  isso funcionar.
Então vamos lá...
Antes de iniciarmos, gostaria de  explicar como a "coisa funciona", para depois partirmos para prática.
O método WriteChartData,  "escreve" o conteúdo  de um TCustomChart dentro de um campo do tipo Graphic. Então, a princípio, nosso  gráfico será montado no TChart ou TDBChart do Delphi, e depois disso, iremos  utilizar o WriteChartData  para fazer com que o  conteúdo do gráfico seja impresso, desenhado dentro do nosso  relatório.
Agora vamos colocar em prática  esta teoria...
Irei utilizar um RVCustomConnection, pois não preciso estar conectado a um  DataSet para gerar o gráfico no Rave, só preciso de alguém que me disponibilize  um campo para poder usá-lo na impressão, então o RVCustomConnection é o ideal para isso. Para quem  não sabe para que serve o RVCustomConnection, vale a pena começar a mexer nele,  pois é muito interessante.
Agora é serio, chega de teoria e  vamos para prática...:-)
1 - Insira os seguintes  componentes no Form:
TRVProject
TRVCustomConnection
TRVSystem
TChart
TRVProject
TRVCustomConnection
TRVSystem
TChart
2 – Na clausula uses,  insira a unit  RPTChart. É esta unit que nos  disponibilizará o método WriteChartData
3 - Ajuste a propriedade  Engine do RaveProject, apontando para o RVSystem.
4 - Ajuste o Chart, de forma que  represente algum gráfico, só para podermos visualizar o resultado  final.
5 – Agora iremos ajustar dois  eventos do componente RVCustomConnection:
OnGetCols:
Este evento é chamado quando o Rave necessita extrair os meta-data dos campos. É aqui que criaremos nosso campo do tipo graphic. Para isso, coloque o seguinte código neste evento:
Este evento é chamado quando o Rave necessita extrair os meta-data dos campos. É aqui que criaremos nosso campo do tipo graphic. Para isso, coloque o seguinte código neste evento:
with  Connection do
begin
WriteField('CampoChart', dtGraphic, 0, '', '');
end;
begin
WriteField('CampoChart', dtGraphic, 0, '', '');
end;
OnGetRow:
Este evento é chamado quando o Rave necessita extrair os valores dos campos do registro atual. É aqui que iremos alimentar o valor do campo que criamos acima. Para isso, coloque o seguinte código neste evento:
Este evento é chamado quando o Rave necessita extrair os valores dos campos do registro atual. É aqui que iremos alimentar o valor do campo que criamos acima. Para isso, coloque o seguinte código neste evento:
WriteChartData(Connection,  Chart1);
Chart1  é o nome do TChart  que inserimos no Form.
A parte de codificação já está  pronta, agora vamos para parte visual.
6 – Entre no RaveDesigner
7 – Crie uma Region  e dentro desta  Region crie uma banda simples.
8 – Dentro da Band1(que acabou de ser criada),  insira o componente MetaFile, que está na palheta Standard do  Rave.
9 – Crie uma DataView, da mesma forma que se fosse  criar uma outra qualquer, a diferença é que os dados agora virão de um  RVCustomConnection.
10 - Após ter criado, perceba que  na TreeView o DataView1  está disponível,  porém se clicar no sinal de mais do DataView1 para exibir os campos, perceberá  que o campo que criamos via código(CampoChart) não está disponível, só tem um  campo, que é o que vem de brinde, mas não use-o. Para que o nosso campo possa  ser criado, o evento OnGetCols terá que ser chamado, e como fazer isso em tempo  de projeto ?
O segredo é : O RaveDesigner  tem que estar aberto juntamente com a aplicação e depois  chamar o Refresh do DataView.
Então vamos lá...
11 - Execute a aplicação e volte  para o RaveDesigner, mas não  feche a aplicação  ainda.
12 – Selecione o DataView1 lá na TreeView e clique com o  botão direito do mouse sobre o DataView1.  Aparecerá um item  chamado Refresh, basta clicar nele e...bingo  :-). Pronto, o campo que criamos via código irá aparecer na lista. Quando clicar  pela primeira vez no Refresh, vai aparecer uma mensagem, é uma alerta de que um  campo será excluído, isso ocorre pois quando criamos a DataView, já veio aquele campo de brinde,  mas como não criamos ele no OnGetCols, então a mensagem alertará de que o mesmo  será excluído.
13 – Agora selecione o componente  MetaFile que foi inserindo em  Band1  e altere duas  propriedades dele:
DataField : CampoChart  (nome do campo que  criamos)
DataView : DataView1 (nome da dataview criada)
DataView : DataView1 (nome da dataview criada)
Pronto...Pode executar a  aplicação e fazer o teste.
Caso queira fazer o teste no  próprio preview do RaveDesigner, basta deixar a aplicação aberta, caso  contrário, se a aplicação não estiver aberta e você chamar o  preview do RaveDesigner, receberá de presente um errinho básico, o famoso "Acess  violation..." :-)
Lembre-se, o exemplo que fizemos  foi com um TChart, o mesmo poderá ser feito com um TDBChart.
Outro detalhe, utilizamos um  RVCustomConnection, mas poderíamos utilizar um  RVDataSetConnection sem problemas, porém neste caso,  só fique atento com o seguinte:
No evento OnGetCols, antes de criar o campo, chame o  método DoGetCols  do Connection que vem como parâmetro neste  evento. Isso deve ser feito para que primeiro sejam criadas as colunas do  DataSet que está associado e depois sim poder criar as suas colunas. 
E no evento OnGetRow, antes de chamar o WriteChartData, chame o método DoGetRow do Connection que vem como parâmetro neste  evento. Isso deve ser feito para que primeiro seja alimentando os campos do  DataSet que está associado e depois sim poder alimentar seus campos criados  manualmente.
Espero que um dia possa surgir um  componente para utilizarmos no Rave, pois assim ficará muito mais fácil, mas  enquanto isso não acontece, temos esta solução.
Utilizando DBExpress de uma Maneira Fácil
DBExpress, segundo meus testes, é a melhor tecnologia para  comunicação com banco de dados. Mas, infelizmente, exige a configuração  de vários parâmetros e manipulação de vários componentes visuais.
Pensando neste problema, resolvi criar um componente que contém um  conjunto de classes, para facilitar a vida do programador em trabalhar  com esta maravilhosa tecnologia.
Procurei criar as classes da melhor maneira possível, com os nomes  dos métodos e propriedades o mais parecido possível com o que conhecemos  e utilizamos em BDE, Zeos, ADO e mesmo no DBExpress.
Neste artigo, descreverei como instalar e fazer uma aplicação simples. Espero que seja útil para a comunidade e, talvez, os pacotes e classes de suas regras de negócio a utilizem.
Neste artigo, descreverei como instalar e fazer uma aplicação simples. Espero que seja útil para a comunidade e, talvez, os pacotes e classes de suas regras de negócio a utilizem.
Passo 1
Download http://sourceforge.net/projects/dddbxfacil/
Este pacote comtém o componente dddbxfacil com suas classes, bem como uma aplicação simples para utilizá-la.
Este pacote comtém o componente dddbxfacil com suas classes, bem como uma aplicação simples para utilizá-la.
Passo 2
Criar arquivo de configuração. Este arquivo, já está contido no  pacote de exemplo e, ele contém a estrutura que é usada pelo  dbconnections.ini e, serve para indicar os parâmetros para conexão ao  banco de dados. Eu não costumo deixar o login e password contido neste  arquivo mas, nada impede de se inserir nele.
A configuração que defini, foi para o Oracle mas, pode ser para  qualquer banco que o Dbexpress é compatível que, acho que são todos:
[NOMESECAOCONFIGORACLE]
CONNECTIONNAME=OracleConnection
GETDRIVERFUNC=getSQLDriverORACLE
VENDORLIB=oci.dll
LibraryName=dbxora30.dll
DriverName=Oracle
HostName=
Database=
User_Name=
Password=
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
Compressed=False
Encrypted=False
CONNECTIONNAME=OracleConnection
GETDRIVERFUNC=getSQLDriverORACLE
VENDORLIB=oci.dll
LibraryName=dbxora30.dll
DriverName=Oracle
HostName=
Database=
User_Name=
Password=
BlobSize=-1
ErrorResourceFile=
LocaleCode=0000
Compressed=False
Encrypted=False
Passo 3
No uses de sua unit, vamos inserir as seguintes units:
DB, DBTables, ddcomumDBX, ddconexaoDBX, ddsqlDBX, ddproviderDBX.
DB, DBTables, ddcomumDBX, ddconexaoDBX, ddsqlDBX, ddproviderDBX.
Passo 4
Vamos no private e, colocar as seguintes “variáveis”:
ConexaoDBX: TConexaoDBX;
ProviderDBX: TProviderDBX;
SqlDBX: TsqlDBX;
ProviderDBX: TProviderDBX;
SqlDBX: TsqlDBX;
Passo 5
Este passo é opcional mas, para mostrar melhor o funcionamento da  classe, criaremos um método chamado MeuDataChange, novamente apontar  ele.
//No private:
procedure MeuDataChange(Sender: TObject; Field: Tfield); //No implementation
procedure TForm2.MeuDataChange(Sender: TObject; Field: TField);
begin
// Nao é necessário colocar teste para ver se tabela tá aberta, DisableControls, etc…
grbTesteGrid.Caption := ‘Testando o grid. Agora são ‘+
FormatDateTime(‘dd/mm/yyyy hh:nn:ss’, now);
end;
procedure MeuDataChange(Sender: TObject; Field: Tfield); //No implementation
procedure TForm2.MeuDataChange(Sender: TObject; Field: TField);
begin
// Nao é necessário colocar teste para ver se tabela tá aberta, DisableControls, etc…
grbTesteGrid.Caption := ‘Testando o grid. Agora são ‘+
FormatDateTime(‘dd/mm/yyyy hh:nn:ss’, now);
end;
Passo 6
Precisamos instanciar as variáveis que criamos no private. Para isso,  criei procedimentos para facilitar isso. No formShow, colocaremos o  seguinte código:
ddconexaoDBX.ConexaoDBXInit(ConexaoDBX,  nil,
IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))+‘configuracao.ini’,
‘NOMESECAOCONFIGORACLE’); ConexaoDBX.Login := ‘usuario’;
ConexaoDBX.Senha := ‘senha’;
ddproviderDBX.ProviderDBXInit(ProviderDBX,
ConexaoDBX,
DBGrid1,
‘ROWID’,
true,
MeuDataChange);
ddsqlDBX.SqlDBXInit(SqlDBX, ConexaoDBX);
IncludeTrailingPathDelimiter(ExtractFilePath(Application.ExeName))+‘configuracao.ini’,
‘NOMESECAOCONFIGORACLE’); ConexaoDBX.Login := ‘usuario’;
ConexaoDBX.Senha := ‘senha’;
ddproviderDBX.ProviderDBXInit(ProviderDBX,
ConexaoDBX,
DBGrid1,
‘ROWID’,
true,
MeuDataChange);
ddsqlDBX.SqlDBXInit(SqlDBX, ConexaoDBX);
Passo 7
Exemplo de código para executar busca no banco de dados:
procedure TForm2.btnProcurarClick(Sender: TObject);
var
Retorno: TProviderRetorno;
begin
ConexaoDBX.ConectarSeDesconectado; ProviderDBX.ClearAll;
with ProviderDBX, ProviderDBX.LinhaSQL do
begin
Add(‘SELECT * FROM TABELA’);
Retorno := OpenDQL;
end;
end;
var
Retorno: TProviderRetorno;
begin
ConexaoDBX.ConectarSeDesconectado; ProviderDBX.ClearAll;
with ProviderDBX, ProviderDBX.LinhaSQL do
begin
Add(‘SELECT * FROM TABELA’);
Retorno := OpenDQL;
end;
end;
Passo 8
Exemplo de evento de inclusão:
procedure TForm2.btnincluirClick(Sender: TObject);
var
iProximoCodigo: integer;
begin
ConexaoDBX.ConectarSeDesconectado; // Pegar Próximo Codigo
with SQLDBX do
begin
setLinhaSQL(‘SELECT MAX(CODIGO) PROXIMO FROM TABELA’);
OpenDQL;
iProximoCodigo := SQLDQl.FieldByName(‘PROXIMO’).AsInteger+1;
end;
ConexaoDBX.Transacao_Abrir;
try
// Incluir
with SqlDBX do
begin
ClearAll;
with LinhaSQL do
begin
Add(‘INSERT INTO TABELA (CODIGO, DESCRICAO)’);
Add(‘VALUES’);
Add(‘(:P_CODIGO,
 _DESCRICAO)’);
end;
AddParam(ftInteger, ‘P_CODIGO’, iProximoCodigo);
AddParam(ftString, ‘P_DESCRICAO’, ‘nome ‘+IntToStr(iProximoCodigo));
ExecDML;
end;
ConexaoDBX.Transacao_Commit;
except
on E:Exception do
begin
ConexaoDBX.Transacao_RollBack;
ShowMessage(E.Message);
end;
end;
end;
var
iProximoCodigo: integer;
begin
ConexaoDBX.ConectarSeDesconectado; // Pegar Próximo Codigo
with SQLDBX do
begin
setLinhaSQL(‘SELECT MAX(CODIGO) PROXIMO FROM TABELA’);
OpenDQL;
iProximoCodigo := SQLDQl.FieldByName(‘PROXIMO’).AsInteger+1;
end;
ConexaoDBX.Transacao_Abrir;
try
// Incluir
with SqlDBX do
begin
ClearAll;
with LinhaSQL do
begin
Add(‘INSERT INTO TABELA (CODIGO, DESCRICAO)’);
Add(‘VALUES’);
Add(‘(:P_CODIGO,
end;
AddParam(ftInteger, ‘P_CODIGO’, iProximoCodigo);
AddParam(ftString, ‘P_DESCRICAO’, ‘nome ‘+IntToStr(iProximoCodigo));
ExecDML;
end;
ConexaoDBX.Transacao_Commit;
except
on E:Exception do
begin
ConexaoDBX.Transacao_RollBack;
ShowMessage(E.Message);
end;
end;
end;
Assinar:
Comentários (Atom)
- 
function GetIP:string;//--> Declare a Winsock na clausula uses da unit var WSAData: TWSAData; HostEnt: PHostEnt; Name:string; begin...