Consulta com Datas

02/12/2005

Analise meu projeto para relatórios:

Variáveis criadas:
- VDataInicial : TDate;
- VDataFinal : TDate;


Dois MaskEdit
- rotina no evento OnExit do primeiro: VDataInicial := if MaskEdit1.text <> ´´ then StrToDate(MaskEdit1.text);
- rotina no evento OnExit do segundo: VDataFinal := if MaskEdit2.text <> ´´ then StrToDate(MaskEdit2.text);

Em inúmeras consultas tenho as seguintes rotinas:
SQLQUERY1.ADD(´SELECT * FROM NOME_DA_TABELA WHERE DATA_VCTO BETWEEN :Inicio AND :Fim´);
SQLQUERY1.PARAMS[0].AsDateTime := VDataInicial;
SQLQUERY1.PARAMS[1].AsDateTime := VDataFinal;


O projeto funciona perfeitamente quando o usuário coloca a data inicial e final nos maskedit. Meu problema é quando ele quer um relatório sem início ou fim, ou seja, quer que sejam listados todos os registro, independente da sua DATA_VCTO.

Consigo fazer funcionar porque fiz uma gambiarra: no activate do relatório, atribuo: VDataInicial := 0; //isso é igual 30/12/1899 e VDataFinal := 110000; //isso é igual 31/07/2200. Com isso, tenho um grande período de tempo antes da data atual e também um grande período depois. Se o usuário não informar a data inicial e final, as variáveis VDataInicial e VDataFinal ficarão com os valores iniciais.
A questão é que isso não é correto e nem 100¬ confiável. Gostaria que os colegas me ajudassem numa solução para que, quando o usuário não informar nada nas datas, a consulta pegar todos os registros.

Já me sugeriram fazer assim:
if usuariopreencheu datas then
begin
SQLQUERY1.ADD(´SELECT * FROM NOME_DA_TABELA WHERE DATA_VCTO BETWEEN :Inicio AND :Fim´);
SQLQUERY1.PARAMS[0].AsDateTime := VDataInicial;
SQLQUERY1.PARAMS[1].AsDateTime := VDataFinal;
end
else
SQLQUERY1.ADD(´SELECT * FROM NOME_DA_TABELA´);

Sim, isso daria certo, só que preciso de outra solução, pois como tenho muitas, mas muitas vezes essa rotina no projeto, daria muitos IFs.

Se você tiver qualquer dica que ajude, por favor poste-a.

Obrigado.


Armindo

Respostas

02/12/2005

Marcio.theis

De uma olhadinha nesta Unit:

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ckbDtVencto: TCheckBox;
    edtDtIni: TMaskEdit;
    Label1: TLabel;
    edtDtFim: TMaskEdit;
    BitBtn1: TBitBtn;
    procedure ckbDtVenctoClick(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ckbDtVenctoClick(Sender: TObject);
begin
edtDtIni.Enabled:=ckbDtVencto.Checked;
edtDtFim.Enabled:=ckbDtVencto.Checked;
if ckbDtVencto.Checked then
    edtDtIni.SetFocus;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
SQLQUERY1.Close;
SQLQUERY1.SQL.Clear;
SQLQUERY1.ADD(´SELECT * ´);
SQLQUERY1.ADD(´FROM NOME_DA_TABELA´);
if ckbDtVencto.Checked then
    begin
    SQLQUERY1.ADD(´WHERE DATA_VCTO BETWEEN :Inicio AND :Fim´);
    SQLQUERY1.PARAMS[0&93;.AsDateTime := VDataInicial;
    SQLQUERY1.PARAMS&91;1&93;.AsDateTime := VDataFinal;
    end;
SQLQUERY1.Open;
end;

end.



e o dfm da unit

object Form1: TForm1
  Left = 189
  Top = 103
  Width = 364
  Height = 145
  Caption = ´Form1´
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = ´MS Sans Serif´
  Font.Style = &91;&93;
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 208
    Top = 26
    Width = 6
    Height = 13
    Caption = ´a´
  end
  object ckbDtVencto: TCheckBox
    Left = 32
    Top = 24
    Width = 81
    Height = 17
    Caption = ´Dt. Vencto.:´
    TabOrder = 0
    OnClick = ckbDtVenctoClick
  end
  object edtDtIni: TMaskEdit
    Left = 120
    Top = 22
    Width = 81
    Height = 21
    Enabled = False
    EditMask = ´99/99/9999;1;_´
    MaxLength = 10
    TabOrder = 1
    Text = ´  /  /    ´
  end
  object edtDtFim: TMaskEdit
    Left = 220
    Top = 22
    Width = 81
    Height = 21
    Enabled = False
    EditMask = ´99/99/9999;1;_´
    MaxLength = 10
    TabOrder = 2
    Text = ´  /  /    ´
  end
  object BitBtn1: TBitBtn
    Left = 272
    Top = 56
    Width = 75
    Height = 57
    Caption = ´BitBtn1´
    TabOrder = 3
    OnClick = BitBtn1Click
  end
end


na tela coloquei um check box antes, o que garante se o usuário esta solicitando filtro por data ou não... e tb, pq vc naum coloca DateTimePicker no lugar dos EditMask, na minha opinião seria bem mais prático.


Responder Citar

02/12/2005

Armindo

Obrigado pela resposta, mas como eu disse, não posso colocar IF por causa de outras rotinas de meu projeto.

Para que me pudesse ser útil.

no activate form onde coloco: VDataInicial := 0; //isso é igual 30/12/1899 e VDataFinal := 110000; //isso é igual 31/07/2200.

Teria que ser algo assim:
VDataInicial := all
VDataFinal := all

OBs.: sei que o ´all´ não existe, mas é algo nesse sentido que preciso, ou seja, algo que atribua valor (data) às variáveis para que peguem todas as datas e, se o usuário mudar o conteúdo dos maskedit, as variáveis recebem o valor que o usuário informou.

Obrigado.


Responder Citar

02/12/2005

Edilcimar

de um valor fixo para a data inicial e final, no oncreate ou no onactivate do form, assim vc teria um valor inicial e um valor final independentemente do usuario preencher ou não o campo


Responder Citar

02/12/2005

Armindo

Sim, é assim q estou fazendo. Se você ler bem minha dúvida (o primeiro post deste tópico), vai ver que fiz assim: VDataIncial := 0 e VDataFinal := 11000. O problema que isso não é muito confiável, pois, se o usuário, por um erro, gravar um lcto com data de 01/01/0005, por exemplo, o relatório não listaria esse registro.

obrigado


Responder Citar

02/12/2005

Edilcimar

Veja que eu falei para colocar no oncreate ou no onactivate do form!
A tua pergunta foi para o caso do usuário não colocar data alguma, se ele por ventura tiver colocado uma data inicial 01/12/2005 ou uma data final de 31/12/2004 é porque ele está querendo apenas um pedaço do relatório


Responder Citar