[RESUELTO] ¿Cómo sacar informes mensuales , osea poder filtrar datos de solo 1 mes ?
#1
Escrito 31 diciembre 2010 - 09:10
#2
Escrito 31 diciembre 2010 - 09:26
Tienes la estructura de tu tabla?
Podrias tener en tu tabla un campo, para el año y tambien otro campo mes, para el mes.
Entonces filtras por esos campos.
Por ejemplo si tienes una tabla llamada:
"PERSONAS", con los campos,
ano
mes
nombre
apellido
cantidad
Y quieres solamente las los registros del año 2010 y del mes de julio.
select *
from personas
where ano = 2010 and mes = 7
obviamente si es para reportes los valores de año y mes tienes que pasarselos al sql con variables.
Espero te sirva, cualquier duda dices...
#3
Escrito 31 diciembre 2010 - 09:29
Así lo haría en Firebird.
SELECT SUM(ventas-gastos) FROM tutabla WHERE EXTRACT(YEAR FROM campofecha) = 2010 AND EXTRACT(MONTH FROM campofecha) = 12
Salud OS
#4
Escrito 31 diciembre 2010 - 10:02
Muchas gracias , no lo pensé antes de esa manera está bien fácil solo basta con hacer las consultas correspondientes.Con una consulta sql.
Tienes la estructura de tu tabla?
Podrias tener en tu tabla un campo, para el año y tambien otro campo mes, para el mes.
Entonces filtras por esos campos.
Por ejemplo si tienes una tabla llamada:
"PERSONAS", con los campos,
ano
mes
nombre
apellido
cantidad
Y quieres solamente las los registros del año 2010 y del mes de julio.
select *
from personas
where ano = 2010 and mes = 7
obviamente si es para reportes los valores de año y mes tienes que pasarselos al sql con variables.
Espero te sirva, cualquier duda dices...
#5
Escrito 02 enero 2011 - 09:46
adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as total from Clientes where Mes = 12 and Año='+combobox2.Text; adoquery3.Open;
Esta es la consulta que realizo luego, sin embargo la comenté y el problema sigue, anteriormente me ponía que el campo id not found y así sucesivamente,
(NOTA)el campo que sumo es numérico.
edit3.Text:=adoquery3.FieldByName('total').AsString;
#6
Escrito 02 enero 2011 - 09:57
En lugar de usar FieldbyName(nombrecampo) usa Fields[numcampo]
adoquery3.SQL.Clear; adoquery3.SQL.Text := 'select sum(Costo) from Clientes where Mes = 12 and Año='+combobox2.Text; adoquery3.Open;
Y lo obtienes de esta forma
edit3.Text := adoquery3.Fields[0].AsString;
Salud OS
#7
Escrito 02 enero 2011 - 09:59
Salud OS
#8
Escrito 02 enero 2011 - 11:09
Lo que si noto es que el año se pasa como un string, a diferencia del més que es un dato numérico. Al menos eso da a entender la consulta que nos ha indicado Master23.
Lo de nombrar a campos con Ñ estoy de acuerdo, eso puede ser motivos de problemas en algunos motores de datos.
Por otro lado, y no es un detalle menor, sería de muchísima ayuda si nos pudieras comentar los errores textuales que te salen y la línea de código. En especial cuando uno dice "y así sucesivamente". Esto me da a entender de que te aparecieron otros errores más...
No se porqué Master23 te estás volviendo más escueto en comentar tus dudas... tu eras más expresivo y detallista al explicarte.
Algo me dice que el problema se debe a que utilizas el mismo ADOQuery para realizar más de una consulta. ¿Por casualidad no habrás creado los campos de manera persistente?
Ese sería un buen motivo para el que recibieses un error como "ID not found" cuando estás lanzando una consulta que no regresa un campo con dicho nombre... de hecho sólo deberías estar recibiendo un solo registro, de un sólo campo.
Si nos pudieras más información del caso quizá podríamos ver en donde está el problemilla.
Saludos,
#9
Escrito 03 enero 2011 - 11:35
Pues no veo el porqué no pueda ser posible la lectura del campo mediante el nombre, o alias como en este caso, y se deba recurrir a Fields[] en lugar de FieldByName().
Lo que si noto es que el año se pasa como un string, a diferencia del més que es un dato numérico. Al menos eso da a entender la consulta que nos ha indicado Master23.
Lo de nombrar a campos con Ñ estoy de acuerdo, eso puede ser motivos de problemas en algunos motores de datos.
Por otro lado, y no es un detalle menor, sería de muchísima ayuda si nos pudieras comentar los errores textuales que te salen y la línea de código. En especial cuando uno dice "y así sucesivamente". Esto me da a entender de que te aparecieron otros errores más...
No se porqué Master23 te estás volviendo más escueto en comentar tus dudas... tu eras más expresivo y detallista al explicarte.
Algo me dice que el problema se debe a que utilizas el mismo ADOQuery para realizar más de una consulta. ¿Por casualidad no habrás creado los campos de manera persistente?
Ese sería un buen motivo para el que recibieses un error como "ID not found" cuando estás lanzando una consulta que no regresa un campo con dicho nombre... de hecho sólo deberías estar recibiendo un solo registro, de un sólo campo.
Si nos pudieras más información del caso quizá podríamos ver en donde está el problemilla.
Saludos,
Delphius , el problema que me salía anteriormente era el de id not found estoy usando adoquery, eliminé del query el campo id porque no lo estaba utilizando, y luego pasó al siguiente campo nombre not found y así sucesivamente , luego por algún motivo dejo de mostrar ese error y mostrar el siguiente no coinciden los tipos de datos en la expresión de los tipos, sin embargo el campo que estoy sumando es numérico por lógica no creo que debería haber este tipo de error la consulta la veo correcta ,el tipo de dato digamos que es numérico y estoy realizando la suma de estos campos para mostrar un total en el Edit correspondiente el porqué del error aun me es una incógnita.
#10
Escrito 04 enero 2011 - 10:10
¿Cómo está diseñada tu tabla? ¿Que campos y tipos de datos son?
¿Podemos ver tu código?
¿Utilizas el mismo ADOQuery para otras consultas? ¿Tienes otros ADOQuerys que lancen consultas relacionadas y/o similares en las que intervenga la tabla Clientes?
¿Cierras el dataset antes de lanzar una nueva consulta? ¿Te aseguraste de haber eliminado todos los campos persistentes y sus definiciones?
La verdad es que nos las estás poniendo difícil ayudarte Marter23. Sin tener mayor información de lo que haces y tienes en tu código va a ser complicado guiarte.
En algún lado está el problema, pero con la escasa información que nos das lo único que podemos hacer es adivinar. Con todo respeto Master23, debes dejar de ser tan escueto y secote al explicarte.
No nos dejemos llevar por un "por lógica no creo". Vayamos a por lo seguro.
Saludos,
#11
Escrito 04 enero 2011 - 04:10
project aplicacion.exe raised exception class EDatabaseError adoquery3: field id not found, esta es la excepción que produce el programa al presionar el botón que ejecuta la consulta dependiendo del case.¿Cuál es el error textual que te sale ahora?
¿Cómo está diseñada tu tabla? ¿Que campos y tipos de datos son?
¿Podemos ver tu código?
¿Utilizas el mismo ADOQuery para otras consultas? ¿Tienes otros ADOQuerys que lancen consultas relacionadas y/o similares en las que intervenga la tabla Clientes?
¿Cierras el dataset antes de lanzar una nueva consulta? ¿Te aseguraste de haber eliminado todos los campos persistentes y sus definiciones?
La verdad es que nos las estás poniendo difícil ayudarte Marter23. Sin tener mayor información de lo que haces y tienes en tu código va a ser complicado guiarte.
En algún lado está el problema, pero con la escasa información que nos das lo único que podemos hacer es adivinar. Con todo respeto Master23, debes dejar de ser tan escueto y secote al explicarte.
No nos dejemos llevar por un "por lógica no creo". Vayamos a por lo seguro.
Saludos,
aquí el código que llevo hasta ahora.
procedure TForm1.FormCreate(Sender: TObject); varConStr,bd:string; begin //Inicio de carga de imágenes para la aplicación.image1.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'imgs/background.png'); image2.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'imgs/background.png'); image3.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'imgs/background.png'); image4.Picture.LoadFromFile(ExtractFilePath(Application.ExeName)+'imgs/background.png'); //*********************** bd:=ExtractFilePath(Application.ExeName)+'bd/jjmobile.mdb';ConStr := 'Provider=Microsoft.Jet.OLEDB.4.0;'+ 'Data Source='+bd+';'+ 'Persist Security Info=False;'+ 'Jet OLEDB:Database Password=Master23'; Adoconnection1.ConnectionString:=ConStr;Adoconnection1.Open;//Activar querys y tablas de la bd. adoquery1.Active:=true; adoquery2.Active:=true; adoquery3.Active:=true; end; procedure TForm1.Button13Click(Sender: TObject); begin //Validaciones. if (combobox1.Text = '') and (combobox2.Text = '') then showmessage('Debe seleccionar mes y año para continuar') else if combobox1.Text = '' then showmessage('Debe seleccionar mes para poder obtener resultados') else if combobox2.Text = '' then showmessage('Debe seleccionar un año para poder obtener resultados') else if (combobox1.Text <> '')and (combobox2.Text <> '') then begin //Consultas para sumatorias de campos de ganancias. case combobox1.ItemIndex of 0:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "1" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 1:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "2" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 2:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "3" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 3:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "4" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 4:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "5" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 5:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "6" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 6:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "7" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 7:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "8" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 8:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "9" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 9:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "10" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 10:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = "11" and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; 11:begin adoquery3.SQL.Clear; adoquery3.SQL.Text:='select sum(Costo) as F_COSTO from Clientes where Mes = 12 and Año='+'"'+combobox2.Text+'"'; adoquery3.Open; end; end; //Asignar resultado de la consulta. //edit3.Text:=adoquery3.FieldByName('F_COSTO').AsString; end; end;
El campo que intento sumar es el de costos
cuenta con 11 campos
id llave primaria
nombre texto
direccion texto
Descripcion memo
Costo númerico
Fecha_de_entrega tipo fecha
Fecha_de_salida tipo fecha
Mes tipo texto
año tipo texto.
todo esto estoy usando sin embargo al ejecutar el botón para las consultas resulta en el una excepción que les mencione arriba .
#12
Escrito 04 enero 2011 - 04:23
Saludos!
#13
Escrito 04 enero 2011 - 04:36
Lo que veo del código puedo decir que en al momento de crear el form1 se está activando el ADOQuery3, que es equivalente a ejecutar la instrucción SQL que esté en él.
Y luego se lo reutiliza a este ADOQuery para generar otras consultas, dependiendo del valor.
Si no hubiera campos persistentes no debería haber problemas alguno con esto ya que al cerrar el dataset se liberarían los campos automáticos que ha creado el ADOQuery. No sucede lo mismo cuando hay campos persistentes... La solución debería ser cerrar borrar esos campos persistentes una vez cerrado.
Ya lo había dicho yo antes pero parece que no se me ha leído bien: hay un problema de campos persistentes. Un "ID not found" no aparece por arte de magia.
Por otro lado, ese código se puede mejorar. Lo más evidente: esos ADOQuery3.Clear y .Open puede ir fácilmente fuera del case.
En segundo lugar, lo recomendable sería que el campo Mes y Año fueran numéricos. Esto llevaría otra ventaja adicional... ya no sería necesario un case para genera la consulta. Si la opción es numérica y aprovechando el uso de parámetros se puede hacer una consulta SQL de esta forma:
SELECT ... FROM ... WHERE (Mes :MesElegido) AND (Anio = ...)
Y luego pasar como dato para el parámetro el propio valor del ItemIndex.
Saludos,
#14
Escrito 04 enero 2011 - 04:41
Disculpa mi ignorancia Delphius, pero es que no entiendo a que refieres con campos persistentes,por ejemplo si elimino el campo id del query automáticamente el error pasa al siguiente campo por ejemplo nombre not found y la excepción correspondiente.Me robaste las palabras felipe. Intuyo que hay campos persistentes o definiciones de campo asociadas a éste.
Lo que veo del código puedo decir que en al momento de crear el form1 se está activando el ADOQuery3, que es equivalente a ejecutar la instrucción SQL que esté en él.
Y luego se lo reutiliza a este ADOQuery para generar otras consultas, dependiendo del valor.
Si no hubiera campos persistentes no debería haber problemas alguno con esto ya que al cerrar el dataset se liberarían los campos automáticos que ha creado el ADOQuery. No sucede lo mismo cuando hay campos persistentes... La solución debería ser cerrar borrar esos campos persistentes una vez cerrado.
Ya lo había dicho yo antes pero parece que no se me ha leído bien: hay un problema de campos persistentes. Un "ID not found" no aparece por arte de magia.
Por otro lado, ese código se puede mejorar. Lo más evidente: esos ADOQuery3.Clear y .Open puede ir fácilmente fuera del case.
En segundo lugar, lo recomendable sería que el campo Mes y Año fueran numéricos. Esto llevaría otra ventaja adicional... ya no sería necesario un case para genera la consulta. Si la opción es numérica y aprovechando el uso de parámetros se puede hacer una consulta SQL de esta forma:
sql
SELECT ... FROM ... WHERE (Mes :MesElegido) AND (Anio = ...)
Y luego pasar como dato para el parámetro el propio valor del ItemIndex.
Saludos,
(NOTA) al iniciar el form hago una consulta con el adoquery3 , seleccionar todos los campos de esa tabla, clientes.
#15
Escrito 04 enero 2011 - 04:49
Saludos!
#16
Escrito 04 enero 2011 - 04:50
Si felipe,conecto el dbgrid con este.Ahora otra duda, ¿el adoquery3 es el mismo componente con el que te conectas a la tabla Cliente?
Saludos!
#17
Escrito 04 enero 2011 - 04:59
Si felipe,conecto el dbgrid con este.
Ahora otra duda, ¿el adoquery3 es el mismo componente con el que te conectas a la tabla Cliente?
Saludos!
Creo que ya podemos ir dando solución a esto.
Ya tienes conectado ese componente, pero estas alterando su consulta, este te intenta retornar el valor F_COSTO cuando en realidad debe hacerlo con todos los campos de la tabla, por eso te dice "field ID not found", porque efectivamente no halla ese valor entre la respuesta del query.
La solución es usar un query auxiliar para hacer esta consulta y te recomiendo la sugerencia de Delphius.
Por otra parte es hacer un filtro (no estoy seguro si en ADO sea igual), aunque esto no garantiza un buen rendimiento a esta consulta.
Saludos!
#18
Escrito 04 enero 2011 - 05:05
Efectivamente ese era el problema que no me permitía avanzar en este proyecto, ya está solucionado, gracias Felipe y Delphius por su gran ayuda, ya me funciona correctamente el utilizar la consulta.
Si felipe,conecto el dbgrid con este.
Ahora otra duda, ¿el adoquery3 es el mismo componente con el que te conectas a la tabla Cliente?
Saludos!
Creo que ya podemos ir dando solución a esto.
Ya tienes conectado ese componente, pero estas alterando su consulta, este te intenta retornar el valor F_COSTO cuando en realidad debe hacerlo con todos los campos de la tabla, por eso te dice "field ID not found", porque efectivamente no halla ese valor entre la respuesta del query.
La solución es usar un query auxiliar para hacer esta consulta y te recomiendo la sugerencia de Delphius.
Por otra parte es hacer un filtro (no estoy seguro si en ADO sea igual), aunque esto no garantiza un buen rendimiento a esta consulta.
Saludos!
#19
Escrito 04 enero 2011 - 05:16
Los campos persistentes, son campos creados explícitamente por un dataset. Estos quedan alojados en el query de forma permanente (de allí el nombre persistentes) y la ventaja que estos ofrecen es que no se necesita de trabajar de forma intermedia con el query, table o cualquier dataset a los que pertenezca.
Cuando uno crea la consulta en tiempo de ejecución, por medio de código, con algo como:
ADOQuery1.SQL := 'select ... ';
El ADOQuery1 internamente crea los campos necesarios para trabar con ellos. ¿Que campos? Los campos que regrese el select. Si tu select regresa los campos ID, Nombre y Fecha por ejemeplo... el query creará 3 campos con idénticos nombres.
Como estos campos quedan en memoria, es necesario hacer esto:
ADOQuery1.FieldByName().As.... := ....;
En tiempo de edición también podemos crear SQL, aprovechando el editor SQL. Y como extra, crear explícitamente los campos. Si haces doble clic sobre tu ADOQuery deberías ver el editor de campos persistentes. Observarás la lista de campos disponibles y los tu tengas creado (si es que hay un consulta válida en la propiedad SQL).
Cuando creas esos campos deberías ver algo como esto en tu unidad:
IBTransaction1: TIBTransaction; IBTable1ID: TIntegerField; IBTable1NOMBRE: TIBStringField; IBTable1FECHA: TDateTimeField; IBTable1CANTIDAD: TIBBCDField; IBTable1MONEDA: TIBBCDField; IBTable1FECHA1: TDateField; IBTable1INTPEQUE: TSmallintField; IBTable1HORA: TTimeField;
En mi ejemplo trabajo con los componentes IBX. Es lo de menos, puedes identificar los campos persistentes porque de forma automática se nombran siguiendo la siguiente regla: NombreDataSet + NombreCampo.
En mi caso, se aprecia que se trata de un IBTable1 que tiene los campos NOMBRE, FECHA, CANTIDAD entre otros.
Tu deberías tener algo como eso:
ADOQuery3ID: .... ADOQuery3....
La ventaja de contar con estos campos persistentes es que te evitas estar haciendo FieldByName() o Fields[].... Ahora puedes trabajar de forma directa, como por ejemplo basado en mi muestra:
IBTable1CANTIDAD.Value := 123456;
Naturalmente, para permitir eso mi Table1 debe estar en modo de edición. Por ello antes de hacer cualquier operación sobre los campos deberé hacer algo como:
IBTable1.Insert; // voy a insertar registro // aqui trabajo con los campos IBTable1.Post; // confirmo
El problema es que si borras esos campos haces la mitad del trabajo.... además de esos campos persistente el Query almacena definiciones de éstos. Estas definiciones las puedes ver si haces clic en FieldDefs en el Object Tree View.
Ahora necesitarás eliminar sus definiciones.
En vista a que es complicado explicar esto en simples palabras, una imagen quizá sirva de ayuda para representar lo que estoy diciendo.
Archivos adjuntos
#20
Escrito 04 enero 2011 - 05:35
Saludos!