Aniversariantes. Onde está o meu erro?

16/05/2019

0

Olá amigos. Dúvida de novato. Tenho um programinha de cadastro de membros de igreja. Estou fazendo um relatório de aniversariantes entre duas datas.

Mas no banco de dados, tenho registros de pessoas falecidas, desligadas e transferidas, e quero eliminar esses registros do relatório.

Fiz assim:

procedure TAniversarios.DateTimePicker1Change(Sender: TObject);
begin
Edit2.Text := DateToStr(Datetimepicker1.Date);
AdoQuery1.Close;
AdoQuery1.SQL.Clear;
AdoQuery1.SQL.Add(''SELECT Nome, DtNasc, tel, Cel, Status FROM CadPessoas'');
if monthOf(Datetimepicker1.DateTime) <= monthOf(Datetimepicker2.DateTime) then
begin
AdoQuery1.SQL.Add(''WHERE ((Month(DtNasc) * 100) + Day(DtNasc)) between :pinicial and :pfinal'');
ADOQuery1.SQL.add('' and status <> '' + QuotedStr(''Falecido''));
ADOQuery1.SQL.add('', '' + QuotedStr(''transferido''));
ADOQuery1.SQL.add('', '' + QuotedStr(''Desligado'') +'')'');
AdoQuery1.SQL.Add(''Order by Day(DtNasc)'');
AdoQuery1.Parameters.ParamByName(''pinicial'').Value := MonthOf(datetimepicker1.Date) * 100 + DayOf(datetimepicker1.Date);
AdoQuery1.Parameters.ParamByName(''pfinal'').Value := MonthOf(datetimepicker2.Date) * 100 + DayOf(datetimepicker2.Date);
Adoquery1.Open;
end
else
begin
AdoQuery1.SQL.Add(''WHERE ((Month(DtNasc) * 100) + Day(DtNasc)) between :pinicial and :pfinal'');
AdoQuery1.SQL.Add(''or ((Month(DtNasc) * 100) + Day(DtNasc)) between :pinicial2 and :pfinal2'');
ADOQuery1.SQL.add('' and status <> '' + QuotedStr(''Falecido''));
ADOQuery1.SQL.add('', '' + QuotedStr(''transferido''));
ADOQuery1.SQL.add('', '' + QuotedStr(''Desligado'') +'')'');
AdoQuery1.SQL.Add(''Order by Day(DtNasc)'');
AdoQuery1.Parameters.ParamByName(''pinicial'').Value := MonthOf(datetimepicker1.Date) * 100 + DayOf(datetimepicker1.Date);
AdoQuery1.Parameters.ParamByName(''pfinal'').Value := 1231;
AdoQuery1.Parameters.ParamByName(''pinicial2'').Value := 101;
AdoQuery1.Parameters.ParamByName(''pfinal2'').Value := MonthOf(datetimepicker2.Date) * 100 + DayOf(datetimepicker2.Date);
Adoquery1.Open;
end;
end;


Mas ele retorna o erro:

Project SGE.exe raised exception class EOleException with message ''Erro de sintaxe(vírgula) na expressão de consulta ''((Month(DtNasc)*100) + Day(DtNasc)) between ? and ? and status <> ''Falecido'', ''transferido'', ''Desligado'')". Process stopped. Use Step or Run to continue.


Onde está o meu erro? Alguém pode ajudar? Obrigado.
Edilson Santiago

Edilson Santiago

Responder

Post mais votado

16/05/2019

tente assim:
procedure TAniversarios.DateTimePicker1Change(Sender: TObject);
begin
	Edit2.Text := DateToStr(Datetimepicker1.Date);
	AdoQuery1.Close;
	AdoQuery1.SQL.Clear;
	AdoQuery1.SQL.Add('SELECT Nome, DtNasc, tel, Cel, Status FROM CadPessoas');
	AdoQuery1.SQL.Add('WHERE ( ((Month(DtNasc) * 100) + Day(DtNasc)) between :pinicial and :pfinal');
	AdoQuery1.SQL.Add('or ((Month(DtNasc) * 100) + Day(DtNasc)) between :pinicial2 and :pfinal2 )');
	ADOQuery1.SQL.add('and not (status in ('+QuotedStr('Falecido')+','+QuotedStr('Transferido')+','+QuotedStr('Desligado')+'))');
	AdoQuery1.SQL.Add('Order by Day(DtNasc)');
	AdoQuery1.Parameters.ParamByName('pinicial').Value := MonthOf(datetimepicker1.Date) * 100 + DayOf(datetimepicker1.Date);
	AdoQuery1.Parameters.ParamByName('pfinal').Value := MonthOf(datetimepicker2.Date) * 100 + DayOf(datetimepicker2.Date);
	AdoQuery1.Parameters.ParamByName('pinicial2').Value := MonthOf(datetimepicker1.Date) * 100 + DayOf(datetimepicker1.Date);
	AdoQuery1.Parameters.ParamByName('pfinal2').Value := MonthOf(datetimepicker2.Date) * 100 + DayOf(datetimepicker2.Date);
	if monthOf(Datetimepicker1.DateTime) > monthOf(Datetimepicker2.DateTime) then
	begin
		AdoQuery1.Parameters.ParamByName('pfinal').Value := 1231;
		AdoQuery1.Parameters.ParamByName('pinicial2').Value := 101;
	end;
	Adoquery1.Open;
end;

Emerson Nascimento

Emerson Nascimento
Responder

Mais Posts

16/05/2019

Edilson Santiago

Perfeito. Funcionou... ficou bem mais limpo também. Obrigado.

Agora estou com um outro problema que já quebrei a cabeça, de todo jeito. Já pedi ajuda a várias pessoas, mas não consigo. Acho que deve ser um bug do delphi.

Usando esse código acima, o programa deveria filtrar os aniversariantes entre os parâmetros pinicial e pfinal, ou os parâmetros pinicial2 e pfinal2.

Fica tudo perfeito, até a primeira data ser em dezembro e a segunda em janeiro.

Por isso fiz
if monthOf(Datetimepicker1.DateTime) > monthOf(Datetimepicker2.DateTime) then
    begin
        AdoQuery1.Parameters.ParamByName('pfinal').Value := 1231;
        AdoQuery1.Parameters.ParamByName('pinicial2').Value := 101;
    end;


Assim, na minha lógica, se a data inicial for 25 de dezembro e a data final for 5 de janeiro, por exemplo, estaria na condicional if, assim:

pinicial = 12 * 100 + 25 = 1225
pfinal = 1231
pinicial 2 = 101
pfinal2 = 1 * 100 + 5 = 105

Logo ele só poderia retornar os aniversários cuja soma fosse entre 101 e 105, e entre 1225 e 1231. Ou seja, os únicos aceitos seriam:

01, 02, 03, 04 e 05 de janeiro, cujas somas são, 101, 102, 103, 104 e 105, respectivamente e
25, 26, 27, 28, 29, 30 e 31 de dezembro, cujas somas são 1225, 1126, 1227, 1228, 1229, 1230 e 1231.

Mas aí está o problema. Ele também retorna datas de nascimento do mês 10 e do mês 11. Por exemplo, nessa consulta, ele retornou um aniversário de 29/10, um de 02/11 e um de 04/11, cujas somas são 1029, 1102 e 1104, três números que estão fora dos parâmetros, mas aparecem no grid.

E nada do que eu faça consegue resolver isso.

Penso que tem algo a ver com o mês 10 e 11 terem o número 1 na composição, mas é algo totalmente sem sentido.

Alguém pode tentar dar uma força?
Responder

17/05/2019

Emerson Nascimento

isto acontece porque você NÃO está usando quatro dígitos no resultado da tua conta.
o correto seria:
pinicial = formatfloat('0000', (12 * 100 + 25)) = '1225'
pfinal = '1231'
pinicial2 = '0101'
pfinal2 = formatfloat('0000', (1 * 100 + 5)) = '0105'

e comparar com um resultado também de quatro dígitos. esta parte vai depender do banco de dados utilizado:
    AdoQuery1.SQL.Add('WHERE RIGHT(CONVERT(VARCHAR(10), DtNasc, 112),4) between :pinicial and :pfinal');
    AdoQuery1.SQL.Add('or RIGHT(CONVERT(VARCHAR(10), DtNasc, 112),4) between :pinicial2 and :pfinal2 )');
Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar