none
Error en fechas inferiores a día 13 desde VB.Net a ACCESS RRS feed

  • Pregunta

  • Hola buen día a todos,

    En una base de datos de Access, tengo una tabla llamada egresos, en ésta tabla hay un campo de fecha en formato dd/mm/aaaa.

    A la hora de insertar un registro en la tabla uso el siguiente código:

    Dim fecha As Date = DateTime.Today
    Dim cmdString As String = "INSERT INTO EGRESOS (FECHA, NUMRECIBO, DESCRIPCION, VALOR, NOTAS) VALUES(#" & fecha.ToShortDateString & "#,'" & txtNumRecibo.Text & "','" & txtDescripcionEgreso.Text & "'," & Convert.ToDouble(txtValorEgreso.Text) & ",'" & txtNotasEgreso.Text & "')"

    La cuestión es la siguiente: Si mando una fecha digamos 21/06/2018 Access me la detecta bien como el 21 de Junio de 2018, hasta ahí todo perfecto.

    Pero, si mando digamos una fecha como 12/06/2018: No la toma como 12 de Junio, sino como 12 de Diciembre.

    en un MsgBox(fecha.toLongDateString) verifico que la variable fecha la toma como 12 de Junio

    Probé a poner el valor manualmente en la tabla y lo toma como 12 de Junio.

    El problema es cuando lo envío desde la sentencia insert

    ¿Alguien me puede ayudar? Graciaaaaaaaas

    miércoles, 27 de junio de 2018 21:02

Respuestas

  • "Pedro Luis Parrales" escribió:

    > En una base de datos de Access, tengo una tabla llamada egresos, en ésta tabla
    > hay un campo de fecha en formato dd/mm/aaaa.

    Hola, Pedro Luis:

    Quiero pensar que el tipo de dato de ese campo es Fecha/Hora, con independencia del formato que tenga, porque me imagino que sabrás que en los campos de Fecha/Hora de una tabla de Access, de SQL Server, o de cualquier otro motor de datos normal y corriente, no se guarda ningún formato de fecha concreto: se guarda la fecha como un valor numérico de punto flotante de doble precisión:

    Cómo almacenar, calcular y comparar datos de fecha y hora en Microsoft Access

    > Dim fecha As Date = DateTime.Today
    > Dim cmdString As String = "INSERT INTO EGRESOS (FECHA, ...) VALUES(#" & fecha.ToShortDateString & "#,'" & ...
    >
    > La cuestión es la siguiente: Si mando una fecha digamos 21/06/2018 Access me la
    > detecta bien como el 21 de Junio de 2018, hasta ahí todo perfecto.
    >
    > Pero, si mando digamos una fecha como 12/06/2018: No la toma como 12 de Junio,
    > sino como 12 de Diciembre.

    Eso es normal que ocurra, y no se debe a un fallo de Access ni del motor de datos Jet/ACE que estás utilizando en tu aplicación de Visual Basic, más bien se debe a que en la consulta INSERT INTO estás especificando un valor literal de fecha con formato de fecha en español (#día/mes/año#), cuando los valores literales de fecha/hora en Access hay que especificarlos, nos guste o no, en formato inglés de Estados Unidos, es decir, en formato #mes/día/año# (encerrados entre el carácter #), tengas en tu sistema operativo una configuración regional de España, Rusia, India o China, porque en el caso de una configuración regional de español de España, siempre que el día del mes sea superior al día 12, no tendrás ningún tipo de problema, no así con las fechas correspondientes a los días 1 a 12 de cada mes, ya que en estos casos, el motor de datos Jet/ACE tomará el valor del día como si fuera el valor del mes. ¡Así de sencillo!

    Para guardar en Access la fecha correspondiente al día 12 de junio de 2018, tienes que especificar el valor alfanumérico #06/12/2018#, y para el día 06 de diciembre de 2018 el valor #12/06/2018#.

    Pero ya que estás utilizando Visual Basic para interactuar con una base de datos, lo correcto es que te olvides de especificar los valores literales dentro de la sintaxis de la propia consulta SQL, y ejecutes una consulta parametrizada, tal y como indico a continuación:

         Try
              Using cnn As New OleDbConnection(escribe aquí tu cadena de conexión)
    
                  Dim cmd As OleDbCommand = cnn.CreateCommand()
           
                  ' Especificar la sintaxis de la consulta SQL que deseamos ejecutar,
                  ' donde los caracteres ? indican los 5 parámetros de entrada que
                  ' se especificaran.
                  '
                  cmd.CommandText = "INSERT INTO EGRESOS (FECHA, NUMRECIBO, DESCRIPCION, VALOR, NOTAS) VALUES(?,?,?,?,?)
    
                  ' Añadir los parámetros, Y EN EL MISMO ORDEN en el que se encuentran
                  ' definidos los campos en la consulta INSERT INTO.
                  '
                  ' Añadir la fecha y hora correspondiente al día actual.
                  cmd.Parameters.AddWithValue("", DateTime.Today)
    
                  ' Añadir los restantes parámetros
                  cmd.Parameters.AddWithValue("", txtNumRecibo.Text)
                  cmd.Parameters.AddWithValue("", txtDescripcionEgreso.Text)
                  cmd.Parameters.AddWithValue("", Convert.ToDouble(txtValorEgreso.Text))
                  cmd.Parameters.AddWithValue("", txtNotasEgreso.Text)
    
                  ' Abrir la conexión
                  cnn.Open()
    
                  ' Ejecutar la consulta
                  Dim n As Integer = cmd.ExecuteNonQuery()
    
                  MessageBox.Show($"Nº de registros insertados: {n}.")
            End Using
    
        Catch ex As Exception
            ' Se ha producido un error.
            MessageBox.Show(ex.Message)
    
        End Try

    Fíjate que de esta manera no es necesario encerrar los valores de fecha entre #, ni tener que encerrar los valores alfanuméricos entre comillas simples ('). ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    jueves, 28 de junio de 2018 6:39
    Moderador

Todas las respuestas

  • "Pedro Luis Parrales" escribió:

    > En una base de datos de Access, tengo una tabla llamada egresos, en ésta tabla
    > hay un campo de fecha en formato dd/mm/aaaa.

    Hola, Pedro Luis:

    Quiero pensar que el tipo de dato de ese campo es Fecha/Hora, con independencia del formato que tenga, porque me imagino que sabrás que en los campos de Fecha/Hora de una tabla de Access, de SQL Server, o de cualquier otro motor de datos normal y corriente, no se guarda ningún formato de fecha concreto: se guarda la fecha como un valor numérico de punto flotante de doble precisión:

    Cómo almacenar, calcular y comparar datos de fecha y hora en Microsoft Access

    > Dim fecha As Date = DateTime.Today
    > Dim cmdString As String = "INSERT INTO EGRESOS (FECHA, ...) VALUES(#" & fecha.ToShortDateString & "#,'" & ...
    >
    > La cuestión es la siguiente: Si mando una fecha digamos 21/06/2018 Access me la
    > detecta bien como el 21 de Junio de 2018, hasta ahí todo perfecto.
    >
    > Pero, si mando digamos una fecha como 12/06/2018: No la toma como 12 de Junio,
    > sino como 12 de Diciembre.

    Eso es normal que ocurra, y no se debe a un fallo de Access ni del motor de datos Jet/ACE que estás utilizando en tu aplicación de Visual Basic, más bien se debe a que en la consulta INSERT INTO estás especificando un valor literal de fecha con formato de fecha en español (#día/mes/año#), cuando los valores literales de fecha/hora en Access hay que especificarlos, nos guste o no, en formato inglés de Estados Unidos, es decir, en formato #mes/día/año# (encerrados entre el carácter #), tengas en tu sistema operativo una configuración regional de España, Rusia, India o China, porque en el caso de una configuración regional de español de España, siempre que el día del mes sea superior al día 12, no tendrás ningún tipo de problema, no así con las fechas correspondientes a los días 1 a 12 de cada mes, ya que en estos casos, el motor de datos Jet/ACE tomará el valor del día como si fuera el valor del mes. ¡Así de sencillo!

    Para guardar en Access la fecha correspondiente al día 12 de junio de 2018, tienes que especificar el valor alfanumérico #06/12/2018#, y para el día 06 de diciembre de 2018 el valor #12/06/2018#.

    Pero ya que estás utilizando Visual Basic para interactuar con una base de datos, lo correcto es que te olvides de especificar los valores literales dentro de la sintaxis de la propia consulta SQL, y ejecutes una consulta parametrizada, tal y como indico a continuación:

         Try
              Using cnn As New OleDbConnection(escribe aquí tu cadena de conexión)
    
                  Dim cmd As OleDbCommand = cnn.CreateCommand()
           
                  ' Especificar la sintaxis de la consulta SQL que deseamos ejecutar,
                  ' donde los caracteres ? indican los 5 parámetros de entrada que
                  ' se especificaran.
                  '
                  cmd.CommandText = "INSERT INTO EGRESOS (FECHA, NUMRECIBO, DESCRIPCION, VALOR, NOTAS) VALUES(?,?,?,?,?)
    
                  ' Añadir los parámetros, Y EN EL MISMO ORDEN en el que se encuentran
                  ' definidos los campos en la consulta INSERT INTO.
                  '
                  ' Añadir la fecha y hora correspondiente al día actual.
                  cmd.Parameters.AddWithValue("", DateTime.Today)
    
                  ' Añadir los restantes parámetros
                  cmd.Parameters.AddWithValue("", txtNumRecibo.Text)
                  cmd.Parameters.AddWithValue("", txtDescripcionEgreso.Text)
                  cmd.Parameters.AddWithValue("", Convert.ToDouble(txtValorEgreso.Text))
                  cmd.Parameters.AddWithValue("", txtNotasEgreso.Text)
    
                  ' Abrir la conexión
                  cnn.Open()
    
                  ' Ejecutar la consulta
                  Dim n As Integer = cmd.ExecuteNonQuery()
    
                  MessageBox.Show($"Nº de registros insertados: {n}.")
            End Using
    
        Catch ex As Exception
            ' Se ha producido un error.
            MessageBox.Show(ex.Message)
    
        End Try

    Fíjate que de esta manera no es necesario encerrar los valores de fecha entre #, ni tener que encerrar los valores alfanuméricos entre comillas simples ('). ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    jueves, 28 de junio de 2018 6:39
    Moderador
  • Muchas gracias por tu respuesta, 

    Sí, ahora estoy usando las secuencias sql como me lo muestras en el ejemplo y es mas sencillo.

    En cuanto a las fechas, tuve que hacer algunos cambios para mandarlas todas en formato inglés.

    Es que había algunas que el usuario debía escribirlas manualmente, pero no fue gran problema cambiarles el formato. De nuevo muchas gracias!

    martes, 10 de julio de 2018 19:07