Array
(
)

Problema com Datas e Números em Consulta

Jrjoliv2003
   - 14 ago 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.


Laercioguerco
   - 14 ago 2004

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


Jrjoliv2003
   - 14 ago 2004

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.


Jrjoliv2003
   - 14 ago 2004

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.


Vinicius2k
   - 14 ago 2004

JR.,

Citação:
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/´


Citação:
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;


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...
#Código

(´where Upper(´+ Campo + ´) LIKE ´ + QuotedStr(UpperCase(Edit1.Text) + ´¬´))


Espero ter ajudado...
T+


Jrjoliv2003
   - 15 ago 2004

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.


Vinicius2k
   - 15 ago 2004

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+


Jrjoliv2003
   - 15 ago 2004

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.


Vinicius2k
   - 15 ago 2004

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+


Jrjoliv2003
   - 15 ago 2004

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.


Vinicius2k
   - 15 ago 2004

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 :
#Código

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 :
#Código
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+


Jrjoliv2003
   - 16 ago 2004

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.


Vinicius2k
   - 16 ago 2004

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 :
#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 :
#Código
var
FieldTypes, FieldNames: TStrings;
IsTexto, IsData, IsNumero, IsValor: Boolean;

e a variável pública é :
#Código
FilterStr: String;


3 - A função do form Filtro, ´AddFieldsToFilter´, que eu chamo é esta:
#Código
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].Field.FieldKind = fkData then
begin
cbx_aplicar.Items.Add(aDBGrid.Columns[i].Title.Caption);
FieldTypes.Add(aDBGrid.Columns[i].Field.ClassName);
FieldNames.Add(aDBGrid.Columns[i].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 :
#Código
procedure Tfrm_filtro.CheckFieldType;
var Item: Integer;
FieldType: String;
begin
Item:= cbx_aplicar.ItemIndex;
FieldType:= FieldTypes.Strings[Item];
{ **** }
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 :
#Código
FilterStr:= MakeFilterStr;
Close;


7 - A função MakeFilterStr tem este código :
#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];
{ **** }
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+


Jrjoliv2003
   - 16 ago 2004

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.


Jrjoliv2003
   - 17 ago 2004

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.


Vinicius2k
   - 17 ago 2004

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+


Jrjoliv2003
   - 17 ago 2004

Beleza!!!

É q eu estou tentando fazer um código aqui e tenho dúvida em montar a consulta para data e para campo numeric.

Valeu a força!!!

JR.