none
Rango de fechas y de horas RRS feed

  • Pregunta

  • Buenos días mis estimados, espero que alguien me pueda ayudar con el siguiente problema. 

    Estoy trabajando en un programa que me devuelva datos de dos tablas en sql server. Esos datos deben ser mostrados en un datagridview por un rango de fechas y de horas. Ejemplo: si selecciono las fechas 12-04-2016 / 14-04-2016 y las horas 10:00 /  15:00 el datagridview me debería mostrar todos los registros desde el 12-04-2016 de las 10 AM en adelante hasta las 15:00 PM del día 14-04-2016.

    Soy bastante nuevo en esto de visual basic.net y solamente he conseguido filtrar el rango de fechas viendo tutoriales en internet, pero no he encontrado nada cercano a lo que busco. Estoy utilizando 4 DateTimePicker y un botón que realiza la consulta. les dejo el código para ver si alguien me puede ayudar, si tienen alguna sugerencia de como deberia realizar la consulta se agradecería.

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim conexionSQL As New SqlConnection(My.Settings.prueba3ConnectionString)
            Dim Fsql As String = "select pos.Fecha,pos.Hora,pos.Lat,pos.Lon,vari.Nombre,vari.NombreBodega,vari.Nivel from  PosiciónBarco pos inner join  Variable vari on pos.Id=vari.Id  where Fecha between '" & Format(DateTimePicker1.Value.Date.ToString, "short date") & _
            " 'and fecha ' " & Format(DateTimePicker2.Value.Date.ToString, "short date") & " 'and Hora between '" & Format(DateTimePicker3, "time") & " 'and hora ' " & Format(DateTimePicker4, "time") ' "

            Try
                conexionSQL.Open()
                Dim comandoSql As New SqlCommand(Fsql, conexionSQL)
                Dim adaptador As New SqlDataAdapter(comandoSql)
                Dim datatable As New DataTable
                adaptador.Fill(datatable)
                DataGridView1.DataSource = datatable
            Finally
                conexionSQL.Close()
            End Try
        End Sub

    los campos son de tipo date y time.


    • Cambiado Enrique M. Montejo miércoles, 27 de abril de 2016 18:20 Pregunta relacionada con el acceso a datos con SQL Server.
    martes, 26 de abril de 2016 14:35

Respuestas

  • Hola,

    Ahora que estás usando el Format es SQL necesitas un valor con la misma estructura:

    dd/MM/yyyy hh:mm:ss

    Para que no tengas parámetros obsoletos, solo manda dos parámetros, uno el inicial y el otro el final, pero ya con la fecha y hora.

    ALTER procedure [dbo].[sp_consulta]
    @fecha1 varchar(50),
    @fecha2 varchar(50)
    as
    	select pos.FechaHora,
    		   pos.Lat,
    		   pos.Lon,
    		   vari.Nombre,
    		   vari.NombreBodega,
    		   vari.Nivel 
    	from  PosiciónBarco pos inner join
    		  Variable vari
    		  on pos.Id=vari.Id
    		  where FORMAT(pos.FechaHora, 'dd/MM/yyyy hh:mm:ss') between @fecha1 and @fecha2

    Y tienes que mandar el parámetro con el mismo formato :

           adaptador.SelectCommand.Parameters.AddWithValue("@fecha1", String.Concat(DateTimePicker1.Value.ToString("dd/MM/yyyy"),
                                                                                     " ",
                                                                                     DateTimePicker3.Value.ToString("hh:mm:ss")))
    
            adaptador.SelectCommand.Parameters.AddWithValue("@fecha2", String.Concat(DateTimePicker2.Value.ToString("dd/MM/yyyy"),
                                                                                     " ",
                                                                                     DateTimePicker4.Value.ToString("hh:mm:ss")))

    Por lo que el valor que te enviará en el parámetro tendrá este formato :

    29/04/2016 02:15:42

    Y con eso estoy seguro de que funcionará tu consulta.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta adriian.91 viernes, 27 de mayo de 2016 14:00
    viernes, 29 de abril de 2016 19:18

Todas las respuestas

  • Hola,

    Te aconsejaría que no uses cadenas para generar tu consulta, primero porque es complicado, segundo porque es muy desordenado.

    Deberías crear un StoredProcedure :

    create procedure sp_consulta
    @fecha1 varchar(30),--PONER EL TIPO
    @fecha2 varchar(30),--PONER EL TIPO
    @hora1 varchar(20),--PONER EL TIPO
    @hora2 varchar(20)--PONER EL TIPO
    as
    	select pos.Fecha,
    		   pos.Hora,
    		   pos.Lat,
    		   pos.Lon,
    		   vari.Nombre,
    		   vari.NombreBodega,
    		   vari.Nivel 
    	from  PosiciónBarco pos inner join
    		  Variable vari
    		  on pos.Id=vari.Id
    		  where (pos.Fecha between @fecha1 and @fecha2) and 
    		        (pos.Hora between @hora1 and @hora2)
    go

    En este caso asumo que estás guardando los campo Fecha y Hora en un campo de tipo varchar.

    Y cuando hagas la consulta solo modifica esto :

       Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
            Using conexionSQL As New SqlConnection(My.Settings.prueba3ConnectionString)
    
                Try
                    conexionSQL.Open()
    
                    Dim adaptador As New SqlDataAdapter("sp_consulta", conexionSQL)
                    adaptador.SelectCommand.CommandType = CommandType.StoredProcedure
    
                    adaptador.SelectCommand.Parameters.AddWithValue("@fecha1", DateTimePicker1.Value.ToString("dd/MM/yyyy"))
                    adaptador.SelectCommand.Parameters.AddWithValue("@fecha2", DateTimePicker2.Value.ToString("dd/MM/yyyy"))
                    adaptador.SelectCommand.Parameters.AddWithValue("@hora1", DateTimePicker3.Value.ToString("hh:mm:ss"))
                    adaptador.SelectCommand.Parameters.AddWithValue("@hora2", DateTimePicker4.Value.ToString("hh:mm:ss"))
    
                    Dim datatable As New DataTable
                    adaptador.Fill(datatable)
    
                    DataGridView1.DataSource = datatable
    
                Catch ex As Exception
                    MessageBox.Show("Se produjo un error : " & ex.Message)
                Finally
                    conexionSQL.Close()
                End Try
    
            End Using
    
        End Sub

    Como puedes ver, mediante un storedProcedure el código es más limpio, así te evitas estar haciendo toda la concatenación que te genera un dolor de cabeza.

    Para tomar los valores de los datetimepicker uso el ToString("formato").

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    martes, 26 de abril de 2016 15:25
  • Hola de nuevo hice lo que me dices pero no me muestra nada en el datagridview, al hacer el procedimiento almacendo en slq server cambie los tipo "varchar" por "date" y "time"  no se si hay este el problema por que el programa compila bien y no me da errores, pero no me muestra nada en el data grid view.   Gracias por la paciencia y por los consejos 
    martes, 26 de abril de 2016 15:59
  • Hola,

    No sería mejor que en vez de partir Fecha y Hora, almacenaras en un columna de tipo DateTime , o necesariamente tiene que estar cada uno independiente?

    Bueno la verdad no he usado el tipo Time, pero intenta cambiando la forma que envías el parámetro.

    Cambia esto :

                    adaptador.SelectCommand.Parameters.AddWithValue("@fecha1", DateTimePicker1.Value.ToString("dd/MM/yyyy"))
                    adaptador.SelectCommand.Parameters.AddWithValue("@fecha2", DateTimePicker2.Value.ToString("dd/MM/yyyy"))
                    adaptador.SelectCommand.Parameters.AddWithValue("@hora1", DateTimePicker3.Value.ToString("hh:mm:ss"))
                    adaptador.SelectCommand.Parameters.AddWithValue("@hora2", DateTimePicker4.Value.ToString("hh:mm:ss"))

    Por esto :

                    adaptador.SelectCommand.Parameters.Add("@fecha1", SqlDbType.Date)
                    adaptador.SelectCommand.Parameters("@fecha1").Direction = ParameterDirection.Input
                    adaptador.SelectCommand.Parameters("@fecha1").Value = DateTimePicker1.Value
    
                    adaptador.SelectCommand.Parameters.Add("@fecha2", SqlDbType.Date)
                    adaptador.SelectCommand.Parameters("@fecha2").Direction = ParameterDirection.Input
                    adaptador.SelectCommand.Parameters("@fecha2").Value = DateTimePicker2.Value
    
                    adaptador.SelectCommand.Parameters.Add("@hora1", SqlDbType.Time)
                    adaptador.SelectCommand.Parameters("@hora1").Direction = ParameterDirection.Input
                    adaptador.SelectCommand.Parameters("@hora1").Value = DateTimePicker3.Value
    
                    adaptador.SelectCommand.Parameters.Add("@hora2", SqlDbType.Time)
                    adaptador.SelectCommand.Parameters("@hora2").Direction = ParameterDirection.Input
                    adaptador.SelectCommand.Parameters("@hora2").Value = DateTimePicker4.Value

    Y supongo que tus pictureBox están así :


    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    martes, 26 de abril de 2016 16:22
  • Amigo copie el codigo pero ahora me muestra el mensaje

    "se produjo un error: error al convertir el valor del parámetro de datatime a timespan"

    con respecto a tu pregunta de si seria mejor un campo datetime no estoy seguro de si me sirve puesto que lo que me pidieron es que se pueda seleccionar un rango de fecha y de hora, si tu crees que seria una mejor forma como tendría que hacerlo? si es necesario modificar la base de datos no tengo ninguna problema solo quiero dar una solucion a este problema. Gracias por tu tiempo y disposición y disculpa mi ignorancia. 

    pd: no puedo adjuntar imágenes por que aun no corroboran mi cuenta, pero el boton datatimepicker se ven como los tuyos.

    martes, 26 de abril de 2016 17:00
  • Hola de nuevo

    cambie esto 

     adaptador.SelectCommand.Parameters.Add("@hora2", SqlDbType.time)

    por esto 

     adaptador.SelectCommand.Parameters.Add("@hora2", SqlDbType.dateTime)

    ahora si me filtra por fecha y hora, pero me esta cortando por día, me explico:  al tomar un rango de fechas y de horas muestra solo las horas de los días elegidos, pero lo que quiero es que me de todas las horas desde un hora de la fecha inicio a la hora y fecha final. Segui tu consejo de cambiar el campo fecha y hora, por uno que contenga los dos, el problema es que ahora no me muestra nada en data gridview. favor ayudame si es que puedes. de lo contrario muchas gracias por que me fue de mucha utilidad lo que me explicaste.

    jueves, 28 de abril de 2016 15:00
  • Hola,

    Disculpa la demora.

    Mencionas que ya has cambiando los tipos de datos a Datetime, ahora solo tendrías dos parámetros.

       adaptador.SelectCommand.Parameters.AddWithValue("@fecha1", DateTimePicker1.Value.ToString("dd/MM/yyyy hh:mm:ss"))
       adaptador.SelectCommand.Parameters.AddWithValue("@fecha2", DateTimePicker2.Value.ToString("dd/MM/yyyy hh:mm:ss"))

    Y en el StoredProcedure cambiarías a esta línea :

    where FORMAT(pos.Fecha, 'dd/MM/yyyy hh:mm:ss') between @fecha1 and @fecha2

    O usar :

    where (@fecha1 < FORMAT(pos.Fecha, 'dd/MM/yyyy hh:mm:ss')) and
          (FORMAT(pos.Fecha, 'dd/MM/yyyy hh:mm:ss') < @fecha2)

    Lo que hago es comparar ambos formatos. Lo he probado en mi PC y si me muestra los registros en un intervalo, prueba y comentas como te va.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI


    jueves, 28 de abril de 2016 23:57
  • Hola Joel gracias de nuevo por responder, probe lo que me decias y no aparece nada en el datagridview. Te comento que aunque cambie en la base de datos el campo "fecha tipo date" y el campo "hora tipo time" por "FechaHora tipo datetime", en el form aun estoy tratando de obtener la fecha y hora por separados y unirlos en una sola columna (fechahora) de la base de datos. ahora si puediera tener los dos campos tanto fecha y hora en un solo datetimepicker, seria lo ideal

    lo que se me ocurria era que el storedprocedure quedara asi

    ALTER procedure [dbo].[sp_consulta]
    @fecha1 Datetime,
    @fecha2 datetime,
    @hora1 datetime,
    @hora2 datetime
    as
    	select pos.FechaHora,
    		   pos.Lat,
    		   pos.Lon,
    		   vari.Nombre,
    		   vari.NombreBodega,
    		   vari.Nivel 
    	from  PosiciónBarco pos inner join
    		  Variable vari
    		  on pos.Id=vari.Id
    		  where FORMAT(pos.FechaHora, 'dd/MM/yyyy hh:mm:ss') between (@fecha1+@hora1) and (@fecha2+@hora2)

    no se si esta bien de esa forma, pero probe los dos tipos de SP y como te digo sigo sin ver nada en el datagridview. 

    adaptador.SelectCommand.Parameters.AddWithValue("@fecha1", DateTimePicker1.Value.ToString("dd/MM/yyyy"))
    adaptador.SelectCommand.Parameters.AddWithValue("@fecha2", DateTimePicker2.Value.ToString("dd/MM/yyyy"))
    adaptador.SelectCommand.Parameters.AddWithValue("@hora1", DateTimePicker3.Value.ToString("hh:mm:ss"))
    adaptador.SelectCommand.Parameters.AddWithValue("@hora2", DateTimePicker4.Value.ToString("hh:mm:ss"))

    espero puedas seguir ayudandome gracias.

     
    • Editado adriian.91 viernes, 29 de abril de 2016 16:18
    viernes, 29 de abril de 2016 13:23
  • Hola,

    Ahora que estás usando el Format es SQL necesitas un valor con la misma estructura:

    dd/MM/yyyy hh:mm:ss

    Para que no tengas parámetros obsoletos, solo manda dos parámetros, uno el inicial y el otro el final, pero ya con la fecha y hora.

    ALTER procedure [dbo].[sp_consulta]
    @fecha1 varchar(50),
    @fecha2 varchar(50)
    as
    	select pos.FechaHora,
    		   pos.Lat,
    		   pos.Lon,
    		   vari.Nombre,
    		   vari.NombreBodega,
    		   vari.Nivel 
    	from  PosiciónBarco pos inner join
    		  Variable vari
    		  on pos.Id=vari.Id
    		  where FORMAT(pos.FechaHora, 'dd/MM/yyyy hh:mm:ss') between @fecha1 and @fecha2

    Y tienes que mandar el parámetro con el mismo formato :

           adaptador.SelectCommand.Parameters.AddWithValue("@fecha1", String.Concat(DateTimePicker1.Value.ToString("dd/MM/yyyy"),
                                                                                     " ",
                                                                                     DateTimePicker3.Value.ToString("hh:mm:ss")))
    
            adaptador.SelectCommand.Parameters.AddWithValue("@fecha2", String.Concat(DateTimePicker2.Value.ToString("dd/MM/yyyy"),
                                                                                     " ",
                                                                                     DateTimePicker4.Value.ToString("hh:mm:ss")))

    Por lo que el valor que te enviará en el parámetro tendrá este formato :

    29/04/2016 02:15:42

    Y con eso estoy seguro de que funcionará tu consulta.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta adriian.91 viernes, 27 de mayo de 2016 14:00
    viernes, 29 de abril de 2016 19:18
  • No se que pasa Joel pero sigue sin mostrarme nada en el datagridview. 

    gracias de todas formas

    viernes, 29 de abril de 2016 20:19