Introducción
Uno de los principales problemas que se pueden encontrar cuando se confecciona una consulta es el trabajo con campos del tipo fecha.
Por lo general estos campos no solo persisten la fecha, sino que también registran la hora.
Es por eso que ciertas consultas pueden no retornar los valores deseados, aunque se este definiendo correctamente los parámetros de la consulta.
Planteo del problema
Para demostrar el problema se plantea el log de actividades del usuario, en donde se registras las acciones que este tiene en la aplicación. Pero el problema se presenta cuando se necesita consultar estos registros para analizar las acciones realizadas en un determinado rango de días, por supuesto se quiere ver los días completo, y es aquí donde nos encontramos con el inconveniente.
Si se analiza los registros de la tabla se ve que el registro de la fecha no solo usa el día, sino también la hora.
La aplicación de ejemplo cuenta con dos opciones de búsqueda, pero en este primer análisis nos centraremos en el primer botón de nombre “Buscar (sin usar CONVERT)”, al utilizarlo veremos el resultado de la imagen:
Pero con solo comparar los registros obtenido con los que se encuentran en la tabla, nos damos cuenta que hay un problema, esta retornando menos filas de las esperadas, la pregunta seria, porque sucedió esto ?
El código utilizado para obtener los registro es el siguiente :
public static LogActividades.RegistroActividadesDataTable GetFilterByDateRange(DateTime desde, DateTime hasta) { LogActividades.RegistroActividadesDataTable dt = new LogActividades.RegistroActividadesDataTable(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) { conn.Open(); string sql = @"SELECT Id, Descripcion, fecharegistro, usuario FROM RegistroActividades WHERE fecharegistro >= @desde AND fecharegistro <= @hasta"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.AddWithValue("@desde", desde); cmd.Parameters.AddWithValue("@hasta", hasta); SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(dt); } return dt; }
El parámetro de la fechas toma el valor directo de los controles que están en la pantalla, pero esta fecha aunque no se conozca también lleva consigo un componente de hora, que puede ser apreciado si se detiene el código y se analiza el valor:
El tipo de dato DataTime, lleva una hora aunque esta no se especifique concretamente.
Esto aclara bastante el porque la consulta arroja menos ítems de los esperados, resulta que esta quitando aquellos registros en donde la hora sea menos a las 12 AM
Solución del problema
La solución al problema se obtiene usando una funciona en la query, que aplicada sobre los campos de fecha en el filtro quiten la componente de la hora. En realidad no remueve la hora, sino que la normaliza para que esta también tenga las 12 AM, por lo tanto el filtro no descartara ningún registro.
Para esto se hará uso de la función CONVERT, la cual permite convertir entre tipos de datos.
Si se ejecuta una consulta usando esta función se podría apreciar lo comentado mas arriba:
Las fechas de los registros dejan de tener la hora original, ahora todos presentan las 12 AM, esto es justamente lo que ayudara en el filtro.
Entonces si ahora se aplica lo comentado al código se obtiene el resultado esperado (usar el botón “Buscar (usando CONVERT)”):
Para que esto resulte se utilizo el siguiente código:
public static LogActividades.RegistroActividadesDataTable GetFilterByDateRangeRemoveHour(DateTime desde, DateTime hasta) { LogActividades.RegistroActividadesDataTable dt = new LogActividades.RegistroActividadesDataTable(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) { conn.Open(); string sql = @"SELECT Id, Descripcion, fecharegistro, usuario FROM RegistroActividades WHERE CONVERT(smalldatetime, CONVERT(char(10), fecharegistro, 103), 103) >= @desde AND CONVERT(smalldatetime, CONVERT(char(10), fecharegistro, 103), 103) <= @hasta"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.AddWithValue("@desde", desde); cmd.Parameters.AddWithValue("@hasta", hasta); SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(dt); } return dt; }
El uso del CONVERT aplicado en los campo de “fecharegistro”, es quien quita la componente de la hora y permite aplicar el filtro correctamente.
Alternativa usando Between
Como alternativa al método anterior se podría lograr usando el Between en la query para filtrar por el rango de fechas.
En el Form2 del ejemplo se podrá encontrar la implementación de este caso.
public static LogActividades.RegistroActividadesDataTable GetFilterByDateRangeWithBetween(DateTime desde, DateTime hasta) { LogActividades.RegistroActividadesDataTable dt = new LogActividades.RegistroActividadesDataTable(); using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString())) { string sql = @"SELECT Id, Descripcion, fecharegistro, usuario FROM RegistroActividades WHERE CAST(CONVERT(CHAR(8), fecharegistro, 112) AS INT) BETWEEN CAST(CONVERT(CHAR(8), @desde, 112) AS INT) AND CAST(CONVERT(CHAR(8), @hasta, 112) AS INT)"; SqlCommand cmd = new SqlCommand(sql, conn); cmd.Parameters.AddWithValue("@desde", desde); cmd.Parameters.AddWithValue("@hasta", hasta); SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(dt); } return dt; }
La lógica principal se encontrara en el método creado para realizar la consulta, allí se ha utilizado el BETWEEN para definir el filtro entre un rango, pero este tienen un problema requiere de un formato especial que justamente el CONVERT (con el código 112) nos proporciona.
Esta conversión lleva la fecha al formato yyyyMMdd, o sea si tenemos la fecha 10/06/2010, será formateada a 20100610, claramente un numero, pero primero deberá pasar por un CHAR para adecuar la conversión del formato de la fecha y luego si será convertido a un valor numérico.
Ejemplo de Código
El código publicado fue desarrollado con visual Studio 2008.
La base de datos utilizada es el Sql Server Express 2008.
En el proyecto encontraran una carpeta de nombre “Script” que contiene el archivo .sql que podrán usar en el “Sql Server Management Studio” para crear la estructura de la base de datos en caso de tener problemas con el archivo .mdf
En caso de usar la base de datos integrada al servicio de Sql Server, se deberá cambiar la cadena de conexión definida en el App.config
[C#] |
[VB.NET] |
Hola Leandro, solo un pequeño apunte, no es necesario hacer el Open del objeto Connection si estamos utilizando un objeto DataAdapter.
ResponderEliminarHola Leandro,
ResponderEliminaryo para evitar utilizar CONVERT en la consulta Sql, por si conlleva consumo de recursos, lo que hago es añadir un día y hora 00:00:00 al hasta y en la consulta hago < hasta.
¿Estoy en lo cierto?, ¿si la fecha fuera índice con el CONVERT se utilizaría?.
Un saludo.
hola Javier
ResponderEliminarTienes razon, el DataAdapter no requiere una apertura explicita de la conexion.
Se ve que tome una parte del código en donde usaba un command simple y quedo esa linea.
Gracias por la aclaracion.
saludos
hola ATP
ResponderEliminarLa verdad nunca aplique esa tecnica que comentas, por eso no sabria decir si es valida o no, pero si en tu caso devuelve los registros que requieres se podria decir que es correcta.
Por el tema de consumo de recurso, puede ser que la conversion de tipos lo sea, pero tampoco deberia ser demasiado, no realice un test de performance con una carga importante de registros, pero tampoco deberia ser tanta la diferencia con alguna otra tecnica que se pudiera aplicar.
Como poder seguro se puede, aunque quizas la indexacion por ese campo la pierdas, y toda la optimizacion que esto lleva.
saludos
Hola Leandro me parece muy util tu post que se acerca a lo que estoy realizando ahora, pregunto como harías para filtrar x el Mes de esta Fecha?
ResponderEliminarhola Ron@ldo VM
ResponderEliminarPara filtrar solo por el mes pdorias saur la funcion DATEPART
con esta funcion podrias tomar solo el mes de la fecha que estas filtrando
SELECT Id, Descripcion, fecharegistro, usuario
FROM RegistroActividades
WHERE DATEPART(month, fecharegistro) >= @mesdesde
AND DATEPART(month, fecharegistro) <= @meshasta
En este caso le pasarias como desde y hasta solo los meses que quieres visualizar.
saludos
tendras una forma de filtrar un rango de fechas a un crystal report desde como obtener las fechas hasta como recibirlas desde el crystal repor?
ResponderEliminarhola omar
ResponderEliminarNo se si entendi del todo el planteo de la pregunta
Si el reporte en Crystal lo usas con DataSet Tipados el filtro por rango de fechas lo aplcias durecto en la query que carga el dataset, y luego este ya filtrado en el rango lo asignas como origen de datos del reporte.
No se si es este el planteo que hacias, o pensabas filtrar la fecha dentro del reporte, quizas porque este se conecta directo a la db.
saludos
Hola Leandro, quisiera consultarte como agrego una seleccion por datetimepiker como fecha inicial y fecha final en crystal report por el momento lo tengo asi.
ResponderEliminarUso Visual Studio 2008
DSTareas dst = new DSTareas();
DSTareasTableAdapters.TareasTableAdapter adaptador = new MS2.DSTareasTableAdapters.TareasTableAdapter();
adaptador.Fill(dst.Tareas);
CrystalReport2 Report = new CrystalReport2();
Report.SetDataSource(dst);
crystalReportViewer1.ReportSource = Report;
Hola Leandro que tal no puedo ejecutar esas consultas cuando esta la bd .mdf siempre me vota un mensaje similar a este
ResponderEliminarthe database.......[CSHARP]FILTRARRANGOFECHAS\FILTRARRANGOFECHAS\BIN\DEBUG\LOGACTIVIDADES.MDF' cannot be opened because it is version 655. This server supports version 612 and earlier. A downgrade path is not supported.
Could not open new database
Y he probado con sql 2008 estandar edition , sql 2005 ,sql 2005 expresss, con cual podria ejecutar la aplicacion sin problemas.
hola Sergio
ResponderEliminarLo que podrias hacer es definir un metodo en el TableAdapter para que permita especificar las fechas desde y hasta que usarias en la query.
De esta forma cargarias el datatable directo con la info que coincide con el rango de fechas que quieres mostrar.
Para crear un nuevo metodo, podrias guarte por este articulo:
Building a DAL using Strongly Typed TableAdapters and DataTables in VS 2005 and ASP.NET 2.0
Alli veras como se extiende la funcionalidad del TableAdapter, creando nuevas consultas que cargan el datatable, en tu caso crearias uno nuevo que tome dos parametros de fecha
saludos
hola Augusto
ResponderEliminarMe parece que el problema se presenta porque las mdf del ejemplo las cree con Sql Server Express 2008 R2
Eso del R2 es una version mayor y trae el problema.
En todo caso veo el finde semana de dejar los script para que puedas crear al db en otra version.
saludos
Ok.
ResponderEliminarLeandro esperare el script .
Gracias.
Saludos.
Feliz Navidad!
Hola Leandro estoy necesitando ayuda en lo siguiente: necesito q figure la ficha del dia en el crystal report, utilizo un procedure store y no deseo generar una tabla temporal para alojar los datos ya q eso hace q la consulta sea mas lenta, me gustaria saber como hago para q el crystal report me tome la fecha del sistema? espero puedas ayudarme y gracias!!
ResponderEliminarhola paola
ResponderEliminarCrystal dispone de Special Filed que podrias usar, si la idea es mostrar la fecha del dia en el reporte.
Mira este otra consulta que se hace en el foro
http://social.msdn.microsoft.com/Forums/es/vbes/thread/a0d72949-a38d-43d2-9e4e-9d61cd71e0a2
checkea la imagen para orientarte, creo que sera de ayuda
saludos
hola muy bueno tu blog me ha servido de mucha ayuda, sabes que pasa que yo trabajo con acces 2010 y necesito hacer una query que contenga el between con las dos fechas, pero al aplicar lo que expones de las fechas en betwenn salta un error "Error de IErrorInfo.GetDescription con E_FAIL(0x80004005)" cabe recalcar que las dos fechas vienen en formato dd/mm/yyyy y entran con parametros de entrada (tipo string) en el metodo que creé
ResponderEliminarhola cachabacha
ResponderEliminarsi es logico que no funcione porque esta tecncia que menciono es particular para sql server
quizas en access se puede aplciar alguna mas simple
a ver veamos, cuando insertas los registros en la tabla de access, usas parametro ? imagino que si
entonces le pasa la fecha como ser
DateTime.Now.Date
o
DateTimePicker1.Value.Date
ese Date que pongo es importante porque pasara al campo un valor sin la compojnente de la fecha
si esto lo haces asi entocnes podrias poner un filtro de esta forma
cmd.Parameters.AddWithValue("@fechadesde", DatetimePicker.Value.ToString(yyyyMMdd))
para el hasta seria igual
con esto aplicas un filtro en formato estandar en la fecha
valida si con este tips que menciono funcion
saludos
Eres el mejor leandro muchisisisisimas gracias me funciono a la perfeccion :DDD
ResponderEliminarpor ultimo ( por ahora) me gustaria saber:
como puedo hacer que desde un boton yo pueda modificar los datos de un datagriview en ejecucion es decir que modifique los datos y que cuando pulse el boton me diga que se modificaron o si hay otra manera mejor que me puedas decir
que sea en c sharp por favor
hola Joel
ResponderEliminarbien para esto hay varias formas de lograrlos
podrias hacer algo como esto
Cómo: Enlazar datos al control DataGridView de formularios Windows Forms
en donde el CommandBuilder creas las actualziaciones por ti y el Update() de DataAdapter impacta los cambios
O podrias controlar tu toda la operacion, recorres los registros armas entidades y actualizas
[N-Tier] – Desarrollo en capas - Ejemplo Facturacion - parte 2
depende de que tanto te animes a desarrollar opta por una u otra
saludos
Saludos Leandro.
ResponderEliminarTengo Problemas al almacenar la fecha en una base de datos sql.
insert into tabla (fecha) values ('18/11/2011') <-- En este ejemplo la almacena correctamente, pero si lo hago de la sig. manera.
string Fecha = DateTime.Today.ToShortDateString();
insert into tabla (fecha) values ('"+Fecha+"') <-- en este ejemplo me marca un error que dice Incorrect syntax near '18/11/2011'.
Me podrias ayudar.
hola Chipujin
ResponderEliminarcomo primer punto debo mencionar que el principal problema se deba a que no usas parametros, no es bueno concatenar la query en un string
debes usar parametros, para que al pasarle el datetime funcione
ademas no has comentado si el campo en la db lo defines como datetiem o como varchar
saludos
Saludos Leandro.
ResponderEliminarel campo en la base de datos es Datetime, lo que no entiendo es por que insertando directamente el valor en el campo si lo registre y por que al insertar el mismo valor pero ahora almacenándolo en una variable string que se convierte a Datetime no lo registre y marque ese tipo de error.
hola
ResponderEliminarmas alla que usando un string lo inserte y concatenado la cadena no lo haga deberias usar parametros es la forma mas segura de insertar informacion en una tabla
saludos
Ok, Gracias Leandro por tu ayuda, si se puede de la forma que dices usando parametros.
ResponderEliminarMuchas Gracias!!!
Hola Leandro,
ResponderEliminarDisculpa pero quisiera convertir esta parte de la consulta sql a una consulta para bases de datos acces, es posible?
Dim sql As String = "SELECT partida,concepto,precio,texto,total,fechapago " & _
"FROM pagos " & _
"WHERE CAST(CONVERT(CHAR(8), fechapago, 112) AS INT) " & _
"BETWEEN CAST(CONVERT(CHAR(8), @desde, 112) AS INT) " & _
"AND CAST(CONVERT(CHAR(8), @hasta, 112) AS INT)"
ya que si lo dejo asi me genera este error: Error: IErrorInfo.GetDescription failed with E_FAIL(0x80004005)
Podrias ayudarme?
hola radx
ResponderEliminarprimero ese mensaje de error no creo que tenga que ver con con un problema de la query que adaptas a Access, parece mas un error de COM por el mensaje
segundo, no creo que las funciones de conversion existan en Access, no estoy seguro que exista un adaptacion exacta
saludos
Hola Leandro,
ResponderEliminarEntonces para hacer una consulta en access donde ponga como limite fechas como la haria? Ya he intentado hacerlo con los codigos que pones de ejemplo, pero no me arroja el resultado de la busqueda en el DataGridVew a que se debe esto? Necesito generar unreporte con estos datos.
repondiendo a radx creo que te puedo ayudar, tambien tuve los mismos problemas al querer hacer el between en una consulta con Acces pero lo solucione de la siguiente manera:
ResponderEliminarSELECT (lo que vas a consultar) y en la parte del between va así BETWEEN #" + fecha1 + "# AND #" + fecha2 + "#" donde fecha1 y fecha2 son variables de entrada tipo string pero convertidas previamente asi dateTimePicker1.Value.Date.ToString("MM/dd/yyyy")cualquier pregunta que tengas con gusto la responderé
Gracias por contestar cachabacha,
ResponderEliminarYa intente hacer la solución que me propones y me quedo asi;
Dim sql As String = "SELECT partida,concepto,precio,texto,total,fechapago " & _
"FROM pagos " & _
"WHERE fechapago= BETWEEN #" + DateTimePicker1.Value.Date.ToString("MM/dd/yyyy") + "# AND #" + DateTimePicker2.Value.Date.ToString("MM/dd/yyyy") + "#"
El detalle es que todabia no me arroja los registros me da este error;
Error de sintaxis (falta operador) en la expresión de consulta 'fechapago= BETWEEN #06/18/2012# AND #06/20/2012#'.
Como podria solucionarlo??
hola radx
ResponderEliminarsi usas el BETWEEN no debes poner el =
solo es
fechapago BETWEEN ...
saludos
leandro ya te ha dicho lo que tienes mal saludos.
ResponderEliminaralguien me puede hacer el favor de ayudarme con el codigo de filtrar por 2 fechas que estan en una columna del datadridview
ResponderEliminarestoy haciendolo en vb 2008 y access 2007 la verda e buscado y intentado mucho pero no me quiere dar
es para mostrar en el datadridview unas ventas realizadas en el transcurso de esa fecha
de antemano gracias
la verdad ni se como empezar el codigo estoy en 0
hola Leonel
ResponderEliminary tenias que usas Access, no podrias ir a una base de datos mejor como sql server
es que en access las fechas son todo un tema
igualmente si asignas como parametro un datetime deberias poder filtrar la query
saludos
haslo con 2 datetimepickers. a cada datetime agregale el evento ValueChanged, este evento se ejecuta cuando cambias el valor del datetimepicker, dentro del evento actualizas el datagridview con la fecha que envias de los datetimepickers. saludos
ResponderEliminarAlgun ejemplo con C# y MySql?
ResponderEliminarTienes algun ejemplo de como hacerlo en C# y Mysql
ResponderEliminarhola McMoran
ResponderEliminarla verdad no tengo un ejemplo con mysql, pero basicamente la tecnica es la misma, lo unico que cambia es la funcion de normalizacion para quitar la componente de la hora
12.7. Date and Time Functions
podrias usar el DATE() para tomar una parte de la fecha
Nota: por supuesto las clases MySqlConnection, MySqlCommand , etc eso tambien cambia
saludos
Buenas tardes, estoy realizando un programa con una tabla de access 2003, estoy usando C# de Visual Studio 2005.
ResponderEliminarEste procedimiento es un botón, que al pulsarlo me debe traer los registros de la tabla de VENTAS de acuerdo al rango de fechas que yo le digite, el problema es que ya no me trae nada. Las fechas son dos campos dateTimePicker1, y en el código ya le puse los parámetros para evitar problemas de que traiga la hora y no ponga problema de compatibilidad de campos por sus tipos.
Antes de ponerle lo de las fechas, y probándolo que me trajera los registros de la tabla, sí me los traía todos; ahora que le di la condición de las fechas, y los parámetros ya no me muestra nada de nada, y sabiendo que determinadas fechas sí tienen información realmente en la base de datos.
Soy prncipiante en esto, les agradezco mucho en lo que me puedan ayudar.
private void BGENEREPOR_Click(object sender, EventArgs e)
{
dtscierrev.Clear();
//string rquery = @"SELECT VENTAS.*, CODIGOS.NOMARTI, ARTICULOS.DESCRIP FROM ((VENTAS INNER JOIN ARTICULOS ON VENTAS.REFEREN = ARTICULOS.REFEREN) INNER JOIN CODIGOS ON VENTAS.CODIGO = CODIGOS.CODIGO) where FECHAVEN between @desde AND @hasta";
string rquery = @"SELECT * FROM VENTAS WHERE FECHAVEN >= @desde AND FECHAVEN <= @hasta";
DateTime fecha = DateTime.Today;
string fechacadena = fecha.ToString("dd/MM/yyyy");
DateTime fecha2 = DateTime.Today;
string fechacadena2 = fecha2.ToString("dd/MM/yyyy");
fechacadena = Convert.ToString(DFECHADES.Text);
fechacadena2 = Convert.ToString(DFECHAHAS.Text);
OleDbCommand cmd = new OleDbCommand(rquery, oleDbConnection1);
cmd.Parameters.AddWithValue("@desde", fechacadena);
cmd.Parameters.AddWithValue("@hasta", fechacadena2);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dtscierrev);
// Crea el reporte
repventas repvent = new repventas();
// Asocia el conjunto de datos con el reporte
repvent.SetDataSource(dtscierrev);
// Asocia el reporte con el Visualizador
crysrepver2.ReportSource = repvent;
}
hola Juan
ResponderEliminares que deberia ser
string rquery = @"SELECT * FROM VENTAS WHERE FECHAVEN >= @desde AND FECHAVEN <= @hasta";
OleDbCommand cmd = new OleDbCommand(rquery, oleDbConnection1);
cmd.Parameters.AddWithValue("@desde", Convert.ToDateTime(DFECHADES.Text));
cmd.Parameters.AddWithValue("@hasta", Convert.ToDateTime(DFECHAHAS.Text));
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
o sea los valores deben ser datetime
saludos
Gracias Leandro, ahora lo que pasa es que me está buscando con la hora, el campo ya está guardando la hora, por eso le había puesto fechacadena y fechacadena2. ¿qué será?
ResponderEliminarhola Juan
ResponderEliminarclaro el tema es que si usas el BETWEEN deberias pasar por parametro la fecha en formato yyyyMMdd porque este solo reconoce un numero como parametro
string fecha1 = Convert.ToDateTime(DFECHADES.Text).ToString("yyyyMMdd");
cmd.Parameters.AddWithValue("@desde", fecha1);
esto mismo esta explicado en el articulo
saludos
Buenas tardes Leandro, precisamente antes así lo habia hecho, con parámetros y teniendo en cuenta tu artículo,pero nada. Asi lo puse nuevamente prácticamente como lo tenia antes con la duda, pero aún no me trae nada, no se poorqué, porqué registros hay en la fechas que le doy pero en ninguna fecha trae nada de nada, gracias por tu ayuda y disculpa tanta molestadera:
ResponderEliminarprivate void BGENEREPOR_Click(object sender, EventArgs e)
{
dtsciervent1.Clear();
string fecha1 = Convert.ToDateTime(DFECHADES.Text).ToString("dd/MM/yyyy");
string fecha2 = Convert.ToDateTime(DFECHAHAS.Text).ToString("dd/MM/yyyy");
//string rquery = @"SELECT VENTAS.*, CODIGOS.NOMARTI, ARTICULOS.DESCRIP FROM ((VENTAS INNER JOIN ARTICULOS ON VENTAS.REFEREN = ARTICULOS.REFEREN) INNER JOIN CODIGOS ON VENTAS.CODIGO = CODIGOS.CODIGO) where FECHAVEN between @desde AND @hasta";
string rquery = @"SELECT * FROM VENTAS WHERE FECHAVEN >= @desde AND FECHAVEN <= @hasta";
OleDbCommand cmd = new OleDbCommand(rquery, oleDbConnection1);
cmd.Parameters.AddWithValue("@desde", fecha1);
cmd.Parameters.AddWithValue("@hasta", fecha2);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dtsciervent1);
// Crea el reporte
repventas repvent = new repventas();
// Asocia el conjunto de datos con el reporte
repvent.SetDataSource(dtsciervent1);
// Asocia el reporte con el Visualizador
crysrepver2.ReportSource = repvent;
}
en el campo de la BD de access ese campo es fecha/hora, y abajo le puse que fuera corta, y si le quito los "/" slash que separa la fecha, me dice que son los campos incompatibles entonces por eso no se los quito en el campo cuando los converto...
ResponderEliminarhola Juan
ResponderEliminarel parametro no tiene que ser un string, sino un DateTime
cmd.Parameters.AddWithValue("@desde", Convert.ToDateTime(DFECHADES.Text));
cmd.Parameters.AddWithValue("@hasta", Convert.ToDateTime(DFECHAHAS.Text));
saludos
Puse lo que me sugeriste anteriormente que fué esto, que pena no entiendo. ¿qué pasa entonces con fecha1 y fecha2?:
ResponderEliminarstring fecha1 = Convert.ToDateTime(DFECHADES.Text).ToString("yyyyMMdd");
cmd.Parameters.AddWithValue("@desde", fecha1);
esto mismo esta explicado en el articulo
Lo había puesto como me dijiste Datetime, luego te comenté que ahora me salía la hora en el mismo campo, me dijiste que para evitar esto usara los string yyyyMMdd, por eso los puse asi...
ResponderEliminarhola Juan
ResponderEliminarcreo que estas confundiendo las tecnicas
una cosa es usar el WHERE con el < o > y otro distinta es usar el BETWEEN
para el WHERE con < o > necesitas asignar un datetime, para el between debe ser un numero, pero numero no un string conformato
si usas el between deberia ser
int fecha1 = Convert.Toint32(Convert.ToDateTime(DFECHADES.Text).ToString("yyyyMMdd"));
saludos
Juan
ResponderEliminarme olvidaba, recuerda que al campo en la query debes aplicarle un CAST o CONVERT sino no funiona
y por supuesto el campo debe ser datetime en la db
saludos
Listo muchas gracias de verdad, lo voy a poner con > <, sí estoy muy nobato y he estado autocapacitándome; lo voy a poner datetime, pero ahora me va a salir lo que te dije en el campo también va ha traer la hora, ahí qué? lo puedo asignar el string con formato cierto "dd/MM/yyyy" cierto? y me disculpas nuevamente...
ResponderEliminarhola Juan
ResponderEliminarpero tu necesitas filtrar por la hora tambien ?
es cierto que el datetime de la db pondra la hora, pere podrias despreciar esta parte si al insertar el registro usas la propiedad "Date" del datetime para que envie una hora estandar y queden todos los campos igual
no necesitas ningun string de la hora porque sino vas a filtrar por esta, con al tecnica del articulo al quitas del medio
saludos
Gracias Leandro, creo que no me has entendido, disculpa ponerte a voltear tanto con este tema. No necesito filtrar por hora, pero cuando pongo date time la pone; le corrijo eso con la técnica que nos enseñas acá, y no me trae nada, ese es el problema.
ResponderEliminarEl código es este, ¿donde puede estar el problema y lo ccrrijo... gracias.
private void BGENEREPOR_Click(object sender, EventArgs e)
{
dtsciervent1.Clear();
string fecha1 = Convert.ToDateTime(DFECHADES.Text).ToString("dd/MM/yyyy");
string fecha2 = Convert.ToDateTime(DFECHAHAS.Text).ToString("dd/MM/yyyy");
//string rquery = @"SELECT VENTAS.*, CODIGOS.NOMARTI, ARTICULOS.DESCRIP FROM ((VENTAS INNER JOIN ARTICULOS ON VENTAS.REFEREN = ARTICULOS.REFEREN) INNER JOIN CODIGOS ON VENTAS.CODIGO = CODIGOS.CODIGO) where FECHAVEN between @desde AND @hasta";
string rquery = @"SELECT * FROM VENTAS WHERE FECHAVEN >= @desde AND FECHAVEN <= @hasta";
OleDbCommand cmd = new OleDbCommand(rquery, oleDbConnection1);
cmd.Parameters.AddWithValue("@desde", fecha1);
cmd.Parameters.AddWithValue("@hasta", fecha2);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(dtsciervent1);
// Crea el reporte
repventas repvent = new repventas();
// Asocia el conjunto de datos con el reporte
repvent.SetDataSource(dtsciervent1);
// Asocia el reporte con el Visualizador
crysrepver2.ReportSource = repvent;
}
hola Juan
ResponderEliminarel problema esta en que asignas string a un parametro que deberia ser datetime
usa
cmd.Parameters.AddWithValue("@desde", Convert.ToDateTime(DFECHADES.Text).Date);
cmd.Parameters.AddWithValue("@hasta", Convert.ToDateTime(DFECHAHAS.Text).Date);
saludos
Buenas noches Leandro, vuelvo a lo mismo del principio, otra vez aparece con la hora el campo de la fecha y así no lo necesito, por eso le había puesto el string que antes me habías dicho.
ResponderEliminarhola Juan
ResponderEliminarpartamos de una base, si el campo de tu tabla es datetime, con un string como quieres plantearlo no funciona, eso es seguro
ahora bine dices que vuelve con la hroa, lo cual es es cierto el "Date" del Datetime si devuelve la hora, pero es una hora normalizada a las 12:00:00, si usando el CONVERT en la query eliminas la hora esta tambien se normaliza, por lo tanto se anula la hora como filtro porque no afectara
de un datetime la hora nunca podras quitarla, pero si puede anular el efecto al filtrar
saludos
Gracias Leandro, pero ¿cómo se hace en el query? eso varia de un lenguaje a otro y no se como hacerlo. Agradezco mucho tu colaboración.
ResponderEliminarhola Juan
ResponderEliminaren la query se aplica como se plantea en el articulo
cuando te refierea a lenguaje apuntas a .net ? porque usar el CONVERT es en sql, .net no tiene nada que ver
si varia de una db a otra, si usas por ejemplo MySql, Oracle, Access, etc ahi si varia la forma en como usar la funcion de conversion
saludos
exacto, uso Access ahí tengo el problema.
ResponderEliminarhola
ResponderEliminarquizas se pueda armar algo con el
DatePart
podrias usar la funcionalidad del between para concatener el año-mes-dia tomando cada parte
saludos
Hola Leandro.
ResponderEliminarTengo una pregunta, me podrías explicar como hacer una consulta entre dos fechas pero con el asistente de Querys (consultas) ya que yo trabajo con el DataSet Designer
Gracias
hola x-carlos
ResponderEliminarcomo se plantea aqui
Tutorial 1: Creating a Data Access Layer
puedes crear metodos custom en los tableadapters asociados a los datatable del dataset tipado
saludos
Hola Leandro, me gusta mucho tu Blogg, es muy completo. Te queria consultar, necesito filtrar en un gridview la fecha
ResponderEliminarUso vb.net y para queries SQL server 2008
Te muestro como tengo la query
Es un stored procedure
@lDate as date,
AS
DECLARE @sTSQL as nvarchar(1500)
SET @sTSQL = @sTSQL + 'CONVERT(VARCHAR(10), pe.peDate,103) AS DATE,'
SET @sTSQL = @sTSQL + ' AND (peDate = ''' + CONVERT(varchar(10), @lDate , 103) + ''')'
El tema es asi quiero filtrar una serie de eventos por fecha, en un textbox (lo que ingreso es un string, 01/01/2013). Pero quiero que a penas entro al programa me muestre TODOS los eventos para poder ir filtrando y que me traiga el dato que contenga la fecha que yo le paso.
Espero se haya entendido.
Gracias saludos y segui asi ;)
hola Magali
ResponderEliminaren el procedure, donde define el WHERE?
lo pregunto porque en esta linea
SET @sTSQL = @sTSQL + 'CONVERT(VARCHAR(10), pe.peDate,103) AS DATE,'
veo que realizas una conversion de la fecha, pero no comparas contra ningun campo
la conversion de tipos parece esta correcta, imagino desde codigo .net estas asignado al parametro de la coleccion del SqlCommand, un valor del tipo DateTime
saludos
Ya lo resolvi Leandro.
ResponderEliminarMuchas gracias, hasta la proxima.
Hola Leandro, me intereso mucho tu Blogg, esta muy completo. Te queria consultar, necesito filtrar en un gridview la fecha
ResponderEliminarUso vb.net y acces 2010 como puedo hacerlo kiero jacer lo mismo k hiciste pero en este caso en acces
Hola Leandro, me intereso mucho tu Blogg, esta muy completo. Te queria consultar, necesito filtrar en un gridview la fecha
ResponderEliminarUso vb.net y acces 2010 como puedo hacerlo kiero jacer lo mismo k hiciste pero en este caso en acces
hola jose
ResponderEliminarpero esto mismo puedes aplicarlo con Access sin problemas, es mas puedes asignar DateTime por parametro a la query
lo que si valida si en la db access se registra la hora o no, en caso de estar la hora quizas podrias ver de aplicar formato y ponerlo en yyyyMMdd para usar el BETWEEN
si usas las clases de OleDbConection, OleDbCommand podrias aplicar esto mismo que uso en el articulo
saludos
Buen Día Leandro gracias por contestar oye ya lo hice y si me funciono solo que tiene un detalle no me muestra las fechas mi codigo que tengo es este:
ResponderEliminarPrivate Sub filtrar_Click(sender As Object, e As EventArgs) Handles filtrar.Click
Try
Using cnn As New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& "C:\Carpeta\Mi_base.accdb" & ";Persist Security Info=False;")
Dim cmd As OleDbCommand = cnn.CreateCommand()
cnn.Open()
'Construimos la consulta SQL de selección con dos parámetros. '
cmd.CommandText = _
"SELECT Expedida, validez FROM Sujeto WHERE Expedida >=@DESDE AND Validez <=HASTA"
'"WHERE CampoFecha BETWEEN @desde AND @hasta"
'Añadimos los parámetros, utilizando solamente
'el componente de la fecha, sin la hora.
cmd.Parameters.AddWithValue("@desde", DESDE)
cmd.Parameters.AddWithValue("@hasta", HASTA)
Dim da As New OleDbDataAdapter(cmd)
Dim dt As New DataTable()
da.Fill(dt)
' Mostramos los datos en un control DataGridView.
DGV.DataSource = dt
End Using
''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''
Return
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
hola jose
ResponderEliminarlas variables DESDE y HASTA son variables del tipo DateTime?
porque si lo son quizas debas usar
cmd.Parameters.AddWithValue("@desde", DESDE.Date)
para que solo envie la fecha sin la hora, eso si asegurate que en la tabla no se defien un horario en la fecha
saludos
Hola Leandro una pregunta como le puedo hacer para filtrar dos fechas en visual y access con datagridview.. lo que pasa que quiero que al definir un rango de fechas este me devuelva en el datagridview las licencias que van a vencer en ese rango, mi sistema consiste en avisar que licencias de conducir van a vencer dentro del rango que definamos..
ResponderEliminarhola jose
ResponderEliminarpero esto lo respondi en la respuesta anterior
puedes aplicar esta misma tecnica si es que en access no guardas la componente de la hora, si solo dejas fechas puedes asignar el parametro para filtrar
saludos
Hola Leandro muy bueno el blog, tengo una consulta yo estoy usando un datetimepicker para el ingreso de datos de la fecha para el usuario en el sistema que estoy desarrollando para mi tesis, lo que necesito es que como valor maximo de la fecha permitida para ingresar figure 12 años para atras desde el momento en que se está ingresando los datos, es para que solo admita registrar a personas mayores de 12 años, gracias
ResponderEliminarhola Samuel
ResponderEliminarDateTimePicker.MaxDate Property
podrias definir la fecha maxima que vas a permitir al usuario seleccionar
a la fecha que tienes le sumas con el AddYears()
saludos
Este comentario ha sido eliminado por el autor.
ResponderEliminarEres grande Leandro, tus ejemplos me han servido muchisimo de verdad que todo esto me ah facilitado la vida como no tienes idea, es el ejemplo mejor explicado y más sencillo de todos los que eh visto por internet, no dejes de subir tutos! saludos
ResponderEliminarBuenos dias Leandro.
ResponderEliminarTe hago una consulta,estoy realizando una consulta con fechas usando he usando operadores >= <= , también usé BETWEEN.
elcampo fecha tiene tipo de dato datetime en la tabla, cuando ejecuto el procedimiento almacenado desde este rango de fechas me arroja una cifra where fecha >=2014-02-01 and fecha <=2014-06-30 = 1687,pero cuando lo hago mes a mes de febrero a junio de 2014, al realizar la sumatoria por mes la sumatoria da 1946, cabe resaltar que estoy haciendo un distinct O GROUP BY al campo documento de identidad para que solo muestre los valores no repetidos.
este es el procedimiento:
[dbo].[spbuscarReporte]
@DateFrom datetime,
@dateTo datetime
as
SELECT DISTINCT Documento from [Historia_Medicina] WHERE Fecha >= @DateFrom AND Fecha <= @dateTo
hola Orlando
ResponderEliminarno validaste si la hora del campo datetime no deja registros por fuera
en este mismo articulo lo menciono, por eso es que aplico un CONVERT para normalizar la hora
saludos
Hola
ResponderEliminartengo este problema al utilizar fechas , hago la usqueda de dos fechas con dos datetimepicker, la base de datos la tengo en access y eltipo de fecha en haces la tengo como text , el prolema que tengo esque cuando es la misma fecha si me muestra la fecha correcta pero ya cuando pones diferentes fechas ya no ,me dafechas de mas
este es el codigo que tengo
cmd.CommandText = "SELECT * FROM Tabla WHERE Fecha BETWEEN'" + dateTimePicker1.Text + "' AND '" + dateTimePicker2.Text + "'";
que eslo que estoy haciendo mal ?
hola BLITZ
ResponderEliminarsi analizaste este articulo veras que en ningun momento asigno los valores del select uniendolos a un string
debes usar parametros para asignar el datetime, se usa el dateTimePicker1.Value al Parameters del SqlCommand
lo que haces mal es no usar parametros
saludos
tengo esta consulta
ResponderEliminary tambien dos cajas te texto que serian mi rango de fechas y no me muestra nada, ojala que puedas ayudarme
hola
Eliminarno veo la consulta
saludos
Me has salvado la vida con este post Leandro! Gracias! :D
ResponderEliminarBuenas tardes Leandro, tengo un gran inconveniente y se que me puedes ayudar.
ResponderEliminarQuiero filtrar por fechas pero fíjate como tengo mi código:
protected void Button1_Click(object sender, EventArgs e)
{
emptacaDataSetE.entradaalDataTable dt = new emptacaDataSetE.entradaalDataTable();
emptacaDataSetETableAdapters.entradaalTableAdapter da = new emptacaDataSetETableAdapters.entradaalTableAdapter();
DateTime fecha1 = Convert.ToDateTime(Calinicio.SelectedDate.ToShortDateString());
DateTime fecha2=Convert.ToDateTime(Calfinal.SelectedDate.ToShortDateString());
da.FillBynotaing(dt,???????); He aquí mi problema, como hago para que me tome las fechas....
ReportDataSource RD = new ReportDataSource();
RD.Value = dt;
RD.Name = "DataSet1";
ReportViewer1.LocalReport.DataSources.Clear();
ReportViewer1.LocalReport.DataSources.Add(RD);
ReportViewer1.LocalReport.Refresh();
}
Gracias...
hola
EliminarUn primer punto que podria mencionar es que al usar el SelectedDate este devuelve un datetime, si quieras quitarle la componente de la hora hubieras usado Calinicio.SelectedDate.Today
Para que puedas pasar los valores deberias adaptar el FillBynotaing() del dataset tipado, pero me pregunto, sabes como extender un xsd ?
Tutorial 1: Creating a Data Access Layer
alli explica como poder crear metodos con parametros
saludos
ok hermano lo voy a revisar. gracias.. saludos...
ResponderEliminarLeandro: tengo una consulta desde vb 2010 a acces con fecha pero me invierte las fechas. Se que acces trabaja con mm-dd-aaaa pero mi fecha viene de un textbox osea es una cadena (string) . Este es mi codigo
ResponderEliminarFunction Filtro(ByVal busqueda As String, ByVal campo As String) As DataTable
con.Open()
Dim dt As New DataTable
Dim da As New OleDbDataAdapter("SELECT * FROM Ficha WHERE [Fecha de Nacimiento] LIKE #" & busqueda & "#", con)
da.Fill(dt)
con.Close()
Return dt
End Function
Desde ya muchas gracias por tu tiempo.
hola
EliminarDeberias usar parametros en el codigo
Function Filtro(ByVal busqueda As String, ByVal campo As String) As DataTable
Dim dt As New DataTable
Dim query As String = "SELECT * FROM Ficha WHERE [Fecha de Nacimiento] = @fecha"
Dim cmd As New OleDbCommand(query, con)
cmd.Parameters.AddWithValue("@fecha", Convert.ToDateTime(busqueda))
Dim da As New OleDbDataAdapter(cmd)
da.Fill(dt)
Return dt
End Function
saludos
Leandro Buenas tardes
EliminarEste comentario ha sido eliminado por el autor.
ResponderEliminaryo estoy buscando como hacer que un datepicker me de cierto rango de fechas que no me deje seleccionar fechas pasadas solo quiero seleccionar fechas de mañana en adelante y no encuentro como, estoy haciendo esto en windows form solo encuentro como hacerlo en wpf
ResponderEliminarBuen post
ResponderEliminarhola leandro
ResponderEliminartengo una bdd en access, con un campo de fecha, necesito filtrar por año, intente como lo explicaste con datepart, pero me arroja un error de System.Data.OleDb.OleDbException: 'No value given for one or more required parameters.', el nombre del campo ya lo verifique bien, el valor lo tomo de un textbox donde el usuario escribe e año que quiere, intente convertir el valor del textbox a entero pero me marca el mismo error, el string que uso es:
convertido en entero
int anio = Convert.ToInt32(tbanio0.Text);
string cadena = "select * from facturas_vta where DatePart(yyyy,fecha_emision)= "+ anio +"";
espero me puedas ayudar
gracias
Hola leandro me podrias ayudar por favor trato de hacer esto para MVC asp.net pero nose como quedaria mi vista
ResponderEliminardeseo que traiga la info de nombre raza desde hasta pero con un solo dato que seria fecha registro, me urge gracias
ResponderEliminarBuenas tardes como se hace en modelo vista contralador lo hice asi pero no me muestra el resultado que yo quiero:
ResponderEliminarpublic ActionResult Cadena(string fromDate, string toDate)
{
var report = this.GenerateCadenaReport(fromDate, toDate);
var stream = report.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
return File(stream, "application/pdf");
}
private ReportClass GenerateCadenaReport(string fromDate, string toDate)
{
//string fromDate = TextBox1.Text;
var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
var connection = new SqlConnection(connectionString);
var dataTable = new DataTable();
var sql = @"SELECT Estates.EstateId AS IdE, Barns.BarnId AS Id, Nutritions.DateOfBirth AS Fecha, Barns.Name AS Nave, Estates.Name AS Granja,
Nutritions.Jumbo, Nutritions.AAA, Nutritions.AA, Nutritions.A, Nutritions.B, Nutritions.C, Nutritions.Blancos, Nutritions.Pipo,
Nutritions.Rotos, SUM(Nutritions.Jumbo+Nutritions.AAA+Nutritions.AA+Nutritions.A+Nutritions.B+Nutritions.C+Nutritions.Blancos+
Nutritions.Pipo+Nutritions.Rotos) AS Totales
FROM Barns INNER JOIN
Nutritions ON Barns.BarnId = Nutritions.BarnId INNER JOIN
Estates ON Barns.EstateId = Estates.EstateId AND Nutritions.EstateId = Estates.EstateId
WHERE CONVERT(DATETIME, Nutritions.DateOfBirth) >= @fromDate AND CONVERT(DATETIME, Nutritions.DateOfBirth) <= @toDate GROUP BY Estates.EstateId, " +
"Barns.BarnId, Nutritions.DateOfBirth, Barns.Name,Estates.Name, Nutritions.Jumbo,Nutritions.AAA, Nutritions.AA, Nutritions.A, Nutritions.B,Nutritions.C," +
"Nutritions.Blancos,Nutritions.Pipo,Nutritions.Rotos";
try
{
connection.Open();
var command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@fromDate", fromDate);
command.Parameters.AddWithValue("@toDate", toDate);
var adapter = new SqlDataAdapter(command);
adapter.Fill(dataTable);
}
catch (Exception ex)
{
ex.ToString();
HttpContext.Trace.Warn("ERROR: " + ex.ToString());
}
var report = new ReportClass();
report.FileName = Server.MapPath("/Reportes/Cadena.rpt");
report.Load();
report.SetDataSource(dataTable);
return report;
}
Hola Leandro! Aprendí muchisimo gracias a tus Blogs y respuestas en todas las web sobre vb.net... Lo que necesito hacer y no encuentro es lo siguiente: Tengo un datagrid que filtro por un rango de fechas y me funciona perfecto, en el mismo Form tengo un textbox que me filtra por varias columnas y tambien me funciona perfecto!... Pero como hago para que me filtre por el textbox y el rango de fecha todo junto?
ResponderEliminarSaludos!