Problema com Datas e Números em Consulta

14/08/2004

Estou fazendo uma consulta em tempo de execução. Essa consulta funciona como FindNeareast da Table (Conforme digita vai filtrando). Está funcionando. Só que agora preciso fazer a mesma consulta em uma tela que contém data (date) e nota(numeric).

Primeiro Problema. Tenho 3 datas.
26/07/2004
2/8/2004
2/8/2004

Quando digito ´26´ ele filtra. Quando digito ´2/´ desaparece tudo.

Segundo Problema:
Digito qualquer nota tudo desaperece.

Veja a consulta:
data.IBQCAva.Close;
data.IBQCAva.SQL.Clear;
data.IBQCAva.SQL.Add(´select * from AVALIACAO join INSCRICAO ON ´);
data.IBQCAva.SQL.Add(´INSC_NUMERO=AVA_INSCALUNO
data.IBQCava.SQL.Add(´where Upper(´+ Campo + ´) LIKE ´ + ´´´´ + UpperCase(Edit1.Text) + ´¬´+ ´´´´);
data.IBQCAva.Open;

Se puder data uma sugestão!!!

Valeu a força!!!

JR.


Jrjoliv2003

Respostas

14/08/2004

Laercioguerco

Sugiro que você abandone Table, e utilize Query. Ai sim, criando dinâmicamente ou passando parâmetros você terá flexibilidade para encontrar registros por faixa.
Se possível utilize SGBD (IB/FB) combinando dbExpress e ClientDataSet.
Istofará grande diferençaquanto a performance, principalmente em ambiente de rede.

Sds
laercio@clubedelphi.com.br


Responder Citar

14/08/2004

Jrjoliv2003

Eu não estou usando Table. Essa consulta funciona como se fosse o FindNearest de um componente Table. Eu uso Query.

O problema está na consulta com datas e notas(campo numérico).

Veja as instruções novamente. ´Tem alguma idéia do que seja?

Valeu a força!!!

JR.


Responder Citar

14/08/2004

Jrjoliv2003

Com campo tipo Integer funciona.
O problema é com campos tipo Date e Numeric(15,2).

Estou fazendo uma consulta em tempo de execução. Essa consulta funciona como FindNeareast da Table (Conforme digita vai filtrando). Está funcionando. Só que agora preciso fazer a mesma consulta em uma tela que contém data (date) e nota(numeric).

Primeiro Problema. Tenho 3 datas.
26/07/2004
2/8/2004
2/8/2004

Quando digito ´26´ ele filtra. Quando digito ´2/´ desaparece tudo.

Segundo Problema:
Digito qualquer nota tudo desaperece.

Veja a consulta:
data.IBQCAva.Close;
data.IBQCAva.SQL.Clear;
data.IBQCAva.SQL.Add(´select * from AVALIACAO join INSCRICAO ON ´);
data.IBQCAva.SQL.Add(´INSC_NUMERO=AVA_INSCALUNO
data.IBQCava.SQL.Add(´where Upper(´+ Campo + ´) LIKE ´ + ´´´´ + UpperCase(Edit1.Text) + ´¬´+ ´´´´);
data.IBQCAva.Open;

Se puder data uma sugestão!!!

Valeu a força!!!

JR.


Responder Citar

14/08/2004

Vinicius2k

JR.,
Primeiro Problema. Tenho 3 datas. 26/07/2004 2/8/2004 2/8/2004 Quando digito ´26´ ele filtra. Quando digito ´2/´ desaparece tudo.

Se a data no banco estiver em formato de data ´2/´, realmente, não existe... seria ´02/´

Segundo Problema: Digito qualquer nota tudo desaperece. Veja a consulta: data.IBQCAva.Close; data.IBQCAva.SQL.Clear; data.IBQCAva.SQL.Add(´select * from AVALIACAO join INSCRICAO ON ´); data.IBQCAva.SQL.Add(´INSC_NUMERO=AVA_INSCALUNO´); [color=red:d7452c8dc2]data.IBQCava.SQL.Add(´where Upper(´+ Campo + ´) LIKE ´ + ´´´´ + UpperCase(Edit1.Text) + ´¬´+ ´´´´);[/color:d7452c8dc2] data.IBQCAva.Open;


Procure sempre que possível usar parametros que facilitam o trabalho, mas caso não queira usá-los, vc não deve usar sequencias de aspas simples pq sempre geram confusão... creio eu, que se vc der um ´ShowMessage´ na SQL q vc está enviando ao banco vai notar erros na colocao das aspas... ao invés disso use a função QuotedStr para ´quotar´ o texto que vc quer enviar ao banco...
(´where Upper(´+ Campo + ´) LIKE ´ + QuotedStr(UpperCase(Edit1.Text) + ´¬´))


Espero ter ajudado...
T+


Responder Citar

15/08/2004

Jrjoliv2003

Obrigado por ter respondido.

Estou com um problema com datas. Percebo que cadastro uma data que contém zeros iniciais, exemplo 01/08/2004. Quando gravo os zeros que são iniciais somem, ficando assim 1/8/2004. Talvez seja pro isso que não consigo fazer a consulta. Sabe pq isso acontece. Uso Delphi 5 com Interbase 6. Coloquei máscara 99/99/9999 no campo das datas direto no componente.

Valeu a força!!!

JR.


Responder Citar

15/08/2004

Vinicius2k

Para vc ter certeza que como ficou a gravação do campo, faça uma consulta direta dentro da base com o IBConsole ou IBExpert...
Nunca vi isso (gravação incorreta) ocorrer, mas lembre-se de que a exibição da data em componentes data-aware, como a DBGrid por exemplo, está vinculada às configurações regionais do Windows...
Quais os componentes que vc está utilizando?
Experimente esquecer como como está sendo exibida data e digitar no seu campo de filtro ´01/´...

T+


Responder Citar

15/08/2004

Jrjoliv2003

Bom verifiquei via IBExpert.
Realmente a gravação está correta. Lá tem tuos os zeros da data. A data está correta.
Na exibição é que está faltando os zeros e a consulta não funciona. O que devo fazer?

Valeu a força!!

JR.


Responder Citar

15/08/2004

Vinicius2k

Vc já verificou nas configurações regionais do seu Windows se a data não está no formato ´d/m/aaaa´ quando o correto é ´dd/mm/aaaa´ ?

T+


Responder Citar

15/08/2004

Jrjoliv2003

Realmente!! O formato estava errado. Eu já alterei e na visualização já está OK! Mas na consulta com o código, em uma data como 02/08/2004, se digito zero, desaparece tudo.


Obrigado por estar ajudando!!!

A consulta:
data.IBQCAva.Close;
data.IBQCAva.SQL.Clear;
data.IBQCAva.SQL.Add(´select * from AVALIACAO join INSCRICAO ON ´);
data.IBQCAva.SQL.Add(´INSC_NUMERO=AVA_INSCALUNO
data.IBQCava.SQL.Add(´where Upper(´+ Campo + ´) LIKE ´ + ´´´´ + UpperCase(Edit1.Text) + ´¬´+ ´´´´);
data.IBQCAva.Open;


JR.


Responder Citar

15/08/2004

Vinicius2k

Jr,

Resolvido o problema de exibição, seu problema agora é outro: LIKE com datas... é bastante trabalhoso conseguir resultados com LIKE em campos tipo DATE e TIMESTAMP (eu nem faço isso, quando se trata de datas e exijo preenchimento total do campo e comparo com ´= :parametro´)...

Para vc visualizar o problema vá no IBExpert e execute a instrução :
select cast(SEU_CAMPO_DATA as varchar(12)) from SUA_TABELA

Este é o formato usado para armazenar datas transformado em varchar para que vc possa comparar com LIKE...
Se vc quiser usar o LIKE, vai precisar usar o CAST em conjunto com o WHERE... algo parecido com isto :
select * from SUA_TABELA where cast(SEU_CAMPO as varchar(12)) like ´2¬´

E dentro do que vc pretende, que pelo que entendi é um filtro dinamico, vai dar um pouco de trabalho para fazer...

T+


Responder Citar

16/08/2004

Jrjoliv2003

Testei a linha q vc me enviou. Aparece os meses em letra e abreviado.

Tá complicado!!!!

Preciso fazer esse tipo de consulta.
Para ter mais detalhes, funciona da seguinte forma:

O Usuário escolhe um Campo (Nome, Data, Responsável etc).
Quando ele digitar no edit, uma variável chamada CAMPO recebe o nome do campo que
está na tabela(Ava_Nome, Ava_dt, Ava_Nota etc) de acordo com a escolha e filtra os dados.

O probelam e com campo tipo Date e com campo tipo Numeric.


Precisso fazer isso!!!

Valeu a força!

JR.


Responder Citar

16/08/2004

Vinicius2k

Jr.,
Eu faço mais ou menos assim :
1 - Tenho um form de filtro dinamico com uma combo que irá receber os nomes dos campos.
Meu botão ´filtro´ tem, basicamente, este código :
frm_filtro:= Tfrm_filtro.Create(Application);
frm_filtro.AddFieldsToFilter(DBGrid);
frm_filtro.Showmodal;
...
FreeAndNil(frm_filtro);

2 - As variáveis globais deste form de filtro são :
var
  FieldTypes, FieldNames: TStrings;
  IsTexto, IsData, IsNumero, IsValor: Boolean;

e a variável pública é :
FilterStr: String;


3 - A função do form Filtro, ´AddFieldsToFilter´, que eu chamo é esta:
procedure Tfrm_filtro.AddFieldsToFilter(aDBGrid: TDBGrid);
var i: integer;
begin
  FieldTypes:= TStringList.Create;
  FieldNames:= TStringList.Create;
  for i:= 0 to (aDBGrid.Columns.Count - 1) do
    begin
      if aDBGrid.Columns[i&93;.Field.FieldKind = fkData then
        begin
          cbx_aplicar.Items.Add(aDBGrid.Columns&91;i&93;.Title.Caption);
          FieldTypes.Add(aDBGrid.Columns&91;i&93;.Field.ClassName);
          FieldNames.Add(aDBGrid.Columns&91;i&93;.Field.FieldName);
        end;
    end;
  cbx_aplicar.ItemIndex:= 0;
end;

Eu tenho 2 string lists que guardam as classes dos campos e nomes reais dos campos, respectivamente.

4 - On Change da minha combo de campos chama a procedure CheckFieldType que tem este código :
procedure Tfrm_filtro.CheckFieldType;
var Item: Integer;
    FieldType: String;
begin
  Item:= cbx_aplicar.ItemIndex;
  FieldType:= FieldTypes.Strings&91;Item&93;;
  { **** }
  if (FieldType = ´TStringField´)     or
     (FieldType = ´TWideStringField´) then
    begin
      tab_texto.TabVisible:=   True;  IsTexto:=   True;
      tab_data.TabVisible:=    False; IsData:=    False;
      tab_numero.TabVisible:=  False; IsNumero:=  False;
      tab_valor.TabVisible:=   False; IsValor:=   False;
    end;
  { **** }
  if (FieldType = ´TDateField´)     or
     (FieldType = ´TDateTimeField´) or
     (FieldType = ´TTimeField´)     then
    begin
      tab_texto.TabVisible:=   False; IsTexto:=   False;
      tab_data.TabVisible:=    True;  IsData:=    True;
      tab_numero.TabVisible:=  False; IsNumero:=  False;
      tab_valor.TabVisible:=   False; IsValor:=   False;
    end;
  { **** }
  if (FieldType = ´TIntegerField´)  or
     (FieldType = ´TSmallIntField´) or
     (FieldType = ´TLargeintField´) then
    begin
      tab_texto.TabVisible:=   False; IsTexto:=   False;
      tab_data.TabVisible:=    False; IsData:=    False;
      tab_numero.TabVisible:=  True;  IsNumero:=  True;
      tab_valor.TabVisible:=   False; IsValor:=   False;
    end;
  { **** }
  if (FieldType = ´TFloatField´)    or
     (FieldType = ´TCurrencyField´) or
     (FieldType = ´TBCDField´)      or
     (FieldType = ´TFMTBCDField´)   then
    begin
      tab_texto.TabVisible:=   False; IsTexto:=   False;
      tab_data.TabVisible:=    False; IsData:=    False;
      tab_numero.TabVisible:=  False; IsNumero:=  False;
      tab_valor.TabVisible:=   True;  IsValor:=   True;
    end;
end;


5 - Essa procedure torna visivel ou invisivel as TabSheets, de uma PageControl que existe neste form de Filtro... cada TabSheet foi desenhada para receber um tipo de dado, por exemplo : se o campo for TDateTime, a TabSheet visível é a tab_data, que tem um DateEdit (RXLib)... se for TInteger, a TabSheet Visível é a tab_numero que tem um CurrencyEdit... e assim por diante...

6 - Tenho um botão aplicar com este código :
FilterStr:= MakeFilterStr;
Close;


7 - A função MakeFilterStr tem este código :
function Tfrm_filtro.MakeFilterStr: String;
var SelectedField: String;
    texto, data, data_ate, numero, numero_ate, valor, valor_ate: String;
begin
  Result:= ´´;
  SelectedField:= FieldNames.Strings[cbx_aplicar.ItemIndex&93;;
  { **** }
  if IsTexto then
    begin
      texto:= edt_texto.Text;
      case cbx_texto_criterio.ItemIndex of
        0:  Result:= SelectedField + ´ = ´     + QuotedStr(texto);
        1:  Result:= SelectedField + ´ like ´  + QuotedStr(texto + ´¬´);
        2:  Result:= SelectedField + ´ like ´  + QuotedStr(´¬´ + texto);
        3:  Result:= SelectedField + ´ like ´  + QuotedStr(´¬´ + texto + ´¬´);
      end;
    end;
  { **** }
  if IsData then
    begin
      data:= DateToStr(ded_data.Date);
      data_ate:= DateToStr(ded_data_ate.Date);
      case cbx_data_criterio.ItemIndex of
        0:  Result:= SelectedField + ´ = ´        + QuotedStr(data);
        1:  Result:= SelectedField + ´ >= ´       + QuotedStr(data);
        2:  Result:= SelectedField + ´ <= ´       + QuotedStr(data);
        3:  Result:= SelectedField + ´ between ´  + QuotedStr(data) + ´ and ´ + QuotedStr(data_ate);
      end;
    end;
  { **** }
  if IsNumero then
    begin
      numero:= ced_numero.Text;
      numero_ate:= ced_numero_ate.Text;
      case cbx_numero_criterio.ItemIndex of
        0:  Result:= SelectedField + ´ = ´        + QuotedStr(numero);
        1:  Result:= SelectedField + ´ >= ´       + QuotedStr(numero);
        2:  Result:= SelectedField + ´ <= ´       + QuotedStr(numero);
        3:  Result:= SelectedField + ´ between ´  + QuotedStr(numero) + ´ and ´ + QuotedStr(numero_ate);
      end;
    end;
  { **** }
  if IsValor then
    begin
      valor:= ced_valor.Text;
      valor_ate:= ced_valor_ate.Text;
      case cbx_valor_criterio.ItemIndex of
        0:  Result:= SelectedField + ´ = ´        + QuotedStr(valor);
        1:  Result:= SelectedField + ´ >= ´       + QuotedStr(valor);
        2:  Result:= SelectedField + ´ <= ´       + QuotedStr(valor);
        3:  Result:= SelectedField + ´ between ´  + QuotedStr(valor) + ´ and ´ + QuotedStr(valor_ate);
      end;
    end;
end;

É ela que monta a clausula WHERE da instrução SQL quer será retornada...

Deu trabalho para fazer isso tudo pela primeira vez, mas eu uso este form de filtro para qualquer form da aplicação... veja se vc consegue tirar proveito deste código para montar a sua rotina...

T+


Responder Citar

16/08/2004

Jrjoliv2003

Caramba!!! Tu teve trabalho!!!!


Eu vou TENTAR entender esse código e verificar como poderia paroveita-lo em meu projeto.


Sou novato em programação!!


Valeu por ter me ajudado!!

JR.


Responder Citar

17/08/2004

Jrjoliv2003

Mostrei seu código a um colega e ele gostou muito.

Me tive uma dúvida, uma não, duas: como eu faria a consulta de data ou números(numeric) em tempo de execução. Estou usando essa linha abaixo para as consultas, porém ela não serve para data e campo numeric.

data.IBQCava.SQL.Add(´where Upper(´+ Campo + ´) LIKE ´ + ´´´´ + UpperCase(Edit1.Text) + ´¬´+ ´´´´);


Valeu a força!!!

JR.


Responder Citar

17/08/2004

Vinicius2k

Jr.

No meu caso, eu não uso a nenhuma instrução nas queries em tempo de projeto...Todas as instruções são passadas em run time o que me permite usar o recurso código que lhe mostrei...

A instrução inteira é passada para a query, da forma correta para cada tipo de campo...

T+


Responder Citar