Anda di halaman 1dari 30

Revista The Club Megazine - 01/2004

A utilizao, reproduo, apropriao, armazenamento em banco de dados,


sob qualquer forma ou meio, de textos, fotos e outras criaes intelectuais
em cada publicao da revista The Club so terminantemente proibidos
sem autorizao escrita dos titulares dos direitos autorais.
CopyrightThe Club2004
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 3 33 33
EDITORIAL EDITORIAL EDITORIAL EDITORIAL EDITORIAL
Editorial
Celso Jefferson Paganelli
Presidente - The Club
Editorial ............................................................................ 03
Write Printer - Criando impresses rpidas para o Delphi ... 04
Trabalhando com eventos ................................................. 14
Retrospectiva .................................................................... 16
Intraweb - Programao Alternativa .................................. 18
Usando o Object Repository .............................................. 24
Perguntas & Respostas ...................................................... 26
THE CLUB
Av. Celso Ferreira da Silva, 190
Jd. Europa - Avar - SP - CEP 18.707-150
Informaes: (0xx14) 3732-3689
Suporte: (0xx14) 3733-1588 - Fax: (0xx14) 3732-0987
Internet
http://www.theclub.com.br
Cadastro: cadastro@theclub.com.br
Suporte: suporte@theclub.com.br
Informaes: info@theclub.com.br
Dvidas
Correspondncia ou fax com dvidas devem ser
enviados ao - THE CLUB, indicando "Suporte".
Opinio
Se voc quer dar a sua opinio sobre o clube em
geral, mande a sua correspondncia para a seo
"Tire sua dvida".
Reproduo
A utilizao, reproduo, apropriao,
armazenamento em banco de dados, sob qualquer
forma ou meio, de textos, fotos e outras criaes
intelectuais em cada publicao da Revista
The Club so terminantemente proibidos sem
autorizao escrita dos titulares dos direitos
autorais.
Copyright

The Club

2004
Impresso e acabamento:
Impressos Gril - Gril Grfica e Repr. Ind. Ltda.
Tel.: (0xx14) 3762.1345 - Fax: (0xx14) 3762.1259
Rua So Paulo, 447 - Cep 18.740-000
Taquarituba - SP
Tiragem: 5.000 exemplares
Diretor - Presidente
Celso Jefferson M. Paganelli
Diretor Tcnico
Mauro SantAnna
Colaboradores
Emerson Facunte
Delphi marca registrada da Borland International, as
demais marcas citadas so registradas pelos seus
respectivos proprietrios.
Primeiramente, gostaria de desejar todos um 2004 cheio de muito sucesso e
realizaes e que possamos estar juntos por mais este ano que se inicia!
2004 com certeza ser marcado por muitas novidades, comeando pelo Delphi 8 que
j est pronto e segundo informaes extra-oficiais, sua verso trial estar disponvel
at o final deste ms de janeiro. Ns j tivemos a oportunidade de fazer um test-drive
nesta verso, e sinceramente, superou nossas expectativas. O desenvolvimento para
plataforma Microsoft .Net no ser o mesmo aps o lanamento do Delphi 8, vale a
pena aguardar!
Enquanto o Delphi 8 no est disponvel, vamos comeando mais uma The Club
Megazine com um artigo que foi muito solicitado ao nosso setor de suporte, o qual trata
sobre a impresso rpida via Delphi, fazendo tratamentos para impresso local e em
rede e ainda em portas USB, confira...
Prosseguindo, uma pequena referncia sobre a manipulao de eventos no Delphi e
nosso amigo Emerson Facunte num artigo dividido em duas partes que ir apresentar
alguns macetes para desenvolvimento de aplicaes para internet via IntraWeb para
obter o melhor resultado.
E para finalizar, algumas dicas sobre o funcionamento do Object Repository do
Delphi, recurso bastante interessante e pouco explorado por muitos programadores, e
encerramos com a sesso Perguntas & Respostas, onde esto compartilhadas algumas
das dvidas que passaram pelo suporte neste ms.
Boa leitura e um 2004 cheio de sucesso!
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 4 44 44
Sempre que falamos de impresso rpida (padro DOS)
dentro do Delphi, normalmente optamos pela impresso atravs
dos comandos AssignFile, ReWrite e Writeln. Esses comandos
funcionam satisfatoriamente, digo satisfatoriamente, porque em
alguns casos apresentaram problemas, como por exemplo,
ocultar determinados caracteres de uma palavra no meio do texto
impresso, no permite uma verificao se a impressora est
pronta para a impresso e tambm no controlam quando vrias
pessoas mandam suas impresses para a mesma impressora e ao
mesmo tempo.
Diante desses problemas criamos um projeto onde fazemos as
impresses rpidas (padro DOS) atravs da procedure
WritePrinter da unit WinSpool. Para entendermos um pouco
melhor primeiramente vamos verificar quais os recursos que
essa procedure nos dar ao utiliz-la e depois passo a passo
criaremos os projetos de exemplo.
Como essa impresso ir funcionar
O Delphi nos traz j h bastante tempo uma unit chamada
WinSpool que, apesar de no ser muito utilizada, bastante til
pois contm mtodos que permitem fazer uma impresso rpida
(padro DOS) como o Writeln, mas utilizando o Spool da
impressora.
Para isso antes de iniciarmos a impresso executamos uma
function que ir fazer um contato com a impressora verificando
se a mesma est pronta para o trabalho, caso positivo fazemos
mais algumas inicializaes para o Spool e comeamos a enviar
os trabalhos de impresso. Neste momento se essa impressora j
est em uso o nosso trabalho de impresso entra na fila do spool e
fica aguardando a sua vez.
Veja que neste momento j resolvemos alguns dos problemas
mencionados no incio, que a verificao se a impressora est
pronta e controlar quando a impressora j est em uso. Mas o
mais importante que tudo isso feito sem perder a velocidade
no momento da impresso.
Na verdade essa unit WinSpool traz inmeros mtodos para
controle do Spool de impresso e que renderiam vrias matrias
em nossa revista, mas isso deixaremos para outra oportunidade,
pois por enquanto trataremos somente das funes as quais
estaremos utilizando em nosso projeto.
Iniciando os trabalhos
Neste primeiro projeto iremos aproveitar para entender um
pouco sobre as funes utilizadas da unit WinSpool para fazer as
impresses. E um detalhe importante que essas impresses
foram testadas com as verses do Delphi3 e Delphi6 e ambas
funcionaram perfeitamente.
Vamos iniciar os nossos trabalhos criando um novo projeto,
chamado Exemplo1.
Neste novo projeto visualize a unit e declare na seo
implementation a unit WinSpool.
Em seguida coloque um boto no form e no evento onClick
deste boto inclua as seguintes instrues:
procedure TForm1.Button1Click(Sender: TObject);
var
hPrinter: THandle;
BytesWritten: DWORD;
DocInfo: TDocInfo1;
NomeImp, Texto: String;
begin
NomeImp := LerImpressora;
if not OpenPrinter(PChar( NomeImp ),
hPrinter, nil) then
WritePrinter WritePrinter
WritePrinter WritePrinter WritePrinter
Criando impresses rpidas para o Delphi Criando impresses rpidas para o Delphi Criando impresses rpidas para o Delphi Criando impresses rpidas para o Delphi Criando impresses rpidas para o Delphi
Por Andr Colavite
Delphi Delphi Delphi Delphi Delphi
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 5 55 55
Delphi Delphi Delphi Delphi Delphi
raise exception.create(THE CLUB - Impressora
no encontrada!);
{ Informaes para o spool de impresso }
DocInfo.pDocName := PChar( THE CLUB - Testando
trabalho de impresso );
DocInfo.pOutputFile := nil;
DocInfo.pDatatype := RAW;
if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
Exit;
if not StartPagePrinter(hPrinter) then
Exit;
Texto := Imprimindo Primeira linha;
WritePrinter(hPrinter, PChar(Texto),
Length(Texto), BytesWritten);
Texto := Imprimindo Segunda coluna da Primeira
linha;
WritePrinter(hPrinter, PChar(Texto),
Length(Texto), BytesWritten);
{ Executa um Eject da folha }
WritePrinter(hPrinter, PChar(#13+#10),
Length(#13+#10), BytesWritten);
Texto := Imprimindo Segunda linha do relatorio;
WritePrinter(hPrinter, PChar(Texto),
Length(Texto), BytesWritten);
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
ClosePrinter(hPrinter);
end;
Neste evento onClick executamos uma function chamada
LerImpressora ao qual ser criada com a seguinte
estrutura:
function LerImpressora: String;
var
MyPrinter, MyDriver, MyPort: array[0..100] of
Char;
DevMode: THandle;
begin
Printer.GetPrinter(MyPrinter, MyDriver, MyPort,
DevMode);
Result := MyPrinter;
end;
Para essa function LerImpressora funcionar devemos
declarar a unit Printers na seo implementation e tambm
declarar essa function acima da seo var da unit. Conforme
exemplo abaixo:
function LerImpressora: String;
var
Form1: TForm1;
Neste momento podemos gravar o projeto e test-lo, ao qual
far a impresso na impressora selecionada como padro no
Windows.
Entendendo os comandos utilizados.
Como podemos observar, bastante simples a criao de
relatrios utilizando essas funes da unit WinSpool. Sendo
assim vamos aproveitar para verificar os detalhes de cada funo
utilizada no Exemplo1.
OpenPrinter(PChar( NomeImp ), hPrinter, nil)
Retorna o controle identificando a impressora ou servidor de
impressora especificado.
Param1 - String que especifica o nome da impressora ou
servidor de impressora.
Param2 - Varivel que recebe o handle de identificao da
impressora aberta.
Param3 - Este valor pode ser nulo.
StartDocPrinter(hPrinter, 1, @DocInfo)
Informa ao Spooler de impresso que o documento pode ser
armazenado no Spool para impresso.
Param1 Identifica a impressora
Param2 Especifica a verso da estrutura a ser usada. Para
o Windows 95 devemos especificar o valor 2 e as demais verses
devemos especificar o valor 1.
Param3 Varivel do tipo TDocInfo1
StartPagePrinter(hPrinter)
Informa ao Spooler que uma pgina est a ponto de ser
impressa na impressora especificada.
Param1 Identifica a impressora
WritePrinter(hPrinter, PChar(Texto),
Length(Texto), BytesWritten);
Informa ao Spooler quais os dados a serem enviados para a
impressora selecionada.
Param1 Identifica a impressora
Param2 Array de bytes que contm os dados que devero
ser enviados para a impressora
Param3 Especifica o tamanho, em bytes, do Array
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 6 66 66
Delphi Delphi Delphi Delphi Delphi
Param4 Varivel que conter a quantidade de bytes
enviados para a impressora.
EndPagePrinter(hPrinter);
Informar o fim da pgina atual e o comeo da pgina
seguinte para a impressora especificada.
Param1 - Identifica a impressora
EndDocPrinter(hPrinter);
Finaliza o trabalho de impresso.
Param1 - Identifica a impressora
ClosePrinter(hPrinter);
Fecha a impressora especificada.
Param1 - Identifica a impressora a ser fechada.
Maiores detalhes sobre essas e outras funes existentes na
unit WinSpool recomendo que sejam verificadas atravs do help
do Delphi.
Criando um projeto mais complexo.
Como agora j conhecemos um pouco como trabalhar com
essas funes, deixaremos as idias flurem e comearemos a
utiliz-las de uma forma mais complexa. Como por exemplo,
criar um projeto onde fazemos a impresso de dados de um banco
de dados separando os campos por coluna, e fazendo o controle da
impresso de cabealho. Sendo assim mos a obra.
Primeiro passo crie um novo projeto no Delphi, chamado
Exemplo2, e em seguida adicione um novo form neste projeto.
Para o Form principal deixaremos o nome Form1 mesmo,
para o segundo form coloque FrmPreview e unPreview para a
sua unit.
A idia desse projeto criar uma estrutura genrica para
impresso de relatrios utilizando as funes da unit WinSpool,
sendo assim essa unit unPreview com o FrmPreview podero ser
utilizados em outros projetos para a gerao de relatrios rpidos.
Comearemos a montar o FrmPreview, sendo assim coloque
neste form um componente Memo, altera a sua propriedade
Align para o valor alClient e na propriedade Font / Name
selecione a fonte Courier New.
Declaraes
Visualize a unit unPreview e nesta unit faa as declaraes
que esto especificadas a seguir:
Declarar na seo Private uma varivel do tipo string
chamada ArqPreview
private
ArqPreview: String;
public
end;
Declarar acima da seo var as Functions e Procedures que
implementaremos na unit, veja a seguir:
function GeraArqTemp: String;
function LerImpressora: String;
function Imp_Inicio(Const pNomeImp, pNomeTrabalho,
pTipo: String; pPreview: Boolean): Boolean;
procedure Imp_InicializaPagina;
procedure Imp_Fim;
procedure Imp_Linha(SaltaLin, EspacoCol: Integer;
Texto: String; TamTotal: Integer; Alinha: Char);
procedure Imp_Ejeta;
Declarar na seo var duas variveis, veja a seguir:
var
FrmPreview: TFrmPreview;
hPrinter: THandle;
BytesWritten: DWORD;
E na seo implementation declarar as units WinSpool e
Printers, veja a seguir:
implementation
Uses WinSpool, Printers;
Implementando as Functions e Procedures
A primeira function que iremos implementar na unit, ser a
LerImpressora que responsvel por retornar informaes da
impressora atualmente selecionada para impresso. Essa
function ficar com a seguinte estrutura:
function LerImpressora: String;
var
MyPrinter, MyDriver, MyPort: array[0..100]
of Char;
DevMode: THandle;
begin
Printer.GetPrinter(MyPrinter, MyDriver,
MyPort, DevMode);
Result := MyPrinter;
end;
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 7 77 77
Delphi Delphi Delphi Delphi Delphi
A prxima function a Imp_Inicio ao qual ser responsvel
por inicializar a impresso passando as informaes necessrias
para o Spool da impressora. Nesta function utilizaremos os
seguintes parmetros:
pNomeImp Nome da impressora para onde o trabalho de
impresso ser enviado
pNomeTrabalho Nome do trabalho de impresso que ser
apresentado na fila do Spool
pTipo Passar o valor RAW ou TEXT.
RAW - deixou a impresso na matricial mais rpida
TEXT - imprimiu com impressora USB
pPreview Indica se iremos mostrar um preview do relatrio
Essa function Imp_Inicio tem um retorno do tipo Boolean ao
qual indicar se a inicializao do relatrio foi realizada com
sucesso e se podemos comear a impresso dos dados. Veja a
estrutura da function Imp_Inicio a seguir:
function Imp_Inicio(Const pNomeImp, pNomeTrabalho,
pTipo: String; pPreview: Boolean): Boolean;
var
DocInfo: TDocInfo1;
begin
Result := False;
if not WinSpool.OpenPrinter(PChar( pNomeImp ),
hPrinter, nil) then
raise exception.create(THE CLUB -
Impressora no encontrada!);
DocInfo.pDocName := PChar( pNomeTrabalho );
DocInfo.pOutputFile := nil;
if pPreview then
begin
DocInfo.pOutputFile := PChar( GeraArqTemp );
FrmPreview := TFrmPreview.Create( Nil );
FrmPreview.ArqPreview := DocInfo.pOutputFile;
end;
DocInfo.pDatatype := PChar( pTipo );
if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
Exit;
if not StartPagePrinter(hPrinter) then
Exit;
Result := True;
end;
Nesta function Imp_Inicio fazemos uma chamada para a
function GeraArqTemp, ao qual ser responsvel pela criao do
nome do arquivo temporrio que armazenar o relatrio para ser
apresentado no Preview, caso o usurio selecione visualizar o
relatrio no Preview. Essa function ter a seguinte estrutura:
function GeraArqTemp: String;
var
TempDir: array[0..MAX_PATH] of char;
Buffer : array[0..MAX_PATH] of Char;
begin
GetTempPath(MAX_PATH, @TempDir);
GetTempFileName(@TempDir, CLUB, 0, Buffer);
Result := Buffer;
end;
Esta procedure GetTempfileName utilizada necessita dos
seguintes parmetros:
Parametros
1. Diretorio,
2. Prefixo,
3. 0 -> indica que no ir repetir o nome do arquivo,
4. Varivel que ir receber o nome gerado
A procedure Imp_InicializaPagina responsvel pela
inicializao da pgina que ser enviada para o Spool de
impresso. Essa procedure ter a seguinte estrutura:
procedure Imp_InicializaPagina;
begin
if not StartPagePrinter(hPrinter) then
raise exception.create(THE CLUB -
Problemas na inicializao da pgina!);
end;
Em seguida iremos criar a prxima function que ser a
Imp_Fim, ao qual ser responsvel pela finalizao do relatrio.
Essa procedure ter a seguinte estrutura:
procedure Imp_Fim;
begin
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
if Assigned( FrMPreview ) then
begin
try
FrmPreview.Memo1.Lines.LoadFromFile
( FrmPreview.ArqPreview );
FrMPreview.ShowModal;
{ Exclui o arquivo temporrio }
try
DeleteFile( FrmPreview.ArqPreview );
except end;
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 8 88 88
Delphi Delphi Delphi Delphi Delphi
finally
FreeAndNil( FrMPreview );
end;
end;
end;
Nesta procedure tambm iremos apresentar o form contendo
a visualizao dos dados em preview. Mas iremos observar que
um preview bem simples, ao qual foi criado para mostrar que
podemos criar um arquivo contendo os dados enviados para a
impressora.
A prxima procedure a ser criada a Imp_Linha ao qual ser
utilizada para fazer a impresso das linhas do relatrio. Nesta
procedure implementamos alguns controles a mais, como por
exemplo, impresso da linha com ou sem o salto da linha,
espaamento para fazer impresso em coluna e alinhamento a
direita ou a esquerda dessas colunas.
Os parmetros criados para essa procedure foram:
SaltaLin - Qtde de linhas que saltar a partir da ltima linha
impressa
EspacoCol - Espao em caracteres que existir entre as
colunas
Texto - String a ser impressa
TamTotal - Tamanho total da string, utilizado para
impresso em coluna
Alinha - Alinhamento da coluna E = Esquerda - D = Direita
A estrutura da procedure ficar da seguinte forma:
procedure Imp_Linha(SaltaLin, EspacoCol: Integer;
Texto: String; TamTotal: Integer; Alinha: Char);
var
i: integer;
Espaco: string;
begin
{ adiciona as linhas }
for i:=1 to SaltaLin do
WritePrinter(hPrinter, PChar(#13+#10),
Length(#13+#10), BytesWritten);
{ Calcula o espao q determinado o tamanho total
do campo }
Espaco := StringOfChar( , TamTotal-
Length(Texto));
if Alinha = E then
Texto := Texto+Espaco
else if Alinha = D then
Texto := Espaco+Texto;
{ adiciona espao entre as colunas }
Texto := StringOfChar( , EspacoCol)+Texto;
{ Imprime o texto }
WritePrinter(hPrinter, PChar(Texto),
Length(Texto), BytesWritten);
end;
A ltima procedure a ser implementada nesta unit a
procedure Imp_Ejeta, ao qual ser responsvel pela salto de
pgina e pela controle de finalizao da pgina atual no Spool.
A estrutura dessa procedure ficar da seguinte forma:
procedure Imp_Ejeta;
var ch: Char;
begin
ch:= #12;
WritePrinter( hPrinter, @ch, 1, BytesWritten );
EndPagePrinter(hPrinter);
end;
Pronto, neste momento finalizamos a criao da unit que
poder ser utilizada na criao de qualquer relatrio em nossos
projetos.
Utilizando a unit unPreview
A segunda parte desse projeto ser a utilizao dessas
functions e procedures que criamos na unit unPreview. Sendo
assim volte ao form principal do nosso projeto e coloque os
seguintes componentes descritos a seguir:
Table,
DataSource,
DBNavigator
DBGrid
PrintDialog
Panel - Dentro desse Panel coloque os seguintes componentes:
GroupBox - Dentro desse GroupBox coloque um Label
3 componentes Button
RadioGroup
CheckBox
Esses componentes sero configurados da seguinte forma:
Componente Table
Name: Table1
DatabaseName: DBDEMOS
TableName: Employee.db
Componente DataSource
Name: DataSource1
DataSet: Table1
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 9 99 99
Delphi Delphi Delphi Delphi Delphi
Componente DBNavigator
Name: DBNavigator1
Align: alTop
DataSource: DataSource1
Componente Panel
Name: Panel1
Align: alBottom
Caption: vazio
Componente DBGrid
Name: DBGrid1
Align: alClient
DataSource: DataSource1
Componente PrintDialog
Name: PrintDialog1
Componente GroupBox
Name: GroupBox1
Caption: Impressora selecionada
Componente Label
Name: Label1
Componente RadioGroup
Name: RadioGroup1
Caption: Tipo
Columns: 1
ItemIndex: 0
Items: RAW TEXT
Componente CheckBox
Name: CheckBox1
Caption: Preview
Componentes Buttons
Name: Button1
Caption: Imprimir registros
Name: Button2
Caption: Selecionar Impressora
Name: Button3
Caption: Relatrio Simples
Aps configurar todos esses componentes o form ficar
parecido com a imagem 1. (abaixo)
No evento onclick dos botes iremos montar os relatrios
utilizando as instruo da unit unPreview, sendo assim o
primeira passo declarar na seo implementation a unit
unPreview, conforme exemplo a seguir:
implementation
Uses UnPreview;
Iniciaremos com o Button2 onde iremos chamar o
PrintDialog para que assim o usurio possa selecionar a
impressora a ser utilizada:
procedure TForm1.Button2Click(Sender: TObject);
begin
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 0 1 0 1 0 1 0 1 0
Delphi Delphi Delphi Delphi Delphi
if PrintDialog1.Execute then
Label1.Caption := LerImpressora;
end;
No evento onclick do Button3 criaremos um relatrio
bastante simples ao qual nos permitir fazer um teste de
impresso. A instruo desse evento ficar da seguinte forma:
procedure TForm1.Button3Click(Sender: TObject);
{ Observao: Caracteres utilizados para impressora
Epson }
Const
NegOn = #27+#71; NegOff = #27+#71;
ItaOn = #27+#52; ItaOff = #27+#52;
CondOn = #15; CondOff = #18;
begin
{ Imprimindo um simples relatrio com
EPSON FX-1170 }
if Imp_Inicio( Label1.Caption, Impresso de
relatrio Simples - THE CLUB, RAW,
CheckBox1.Checked) then
begin
Imp_InicializaPagina;
Imp_Linha(01, 00, Essa e a primeira linha
do relatorio, 0, D);
Imp_Linha(00, 20, Segunda coluna impressa,
0, D);
Imp_Linha(01, 00, NegOn+Negrito+NegOff, 0,
D);
Imp_Linha(00, 10, ItaOn+Italico+ItaOff, 0,
D);
Imp_Linha(00, 10, CondOn+Condensado Primeira
linha, 0, D);
Imp_Linha(00, 10, Condensado Segunda
linha+CondOff, 0, D);
Imp_Ejeta;
Imp_InicializaPagina;
Imp_Linha(01, 00, Imprimindo a prxima
pgina do relatrio, 0, D);
Imp_Linha(01, 00, Segunda linha impressa, 0,
D);
Imp_Ejeta;
Imp_Fim
end;
end;
Finalizando iremos criar o relatrio principal ao qual imprime
os dados do componente Table e faz o controle de cabealho e
coluna. A seguir podemos verificar as instrues criadas dentro
do evento onClick do Button1.
procedure TForm1.Button1Click(Sender: TObject);
var nLin: Integer;
Tipo: String;
procedure Cabecalho;
begin
Imp_InicializaPagina;
{ Impresso do Cabealho }
Imp_Linha(01, 00, Cdigo, 6, E);
Imp_Linha(00, 03, Nome, 15, E);
Imp_Linha(00, 02, Sobrenome, 24, E);
Imp_Linha(00, 02, Data, 10, E);
Imp_Linha(00, 01, Valor, 12, D);
Imp_Linha(01, 00, StringOfChar(-, 80), 80,
E);
nLin := nLin + 2;
end;
begin
Table1.First;
if RadioGroup1.ItemIndex = 0 then
Tipo := RAW // Dica: Imprime com matricial
// Epson mais rpido
else
Tipo := TEXT; // Dica: Funciona para
// impressora USB
if Imp_Inicio( Label1.Caption, Impresso de dados
Employee - THE CLUB, Tipo, CheckBox1.Checked) then
begin
{ Impresso dos dados }
nLin := 0;
While not Table1.Eof do
begin
if nLin = 0 then
begin
Cabecalho;
end;
Imp_Linha(01, 00, Table1.FieldByName
(EmpNo).AsString, 5, D);
Imp_Linha(00, 04, Table1.FieldByName
(FirstName).AsString, 15, E);
Imp_Linha(00, 02, Table1.FieldByName
(LastName).AsString,
Table1.FieldByName(LastName).
DisplayWidth, E);
Imp_Linha(00, 02, FormatDateTime
(dd/mm/yyyy, Table1.FieldByName
(HireDate).AsDateTime), 10, E);
Imp_Linha(00, 01, FormatFloat(###,##0.00,
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 1 1 1 1 1 1 1 1 1
Delphi Delphi Delphi Delphi Delphi
Table1.FieldByName(Salary).asFloat),
Table1.FieldByName(Salary).DisplayWidth, D);
Inc( nLin );
if nLin >= 62 then
begin
Imp_Ejeta;
nLin := 0;
end;
Table1.Next;
end;
Imp_Ejeta;
Imp_Fim
end;
end;
Pronto, neste momento estamos com o projeto de relatrio
quase pronto, faltando somente implementar o evento onShow do
Form onde abriremos a Table1 e iremos mostrar qual a
impressora que est selecionada como padro. Veja exemplo do
evento onShow do form a seguir:
procedure TForm1.FormShow(Sender: TObject);
begin
Table1.Open;
Label1.Caption := LerImpressora;
end;
Agora podemos compilar o nosso projeto e efetuar os testes de
impresso e de apresentao do preview.
Redefinindo o Whiteln da unit System
Espero que no estejam cansados, pois temos um ltimo
exemplo a seguir ao qual nos ajudar bastante caso j tenhamos
criado algum relatrio utilizando os comandos AssignFile,
ReWrite, Writeln e CloseFile da unit System.
A idia desse novo projeto redirecionar as chamadas das
procedures da unit System para as procedures da unit que
iremos criar, sendo assim toda vez que seu projeto chamar uma
impresso pelo Writeln ele estar chamando a procedure Writeln
que iremos criar ao qual usar a impresso pelo WritePrinter.
Vamos entender melhor assim que criarmos o projeto de exemplo,
portanto mos a obra.
Crie um novo projeto, chamado Exemplo3, e neste novo
projeto crie uma nova unit sem form chamada unImpTH.
Nesta unit unImpTH iremos iniciar os trabalhos com as
declaraes, pois precisamos declarar na seo Uses as seguintes
units:
Uses Windows, WinSpool, Printers, SysUtils, Dialogs;
Depois necessitamos declarar as procedure e functions que
sero criadas posteriormente.
function LerImpressora: String;
procedure AssignFile(var FTH: TextFile;
FileNameTH: String);
procedure CloseFile(var FTH: TextFile);
procedure WriteLn(var FTH: TextFile;
TextoTH: String);
procedure ReWrite(var FTH: TextFile);
E para finalizar as declaraes iremos declarar duas
variveis na seo var.
var
hPrinter: THandle;
BytesWritten: DWORD;
Agora iremos implementar as procedures e function, sendo
assim iniciaremos com a function LerImpressora, ao qual
conter as seguintes instrues:
function LerImpressora: String;
var
MyPrinter, MyDriver, MyPort: array[0..100]
of Char;
DevMode: THandle;
begin
Printer.GetPrinter(MyPrinter, MyDriver,
MyPort, DevMode);
Result := MyPrinter;
end;
Em seguida criaremos a procedure AssigFile ao qual devemos
criar com parmetros idnticos aos da procedure da unit System,
ficando a procedure da seguinte forma:
procedure AssignFile(var FTH: TextFile; FileNameTH:
String);
var
DocInfo: TDocInfo1;
PD: TPrintDialog;
begin
{ Chama o PrintDialog para selecionar a
impressora }
PD := TPrintDialog.Create(Nil);
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 2 1 2 1 2 1 2 1 2
Delphi Delphi Delphi Delphi Delphi
try
if not PD.Execute then
Exit;
finally
PD.Free;
end;
if not WinSpool.OpenPrinter(PChar( Printer.
Printers[Printer.PrinterIndex] ),
hPrinter, nil) then
raise exception.create(THE CLUB -
Impressora no encontrada!);
DocInfo.pDocName := Impresso THE CLUB;
DocInfo.pOutputFile :=
PChar( FileNameTH );//c:\arq.txt;
{ Foi testado o DataType com o valor RAW e TEXT
RAW -> deixou a impresso matricial mais rpida
TEXT -> imprimiu com impressora USB }
DocInfo.pDatatype := RAW;
if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
Exit;
if not StartPagePrinter(hPrinter) then
Exit;
end;
A prxima procedure ser a ReWrite, mas essa somente ser
criada para anular a chamada da procedure da unit System, pois
no implementaremos nenhuma funcionalidade na mesma. Veja
a procedure a seguir:
procedure ReWrite(var FTH: TextFile);
begin
// criado somente para anular a
// function da unit System
Exit;
end;
A procedure CloseFile a prxima a ser criada e esta ser
utilizada para finalizar a impresso da pgina e do relatrio,
conforme pode ser observado a seguir:
procedure CloseFile(var FTH: TextFile);
begin
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
WinSpool.ClosePrinter(hPrinter);
end;
E para finalizar criaremos as procedures Write e Writeln ao
qual faro a impresso dos dados para a impressora, veja que
seguem com os mesmos parmetros das originais.
procedure Writeln(var FTH: TextFile; TextoTH:
String);
begin
TextoTH := TextoTH + #13+#10;
WritePrinter(hPrinter, PChar(TextoTH),
Length(TextoTH), BytesWritten);
end;
procedure Write(var FTH: TextFile; TextoTH: String);
begin
WritePrinter(hPrinter, PChar(TextoTH),
Length(TextoTH), BytesWritten);
end;
Bem neste momento finalizamos a criao da unit unImpTH
e agora podemos fazer o teste implementando no projeto um
simples relatrio usando o Writeln para impresso.
No incio usaremos o Writeln da unit System e depois iremos
declarar a nossa unit unImpTH e poderemos observar o mesmo
relatrio sendo impresso utilizando o Spool de impresso.
Implementando o form Principal do projeto
No form principal coloque dois botes, configurando-os da
seguinte forma:
Button1
Caption: Exemplo de Whiteln 1
Button2
Caption: Exemplo de Writeln 2
Aps configurar os dois botes o form do projeto ficar
parecido com a imagem2. (abaixo)
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 3 1 3 1 3 1 3 1 3
Delphi Delphi Delphi Delphi Delphi
No evento onclick do Button1 iremos incluir a seguinte
instruo:
procedure TForm1.Button1Click(Sender: TObject);
var F: TextFile;
begin
{ Manda para impressora na rede }
AssignFile(f, \\Servidor\EpsonFX);
Rewrite(f);
Writeln(f, Linha1);
Write(f, Linha1);
Writeln(f, Linha2);
CloseFile(f);
end;
No evento onclick do Button2 iremos incluir a seguinte
instruo:
procedure TForm1.Button2Click(Sender: TObject);
var Texto1 : string;
F : TextFile;
Valor : Extended;
T : Integer;
begin
{ Gerar um arquivo }
AssignFile(F,c:\writeln.txt);
Rewrite(F);
T := 21; { Tamanho total da string,
que dever ser impresso }
Texto1 := THE CLUB;
Valor := 1.00;
Writeln(F,Format(%s%+IntToStr
(T-Length(Texto1))+s%8.2f,
[Texto1, ,Valor])+
Fim da linha);
Texto1 := THE CLUB DELPHI DELP;
Valor := 100.21;
Writeln(F,Format(%s%+IntToStr
(T-Length(Texto1))+s%8.2f,
[Texto1, ,Valor])+Fim da linha);
Texto1 := THE;
Valor := 1000.10;
Writeln(F,Format(%s%+IntToStr
(T-Length(Texto1))+s%8.2f,
[Texto1, ,Valor])+Fim da linha);
Writeln(F,#12); // Ejeta a pgina
CloseFile(F);
end;
Vejam que esses dois exemplos foram criados utilizando a
procedures da unit System do Delphi.
Neste momento se compilarmos o projeto poderemos observar
que os relatrios sero impressos sem passar pelo Spool de
impresso.
Agora para passarmos a utilizar as procedures da nossa unit
unImpTH, basta declar-la na seo implementation do seu
projeto.
Um detalhe importante, sempre essa unit unImpTH deve ser
declarada depois da unit System, por esse motivo que a colocamos
na seo implementation, conforme exemplo abaixo:
implementation
Uses UnImpTH;
Pronto, faa novamente os testes no relatrio e poder
observar que o mesmo foi impresso utilizando o spool da
impressora e as procedure da nossa unit unImpTH.
Concluso
Bem, aqui finalizamos um artigo que gostei bastante, pois
nos trar um pouco mais de recurso para as impresses rpidas
pelo Delphi.
Um grande abrao a todos e um 2004 com muita Paz, Sade
e bons negcios.
At a prxima.
Download
Os projetos de exemplo deste artigo esto disponveis para
download em:
http://www.theclub.com.br/revista/download/
Imp-WritePrinter.zip
Sobre o autor
Andr Colavite
Consultor Tcnico do The Club
colavite@theclub.com.br
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 4 1 4 1 4 1 4 1 4
Delphi Delphi Delphi Delphi Delphi
Quase todos os cdigos que voc escreve so executados direta
ou indiretamente em resposta a algum evento. Um evento um
tipo especial de propriedade que representa uma ocorrncia em
tempo de execuo, muitas vezes uma ao do usurio. O cdigo
que responde diretamente a um evento, chamado controlador de
evento, uma procedure do Delphi.
Gerando um novo controlador de evento
Voc pode gerar um esqueleto de um evento para ser utilizado
por um form ou para outros componentes. Para criar um
controlador de evento faa o seguinte:
1 Selecione um componente.
2 V at o Object Inspector e clique na aba Events. A partir
da voc ter acesso a todos os eventos do componente selecionado.
3 Selecione o evento que voc quiser e ento d um duplo
clique ou pressione as teclas Ctrl+Enter simultaneamente. Isto
far com que o editor de cdigo do Delphi seja acionado e o cursor
seja posicionado dentro do esqueleto do evento, mais precisamente
dentro do bloco begin...end.
4 Agora basta voc digitar o cdigo que voc quer que seja
executado assim que este evento for disparado.
Gerando um controlador para um evento default.
Alguns componentes tem um evento default, que o evento
chamado com mais freqncia. Por exemplo, o evento padro do
componente Button o evento OnClick. Para saber qual o
evento default de um determinado componente basta que em
tempo de desenvolvimento voc d um duplo clique sobre o
componente. Ento o editor de cdigo do Delphi ser acionado e o
cursor ser posicionado dentro do esqueleto do evento, no bloco
begin...end. Mas vale lembrar que nem todos os componentes tem
evento default. Alguns componentes como o TBevel por exemplo
no responde a qualquer evento. Outros componentes respondem
de forma diferente quando se d um duplo clique. Por exemplo,
alguns componentes abrem um editor de cdigo ou uma janela de
dilogo.
Localizando eventos
Se voc gerou um evento default para um determinado
componente atravs de um duplo clique, voc pode localizar
aquele evento da mesma forma, ou seja, d um duplo clique sobre
o componente e ento o editor de cdigo do Delphi ser acionado e
o cursor ser posicionado dentro do esqueleto do evento. Para
localizar um evento que no default, faa o seguinte:
1 No form, selecione o componente ao qual voc quer
procurar pelo evento.
2 V at o Object Inspector e clique na aba Events
3 Selecione o evento que voc quiser e ento d um duplo
clique ou pressione as teclas Ctrl+Enter simultaneamente. Isto
far com que o editor de cdigo do Delphi seja acionado e o cursor
seja posicionado dentro do esqueleto do evento, mais precisamente
dentro do bloco begin...end.
Associando um evento com outro evento j
existente
Voc pode reutilizar um cdigo fazendo que um determinado
evento responda para mais de um evento. Por exemplo, muitas
aplicaes fazem com que alguns botes sejam equivalentes a
comandos do menu. Sendo assim em sua aplicao, quando um
boto for executar a mesma coisa que um determinado item do
menu voc pode fazer com que eles compartilhem do mesmo
evento.
Vamos fazer um teste:
1 No form inclua um componente MainMenu e um
componente Button.
2 D um duplo clique no componente Button para que o
evento default seja ativado e ento digite o seguinte:
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(Evento OnClick do boto.);
end;
3 Agora crie alguns itens no componente MainMenu.
Selecione um dos itens e v at o Object Inspector. Clique na aba
Events e selecione o evento OnClick. Clique no boto onde tem
uma setinha para baixo. Fazendo isto lhe aparecer o nome do
evento OnClick do boto, por exemplo Button1Click. Selecione
este item e compile o programa.
Agora voc pode clicar no boto ou no item do menu do que
voc escolheu que ambos usaro a mesma procedure ou evento.
Trabalhando com eventos Trabalhando com eventos
Trabalhando com eventos Trabalhando com eventos Trabalhando com eventos
Por Claudinei Rodrigues
Delphi Delphi Delphi Delphi Delphi
Este o caminho mais simples para se reutilizar eventos. O
Delphi tambm fornece o Action Lists, Action Bands que tambm
permitem este reaproveitamento de cdigo. Mas falaremos mais
sobre estes componentes numa outra oportunidade.
Usando o parmetro Sender
O parmetro Sender de um evento indica qual componente
chamou um determinado evento. Algumas vezes ele muito til
quando se tem vrios componentes compartilhando o mesmo
evento comportando-se de forma diferente dependendo de qual
componente o chamou. Voc pode fazer isto utilizando o
parmetro Sender em uma instruo if...then....else.
Tomando como exemplo a rotina que escrevemos
anteriormente, vamos fazer uma modificao no evento OnClick
do boto. Como voc pode ver a seguir ns estamos verificando
atravs do Sender qual o componente que chamou o evento.
Outro detalhe interessante que o Sender tem uma propriedade
chamada ClassName que retorna o nome da classe do
componente que a chamou.
procedure TForm1.Button1Click(Sender: TObject);
begin
if Sender = Button1 then
ShowMessage(Este evento foi chamado pelo
Button1.)
else
ShowMessage(Este evento foi chamado
pelo +Sender.ClassName); end;
Deletando eventos
Quando voc deleta um componente do form, o prprio Delphi
remove a declarao do componente da unit, mas os eventos no
so removidos. Caso voc tenha algum outro componente
associado ao evento deste componente que voc acabou de deletar,
ele continuar funcionando. Voc pode delet-los manualmente,
mas se voc for fazer isto, no esquea que alm da procedure
voc tambm deve remover a declarao que est no inicio da
unit. Caso isto no seja feito, um erro ocorrer no sistema.
Concluso
O objetivo deste artigo foi dar uma idia de como se utilizar os
eventos no Delphi para programadores iniciantes nesta
ferramenta. O Delphi uma linguagem muito poderosa que nos
d inmeros recursos.
Sobre o autor
Claudinei Rodrigues,
Consultor Tcnico do The Club
nei@theclub.com.br
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 6 1 6 1 6 1 6 1 6
Retrospectiva Retrospectiva Retrospectiva Retrospectiva Retrospectiva
Retrospectiva Retrospectiva
Retrospectiva Retrospectiva Retrospectiva
Este ms em nossa restrospectiva, chegamos a 1998, com o lanamento do Delphi
4 e claro, sua grande aceitao por parte do mercado.
Tambm tivemos uma matria sobre o ADO, tecnologia recm lanado pela
Microsoft e que viria a se tornar um padro para acesso banco de dados em
praticamente todas as linguagens de programao. Esta matria, escrita por Mauro
SantAnna, mostrou que a utilizao do ADO deixava mais rpido o acesso ao banco
de dados do que as outras tecnologias existentes. No mercado tambm comeavam
a aparecer empresas que vendiam componentes ADO especficos, como o
ADOSolutions, Adonis, etc.
O nosso amigo Mrio Camilo Bohm tambm participou, com uma matria sobre
travamento de registros com o banco de dados Oracle.
Importante lembrar tambm que haviam pessoas neste ano que ainda estavam
resistentes a trocar o seu velho Windows 95 pelo Windows 98, o que gerava muitos
problemas e aborrecimentos, tantos para ns desenvolvedores quantos para os
usurios finais.
Em Setembro/98 a Microsoft estava para saber o que iria acontecer sobre o
processo que a Sun moveu contra ela, por causa do Java, alegando que a Microsoft
havia alterado o cdigo do Java, assim quebrando a filosofia do "escreva uma vez,
rode em qualquer lugar". Mais tarde veramos que o Java, apesar de uma linguagem
poderosa, no costumava "rodar em qualquer lugar", e tampouco houve
consequncias graves para a Microsoft, apesar dos apuros que ela passou, inclusive
com o processo dos mais de 20 estados americanos, com a acusao de monoplio.
Enfim, 98 foi um ano interessante e cheio de novidades! Ele deixou saudades...
At o ms que vem!
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 8 1 8 1 8 1 8 1 8
Delphi Delphi Delphi Delphi Delphi
Salve, salve Delphianos!
Antes de concluir a ltima parte do artigo sobre WebServices,
vamos iniciar uma luta inglria contra o Intraweb. Calma,
calma! No quero destruir o Intraweb, e sim demonstrar o que
resta de bom nesta fantstica ferramenta.
Neste artigo, iniciaremos o desenvolvimento de aplicao
completa para Intraweb, extrada do meu livro Delphi 7 Internet
e Banco de Dados.
Antes de iniciar nosso projeto com banco de dados, devemos
criar nossa base no Firebird/Interbase.
Figura 1 Registrando Servidor Local Interbase Figura 2 criao do banco de dados Clientes.GDB
Entre no IBConsole e caso no tenha registrado o Servidor
Local, selecione a opo Server/Register e informe as
propriedades conforme a figura 1.
No campo UserName digite SYSDBA (com letras maisculas),
e no campo PassWord digite masterkey (com letras minsculas).
Estas informaes so para o usurio padro.
Agora vamos criar o banco de dados Clientes.GDB.
Selecione a opo DataBase/Create Database e crie um novo
banco de dados como ilustra a figura 2.
Por Emerson Facunte
IntraWeb IntraWeb
IntraWeb IntraWeb IntraWeb
Programao Alternativa Programao Alternativa Programao Alternativa Programao Alternativa Programao Alternativa
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 1 9 1 9 1 9 1 9 1 9
Delphi Delphi Delphi Delphi Delphi
Agora iremos criar os objetos do banco de dados
Clientes.GDB.
Dentro do Interative SQL execute os seguintes comandos:
Criao da Tabela TBCLIENTE
create table tbcliente
(
cod_cliente integer not null,
razao_social varchar(50),
endereco varchar(50),
cidade varchar(50),
estado varchar(2),
cep varchar(8),
email varchar(50),
primary key (cod_cliente)
);
Execute o comando atravs das teclas CTRL-E.
Criao do Generator
create generator gen_clientes;
Execute o comando atravs das teclas CTRL-E.
Criao da Trigger TGClientes
set term ||;
CREATE TRIGGER TG_CLIENTES FOR TBCLIENTE
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
NEW.COD_CLIENTE = GEN_ID(GEN_CLIENTES,1);
END ||
SET TERM;
Execute o comando atravs das teclas CTRL-E. Com isso
finalizamos a criao dos objetos.
Finalize o IBConsole, e vamos iniciar nossas atividades no
Delphi.
Atravs das opes File/New/Other..., selecione a seo
Intraweb e escolha o modelo Stand Alone Application with Data
Module (figura 3).
Selecione o DataModule e insira um objeto do tipo
TSQLConnection. Atravs do duplo-clique, j na tela de
configurao, aponte para a nossa conexo Clientes, criada
anteriormente.
Figura 3 Iniciando a aplicao
Altere tambm a propriedade LoginPrompt para false.
Nunca esquea de fazer esta alterao, pois numa aplicao
servidora, no existe a possibilidade do usurio interagir no login
do banco de dados.
Agora vamos inserir o objeto para manipular nossa tabela de
clientes. Insira um objeto do tipo TSQLDataSet, e altere as
seguintes propriedades:
Objeto de Incluso
Insira um objeto do tipo TSQLQuery e altere as propriedades
que seguem.
Na propriedade PARAMS do SQLInclui altere os tipos dos
parmetros para String.
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 0 2 0 2 0 2 0 2 0
Delphi Delphi Delphi Delphi Delphi
Objeto de Alterao
Insira um objeto do tipo TSQLQuery e altere as propriedades
que seguem.
Na propriedade PARAMS do SQLAltera altere os tipos dos
parmetros para String, com exceo do parmetro PCODIGO,
que deve ser Integer.
Objeto de Excluso
Insira um objeto do tipo TSQLQuery e altere as propriedades
que seguem.
Na propriedade PARAMS do SQLExclui altere o tipo do
parmetro para Integer.
Criando o Formulrio Principal
No formulrio principal (FormMain), adicione um componente
do tipo TMainMenu, e configure as opes como segue:
Arquivo Sobre
Incluso Clientes Informaes
Manuteno/Consulta
Finaliza
A figura 4 ilustra o nosso menu principal.
Insira um objeto do tipo TIWMenu (seo IW Standard), e
altere a propriedade Attached Menu para MainMenu1. Na
realidade estamos vinculando nosso objeto MainMenu1 com o
IWMenu1 do Intraweb.
Figura 4 Menu Principal
Configure a propriedade BackGroundColor do objeto FormMain
para $00DDFFFF. Amigos, isto apenas uma sugesto de cor.
Insira os componentes que seguem no FormMain.
A figura 5 ilustra o nosso formulrio principal.
Figura 5 Formulrio principal
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 1 2 1 2 1 2 1 2 1
Delphi Delphi Delphi Delphi Delphi
Agora iremos codificar duas opes do menu principal:
Finaliza e Informaes/Sobre.
Selecione a opo Finaliza no objeto MainMenu1 e insira o cdigo
que segue no evento OnClick.
WebApplication.Terminate(At logo !);
Neste evento estamos finalizando a aplicao e apresentando
a mensagem At Logo !, ao usurio.
Agora selecione a opo Informaes/.Sobre e insira o cdigo que
segue.
WebApplication.ShowMessage(Cadastro de Clientes
+#13#10+ Verso 1.0,smAlert);
Neste evento apresentamos uma janela de dilogo ao usurio,
com as informaes da aplicao. Bastante simples, no?
Criando o Formulrio de Incluso
Atravs das opes File/New/Other..., selecione a seo
Intraweb e escolha o modelo Application Form (figura 6).
Figura 6 Criando um novo formulrio
Altere a propriedade Name do formulrio para FmInclusao e
BackGroundColor para $00DDFFFF. . Grave a unit com o nome
un_inclusao.
Insira os componentes que seguem no FmInclusao..
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 2 2 2 2 2 2 2 2 2
Delphi Delphi Delphi Delphi Delphi
Agora vamos codificar o formulrio.
Insira a unit DataModuleUnit na clusula uses do formulrio.
uses
ServerController, DatamoduleUnit;
No evento OnClick do objeto btDesiste insira o cdigo que segue:
Hide;
Para que possamos retornar ao formulrio de origem,
utilizamos o mtodo Hide do formulrio.
Agora vamos codificar o evento OnClick do objeto btConfirma.
try
{Inclui Cliente}
with DataModule1.SQLInclui do
begin
ParamByName(prazao).Value:=edRazao.Text;
ParamByName(pendereco).Value:=
edEndereco.Text;
ParamByName(pcidade).Value:=edCidade.Text;
ParamByName(pestado).Value:=edUf.Items
[edUf.ItemIndex];
ParamByName(pcep).Value:=edCep.Text;
ParamByName(pemail).Value:=edEmail.Text;
ExecSQL;
end;
WebApplication.ShowMessage(Cliente incluido
com sucesso,smSameWindow);
except
WebApplication.ShowMessage(Houve um problema
na incluso do cliente, smSameWindow);
end;
Hide;
Vamos analisar o cdigo.
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 3 2 3 2 3 2 3 2 3
Delphi Delphi Delphi Delphi Delphi
Nesta primeira parte, iniciamos um bloco protegido.
try
Em seguida, estamos atribuindo parmetros ao objeto
SQLInclui do DataModule1.
{Inclui Cliente}
with DataModule1.SQLInclui do
begin
ParamByName(prazao).Value:=edRazao.Text;
ParamByName(pendereco).Value:=
edEndereco.Text;
ParamByName(pcidade).Value:=edCidade.Text;
ParamByName(pestado).Value:=edUf.Items
[edUf.ItemIndex];
ParamByName(pcep).Value:=edCep.Text;
ParamByName(pemail).Value:=edEmail.Text;
E finalmente executando a operao e apresentando a
mensagem de sucesso na opero.
ExecSQL;
WebApplication.ShowMessage(Cliente incluido com
sucesso,smSameWindow);
Figura 7 Formulrio incluso de clientes
Em caso de erro, estamos criando o bloco except.
except
WebApplication.ShowMessage(Houve um problema
na incluso do cliente, smSameWindow);
end;
E apresentando a mensagem do problema.
A figura 7 ilustra o nosso formulrio de incluso de clientes.
Conclumos a primeira parte do nosso tutorial. At a
prxima.
Imensa luz e sucesso a todos.
Sobre o autor
Emerson Facunte Consultor de Tecnologia
com diversos livros publicados, especialista em
desenvolvimento de aplicaes e-business
utilizando a ferramenta Delphi, baseado em
webSnap, dataSnap, BizSnap e ISAPI/Apache
Modules.
Emersonf@livrariasaraiva.com.br
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 4 2 4 2 4 2 4 2 4
Delphi Delphi Delphi Delphi Delphi
O Object Repository torna mais fcil o compartilhamento de
formulrios, caixas de dilogo, frames e data modules. Ele
tambm fornece templates para novos projetos e wizards que
guiam o usurio na criao de forms e projetos. O repositrio
mantido no arquivo Delphi32.dro que fica por default no
subdiretrio \BIN. Este arquivo do tipo texto que contm as
referncias para itens que aparecem na caixa de dilogo
Repository e New Items.
Compartilhando itens dentro de um projeto
Voc pode compartilhar itens dentro de um projeto sem que
seja necessrio adicion-los ao repositrio. Quando voc abre a
caixa de dilogo New Itens, File | New | Other, voc ver uma
pgina com o nome do seu projeto. Esta pgina lista todos os
forms, data modules constantes no seu projeto. Voc pode derivar
um novo item a partir de um item j existente e modific-lo de
acordo com a sua necessidade.
Adicionando itens ao Object Repository
Voc pode adicionar seu prprio projeto, forms, frames e data
modules para aqueles j disponveis no Object Repository. Para
adicionar um item ao Object Repository faa o seguinte:
1 Se o item um projeto ou est em um projeto, abra o
projeto.
2 Para um projeto, escolha Project | Add To Repository.
Para um form ou data module, clique com o boto direito no item
e escolha a opo Add To Repository.
3 Digite uma descrio, titulo e autor.
4 Informe em qual pgina voc quer que o item aparea na
caixa de dilogo New Item, ento digite o nome da pgina ou
selecione alguma que esteja disponvel no combobox Page. Se voc
digitar o nome de uma pgina que no exista, o Object Repository
criar uma nova pgina.
5 Escolha Browse para selecionar um cone para
representar o objeto no Object Repository.
6 Clique em OK.
Compartilhando objetos
Voc pode compartilhar objetos com o seu grupo de trabalho
ou time de desenvolvimento tornando o repositrio disponvel na
rede. Para utilizar um repositrio compartilhado, toda a equipe
deve acessar o mesmo diretrio compartilhado. Sendo assim faa
o seguinte:
1 Com o Delphi aberto escolha a opo Tools | Environment
Options.
2 Na pgina Preferences, localize o painel Shared
Repository.
Em Directory informe o diretrio onde voc quer localizar o
repositrio compartilhado. Esteja ciente de informar um diretrio
onde toda a equipe de desenvolvimento tenha acesso.
A primeira vez que um item for adicionado ao repositrio, um
arquivo DELPHI32.DRO ser criado no diretrio que est
compartilhado.
Usando um item do Object Repository no projeto
Usando o Usando o
Usando o Usando o Usando o
Object Repository Object Repository
Object Repository Object Repository Object Repository
Por Claudinei Rodrigues
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 5 2 5 2 5 2 5 2 5
Delphi Delphi Delphi Delphi Delphi
Para acessar um item no Object Repository, escolha File |
New | Other.
A caixa de dilogo New Items aparecer mostrando todos os
itens disponveis. Dependendo do tipo de item que voc queira
usar, voc ter trs opes para adicionar o item ao seu projeto:
Copy
Inherit
Use
Copy - Copiando um item
Escolha Copy para fazer uma cpia exata de um item
selecionado e adicion-lo em seu projeto. Futuras modificaes
feitas no item no Object Repository no sero refletidas em sua
cpia e as alteraes feitas na cpia no iro alterar a original.
Inherit - Herdando um item
Escolha Inherit para derivar uma nova classe a partir de um
item selecionado no Object Repository e adicionar uma nova
classe para o seu projeto. Quando voc recompila o seu projeto,
qualquer modificao que tenha sido feita para o item no Object
Repository ser refletida em sua classe derivada. As modificaes
feitas na classe derivada no tero efeito no item do Object
Repository. Inherit est disponvel para forms, caixa de dilogo e
data modules, mas no para projetos. Esta opo apenas para
reutilizao de itens dentro de um mesmo projeto.
Use - Usando um item
Escolha a opo Use quando voc quiser que o prprio item
selecionado torne-se parte de seu projeto. As modificaes feitas
neste item sero refletidas em todos os projetos que tem este item
adicionado. Utilize esta opo com muita ateno. A opo Use
est disponvel para forms, caixa de dilogos e data modules.
Usando templates de projetos
Os templates so projetos pr-designados que voc pode usar
como ponto de partida para novos projetos. Para criar um novo
projeto a partir de um template, faa o seguinte:
1 Escolha File | New | Other para que voc tenha acesso a
caixa de dilogo New Items.
2 Escolha a pgina Projects.
3 Selecione o projeto de template que voc quer e pressione
OK.
4 Na caixa de dilogo Select Directory, informe um diretrio
onde ser armazenado o novo projeto.
Os arquivos de template so copiados para o diretrio
especificado, onde voc poder modific-los. O projeto original no
ser afetado.
Modificando os itens compartilhados.
Se voc modificar um item no Object Repository, sua
modificao ir afetar a todos os novos projetos que usem este
item assim como os projetos existentes que tenham adicionado o
item com a opo Use ou Inherit. Para evitar a propagao de
modificaes para outros projetos, voc pode fazer o seguinte.
Copie o item e modifique-o apenas no projeto corrente.
Copie o item para o projeto corrente, modifique-o, e ento
adicione-o ao repositrio com um outro nome.
Especificando um projeto default, um novo form e um novo
form principal
Por default, quando voc escolhe File | New | Application ou
File | New | Form, um form em branco aparece.
Voc pode modificar este comportamento reconfigurando o
repositrio.
1 - V at o menu do Delphi e clique em Tools|Repository.
2 Se voc quiser especificar um projeto default, selecione a
pgina Projects e escolha um item abaixo de Objects. Ento
selecione o checkbox New Project.
3 Se voc quiser especificar um form default, selecione uma
pgina do repositrio como por exemplo Forms, selecione o
checkbox New Form. Para especificar o form principal para o
novo projeto, selecione o checkbox Main Form.
4 Agora clique em OK.
Concluso
Este artigo tem o objetivo de oferecer uma explanao sobre o
trabalho com o repositrio de objetos. Mais uma opo do Delphi
que nos auxilia muito no dia a dia. E pra voc que ainda no
conhecia, com certeza isto tambm lhe ser muito til.
Sobre o autor
Claudinei Rodrigues,
Consultor Tcnico do The Club
nei@theclub.com.br
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 6 2 6 2 6 2 6 2 6
Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas
Pergunta: Migrei minha aplicao para o IntraWeb 5 e
encontrei uma srie de problemas. Quais os passos necessrios
para compatibilizar minha aplicao com o IW5?
Resposta: O primeiro passo ignorar todos os avisos que
forem gerados ao abrir o IWForm. Aps isso, acesse o arquivo de
projeto DPR e faa as seguintes alteraes:
{ Verso Anterior }
program Fishfact;
uses
IWInitStandAlone,
Main in Main.pas {formMain: TIWFormModuleBase},
ServerController in ServerController.pas
{IWServerController: TIWServerControllerBase};
{$R *.res}
begin
IWRun(TFormMain, TIWServerController);
end.
{ Nova Verso }
program Fishfact;
uses
DBClient,
Forms,
IWMain,
Main in Main.pas {formMain: TIWFormModuleBase},
ServerController in ServerController.pas
{IWServerController: TIWServerControllerBase};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TformIWMain, formIWMain);
Application.Run;
end.
Agora, abra o formulrio principal do projeto IW e adicione a
seguinte instruo, antes do final da unit, ou seja, anotes end.:
initialization
TformMain.SetAsMainForm;
TformMain a classe do seu formulrio principal.
Agora, abra o seu ServerController...
{ Verso Anterior }
unit ServerController;
{PUBDIST}
interface
uses
SysUtils, Classes, Forms, IWServerControllerBase;
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 7 2 7 2 7 2 7 2 7
type
TIWServerController =
class(TIWServerControllerBase)
private
public
end;
implementation
{$R *.dfm}
end.
{ Nova Verso }
unit ServerController;
{PUBDIST}
interface
uses
SysUtils, Classes, Forms, IWServerControllerBase;
type
TIWServerController =
class(TIWServerControllerBase)
private
public
end;
implementation
{$R *.dfm}
initialization
TIWServerController.SetServerControllerClass;

end.
Pronto, com isso poder recompilar e executar a aplicao
sem problemas!
Dvida enviada por AT&M Informtica Ltda, Sapiranga/RS.
Pergunta: Encontrei um cdigo para registrar um arquivo
OCX no registro do Windows mas o mesmo no est
funcionando! Gostaria de saber o que est errado ou caso tenha
outro cdigo que faa a mesma coisa, favor me enviar.
Os erros gerados durante a compilao so os seguintes:
[Error] Unit1.pas(30): Undeclared identifier:
TDllRegisterServer
[Warning] Unit1.pas(34): Comparing signed and unsigned
types - widened both operands
[Fatal Error] Project1.dpr(5): Could not compile used unit
Unit1.pas
Resposta: As classes mencionadas da mensagem de erro
fazem parte da unit ActiveX, assim sendo, bastar declarar a
unit ActiveX na lista de units que ir compilar sem problemas.
implementation
uses ActiveX;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
OCXHand: THandle;
RegFunc: TDllRegisterServer;
begin
OCXHand := LoadLibrary (SeuArquivo.ocx);
RegFunc:= GetProcAddress
(OCXHand, DllRegisterServer);
if RegFunc < 0 then
ShowMessage(Erro!);
FreeLibrary (OCXHand);
end;
Dvida enviada por Atual Tecnologia Em Informatica,
Araatuba/SP.
Pergunta: Gostaria de saber como verificar a verso do
DAO instalado na mquina.
Resposta: Para retornar a verso do DAO instalado na
mquina, poderemos tentar instanciar um objeto DAO via OLE
Automation, veja o cdigo a seguir:
implementation
Uses comObj;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
const
DAOConst36 = DAO.DBEngine.36;
DAOConst35 = DAO.DBEngine.35;
var DBEngine: Variant;
begin
try
DBEngine := CreateOLEObject(DAOConst36);
Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 8 2 8 2 8 2 8 2 8
// DBEngine := CreateOLEObject(DAOConst35);
showmessage( DAO, verso +DBEngine.Version+
est instalado );
except On E: Exception do
ShowMessage(E.Message+ DAO no instalado );
end
end;
Dvida enviada por Elmar Processamento De Dados Ltda,
Joo Pessoa/PB.
Pergunta: O gerador de relatrios Report Builder possui
recursos para que o usurio final possa desenvolver seus prprios
relatrios, inclusive gerando consultas SQL. Porm, no estou
conseguindo utiliz-lo corretamente com dbExpres e IBExpress
visto estar apresentando alguns problemas. O que necessito fazer
para utilizar o RB corretamente com estas engines de acesso?
Resposta: Para utilizar o acesso ao DBExpress e IBExpress
pelo Report builder do Delphi7 devemos adicionar os pacotes
referentes a esses acessos, pois os mesmos no foram adicionados
ao Delphi. Portanto para adicion-los devemos fazer os seguintes
passos:
Instalando o DBExpress:
Abra o Delphi e acesso o menu Component opo Install
Packages, clique no boto Add e no diretrio do System ou
System32 do Windows selecione o arquivo rbDBE77.bpl
Instalando o IBExpress:
Para o IBExpress foi necessrio abrir o DPK e compil-lo, pois
somente adicionando o pacote ocorreu um erro devido a diferena
de verses. Portanto selecione no Delphi o menu File opo Open,
depois no diretrio Source do Report Builder selecione o arquivo
rbIBE77.dpk. Estando com o pacote aberto clique no boto
Compile e depois no boto Install e pronto pode fechar o pacote,
pois o mesmo j est instalado no delphi.
Fazendo esses dois passos voc habilitar o acesso do Report
Builder do Delphi7 para o DBExpress e IBExpress.
Dvida enviada por Procel Informtica Ltda, Florianpolis/
SC.
Pergunta: Gostaria de saber como obter a lista dos tipos de
papis disponveis no QuickReport.
Resposta: No caso do QReport, o mesmo possui uma
tipagem prpria com nomes dos papeis que no coincidem com os
tipos pr-definidos no Windows. Assim sendo, adicione estes
valores fixos ao seu ComboBox, pois, estes so dos tipos possvel
aceitos pelo QR:
TQRPaperSize = (Default, Letter, LetterSmall,
Tabloid, Ledger, Legal, Statement, Executive, A3,
A4, A4Small, A5, B4, B5, Folio, Quarto, qr10X14,
qr11X17, Note, Env9, Env10, Env11, Env12,
Env14, CSheet, DSheet, ESheet, Custom)
Para pegar o valor do ComboBox e alterar no QReport, utilize
o seguinte:
implementation
uses QrPrNtr, TypInfo;
{$R *.dfm}
procedure SetPaper(const PaperName: string; QR:
TQuickRep);
var
Paper : TQRPaperSize;
begin
Paper := TQRPaperSize(GetEnumValue(TypeInfo
(TQRPaperSize),PaperName));
QR.Page.PaperSize := Paper;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SetPaper(LetterSmall, QuickRep1);
// ou
SetPaper(ComboBox.Items[ComboBox.ItemIndex],
QuickRep1);
end;
Dvida enviada Elson Carlos Almeida, Irec/BA.
Pergunta: Tentei abrir a seguinte instruo e ocorreu um
erro:
select codigo , sum(quantidade) from tabela1
where (sum(quantidade))>100
group by codigo
Constatei que pela clusula where, ento pergunto, no
possvel fazer where por campo calculado? Qual a maneira
correta de abrir uma instruo do tipo? Onde o campo a ser
comparado um SUM?
Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 2 9 2 9 2 9 2 9 2 9
Resposta: A condicional referente ao SUM deve ser
aplicada ao GROUP BY e no na clusula where. Isso pode ser
feito atravs da clusula HAVING (que funciona como um
WHERE para o GROUP), veja abaixo:
SELECT Company, SUM(sales) AS TOTALSALES
FROM Sales1998
WHERE (State = CA)
GROUP BY Company
HAVING (SUM(Sales) >= 1000)
ORDER BY Company
Dvida enviada por CyberSul - Solues em Informtica,
Porto Alegre/RS.
Pergunta: Com fao para ativar/desativar uma triger no
Interbase, via programao Delphi.
Resposta: Poder utilizar o componente IBScript e neste
adicionar a seguinte instruo para desativar sua trigger:
ALTER TRIGGER SUA_TRIGGER
INACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
/* instrues da Sua_Trigger */
END
Para executar utilize:
IBScript.ExecuteScript;
Dvida enviada por Sinval Alcntara Lopes, So Paulo/SP.
Pergunta: Por que quando eu vou digitar algum cdigo
para um evento qualquer no Delphi 7 ele coloca automaticamente
logo aps a palavra begin a palavra de herana inherited?
Exemplo:
procedure
TFormCadastroCidade.IBQueryQtdSecoesNUMERO_SECOESGetText(
Sender: TField; var Text: String; DisplayText:
Boolean);
begin
inherited; // <-
end;
Resposta: Isso ocorre porque possivelmente o Sr. esteja
trabalhando com herana de formulrios, ou seja, o
TformCadastroCidade foi herdado com opo inherit a partir de
um outro formulrio.
Quando trabalhamos com este tipo de arquitetura, o Delphi
insere esta chamada automaticamente, porque ele imagina que
voc possa ter um cdigo no formulrio base que dever ser
executado neste formulrio herdado.
Por exemplo, no formulrio base voc possui no evento
OnClose a instruo:
Action := CaFree;
Em todos os formulrios herdados a partir deste formulrio
base, automaticamente iro executar esta mesma instruo.
Suponhamos que em um destes formulrios herdados voc
necessite acrescentar algum cdigo especfico:
Inherited;
ShowMessage(Meu Cdigo!);
A clusula Inherited ir forar a execuo do cdigo original
existente no formulrio base e logo em seguida o seu cdigo
especfico.
A clusula Inherited ir aparecer nos formulrios herdados,
mesmo que no haja cdigo para aquele evento no formulrio
base, contudo, no trs nenhum problema e recomendo no
remov-la.
Dvida enviada por Rodrigo Jos Marques, Itana/MG.
Pergunta: Conforme exemplo que estou envinado em
anexo, estou tentando alterar uma Query, mas ao tentar fazer
esta operao, ocorre a seguinte mensagem:
Query: Canoot modify a read-only dataset.
Gostaria que vocs me apontassem o que estou fazendo de
errado neste programa.
Resposta: Quando adicionamos instrues um pouquinho
mais complexas em um Query, como exemplo um ORDER BY, a
mesma tornar-se-a read-only. Nestes casos, para que possamos
edit-la necessrio utilizar um componente UpdateSQL, bem
como alterar a propriedade CachedUpdates da Query para True.
Veja seu projeto com esta implementao.
Dvida enviada por Infoque Informatica Produtos Servicos
Ltda, So Roque/SP.
Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas
MeGAZINE MeGAZINE MeGAZINE MeGAZINE MeGAZINE 3 0 3 0 3 0 3 0 3 0
Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas Perguntas & Respostas
Pergunta: Usando o Interbase tem como fazer segurana
de tabelas a nvel de registro? Exemplo: Temos um cadastro de
conta bancaria. Alguns usurios podero acessar apenas a conta
25889-3 E outros usurios podero acessar apenas a conta
71658-9. Hoje temos no sistemas segurana a nvel de tela e de
boto, mas no sabemos como dar acesso a nvel de registro, como
poderamos fazer isso?
Resposta: Infelizmente no existe este tipo de controle por
parte do Interbase, sendo necessrio voc efetuar um controle
manual para seus usurios. Uma alternativa seria voc criar
uma tabela onde ficaro cadastrados seus usurios/senhas, e
uma tabela detalhe ligada a esta tabela onde iro ficar as
configuraes a que cada usurio ter direito. Dessa forma, ao
iniciar o aplicativo voc ir solicitar o login do usurio e tendo
com isso as opes que o mesmo poder ter acesso. No caso
especfico de registros, ao entrar no formulrio de contas,
recomendaria voc utilizar um componente Query com um
Select que no mostre nenhum registro a princpio:
Select * From Contas where ID is null;
Quando o usurio acessar o Form, voc ir solicitar uma
pesquisa para que o mesmo escolha a conta que deseja acessar.
Aps a pesquisa, faa uma comparao entre a conta escolhida e
a conta configurada na tabela de permisses e caso no haja
restrio, permita ou no o acesso.
Temos um exemplo de controle de usurios publicado em
nossa revista de Junho/2003 Acesso - Controlando e
Identificando Usurios. Caso no possua a revista poder
acessar em nosso site, www.theclub.com.br.
Dvida enviada por New Century Gesto e Informtica,
Santo Andr/SP.
Pergunta: Como fao pra construir aqueles forms com
formato e desenhos diferenciados, como imitando um aparelho de
som, com fundo semelhante a metal lixado, cantos arredondados,
contornos e coisas do tipo? Como exemplo, veja o form usado no
Quick Time, Media Player, etc. Tentei deixar meu form
transparente, e deu pra causar alguns efeitos, mas o que mais
posso fazer? Inserir um BMP no form com o formato desejado?
Resposta: Estas aplicaes trabalham com Skins que
possibilitam moldar o formulrio de acordo com imagens. Existe
uma suite de componentes da empresa KsDev que possibilita
mudar a aparncia dos formulrios via Delphi. Poder baixar
uma cpia de avaliao no site do fabricante, www.ksdev.com,
no gratuto.
Existe um outro componente chamado Scheme VCL o qual
gratuto, porm, mais simples. Poder baixar em: http://
www.torry.net/vcl/forms/effects/ksscheme.zip.
Dvida enviada por Samuel Della Savia de Oliveira, So
Paulo/SP.
Pergunta: Gostaria de fazer um clculo registro a registro
no Rave Report imprimindo a diferena de dias entre uma data
gravada em um campo e a data atual do sistema. Como posso
fazer isso?
Resposta: Isso poder ser feito programando o evento
OnGetRow do componente RvCustomDataSet, onde iremos
pesquisar os componentes dentro do projeto Rave e atribuir
valores aos mesmos. Exceto o fato de termos que pesquisar
componentes, a abordagem fica bem parecieda com o que
estamos acostumados a fazer no QuickReport. Veja o cdigo a
seguir:
implementation
uses RVClass, RVProj, RvCsData;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
rvTestes.ExecuteReport(Rep_Employee);
end;
// evento OnGetRow do componente RvDataSetConnection
procedure TForm1.rvdsEmployeeGetRow(Connection:
TRvCustomConnection);
var
Dias: Double;
P: TRavePage;
D: TRaveDataText;
begin
// Pesquisa o Report e a Pgina.
P := RvTestes.ProjMan.FindRaveComponent
(Rep_Employee.MainPage, nil) as TRavePage;
// Localiza o DataText
D := RvTestes.ProjMan.FindRaveComponent
(DataText4, P) as TRaveDataText;
// Clcula # dias
Dias := Date - tabEmployee.FieldByName
(HireDate).AsDateTime;
// Atribui ao Datatext
D.Text := FormatFloat(000, Dias);
Connection.DoGetRow; end;
Dvida enviada por Denis Fonseca Loureiro, Salvador/BA.

Anda mungkin juga menyukai