Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   MS SQL Server (https://www.clubdelphi.com/foros/forumdisplay.php?f=23)
-   -   DatetimePicker buscar desde hasta en SQL (https://www.clubdelphi.com/foros/showthread.php?t=95979)

giantonti1801 24-11-2022 04:27:32

DatetimePicker buscar desde hasta en SQL
 
Buena noche tengo un inconveniente en relacion una consulta que debo hacer desde delphi 11 a la base de datos y para ellos estoy usando los componente datetimepicker para que dentro de la consulta se pueda señalar la fecha desde hasta.

Código Delphi [-]
ADOQuery1.SQL.Add('where FechaCre := '+DateToStr(DateTimePicker1.Date));

al darle click a un evento on chancge no me retorna ningún resultado.

en un principio pensé que no tenía el mismo formato de fecha que la base de dato y lo verifico con un showmessage y veo que efectivamente tenemos el mismo formato. pero ahora tengo una dura:
Es posible que no me esté regresando ningún resultado porque el campo de la base de dato en de tipo Datetime y esta almacenando tanto la fecha como la hora en el mismo campo y por eso que no me retorna ningún resultado?

Código SQL [-]
2022-11-17 00:00:00.000
2022-11-18 00:00:00.000
2022-11-23 22:31:00.000

este campo fecha lo coloco el default value en cada insert
Código SQL [-]
(CONVERT([varchar](16),getdate(),(27)))
.

Como puedo arreglar para poder utilizar esta consulta desde hasta en un formulario?

NOTA: También he intentado hacer un LIKE
Código Delphi [-]
ADOQuery1.SQL.Add('where FechaCre like '+DateToStr(DateTimePicker1.Date)+'%');
pero me retorna un error '%'.

Neftali [Germán.Estévez] 24-11-2022 08:32:26

Cita:

Empezado por giantonti1801 (Mensaje 549384)
...tengo un inconveniente en relacion una consulta que debo hacer desde delphi 11 a la base de datos y para ellos estoy usando los componente datetimepicker para que dentro de la consulta se pueda señalar la fecha desde hasta.
Código Delphi [-]
ADOQuery1.SQL.Add('where FechaCre := '+DateToStr(DateTimePicker1.Date));

al darle click a un evento on chancge no me retorna ningún resultado.

En este caso para obtener los datos entre dos fechas (desde...hasta) como comentas debes usar el operador BETWEEN e indicar las dos fechas.
Si segun la Base de Datos que utilices no puedes usarlo deberás usar algo como:

Código Delphi [-]
WHERE (FechaCre >= fecha1) and (FechaCre <= fecha2)

Cita:

Empezado por giantonti1801 (Mensaje 549384)
Es posible que no me esté regresando ningún resultado porque el campo de la base de dato en de tipo Datetime y esta almacenando tanto la fecha como la hora en el mismo campo y por eso que no me retorna ningún resultado?

Seguramente es por eso y al estar usando un =, sólo te retornaría registros que coincidan exactamente con la fecha y hora.
Lo primero, yo te aconsejaría utilizar parámetros en la consulta, eso te evita todos los problemas relacionados con el formato del campo.

Código Delphi [-]
  ADOQuery1.SQL.Add('where FechaCre where Fecha between :fecha1 and :fecha2)');
  ADOQuery1.Parameters.ParamByName('fecha1').Value := DateTimePicker1.Date;
  ADOQuery1.Parameters.ParamByName('fecha2').Value := DateTimePicker2.Date;

Lo segundo es que resuelvas el tema de fecha o FechayHora en los valores. Asegúrate de enviar sólo valores de fecha (sin hora).

duilioisola 24-11-2022 16:13:53

Para el tema horas puedes hacer lo siguiente:

Código Delphi [-]
procedure Filtra(Desde, Hasta: TDateTime);
begin
  // Quito la hora del la fecha inicial
  Desde := RecodeTime(Desde, 0, 0, 0, 0);
  // Agrego hasta el ultimo milisegundo del día a la hora final
  Hasta := RecodeTime(Hasta, 23, 59, 59, 999);

  ADOQuery1.SQL.Add('where FechaCre where Fecha between :fecha1 and :fecha2)');
  ADOQuery1.Parameters.ParamByName('fecha1').Value := Desde;
  ADOQuery1.Parameters.ParamByName('fecha2').Value := Hasta;
  [...]

giantonti1801 25-11-2022 03:13:56

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 549386)
En este caso para obtener los datos entre dos fechas (desde...hasta) como comentas debes usar el operador BETWEEN e indicar las dos fechas.
Si segun la Base de Datos que utilices no puedes usarlo deberás usar algo como:

Código Delphi [-]
WHERE (FechaCre >= fecha1) and (FechaCre <= fecha2)



Seguramente es por eso y al estar usando un =, sólo te retornaría registros que coincidan exactamente con la fecha y hora.
Lo primero, yo te aconsejaría utilizar parámetros en la consulta, eso te evita todos los problemas relacionados con el formato del campo.

Código Delphi [-]
  ADOQuery1.SQL.Add('where FechaCre where Fecha between :fecha1 and :fecha2)');
  ADOQuery1.Parameters.ParamByName('fecha1').Value := DateTimePicker1.Date;
  ADOQuery1.Parameters.ParamByName('fecha2').Value := DateTimePicker2.Date;

Lo segundo es que resuelvas el tema de fecha o FechayHora en los valores. Asegúrate de enviar sólo valores de fecha (sin hora).

Gracias por la ayuda, fijate algo curioso que esta sucediendo.

Código Delphi [-]
procedure TFormConsulta.DateTimePicker1Change(Sender: TObject);
begin
   LabelDesde.Caption := DateToStr(DateTimePicker1.Date);
   ADOQuery1.Close;
   ADOQuery1.SQL.Clear;
   ADOQuery1.SQL.Add('Select * from Tiket');
   ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
   ADOQuery1.Parameters.ParamByName('Fecha1').Value := DateTimePicker1.Date;
   ADOQuery1.Parameters.ParamByName('Fecha2').Value := DateTimePicker2.Date;
   ADOQuery1.Open;
end;

procedure TFormConsulta.DateTimePicker2Change(Sender: TObject);
begin
  LabelHasta.Caption := DateToStr(DateTimePicker2.Date);
  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from Tiket');
  ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
  ADOQuery1.Parameters.ParamByName('Fecha1').Value := DateTimePicker1.Date;
  ADOQuery1.Parameters.ParamByName('Fecha2').Value := DateTimePicker2.Date;
  ADOQuery1.Open;
 end;


Código SQL [-]
2022-11-24 22:53:00.000
2022-11-25 21:58:00.000
2022-11-26 21:58:00.000
2022-11-27 21:58:00.000
2022-11-28 21:58:00.000

Haciéndolo de esta forma cuando le pongo la fecha desde 24-11-2022 hasta el 24-11-2022 debería mostrarme la operaciones en esta fecha pero no lo hace, es decir no me retorna ningún valor y así siguientemente si lo hago con las otras fecha del 25 hasta el 25 y del 26 hasta el 26. pero si pongo desde 24 hasta el 25 me muestra las operaciones del día 24 y si lo hago desde 25 hasta 26 me muestra la operaciones del día 25.
Pero si lo hago desde 24-11-2022 hasta el 25-11-2022

duilioisola 25-11-2022 08:51:00

El problema es la hora.

Modifica la hora de la fecha que utilizas como parámetro.

Código Delphi [-]
procedure TFormConsulta.DateTimePicker1Change(Sender: TObject);
begin
  LabelDesde.Caption := DateToStr(DateTimePicker1.Date);
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date);
end;

procedure TFormConsulta.DateTimePicker2Change(Sender: TObject);
begin
  LabelHasta.Caption := DateToStr(DateTimePicker2.Date);
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date);
 end;

procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime);
begin
  /// Modifico la hora de las fechas para abarcar el dia completo
  /// DESDE = dd/mm/yyyy **00:00:00**
  /// HASTA = dd/mm/yyyy **23:59:59**

  // Quito la hora del la fecha inicial
  Desde := RecodeTime(Desde, 0, 0, 0, 0);
  // Agrego hasta el ultimo milisegundo del día a la hora final
  Hasta := RecodeTime(Hasta, 23, 59, 59, 999);

  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from Tiket');
  ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
  ADOQuery1.Parameters.ParamByName('Fecha1').Value := Desde;
  ADOQuery1.Parameters.ParamByName('Fecha2').Value := Hasta;
  ADOQuery1.Open;
end;

Neftali [Germán.Estévez] 25-11-2022 09:14:45

Cita:

Empezado por giantonti1801 (Mensaje 549398)
Haciéndolo de esta forma cuando le pongo la fecha desde 24-11-2022 hasta el 24-11-2022 debería mostrarme la operaciones en esta fecha pero no lo hace, es decir no me retorna ningún valor

Eso es porque ambos llevan la misma fecha y hora:
Por ejemplo estás haciendo:

Código SQL [-]
... BETWENN 14/11/2022 15:23:23 AND  14/11/2022 15:23:23

Para corregirlo debes añadir lo que te dicho [duilioisola] aquí, para conseguir:

Código SQL [-]
... BETWENN 14/11/2022 00:00:00 AND  14/11/2022 23:59:59

giantonti1801 25-11-2022 13:44:49

Cita:

Empezado por duilioisola (Mensaje 549400)
El problema es la hora.

Modifica la hora de la fecha que utilizas como parámetro.

Código Delphi [-]
procedure TFormConsulta.DateTimePicker1Change(Sender: TObject);
begin
  LabelDesde.Caption := DateToStr(DateTimePicker1.Date);
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date);
end;

procedure TFormConsulta.DateTimePicker2Change(Sender: TObject);
begin
  LabelHasta.Caption := DateToStr(DateTimePicker2.Date);
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date);
 end;

procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime);
begin
  /// Modifico la hora de las fechas para abarcar el dia completo
  /// DESDE = dd/mm/yyyy **00:00:00**
  /// HASTA = dd/mm/yyyy **23:59:59**

  // Quito la hora del la fecha inicial
  Desde := RecodeTime(Desde, 0, 0, 0, 0);
  // Agrego hasta el ultimo milisegundo del día a la hora final
  Hasta := RecodeTime(Hasta, 23, 59, 59, 999);

  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from Tiket');
  ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
  ADOQuery1.Parameters.ParamByName('Fecha1').Value := Desde;
  ADOQuery1.Parameters.ParamByName('Fecha2').Value := Hasta;
  ADOQuery1.Open;
end;

con mucha pena le pido me ayude a crear es procedimiento
Código Delphi [-]
procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime);

duilioisola 25-11-2022 14:18:57

No entiendo la petición... ya está creado en el ejeplo:
Lo único que debes revisar es si el SQL es el que deseas.

Código Delphi [-]
procedure TFormConsulta.DateTimePicker1Change(Sender: TObject);
begin
  LabelDesde.Caption := DateToStr(DateTimePicker1.Date);
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date); >>>-------------+
end;                                                                  |
                                                                      |
procedure TFormConsulta.DateTimePicker2Change(Sender: TObject);       |
begin                                                                 |
  LabelHasta.Caption := DateToStr(DateTimePicker2.Date);              |
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date); >>>-------------+
end;                                                                  |
                                                                      |
procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime); <<<----------+
begin
  /// Modifico la hora de las fechas para abarcar el dia completo
  /// DESDE = dd/mm/yyyy **00:00:00**
  /// HASTA = dd/mm/yyyy **23:59:59**

  // Quito la hora del la fecha inicial
  Desde := RecodeTime(Desde, 0, 0, 0, 0);
  // Agrego hasta el ultimo milisegundo del día a la hora final
  Hasta := RecodeTime(Hasta, 23, 59, 59, 999);

  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from Tiket');
  ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
  ADOQuery1.Parameters.ParamByName('Fecha1').Value := Desde;
  ADOQuery1.Parameters.ParamByName('Fecha2').Value := Hasta;
  ADOQuery1.Open;
end;

giantonti1801 25-11-2022 14:24:12

Cita:

Empezado por duilioisola (Mensaje 549407)
No entiendo la petición... ya está creado en el ejeplo:
Lo único que debes revisar es si el SQL es el que deseas.

Código Delphi [-]
procedure TFormConsulta.DateTimePicker1Change(Sender: TObject);
begin
  LabelDesde.Caption := DateToStr(DateTimePicker1.Date);
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date); >>>-------------+
end;                                                                  |
                                                                      |
procedure TFormConsulta.DateTimePicker2Change(Sender: TObject);       |
begin                                                                 |
  LabelHasta.Caption := DateToStr(DateTimePicker2.Date);              |
  Filtra(DateTimePicker1.Date, DateTimePicker2.Date); >>>-------------+
end;                                                                  |
                                                                      |
procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime); <<<----------+
begin
  /// Modifico la hora de las fechas para abarcar el dia completo
  /// DESDE = dd/mm/yyyy **00:00:00**
  /// HASTA = dd/mm/yyyy **23:59:59**

  // Quito la hora del la fecha inicial
  Desde := RecodeTime(Desde, 0, 0, 0, 0);
  // Agrego hasta el ultimo milisegundo del día a la hora final
  Hasta := RecodeTime(Hasta, 23, 59, 59, 999);

  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from Tiket');
  ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
  ADOQuery1.Parameters.ParamByName('Fecha1').Value := Desde;
  ADOQuery1.Parameters.ParamByName('Fecha2').Value := Hasta;
  ADOQuery1.Open;
end;

Exactamente pero no se como hacer para crear un procedimiento nuevo ya que en lo que usted envía está creando un procedimiento nuevo
Código Delphi [-]
procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime)
este procedimiento no puedo copiarlo de aqui y pegarlo en el Unit porque me da problema asumo que debo crear el procedimiento manualmente para luego llamarlo y es justamente esto que no se como hacerlo. aunque lo busque por todo lado pero no encontré nada.

duilioisola 25-11-2022 14:37:16

Vale, entiendo tu problema.
Debes copiarlo a tu unit y luego ponerlo en la definicion de la clase TFormConsulta dentro de la parte private o public.
  • private: solo se podrá utilizar dentro de la clase (a efectos prácticos, no podrás llamarlo desde otros sitios)
  • public: otros objetos podrán llamarlo mediante TFormConsulta.Filtrar(...).

Ejemplo para un formulario llamado "Form1" que en su parte privada define el procedimiento Filtrar().
Si quieres más información deberás aprender qué significa interface (donde se define lo que hay en la unidad) / implementation (donde se implementa el codigo que ejecuta cada cosa definida).

Código Delphi [-]
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure Filtra(Desde, Hasta: TDateTime);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Filtra(Desde, Hasta: TDateTime);
begin
  [...]
end;

end.

giantonti1801 25-11-2022 15:03:39

Cita:

Empezado por duilioisola (Mensaje 549409)
Vale, entiendo tu problema.
Debes copiarlo a tu unit y luego ponerlo en la definicion de la clase TFormConsulta dentro de la parte private o public.
  • private: solo se podrá utilizar dentro de la clase (a efectos prácticos, no podrás llamarlo desde otros sitios)
  • public: otros objetos podrán llamarlo mediante TFormConsulta.Filtrar(...).

Ejemplo para un formulario llamado "Form1" que en su parte privada define el procedimiento Filtrar().
Si quieres más información deberás aprender qué significa interface (donde se define lo que hay en la unidad) / implementation (donde se implementa el codigo que ejecuta cada cosa definida).

Código Delphi [-]
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure Filtra(Desde, Hasta: TDateTime);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Filtra(Desde, Hasta: TDateTime);
begin
  [...]
end;

end.

Muchas gracias por tu paciencia, efectivamente lo hice tal cual como tu me explicaste, pero tengo un problema con
Código Delphi [-]
[dcc64 Error] UnitConsulta.pas(242): E2003 Undeclared identifier: 'RecodeTime'

posiblemente yengo que declarar el recordtime en algun lado.

Código Delphi [-]
procedure TFormConsulta.Filtra(Desde, Hasta: TDateTime);
begin
  /// Modifico la hora de las fechas para abarcar el dia completo
  /// DESDE = dd/mm/yyyy **00:00:00**
  /// HASTA = dd/mm/yyyy **23:59:59**

  // Quito la hora del la fecha inicial
  Desde := RecodeTime(Desde, 0, 0, 0, 0);
  // Agrego hasta el ultimo milisegundo del día a la hora final
  Hasta := RecodeTime(Hasta, 23, 59, 59, 999);

  ADOQuery1.Close;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('Select * from Tiket');
  ADOQuery1.SQL.Add('where FechaCre between :Fecha1 and :Fecha2');
  ADOQuery1.Parameters.ParamByName('Fecha1').Value := Desde;
  ADOQuery1.Parameters.ParamByName('Fecha2').Value := Hasta;
  ADOQuery1.Open;
end;

duilioisola 25-11-2022 15:14:03

RecodeTime es una función de la unidad DateUtils (Por lo menos en Delphi 6).
Deberás agregar esa unidad a tu cláusula uses.

Si no existe esa unidad, prueba poniendo el cursor sobre RecodeTime y presiona F1.
Te llevará a una página de ayuda donde seguramente te indicará a qué unidad pertenece.

Buscando en Internet:
https://docwiki.embarcadero.com/Libr...ils.RecodeTime

Cita:

System.DateUtils.RecodeTime

Up to Parent: System.DateUtils

Delphi

function RecodeTime(const AValue: TDateTime; const AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;

C++

extern DELPHI_PACKAGE System::TDateTime __fastcall RecodeTime(const System::TDateTime AValue, const System::Word AHour, const System::Word AMinute, const System::Word ASecond, const System::Word AMilliSecond);

Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, 
  {***}DateUtils{***};
  // o 
  {***}System.DateUtils{***};

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure Filtra(Desde, Hasta: TDateTime);
  public
    { Public declarations }
  end;

[...]

giantonti1801 25-11-2022 21:41:41

Cita:

Empezado por duilioisola (Mensaje 549411)
RecodeTime es una función de la unidad DateUtils (Por lo menos en Delphi 6).
Deberás agregar esa unidad a tu cláusula uses.

Si no existe esa unidad, prueba poniendo el cursor sobre RecodeTime y presiona F1.
Te llevará a una página de ayuda donde seguramente te indicará a qué unidad pertenece.

Buscando en Internet:
https://docwiki.embarcadero.com/Libr...ils.RecodeTime



Código Delphi [-]
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, 
  {***}DateUtils{***};
  // o 
  {***}System.DateUtils{***};

type
  TForm1 = class(TForm)
  private
    { Private declarations }
    procedure Filtra(Desde, Hasta: TDateTime);
  public
    { Public declarations }
  end;

[...]

Excelente, Muy bien de verdad eso soluciono el problema que tenía, ya funciona a la perfección, GRACIAS por tu paciencia y dedicación.


La franja horaria es GMT +2. Ahora son las 21:45:49.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi