none
Como manejar datos de tipo fecha en blanco RRS feed

  • Pregunta

  • hola.
    Estoy haciendo una aplicación de escritorio, que usa una db-Access. Pero los datos, originalmente estaban en Excel. Excel perimite poner en balco campos de tipo fecha. Al importar los desde Access, su valor será "null" o "DbNull" (no se bien cual de los dos, pero lo detenco asi: if(Convert.IsDBNull(dr["FechaNac"]))....

    Para acceder a los datos. empecé por crear un origen de datos, lo arrastré al form y se crearon los Labels, textbox, combobox y DataTimePicker.
    Los DataTimePicker manejan los deatos de fecha. Y muestran por defecto la fecha de hoy. Al enlazarlo a un campo de fecha muestra la fecha que tiene ese registo, pero se el valor es null, lo ignora y muestra su valor por defecto.
    Lo deseable sería que cuando hay un valor null, se quede en blanco, pero no pude hacerlo.
    Finalmente opté por eliminar el origen de datos y mantener los datos por código, y en los casos de fechas null le pongo un dias después de hoy asi:

    if(Convert.IsDBNull(dr["FechaNac"]))
                    dTPFechaNac.Value = DateTime.Now.AddDays(1);

    y en el evento dTPFechaNac_ValueChanged seteo un ErroProvider que advierte que la FechaNac es erronea.

    Esto funcion, pero lleva muchisimo trabajo. Y con el riesgo de errores en el mantenimiento de los datos.

    ¿como se puede hacer esto?¿como se acostumbra a manejar las fechas null?¿que dicen la buena prácticas de programación?
    sábado, 21 de febrero de 2009 21:52

Respuestas

  • Hola, que tal.

    Te comento desde hace varios años que programo y nunca he usado Origenes de datos, me imagino que estas usando el AccessDataSource.

    La verdad que siempre programe en capas, por ahi cuando uno habla de capas piensa que estas deben estar distribuidas en varios servidores y cosas asi, pero puede que este en capas y se encuentren en varios ensamblados pero instalado todo en una pc sola.

    Por ahi la codificancion en capas tiene mas que ver con una separacion logica de las responsabilidad, las tipicas capas de presentacion, negocio y acceso a datos.


    Si estoy de acuerdo con lo que mencionas, requiere mas esfuerzo, si por supuesto que lo requiere, pero te da un control que con ningun otro metodo lo lograras.

    Usar controles que arrastras y soltas y generan la aplicacion en 2 click, estan muy buenos, y estan excelentes para cuando tienes una demo, o quieres mostrar algun concepto rapido, pero para aplicaciones relativamente serias, la verdad dudaria mucho si un Arquitecto de software me aconseja utilizarlas.
    O sea en un entorno productivo que debo darle a un cliente, o sie stoy pensando armar una Software Factory, ni loco pensaria en utilizar controles de origenes de datos, son simplemente incontrolables.


    Igualmente se que en todo proyecto de software hay una analisis de costo beneficio, si tu aplicacion es bastante chica, por ahi no se justifica armar capas, ya que es bastante costoso, por ejemplo si tu aplicacion tiene solo 2 formularios, es como que no se justificaria, aunque tambien se que son los mejores proyectos para tomar experiencia y probar nuevas tecnicas.

    Si quieres usar los controles de Binding, puede agregar codigo custom para el caso de DataTimePicker.
    Aqui te paso algunos links que te puede ayudar:

    DataBinding DateTimePicker to a Nullable Type

    InvalidCastException al enlazar DateTimePicker que contiene un valor null en Visual Basic

    Como veras los dos ejemplos de arriba basicamente utilizan los eventos Parse y Format, para controlar el resultado cuando al bindearlo viene un nulo, o un dbnull.


    Ahora si quieres algo un poco mas resuelto, puede usar un control que ya realice estas validaciones de tipos de datos, este que encontre parece muy bueno:

    Yet another nullable DateTimePicker control



    Bueno espero te haya sido de utilidad.
    Saludos



    Leandro Tuttini
    • Marcado como respuesta Anti_Work domingo, 22 de febrero de 2009 22:09
    sábado, 21 de febrero de 2009 22:43

Todas las respuestas

  • Hola, que tal.

    Te comento desde hace varios años que programo y nunca he usado Origenes de datos, me imagino que estas usando el AccessDataSource.

    La verdad que siempre programe en capas, por ahi cuando uno habla de capas piensa que estas deben estar distribuidas en varios servidores y cosas asi, pero puede que este en capas y se encuentren en varios ensamblados pero instalado todo en una pc sola.

    Por ahi la codificancion en capas tiene mas que ver con una separacion logica de las responsabilidad, las tipicas capas de presentacion, negocio y acceso a datos.


    Si estoy de acuerdo con lo que mencionas, requiere mas esfuerzo, si por supuesto que lo requiere, pero te da un control que con ningun otro metodo lo lograras.

    Usar controles que arrastras y soltas y generan la aplicacion en 2 click, estan muy buenos, y estan excelentes para cuando tienes una demo, o quieres mostrar algun concepto rapido, pero para aplicaciones relativamente serias, la verdad dudaria mucho si un Arquitecto de software me aconseja utilizarlas.
    O sea en un entorno productivo que debo darle a un cliente, o sie stoy pensando armar una Software Factory, ni loco pensaria en utilizar controles de origenes de datos, son simplemente incontrolables.


    Igualmente se que en todo proyecto de software hay una analisis de costo beneficio, si tu aplicacion es bastante chica, por ahi no se justifica armar capas, ya que es bastante costoso, por ejemplo si tu aplicacion tiene solo 2 formularios, es como que no se justificaria, aunque tambien se que son los mejores proyectos para tomar experiencia y probar nuevas tecnicas.

    Si quieres usar los controles de Binding, puede agregar codigo custom para el caso de DataTimePicker.
    Aqui te paso algunos links que te puede ayudar:

    DataBinding DateTimePicker to a Nullable Type

    InvalidCastException al enlazar DateTimePicker que contiene un valor null en Visual Basic

    Como veras los dos ejemplos de arriba basicamente utilizan los eventos Parse y Format, para controlar el resultado cuando al bindearlo viene un nulo, o un dbnull.


    Ahora si quieres algo un poco mas resuelto, puede usar un control que ya realice estas validaciones de tipos de datos, este que encontre parece muy bueno:

    Yet another nullable DateTimePicker control



    Bueno espero te haya sido de utilidad.
    Saludos



    Leandro Tuttini
    • Marcado como respuesta Anti_Work domingo, 22 de febrero de 2009 22:09
    sábado, 21 de febrero de 2009 22:43
  • Muchas gracias por tu respuesta.
    Me baje el NulableDateTimePicker de link que me dejaste y funciona perfectamente.
    El NulableDateTimePicker es un contro que hereda de DateTimePicker y admite valores de fecha null. Tiene una propiedad: NullValue. A esta prop. le seteas el texto que quieres que se muestre cuando la fecha es nula.
    Me imagino que otra historia será cuando quieres guardar en la db el contenido del control. Aun no he probado tanto.
    El control es fantastico.

    Tambien me interesa mucho el tema de la programación en capas. yo empecé una para aprender, pero por falta de tiempo esta suspendida, en cualquier momento retomo y, seguramente voy a hacer preguntas.
    Por lo poco que hice, una duda que se me presentaba con frecuencia es el tema de la responsabilidad de cada tarea.
    Por ej: si hay que filtrar los datos. Que capa debe hacerlo. Esto me genera dudas porque, si bien es cierto que, sea cual sea la interfaz del usuario, este necesitará los datos filtrados, y entonces, si no depende de la interfaz, habria que ponerlo en una capa mas abajo. Pero por otra parte lo controles que muestran los datos no reciben los datos de la misma manera, lo que daría lugar a comportamiento distrinto que habria que programar en la capa de presentación.

    Muchas gracias.
    saludos
    domingo, 22 de febrero de 2009 14:05

  • Excelente que te haya funcionado el control.

    Te comento el desarrollo en capas, la verdad que una vez que empiezas vas a notar que tiene una potencia increible, pude ser medio frustrante al principio porque no sepas donde poner cada cosa, pero solo la practica y el involucrarte en el tema te dara la respuestas.

    Con respecto a las consultas y filtros te dire que depende que tipo de filtro quieras aplicar, a ver me voy a explicar.

    Si a filtros te refieres a por ejemplo si tienes una aplicacion de Agenda de Contactos y quieres darle la capacidad de busqueda al usuario, te dire que la responsabilidad del filtro es la capa de datos.
    porque es esto, resulta que seguramente la capasa de datos use un motor de base de datos, puede ser grande o chico (SQL Server o Access), no importa, el sabe aplicar los filtros de datos de forma bien performante.
    o sea, desde la capa de datos simplemente tomara los datos del filtro y asi como estans e los pasara a la de negocio, y ene ste caso puede que sea un simple pasamano, a la de datos, suele pasar, y se la de datos que use los filtros para crear la consulta y devolver los datos.

    En algunas arquitecturas en casos como estos por ahi se obvia el pasaje por la capa de negocio, y la capa de presentacion interactua con al de datos directamente, esto se puede dar si asl capas estan fisicamente juntas, si estas usando aplication servers o sea algo un poco ms distribuido puede que no puedas saltarte capas, y las tengas que respetas aunque sean obvias.

    Esto se te puede presentar si por ejemplo separas la presentacion del resto usando, por ejemplo WCF, ahi al haber una capa de transporte en el medio simpre debes apuntar a esa capa, y no puedes saltarte a la de acceso a datos directamente.

    Ojo, que cuando hablas de filtros tambien te puedes referir a que los datos que devolvio la consulta de la Agenda, o sea un listado de nombres, y quieras que estos sean discriminados por la letra con que empiezan sus apellidos, aqui ya la de datos no participa, la de datos tomo los filtros ingresados por el usuario y devolvio la lista de resultados que coinnciden hasta ahi llego, ahora es responsabilidad de la presentacion mostrarlos separados por letras, y ante la presion del usuario en cada letra mostrar la lista de nombres que corresponden.
    Como te habras dado cuenta use el verbo mostrar, o sea todo lo que sea visualizacion de datos es responsabilidad de la presentacion.
    Por ahi en este caso concreto podria haber sido ayudada por la capa de negocio, que realice alguna operacion de clasificacion para indicarle a la presentacion que nombres deben ir con que letra.

    La capa de negocio por ahi podria tener metodos de filtros como ser ObtenerClientesPorBarrio(), ObtenerClientesConOrdenesdeCompra(), ObtenerFacturasPorCliente(), ObtenerFacturasPorClientePorVencer(), ObtenerFacturasporClienteVencidas().

    Como veras la capa de negocio tiene metodos que representan algo para tu negocio, puede que en la capa de datos tenga exactamente los mismo metodos, o no, puede que la capa de datos use metodo mas generico, eso va a depender de como este diseñada la aplicacion.
    Puede ser que los metodos ObtenerFacturasPorClientePorVencer(), ObtenerFacturasporClienteVencidas(), usen el mismo metodos de la capa de datos, solo que se le indica un parametro de filtro, ejemplos DAL.ObtenerFacturasporCliente(int estado)


    Estos links podran servirte de referencia:

    http://faeryfantasy.wordpress.com/2007/10/15/desarrollo-en-tres-capas-net-ejemplo/

    Este link pude darte una nocion sobre la responsabilida de la capa de datos:
    Programación en Capas Primera Parte (Capa de Acceso a Datos)

    Esta ppt te puede ayudar mucho
    Fundamental: Desarrollo en Capas

    Bueno espero te haya servido la explicacion
    Saludos



    Leandro Tuttini
    domingo, 22 de febrero de 2009 18:56
  • Muchas gracias una vez más.

    Muy clara te explicación y realmente muy interesante el tema. Ya le di un vistazo a lo link que me dejaste; muy buen material, te lo agradezco.

    Saludos
    domingo, 22 de febrero de 2009 22:07
  • Hola Lenadro Tuttini, te escribo para pedirte ayuda sobre este tema, lo que pasa es que yo estoy trabajando en VB.NET, he tratado de traducir el código que tienes en la pagina de codeproject con el conversor de C#a VB.NET, pero me parece que hay algunas cosas que no son traducidas bien o que no son soportadas en VB.Net.

    Aqui van algunas:

    OnFormatChanged,OnvalueChanged - No se ha declarado el nombre OnFormatChanged,etc.

    Mybase.CustomFormat - No es un miembro de System.Windows.Form.Form

    MyBase.Value - Aqui para que no de error le quite el Mybase y lo toma como la variable Value, no se si sea lo correcto.

    mybase.customformat

    NullableDateTimePicker() lo toma como tipo

     

    No se si puedas enviarme el codigo necesario en VB.Net para corregir estos errores, o si puedas subir un ejemplo en VB.NET, ya que he buscado por todos lados y solo hay ejemplos en C#, y no puedo pasarlos a VB.NET.

    Espero no molestarte con esto, ya que realmente necesito controlar las fechas con valores null o simplemente que se muestren valores en blanco.

    P.D.: Lo que quiero lograr es que al quitarle el check a mi DatetimePicker en el Grid que esta enlazado por el databinding se muestre en blanco el campo fecha. De manera que exista la posibilidad de ingresar o no el campo fecha.

     

    Muchas Gracias

    miércoles, 16 de junio de 2010 16:20