Vous êtes sur la page 1sur 28

Dicas de Delphi - Banco de Dados

y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y

Solucionando problemas de arredondamentos Criando tabelas via SQL Salvar imagem em tabela Paradox Evitar a biblioteca midas.dll Copiar qualquer texto para o Clipboard Avaliar de expresso matemtica Rolagem automtica em ListBox Obter data/hora do prprio EXE Mostrar aviso em forma de hint Sons no alto-falante do micro Acessar tabela DB/DBF no diretrio do EXE Ordenar datas pelo ms em Paradox? Excluir todas as ocorrncias de um caractere de uma string Fazer pesquisa incremental apenas com DBGrid Consulta SQL que usa a data do sistema Obter nomes dos campos de uma tabela Obter path de um Alias do BDE Copiar todos os registros de uma tabela para o Clipboard Copiar um registro de uma tabela para o Clipboard Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condio Fazer pesquisa incremental com DBGrid e Edit Limpar um campo tipo data via programao Implementar um campo auto-incremental via programao Exibir a caixa de dilogo padro de solicitao de senha do banco de dados Usar o evento OnGetText de um TField Verificar, via programao, se Local Share do BDE est TRUE Resolver "Internalerrornear: IBCheck" do Interbase 5.1.1 Server no NT Excluir todos os registros de uma tabela Mudar a coluna ativa em um DBGrid via programao Obter o nmero do registro atual Trabalhar com Filter de forma mais prtica Obter a quantidade de registros total e visvel de uma tabela Gravar fisicamente com Paradox Criar uma tabela (DB, DBF) atravs do seu programa Criar um Alias temporrio atravs do seu programa

Solucionando problemas de arredondamentos


Como sempre observo longas discusses sobre este tema, resolvi apresentar minha experincia nesta rea. Eu tive muitos problemas com arredondamentos h muito tempo, especialmente quando comecei a implantar sistemas para uso com ECF (emissor de cupom fiscal). Acontecia do programa apresentar um total de venda diferente do valor impresso pelo ECF. Ento

fui estudando a questo com carinho e cheguei a algumas concluses que resolveram meus problemas. O modo de arredondamento do Firebird igual ao modo das calculadoras financeiras. J no Delphi o arredondamento leva em considerao se a parte inteira par ou mpar quando a parte decimal termina em 5. Os ECFs tambm calculam como no Firebird. Para resolver as diferenas entre Delphi e Firebird escrevi a funo abaixo (a converso para string resolve alguns problemas de arredondamento do Delphi):
function ExRound(Value: Extended; Decimals: Integer): Extended; var Factor, Fraction: Extended; begin Factor := IntPower(10, Decimals); Value := StrToFloat(FloatToStr(Value * Factor)); Result := Int(Value); Fraction := Frac(Value); if Fraction >= 0.5 then Result := Result + 1 else if Fraction <= -0.5 then Result := Result - 1; Result := Result / Factor; end;

Algumas vezes o Delphi gera uns problemas de arredondamento quando voc faz vrios clculos (especialmente multiplicao e diviso) sem aplicar o arredondamento em cada etapa do clculo. Isto ocorre devido ao modo que o Delphi armazena um valor de ponto flutuante numa varivel. Procure fazer o arredondamento a cada etapa do clculo, exceto se este arredondamento passo-a-passo for prejudicar o resultado do clculo. Sempre que possvel use o tipo Currency para variveis que recebero nmeros reais com at 4 casas decimais. Lembre-se tambm de usar AsCurrency ao acessar valores de campos de DataSets. Use no Firebird campos do tipo NUMERIC(x,y) para armazenar valores financeiros e quantidades, mas tome o cuidado de criar o banco de dados com o dialeto 3, pois no dialeto 1 o tipo NUMERIC poder ser convertido para DOUBLE PRECISION internamente. Exemplos:
Quantidade NUMERIC(9,3) Quantidade NUMERIC(18,3) PrecoNUMERIC(9,2) PrecoNUMERIC(18,2) PrecoNUMERIC(18,4) Desconto NUMERIC(4,2)

Crie campos calculados no banco (COMPUTED BY) j com os devidos ajustes de arredondamento. No Firebird existem alguns problemas de arredondamento tambm, mas geralmente se resolve com CASTs. Veja alguns exemplos: Itens de venda:
ValorDescto NUMERIC(9,2) COMPUTED(CAST(Qtd * PrecoVenda * Descto / 100 AS NUMERIC (9,2))),

Total NUMERIC(9,2) COMPUTED(CAST(Qtd * PrecoVenda ValorDescto AS NUMERIC (9,2))), ValorComissao NUMERIC(9,2) COMPUTED(CAST(Total * Comissao / 100 AS NUMERIC(9,2)))

Contas a receber/recebidas:
Atraso INTEGER COMPUTED ( CASE WHEN Recda = 'N' AND Vencto <CURRENT_DATE THEN CURRENT_DATE - Vencto WHEN Recda = 'S' AND Vencto < DataRecto THEN DataRecto - Vencto ELSE 0 END), ValorJuro NUMERIC(9,2) COMPUTED(CAST(Valor * Juro * Atraso / 100 / 30 AS NUMERIC (9,2))), Total NUMERIC(9,2) COMPUTED(CAST(Valor + ValorJuro AS NUMERIC(9,2))), TotalRecdo NUMERIC(9,2) COMPUTED(CAST(CapitalRecdo + JuroRecdo AS NUMERIC(9,2)))

Enfim, use CASTs no Firebird sempre que fizer clculos envolvendo multiplicao e diviso para que o resultado tenha de fato as casas decimais desejadas. Com estas tcnicas acima resolvi completamente os problemas que eu tinha com relao aos arredondamentos, tanto no Delphi quanto no Interbase ou Firebird. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Criando tabelas via SQL


Inclua na seo uses:dbTables
- Coloque um TButton no form; - Escreve no OnClick do Button como abaixo: procedure TForm1.Button1Click(Sender: TObject); var Q: TQuery; begin Q := TQuery.Create(Application); try Q.DatabaseName := 'SF'; with Q.SQL do begin Add('Create Table Funcionarios'); Add('( Codigo AutoInc,'); Add(' Nome Char(30),'); Add(' Salario Money,'); Add(' Depto SmallInt,'); Add(' Primary Key (Codigo) )'); end; Q.ExecSQL; finally

Q.Free; end; end;

Observaes Este exemplo foi testado com banco de dados Paradox, porm dever funcionar em vrios outros bancos de dados com pouca ou nenhuma alterao. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Salvar imagem em tabela Paradox


O exemplo abaixo demonstra como salvar imagens Bitmap em tabelas Paradox. 1. Crie uma tabela Paradox com um campo do tipo Binary (B). 2. Coloque no form um Table e ligue -o com a tabela Paradox recm criada. 3. Coloque tambm um OpenDialog. 4. Para car regar a imagem de um arquivo bitmap para a tabela faa assim: procedure TForm1.Button1Click(Sender: TObject); var Bmp: TBitmap; begin if not OpenDialog1.Execute then Exit; Bmp := TBitmap.Create; try Bmp.LoadFromFile(OpenDialog1.FileName); Table1.Insert; Table1.FieldByName('Imagem').Assign(Bmp); Table1.Post; finally Bmp.Free; end; end; Para mostrar no form a imagem que foi salva na tabela siga o exemplo: procedure TForm1.Button2Click(Sender: TObject); var Bmp: TBitmap; begin

Bmp := TBitmap.Create; try Bmp.Assign(Table1.FieldByName('Imagem')); Form1.Canvas.Draw(0, 0, Bmp); finally Bmp.Free; end; end;

Observaes O exemplo acima pinta a imagem diretamente no Canvas do Form1. Uma alternativa mais elegante seria usar um objeto TImage para mostrar a imagem. Para salvar em outros bancos de dados a tcnica usava ser semelhante. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Evitar a biblioteca midas.dll


At a verso 5 do Delphi, se usarmos o componente TClientDataSet teremos, invariavelmente, que distribuir juntamente com nosso aplicativo, a biblioteca midas.dll. Porm a partir do Delphi 6 este inconveniente pode ser evitado. Para isto adicione no uses de seu aplicativo a unitMidasLib. Pode fazer isto na seo uses do form principal ou em qualquer outra unit.

Observaes importante lembrar que a distribuio do arquivo midas.dll est sugeito ao pagamento de licenas para a Borland. Entre em contato com a Borland para saber mais detalhes. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Copiar qualquer texto para o Clipboard


Inclua na seo uses:Clipbrd
O objeto global Clipboard pode ser usado para fazer a transferncia de dados entre a rea de Transferncia e seu aplicativo. Veja o exemplo: procedure TForm1.Button2Click(Sender: TObject); begin

Clipboard.AsText := Edit1.Text; end;

Observaes Alguns componentes possuem mtodos tais como CopyToClipboard() que podem ser usados para copiar dados para a rea de transferncia de forma bastante simples. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Avaliar de expresso matemtica


Muitas pessoas procuram um parser (avaliador) de expresses matemtica. Em resposta a tanta procura estou colocando abaixo duas possveis solues: 1. Pegue em nosso download o arquivo Formula.zip. Ele contm um componente (no profissional) que fiz para avaliar frmulas matemticas simples. 2. Pegue o componente TMathParser no end ereo: www.bitsoft.com

Observaes Se voc conhece outro componente queira por gentileza nos informar o endereo da pgina para download. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Rolagem automtica em ListBox


Inclua na seo uses: Windows, Messages
Para rolar o contedo de um ListBox automaticamente basta enviar uma mensagem WM_VSCROLL para a janela do componente. No primeiro parmetro da mensagem devemos passar o tipo de rolagem que dever ser feita, ou seja: SB_LINEDOWN - Uma linha para baixo. SB_LINEUP - Uma linha para cima. SB_PAGEDOWN - Uma pgina para baixo. SB_PAGEUP - Uma pgina para cima. SB_TOP - Topo da lista. SB_BOTTOM - Fim da lista.

SendMessage(ListBox1.Handle, WM_VSCROLL, SB_LINEDOWN, 0);

Observaes A mensagem WM_VSCROLL aceita outros parmetros. Pesquise no Help da API do Windows por WM_VSCROLL para obter mais informaes. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Obter data/hora do prprio EXE


Inclua na seo uses:SysUtils
Eis uma funo que pega a data e hora do prprio EXE. function ExeDateTime: TDateTime; begin Result := FileDateToDateTime(FileAge(ParamStr(0))); end;

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Mostrar aviso em forma de hint


Inclua na seo uses:Controls
Nos tempos do Clipper era comum mostrar uma mensagem, aguardar alguns segundos e depois ocult -la. Para quem ainda gosta deste estilo apresento uma dica interessante. A rotina abaixo mostra a mensagem de aviso em forma de "Hint", aguarda o tempo especificado e finalmente retira a mensagem da tela. procedure Aviso(const Msg: string; const Tempo: Cardinal); var R: TRect; X: integer; begin with THintWindow.Create(Application) do try { Calcula o retngulo } R := CalcHintRect(Screen.Width, Msg, nil); { Centraliza horizontalmente } X := R.Right - R.Left + 1; R.Left := (Screen.Width - X) div 2; R.Right := R.Left + X;

{ Centraliza verticalmente } X := R.Bottom - R.Top + 1; R.Top := (Screen.Height - X) div 2; R.Bottom := R.Top + X; { Mostra } ActivateHint(R, Msg); Update; { Aguarda } Sleep(Tempo); finally Free; end; end; Exemplo de uso: Aviso('Mensagem de aviso', 5000); { Aguarda 5 segundos }

Observaes Usei este recurso por dois motivos. Primeiro para lembrar os velhos tempos do Clipper (legal!) e em segundo lugar para mostrar um breve exemplo que pode ser ampliado para melhorar as mensagens de dicas (hint) de aplicaes feitas em Delphi. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Sons no alto-falante do micro


Inclua na seo uses: Windows
Desde que migrei de Clipper para Delphi no uso este recurso em minhas aplicaes. Primeiro porque o Windows oferece sons mais sofisticados e em segundo lugar porque eu realmente no sabia como fazer (verdade!). Recentemente, em uma visita ao news da borland encontrei as rotinas abaixo e achei muito interessantes. Ento resolvi disponibiliz -las aqui. procedure Sound(Freq: Word); asm MOV DX, AX IN AL, $61 MOV AH, AL AND AL, 3 JNE @@1 MOV AL, AH OR AL, 3 OUT $61, AL MOV AL, $B6 OUT $43, AL @@1: MOV AX, DX

OUT $42, AL MOV AL, AH OUT $42, AL end; procedure NoSound; asm IN AL, $61 AND AL, $FC OUT $61, AL end; procedure DoBeep(Freq, Duration: LongWord); begin if Win32Platform = VER_PLATFORM_WIN32_NT then Windows.Beep(Freq, Duration) else begin Sound(1193181 div Freq); Sleep(Duration); NoSound; end; end; Se voc no entendeu as rotinas, eis um resumo:

Sound: Inicia um som com uma determinada freqncia (hertz). NoSound: Interrompe o som iniciado por Sound. DoBeep: Esta rotina verifica se o sistema operacional o Windows NT. Se for, chama a API Windows.Beep. Caso contrrio chama Sound, aguarda e, chama NoSound.

Observaes Pelo menos no meu caso, a maioria dos usurios no possuem computadores munidos de caixas de som. Para estes casos as rotinas acima seriam a soluo se o som for indispensvel. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Acessar tabela DB/DBF no diretrio do EXE


Inclua na seo uses:SysUtils
Problema: Gostaria de acessar tabelas DB/DBF que esto no diretrio do EXE sem ter que criar um alias no BDE. Como fazer?

Soluo: No evento BeforeOpen do Table coloque o cdigo abaixo: procedure TForm1.Table1BeforeOpen(DataSet: TDataSet); begin Table1.DatabaseName := ExtractFilePath(ParamStr(0)); end;

Observaes Este procedimento no dispensa o BDE, mas apenas a criao do Alias. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Ordenar datas pelo ms em Paradox?


Problema: Gostaria de organizar uma lista dos clientes por ms a partir da data de nascimento. Soluo: Use o componente TQuery com a instruo SQL abaixo: select Codigo, Nome, DataNasc, extract(month from DataNasc) as Mes from Cliente order by Mes ordenados

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Excluir todas as ocorrncias de um caractere de uma string


Inclua na seo uses:SysUtils
Problema: Em determinados casos gostaria de poder eliminar alguns caracteres indesejados que os usurios podem digitar, tais como pontos, aspas, etc. Como fazer isto ?

Soluo: Na funo abaixo, o primeiro parmetro o caractere a ser eliminado e o segundo parmetro a string, donde o caractere ser eliminado. function DeleteChar(const Ch: Char; const S: string): string; var Posicao: integer; begin Result := S; Posicao := Pos(Ch, Result); while Posicao > 0 do begin Delete(Result, Posicao, 1); Posicao := Pos(Ch, Result); end; end; === Exemplo de uso === - Coloque um Edit e um Button. - Programe o OnClick do boto conforme abaixo: procedure TForm1.Button1Click(Sender: TObject); begin Edit1.Text := DeleteChar('"', Edit1.Text); { Exclui aspas } Edit1.Text := DeleteChar('.', Edit1.Text); { Exclui pontos } end;

Observaes Para eliminar vrios caracteres poderamos escrever uma funo que fizesse toda a tarefa numa nica chamada. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Fazer pesquisa incremental apenas com DBGrid


Problema: Gostaria de fazer um formulrio de pesquisa que, ao digitar algo sobre o DBGrid, o registro correspondendo fosse localizado. Soluo: - Coloque no form: TTable, TDataSource, TDBGrid e - Ajuste as propriedades do Table1: DatabaseName = TableName = Active = true TLabel.

- Ajuste as propriedades do DataSource1: DataSet = Table1 - Ajuste as propriedades do DBGrid1: DataSource = DataSource1 Options -> dgEditing = false ReadOnly = true * Pode tambm ajustar a propriedades Columns para escolher as colunas que sero exibidas. - Na seo private da unit declare: private FTexto: string; - No evento OnCreate do form coloque: FTexto := ''; Label1.Caption := ''; - No evento OnKeyPress do DBGrid1: procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char); begin if Key in [#8, #32..#255] then begin if Key = #8 then { BackSpace } FTexto := Copy(FTexto, 1, Length(FTexto) -1) else FTexto := FTexto + Key; { Posiciona na coluna Nome } Table1.FieldByName('Nome').FocusControl; { Escolhe o ndice e procura } Table1.IndexFieldNames := 'Nome'; Table1.FindNearest([FTexto]); { Mostra o texto procurado } Label1.Caption := FTexto; end; end;

Observaes No nosso exemplo estamos pesquisando atravs do campo "Nome". Para esta pesquisa precisamos de um ndice com este campo. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Consulta SQL que usa a data do sistema


Problema:

Preciso fazer uma consulta com SQL que me retorne todos os registros em que o valor de um campo do tipo data seja igual ou anterior dada do sistema. Como fazer? Soluo: Query.Close; Query.SQL.Text := 'select * from Tabela where CampoData <= :Hoje'; Query.ParamByName('Hoje').AsDate := Date; Query.Open;

Observaes Este exemplo foi testado com tabelas Paradox, mas deve funcionar na maioria dos bancos de dados com pouca ou nenhuma alterao. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Obter nomes dos campos de uma tabela


Inclua na seo uses:dbTables, Classes, Forms
A funo abaixo obtm os nomes de todos os campos de uma tabela do banco de dados. procedure tbGetFieldNames(const DBName, TblName: string; List: TStringList); var I: integer; begin List.Clear; with TTable.Create(Application) do try DatabaseName := DBName; TableName := TblName; with FieldDefs do begin Update; for I := 0 to Count -1 do List.Add(Items[I].Name); end; finally Free; end; end; === Exemplo de uso === - Coloque um TMemo e um TButton no Form; - Coloque o cdigo abaixo no evento OnClick do Button: procedure TFor m1.Button1Click(Sender: TObject); var List: TStringList; begin

List := TStringList.Create; try tbGetFieldNames(Edit1.Text, Edit2.Text, List); Memo1.Lines.Assign(List); finally List.Free; end; end;

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Obter path de um Alias do BDE


Inclua na seo uses: BDE
{ A funo abaixo retorna o path (caminho) de um Alias do BDE } function GetAliasPath(AliasName: String):String; var dbDes: DBDesc; begin Result:=''; DBiInit(Nil);// invoca o BDE , se no inicializado If DbiGetDatabaseDesc(PChar(AliasName), @dbDes)= DBIERR_NONE then with dbDes do Result:=StrPas(szPhyName); DBiExit;// Libera o BDE end; Dica enviada por: Angelo Ricardo Miquelin Neto.

Observaes Se a unit em que essa rotina for colocada utilizar as units DB e DBTABLES, as chamadas a DbiInit() e DbiExit() podero ser omitidas. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Copiar todos os registros de uma tabela para o Clipboard


Inclua na seo uses:Clipbrd
Problema: Gostaria de colocar em minha aplicao o recurso de copiar todos os registros de uma tabela para a rea de transferncia,

permitindo ao usurio colar estes dados em outro aplicativo (ex: MS -Word). Isto possvel? Soluo: Sim. Siga os passos abaixo: - Crie seu form normalmente, colocando DataSource, Table e demais componentes; - Coloque um boto e no evento OnClick deste boto coloque o cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); const SeparadorCampoValor = ': '; SeparadorCampo = #13#10; { Quebra de linha } SeparadorRegistro = '===========' + #13#10; var S: string; I: integer; begin S := ''; Table1.First; while not Table1.EOF do begin for I := 0 to Table1.FieldCount -1 do S := S + Table1.Fields[I].FieldName + SeparadorCampoValor + Table1.Fields[I].AsString + SeparadorCampo; S := S + SeparadorRegistro; Table1.Next; end; Clipboard.AsText := S; end; Para testar: - Execute este aplicativo; - Clique no boto; - V em outro aplicativo (ex: MS -Word) e mande colar (Ctrl+V).

Observaes CUIDADO! No use este recurso com tabelas grandes, pois poder usar memria demasiadamente. No teste que fiz, o tamanho da string S atingiu 20K e funcionou normalmente. Mas isto pode variar de uma mquina para outra. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Copiar um registro de uma tabela para o Clipboard


Inclua na seo uses:Clipbrd
Problema: Gostaria de colocar em minha aplicao o recurso de copiar

um registro de uma tabela para a rea de transferncia, permitindo ao usurio colar estes dados em outro aplicativo (ex: MS -Word). Isto possvel? Soluo: Sim. Siga os passos abaixo: - Crie seu form normalmente, colocando DataSource, Table e demais componentes; - Coloque um boto e no evento OnClick deste boto coloque o cdigo abaixo: procedure TForm1.Button1Click(Sender: TObject); const SeparadorCampoValor = ': ' ; SeparadorCampo = #13#10; { Quebra de linha } var S: string; I: integer; begin S := ''; for I := 0 to Table1.FieldCount -1 do S := S + Table1.Fields[I].FieldName + SeparadorCampoValor + Table1.Fields[I].AsString + SeparadorCampo; Clipboard.AsText := S; end; Para testar: - Execute este aplicativo; - Clique no boto; - V em outro aplicativo (ex: MS -Word) e mande colar (Ctrl+V).

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Mudar a cor de um DBEdit dentro de um DBCtrlGrid de acordo com uma condio


Problema: Uso um DBCtrlGrid e gostaria que, quando o valor de um determinado campo for negativo, o DBEdit ligado a este campo seja exibido em vermelho e, caso contrrio, em azul. Isto possvel? Soluo: - Monte o form normalmente colocando DataSource, Table, DBCtrlGrid e os DBEdit's, DBText's, etc. - Escreva no manipulador do evento OnPaintPanel do DBCtrlGrid conforme abaixo:

procedure TForm1.DBCtrlGrid1PaintPanel(DBCtrlGrid: TDBCtrlGrid; Index: Int eger); begin ifTable.FieldByName('NomeDoCampo').AsFloat< 0 then DBEdit1.Font.Color := clRed else DBEdit1.Font.Color := clBlue; end;

Observaes Neste exemplo mudamos a cor da fonte do componente DBEdit, Porm, pode-se tambm mudar a cor do prprio componente (DBEdit1.Color). Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Fazer pesquisa incremental com DBGrid e Edit


Problema: Gostaria de montar um formulrio de pesquisa com um DBGrid e um Edit de modo que, enquanto o usurio digita um nome do Edit, o registro vai sendo localizado no DBGrid. Como fazer? - Crie um ndice na tabela com campo a ser usado na pesquisa. Coloque no Form: Um Um Um Um DataSource Table DBGrid Edit

Altere as seguintes propriedades: DataSource1.DataSet = Table1 Table1.DatabaseName = 'NomeDoAlias' Table1.TableName = 'NomeDaTabela' Table1.IndexFieldNames = 'NomeDoCampo' Table1.Active = true DBGrid1.DataSource = DataSource1

Escreva a instruo abaixo no evento OnChange do Edit: Table1.FindNearest([Edit1.Text]);

Observaes Este exemplo considera que o campo seja tipo string. Para outros tipos de campos pode ocorrer erro dependendo dos valores digitados no Edit1.

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Limpar um campo tipo data via programao


Table1.FieldByName('Data').Clear; { ou } Table1.FieldByName('Data').AsString := '';

Observaes Podemos usar este recurso para limpar tambm campos numricos, string, etc. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Implementar um campo auto-incremental via programao


Inclua na seo uses: dbTables
procedure tbAutoInc(Table: TTable; const FieldName: string); var Q: TQuery; begin if not Table.FieldByName(FieldName).IsNull then Exit; Q := TQuery.Create(nil); try Q.DatabaseName := Table.DatabaseName; Q.SQL.Add('select max(' + FieldName + ') from ' + Table.TableName); Q.Open; try Table.FieldByName(FieldName).AsInteger := Q.Fields[0].AsInteger +1; finally Q.Close; end; finally Q.Free; end; end; { Chame esta procedure no evento BeforePost de um Table: } procedure TForm1.Table1BeforePost(DataSet: TDataSet) ; begin

tbAutoInc(Table1, 'Codigo'); end;

Observaes A funo acima incrementa o campo somente se estiver vazio. Assim podemos dar ao usurio a opo de digitar neste campo ou deix-lo vazio para que seja autoincrementado. Existem vrias outras formas de implementar este recurso. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Exibir a caixa de dilogo padro de solicitao de senha do banco de dados


Inclua na seo uses:DbPwDlg
{ Coloque um boto no form e escreve seu evento OnClick como abaixo } procedure TForm1.Button1Click(Sender: TObject); var pw: TPasswordDialog; begin pw := TPasswordDialog.Create(Self); try pw.Caption := 'Banco de Dados'; pw.GroupBox1.Caption := 'Senha'; pw.AddButton.Caption := '&Adicionar'; pw.RemoveButton.Caption := '&Remover'; pw.RemoveAllButton.Caption := 'Remover &Tudo'; pw.OKButton.Caption := '&OK'; pw.CancelButton.Caption := '&Cancelar'; pw.ShowModal; finally pw.Free; end; end;

Observaes As senhas adicionadas nesta caixa de dilogo so adicionadas na sesso (TSession) atual. Isto til quando colocamos senha em tabelas Paradox, ou mesmo quando trabalhamos com banco de dados Client Servidor, e queremos que o usurio digite a senha de acesso. Se no fizermos desta forma, nem adicionarmos via programao as senhas necessrias, esta caixa de dilogo ser mostrada quando o programa tentar abrir uma tabela com senha. A grande vantagem aqui que podemos traduzir os Caption's dos componentes. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br

Incio

Usar o evento OnGetText de um TField


{ Problema: Tenho um sistema de contas a receber, onde um campo chamado "Tipo" contm um nmero inteiro que indica o tipo do documento conforme abaixo: 1 - Promissria 2 - Duplicata 3 - Boleto Gostaria que, ao exibir os dados (num DBGrid por exemplo), fosse exibido o nome e no o nmero, ou seja, "Promissria" em vez de "1". Soluo: Isto pode ser feito de vrias formas, mas aqui vou mostrar como resolver usando o evento OnGetText do TField. Vejamos: - Adicione todos os campos no Field Editor; - Clique no campo "Tipo"; - V ao ObjectInspector e d um duplo -click no evento OnGetText; - Neste evento, digite o cdigo abaixo: } procedure TForm1.Table1TipoGetText(Sender: TField; var Text: String; DisplayText: Boolean); begin if DisplayText then begin case Table1Tipo.AsInteger of 1: Text := 'Promissria'; 2: Text := 'Duplicata'; 3: Text := 'Boleto'; else Text := 'Desconhecido'; end; end else Text := Table1Tipo.AsString; end;

Observaes Ao exibir ser exibido os nomes. Mas ao digitar continue com os 1, 2, 3, etc. Para usar este recurso em relatrios, acesse a propriedade DisplayText em vez de AsString para obter o valor do campo. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Verificar, via programao, se Local Share do BDE est TRUE


Inclua na seo uses: Registry, SysUtils, Windows
{ Esta funo retorna true se Local Share estiver "TRUE". Caso contrrio, retorna false. } functionTBBDELocalShare: boolean; const BdeKey = 'SOFTWARE \Borland\Database Engine \Settings\SYSTEM\INIT'; Ident = 'LOCAL SHARE'; var Reg: TRegistry; begin Result := false; Reg := TRegistry.Create; try Reg.RootKey := HKEY_LOCAL_MACHINE; if Reg.OpenKey(BdeKey, False) then if Reg.ValueExists(Ident) then Result := UpperCase(Reg.ReadString(Ident)) = 'TRUE'; finally Reg.Free; end; end; { Use-a como abaixo: } if TBBDELocalShare then { Local Share est TRUE } else { Local Share est FALSE }

Observaes A funo acima faz a verificao no registro do Windows. Por isto est sujeita a falha caso o BDE coloque as configuraes em outro local ( o caso do BDE salvar as configuraes no formato do Windows 3.x). O ideal seria usar uma API do BDE, mas at o momento no conheo uma que retorne esta informao. Caso algum saiba, queira por gentileza nos informar. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Resolver "Internalerrornear: IBCheck" do Interbase 5.1.1 Server no NT


Recebi esta mensagem do desenvolvedor Alexsando S. Pimenta. Como deve ser do interesse de outros desenvolvedores, coloquei-a aqui: ==== Mensagem original ==== Ol Daniel,

Anote est soluo, muitos tem o mesmo problema mas no conseguem a soluo to facilmente como eu. Look: Problema: Estou com um problemo. Trabalho com o NT 4 workstation Service Pack 3, Delphi 3 e Interbase 4.2.xxx. E instalei o Interbase 5.1.1 Serve r nesta mquina. At a tudo bem. Quando fui rodar a aplicao deram alguns problemas de converso do tipo de Dado. Analisando o problema percebi que havia esquecido de instalar o Client do Interbase. Foi a que comearam os problemas. Tentei instalar o client, porm o instalador aps preparar os arquivos de instalao mostrava a seguinte mensagem e parava : Titulo da janela = "Severe", mensagem = "Internalerrornear: IBCheck"; comecei a ler os manuais, em certo ponto aconselhava desinstalar qualquer verso posterior do Interbase da minha mquina. Foi ento que desinstalei o Interbase 4.2.xxx (atravs do "ControlPanel", "Add/Remove Programs"). Nova tentativa de instalar o client, o erro persistia. Resolvi desinstalar (atravs do "Control Panel", "Add/Remov e Programs") todo o Interbase da minha mquina e comear tudo de novo. Porm quando tentei instalar novamente o Interbase Server, surpresa, o erro apareceu novamente. Mas agora no havia interbase instalado. Fui desinstalando Delphi, BDE, ... e nada. Entr ei no Regedit, pois o desinstalador, normalmente, faz o trabalho incompleto e necessrio excluir um monte de lixo do Registry. Deparei com a seguintes chaves: hkey_local_machine \system\controlset001 \enum\root\legacy_interbase_gua rd hkey_local_machine \system\controlset001 \enum\root\legacy_interbase Tentei exclu -las, porm so chaves protegidas, e o regedit no permitiu que eu exclusse -as. Poderiam me dar uma soluo para eu poder instalar o Interbase em minha mquina? Preciso disto com urgncia. Obrigado, Alexsandro Pimenta Xenon Software Comrcio e Servios Ltda apepper@uol.com.br Soluo: Sr. Alexsandro, Esse erro: 'Internalerrornear: IBCheck' acontece apenas em algumas mquinas NT 4. Na hora da instalao, criada uma chave com valor errado.

Entre no registry do Windows e altere a opo, PATH de binrio para string, da chave: HKEY_CURRENT_USER \Environment

Renata Oliva InpriseSupport Center

Autor: Renata Oliva - InpriseSupport Center Incio

Excluir todos os registros de uma tabela


procedure tbDBDeleteAll(const DataSet: TDataSet); begin with DataSet do while RecordCount > 0 do Delete; end; { Chame-a como nos exemplos abaixo: } tbDBDeleteAll(Table1); ou tbDBDeleteAll(Query1);

Observaes Se houver um filtro ou range ativo, somente os registros filtrados sero excludos. Portanto diferente de Table1.EmptyTable. Esta funo poder ser chamada no evento BeforeDelete do Table (ou Query) principal em um formulrio mestre-detalhe para excluir os itens (da parte detalhe). Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Mudar a coluna ativa em um DBGrid via programao


{ Usando nmero da coluna (zero a primeira coluna): } DBGrid1.SelectedIndex := 0; { Usando o nome do campo } DBGrid1.SelectedField := Table1.FieldByName(Edit2.Text);

Observaes Aconselho usar o nome do campo quando o que importa o campo e no a posio. Use o nmero da coluna somente quando o que importa a posio, e no o campo. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br

Incio

Obter o nmero do registro atual


Table1.RecNo()

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Trabalhar com Filter de forma mais prtica


Se voc est habituado a usar este cdigo no filter... Table1.Filter := 'Nome = '''+ Edit1.Text + ''''; ou Table1.Filter := 'Data = ''' + DateToStr(Date) + ''''; Tente usar este: Table1.Filter := 'Nome = ' + QuotedStr(Edit1.Text); ou Table1.Filter := 'Data = ' + QuotedStr(DateToStr(Date));

Observaes A funo QuitedStr() coloca apstrofos envolvendo a string. Se houver um apstrofo como parte da string, ela o subtitui por dois apstrofos, para que seja corretamente interpretado. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Obter a quantidade de registros total e visvel de uma tabela


Inclua na seo uses:DbiProcs
Os componentes TTable e TQuery possuem a propriedade RecordCount que indicam a quantidade de registros da tabela. No entanto esta propriedade dependente de filtros, ou seja, se tivermos uma tabela com dez registros com campo "Codigo" de 1 a 10 e aplicarmos o filtro mostrado a seguir, a propriedade RecordCount retornar 5 e no 10. Table1.Filter := 'Codigo <= 5';

Table1.Filtered := true; Se quizermos obter a quantidade total de registros, independentemente de filtros, devemos usar uma API do BDE conforme abaixo: var Total: integer; begin Check(DbiGetRecordCount(Table1.Handle, Total)); ShowMessage('Total de registros: ' + IntToStr(Total)); end;

Observaes Para testar o exemplo acima, o Table1 precisa estar aberto. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Gravar fisicamente com Paradox


Inclua na seo uses:DbiProcs
{ Se estiver usando TTable, coloque nos eventos AfterPost e AfterDelete a seguinte linha: } dbiSaveChanges(Table1.Handle); { Para TQuery, a instruo semelhante: } dbiSaveChanges(Query1.Handle);

Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Criar uma tabela (DB, DBF) atravs do seu programa


Inclua na seo uses:dbTables, DB
procedure CriaTabelaClientes; var Tabela: TTable; begin Tabela := TTable.Create(Application); try Tabela.DatabaseName := 'C: \'; { ou Tabela.DatabaseName := 'NomeAlias'; }

Tabela.TableName := 'Clientes.DB'; Tabela.TableType := ttParadox; { ou ttDBase } { Somente Delphi4 } ifTabela.Existsthen { Se a tabela j existe... } Exit; {***} { Cria a tabela } Tabela.FieldDefs.Add('Codigo', ftInteger, 0, true); Tabela.FieldDefs.Add('Nome', ftString, 30, true); Tabela.FieldDefs.Add('DataNasc', ftDate, 0, false); Tabela.FieldDefs.Add('RendaMes', ftCurrency, 0, false); Tabela.Field Defs.Add('Ativo', ftBoolean, 0, true); { etc, etc, etc } Tabela.CreateTable; { Cria os ndices } Tabela.AddIndex('ICodigo', 'Codigo', [ixPrimary, ixUnique]); Tabela.AddIndex('INome', 'Nome', [ixCaseInsensitive]); { etc, etc, etc } finally Tabela.Free; end; end;

Observaes Para verificar se o arquivo j existe na verso 3 ou anterior do Delphi, voc dever usar a funo "FileExists" do Delphi. Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Criar um Alias temporrio atravs do seu programa


Inclua na seo uses: DB
{ Enxergar somente configuraes da sesso atual } Session.ConfigMode := cmSession; { Adicionar o Alias } Session.AddStandardAlias('MeuAlias', 'C: \DirProg', 'PARADOX');

Observaes Autor: Daniel P. Guimares Home-page: www.tecnobyte.com.br Incio

Pgina atualizada em 01 de maio de 2007 Todos os direitos reservados www.tecnobyte.com.br


No se recomenda a incluso de imagens nos campos de tabelas deBD, ento o recomendvel que voc armazene na tabela apenas o caminho de onde a imagem/foto est localizada, sendo assim: Inicialmente vc precisa definir na tabela um campo varchar onde ser armazenado o caminho da foto, no meu caso, eu coloquei um campo de tamanho 100 no nulo para isso. Muito bem, depois disso, insira o componente OpenDialog, da palheta Dialogs no seu formulrio. Na propriedade FilterdoOpenDialog coloque os tipos de imagens a serem aceitas, no meu caso eu digitei: Image files (*.jpg),(*.jpeg),(*.bmp),(*gif) A seguir, marque na propriedade initialDir o diretrio inicial onde a caixa de dilogo vai apontar, por ex: E:Meus documentosMinhas Imagens Agora coloque um componente Image da paleta Additional, onde ser exibida a foto, marque true para a propriedade Center, na propriedade Picture carregue a imagem que vc vai deixar antes de carregar a foto pretendida, por ex, mo meu caso eu deixei uma figura de uma camerafotografica para indicar ao usurio que o campo para insero de fotografia. No evento OnDblClick do componente Image adicione o seguinte cdigo: ifOpenDialog.Executethen begin ClientDataSetNOMEDOCAMPO.asString := OpenDialog.FileName; Image.Picture.LoadFromFile(OpenDialog.FileName); end; Lembrando que na hora de editar o registro, alm das instrues pertinentes, adicione o seguinte cdigo no boto Editar: ifnotFileExists(ClientDataSet.fieldByName('NOME_DO_CAMPO').asString) then //carregando a foto Image.Picture.LoadFromFile('C:MeusdocumentosMinhas Imagensmaquina.jpg') //maquina o nome da figura inicial else try Image.Picture.LoadFromFile(ClientDataSet.fieldByName('NOME_DO_CAMPO').asString); except Image.Picture := NIL; Application.MessageBox('Erro na abertura da foto!','ATENO!',MB_ICONERROR); end;

Estou usando os componentes: SQLQuery, DataSetProvider, ClientDataSet e DataSource para manipular os dados, delphi 7 e Firebird.

Vous aimerez peut-être aussi