Asunto: Contar filas de un DBGrid y comparar un campo especifico
Hola!
Tengo una TtablaMateria, donde tengo los campos de IdM, CodigoMateria,NombreMateria, "Calificacion", etc.... y estas ya estan guardadas y se visualizan en un DBGrid2.
Donde en calificacion puede aparecer la informacion de: Aprobado, Reprobado o Ninguno. Y en IdM solo es contador.
Ahora lo que quiero es, contar, cuantas Aprobados , Reprobados y SinNota existen de las materias que se programaron, que esta informacion se encuentra en el DBGrid2?
Intente realizar este codigo:
Código:
For i:=1 to Tacademico['IdM'] do
begin
Kon:=Kon+1;
if Facademico.Tmateria['CalificacionM']='Aprobado'then A:=A+1
else
begin
if Facademico.Tmateria['CalificacionM']='Reprobado'then R:=R+1
else N:=N+1;
end;
end;
Donde Kon es la variable para saber cuantas materias se programaron, y esas materias estan guardadas en el DBGrid2.
Pero con este codigo solo me da como resultado...por decir en el DBGrid2 de Materias tengo 4 materias programas y seleccionado toda la fila "3"
Donde :
IdM "1" Calificacion "Aprobado"
IdM "2" Calificacion "Aprobado"
IdM "3" Calificacion "Reprobado"
IdM "4" Calificacion "SinNota"
Y cuando ejecuto la sentencia pues me da como resultado TtotalProgramadas=3, Aprobadas=0, Reprobadas=3 y SinNota=0.
Cuando deberia dar de resultado: TtotalProgramadas=4, Aprobadas=2, Reprobadas=1 y SinNota=1.
Y por decir esta seleccionado en el DBGrid2 la fila 2.
Y cuando ejecuto la sentencia pues me da como resultado TtotalProgramadas=2, Aprobadas=2, Reprobadas=0 y SinNota=0.
Cabe notar que estos resultados muestran en otros DBEdits.
Como te daras cuenta, pues solo cuenta en el mismo lugar nada mas...
Como seria el codigo para contar y comparar cada campo? Cual la solucion?
Gracias!
Publicado:
Mie Mar 24, 2010 8:31 pm
alonsojpd Administrador/Moderador
Registrado: Sep 16, 2003 Mensajes: 2687
Asunto: Re: Contar filas de un DBGrid y comparar un campo especifico
Anuncios
Sizne escribió:
Hola!
Tengo una TtablaMateria, donde tengo los campos de IdM, CodigoMateria,NombreMateria, "Calificacion", etc.... y estas ya estan guardadas y se visualizan en un DBGrid2.
Donde en calificacion puede aparecer la informacion de: Aprobado, Reprobado o Ninguno. Y en IdM solo es contador.
Ahora lo que quiero es, contar, cuantas Aprobados , Reprobados y SinNota existen de las materias que se programaron, que esta informacion se encuentra en el DBGrid2?
Intente realizar este codigo:
Código:
For i:=1 to Tacademico['IdM'] do
begin
Kon:=Kon+1;
if Facademico.Tmateria['CalificacionM']='Aprobado'then A:=A+1
else
begin
if Facademico.Tmateria['CalificacionM']='Reprobado'then R:=R+1
else N:=N+1;
end;
end;
Donde Kon es la variable para saber cuantas materias se programaron, y esas materias estan guardadas en el DBGrid2.
Pero con este codigo solo me da como resultado...por decir en el DBGrid2 de Materias tengo 4 materias programas y seleccionado toda la fila "3"
Donde :
IdM "1" Calificacion "Aprobado"
IdM "2" Calificacion "Aprobado"
IdM "3" Calificacion "Reprobado"
IdM "4" Calificacion "SinNota"
Y cuando ejecuto la sentencia pues me da como resultado TtotalProgramadas=3, Aprobadas=0, Reprobadas=3 y SinNota=0.
Cuando deberia dar de resultado: TtotalProgramadas=4, Aprobadas=2, Reprobadas=1 y SinNota=1.
Y por decir esta seleccionado en el DBGrid2 la fila 2.
Y cuando ejecuto la sentencia pues me da como resultado TtotalProgramadas=2, Aprobadas=2, Reprobadas=0 y SinNota=0.
Cabe notar que estos resultados muestran en otros DBEdits.
Como te daras cuenta, pues solo cuenta en el mismo lugar nada mas...
Como seria el codigo para contar y comparar cada campo? Cual la solucion?
Gracias!
Si te he entendido bien, quieres recorrer toda la tabla e ir sumando las variables según los valores del campo "Facademico.Tmateria['CalificacionM']".
Para recorrer los registros de una tabla tienes dos opciones:
1. Ejecutar un "while not TtablaMateria.Eof do..."
2. Hacerlo con una consulta SQL a parte (recomendable). Esto es más eficiciente.
Para el primer caso sería algo así:
Código:
TtablaMateria.First;
while not TtablaMateria.Eof do
if TtablaMateria['CalificacionM']='Aprobado'then
A:=A+1
else
begin
if TtablaMateria['CalificacionM'] = 'Reprobado' then
R:=R+1
else
N:=N+1;
end;
TtablaMateria.Next;
end;
Más o menos sería algo así, ten en cuenta que no sé el nombre de tus campos ni de tus tablas ni de tus formularios, es un ejemplo de cómo recorrer los registros de una tabla.
Además, si tienes enlazado el TtablaMateria a un DBGrid o a componentes visuales, antes de ejecutar lo anterior es recomendable ejecutar esto:
TtablaMateria.DisableControls;
y después:
TtablaMateria.EnableControls;
Esto hace que el proceso sea un poco más rápido, si no lo haces verás como en la pantalla se mueven los registros y eso no queda muy profesional.
De ahí que te recomendemos el segundo método, es mucho más eficiente. Te ponemos un ejemplo, aunque las tablas y los campos no son los mismos, te sirve como ejemplo cambiando la tabla, el nombre de los campos y el nombre de las variables:
Por un lado el procedimiento que te devolverá los datos:
Código:
procedure rutaDificultad (var media : integer;
var baja : integer; var alta : integer);
begin
md.tc.Close;
md.tc.SQL.Add('select dificultad from nuke_biker_etapa');
md.tc.Open;
media := 0;
baja := 0;
alta := 0;
while not md.tc.Eof do
begin
if md.tc.FieldByName('dificultad').AsString = 'Media' then
media := media + 1
else
if md.tc.FieldByName('dificultad').AsString = 'Baja' then
baja := baja + 1
else
alta := alta + 1;
md.tc.Next;
end;
end;
Un ejemplo de llamada a este procedimiento (desde un botón o desde donde quieras):
* "md" es un módulo de datos donde tenemos todos los TTable, TQuery, etc.
* "tc" es un componente de tipo TQuery (para ejecutar consultas SQL).
Por lo tanto "md.tc" hace referencia a este TQuery del módulo de datos.
El "TQuery" puede estar en otro formulario, en el mismo formulario o en un módulo de datos. Es recomendable que esté en un módulo de datos (DataModule).
Nota: el segundo método aún puede ser mejorado en cuanto a eficiencia si en vez de ejecutar un "SELECT ... FROM ..." ejecutas un:
select nombre_campo, count(*) Numero
from tabla
group by nombre_campo
De esta forma evitarás tener que recorrer toda la tabla, pues la consulta SQL ya te mostrará el número de cada tipo de registro. En este caso varía un poco el código del procedimiento.
Publicado:
Mie Mar 24, 2010 9:52 pm
Sizne Magnífico usuario
Registrado: Oct 16, 2006 Mensajes: 46
Asunto:
Hola!
Antes que nada agradecerte por el seguimiento Graaaacias!!! Me entendiste TODO a la perfección.
1.- Para la busqueda coloqué la primera opcion que me diste, este es el código:
Código:
TtablaMateria.DisableControls;
TtablaMateria.First;
while not TtablaMateria.Eof do
if TtablaMateria['CalificacionM']='Aprobado'then
A:=A+1
else
begin
if TtablaMateria['CalificacionM'] = 'Reprobado' then
R:=R+1
else
N:=N+1;
end;
TtablaMateria.Next;
end;
TtablaMateria.EnableControls;
Funciona el codigo muy bien! La pregunta es TtablaMateria.EnableControls y TtablaMateria.DisableControls; debo colocar tal como muestro en el codigo? O donde debo colocarlo? Si es que es como lo estoy colocando, pues comentarte que aun me muestra el conteo que realiza y si, no se ve bien.
Y si TTablaMateria lo tengo enlazado a un DBGrid.
2.- Realizando la segunda opcion, creo un procedimiento privado... luego como usaria el query creado en el DataModule o en el Form...la pregunta es...en el Query en sus propiedades (SQL|(Strings)) que código coloco? Solo una simple seleccion?
Código:
Select*
From TTablaMaterias
3.- Para el ultimo caso que me dices, entendi q el procedimiento cambiaria...
select nombre_campo, count(*) as Numero
from tabla
group by nombre_campo
Imagino q falta el "as", o me equivoco? Y este codigo donde lo coloco? En el Query imagino. o donde? Luego que colocaria en Delphi esto?...
Código:
......//solo un ejemplo de
md.Query.Close;
md.Query.SQL.Add('//que tendria q colocar aqui.....');
md.Query.Open
En todo caso quisiera saber mas sobre las consultas/Querys, ya que debo realizar varias consultas...
Gracias por tu rapida respuesta.
Graaaaaaaaacias
Publicado:
Vie Mar 26, 2010 6:04 am
alonsojpd Administrador/Moderador
Registrado: Sep 16, 2003 Mensajes: 2687
Asunto:
Sizne escribió:
1.- Para la busqueda coloqué la primera opcion que me diste, este es el código:
Código:
TtablaMateria.DisableControls;
TtablaMateria.First;
while not TtablaMateria.Eof do
if TtablaMateria['CalificacionM']='Aprobado'then
A:=A+1
else
begin
if TtablaMateria['CalificacionM'] = 'Reprobado' then
R:=R+1
else
N:=N+1;
end;
TtablaMateria.Next;
end;
TtablaMateria.EnableControls;
Funciona el codigo muy bien! La pregunta es TtablaMateria.EnableControls y TtablaMateria.DisableControls; debo colocar tal como muestro en el codigo? O donde debo colocarlo? Si es que es como lo estoy colocando, pues comentarte que aun me muestra el conteo que realiza y si, no se ve bien.
Y si TTablaMateria lo tengo enlazado a un DBGrid.
Efectivamente, el código está bien. Te explico lo que hace el DisableControls: si tienes un TTable o TQuery enlazado a un DBGrid (como es tu caso) o a otros componentes visuales (que muestran los datos de los registros en el formulario) y ejecutas un proceso que recorre todos los registros del TTable o TQuery (como también es tu caso con el "while not ...eof do" y no ejecutas antes un DisableControls, verás que en la pantalla se mueven los registros y esto, como te he comentado, no queda muy profesional. El usuario vería moverse los registros en la pantalla al pulsar un botón (o lo que sea). El DisableControls desactiva los controles visuales conectados al DataSource que a su vez está conectado al TTable. De esta forma ganarás también en velocidad. Luego, tras el "while..." hay que volver a activar los componentes con el EnableControls.
En resumen, el código sí lo tienes bien.
Sizne escribió:
2.- Realizando la segunda opcion, creo un procedimiento privado... luego como usaria el query creado en el DataModule o en el Form...la pregunta es...en el Query en sus propiedades (SQL|(Strings)) que código coloco? Solo una simple seleccion?
Código:
Select*
From TTablaMaterias
En el Query pondrías la selección que necesites, por ejemplo:
Código:
nombreDataModule.NombreQuery.Close;
nombreDataModule.NombreQuery.SQL.Clear;
nombreDataModule.NombreQuery.SQL.Add('select * from nombre_tabla_materias');
nombreDataModule.NombreQuery.Open;
Con lo anterior obtendrías todos los campos de la tabla "nombre_tabla_materias" y todos los registros en el "NombreQuery".
El SQL tiene la ventaja de que puedes sacar casi cualquier consulta con los datos que desees, por ejemplo (sin saber el nombre de tus campos):
Código:
nombreDataModule.NombreQuery.Close;
nombreDataModule.NombreQuery.SQL.Clear;
nombreDataModule.NombreQuery.SQL.Add('select nombre from nombre_tabla_materias');
nombreDataModule.NombreQuery.SQL.Add('where nombre like "%Alonso%"');
nombreDataModule.NombreQuery.Open;
Lo anterior te mostrará el campo "nombre" y todos los registros cuyo campo "nombre" contenga la palabra "Alonso".
Sizne escribió:
3.- Para el ultimo caso que me dices, entendi q el procedimiento cambiaria...
select nombre_campo, count(*) as Numero
from tabla
group by nombre_campo
Imagino q falta el "as", o me equivoco? Y este codigo donde lo coloco? En el Query imagino. o donde? Luego que colocaria en Delphi esto?...
Código:
......//solo un ejemplo de
md.Query.Close;
md.Query.SQL.Add('//que tendria q colocar aqui.....');
md.Query.Open
Efectivamente, como te he comentado antes, la consulta SQL va en la propiedad "SQL" del Query. Y sí, es posible que para tu caso, que creo que utilizas Microsoft SQL Server necesites el "as" para el alias del nombre del campo en SQL. Me explico, la siguiente consulta SQL:
Código:
md.Query.Close;
md.Query.SQL.Add('select count(*) as Numero_Registros');
md.Query.Open
Te vale para SQL Server pero no para otros motores de base de datos como MySQL donde el "as" no está soportado.
Publicado:
Lun Mar 29, 2010 9:45 am
Sizne Magnífico usuario
Registrado: Oct 16, 2006 Mensajes: 46
Asunto:
Hola!
Como siempre gracias por tu rápida respuesta.
Le cuento que coloque:
No me expliqué bien. Cuando realizo el conteo(haciendo un click en un boton), sin importar en cual fila del DBGrid2 este seleccionado, me aparece esa fila seleccionado y la ultima fila seleccionado. Quizás algo mas tengo que activar o desactivar?
//este era para saber cuantos Aprobados, Reprobados...habia.
Por otra parte en otro DBGrid1 en Events en la opcion OnCellClick coloqué el mismo código antes de realizar un while y al finalizar idem al anterior...//esto para q me cuente cuantas materias lleva un X alumno.
DBgrid1: muestra todos los datos de los alumnos.(Tuniversitarios)
DBGrid2: Muestra todas las materias de un X alumno.(TMaterias)
DBGrid3: Muestra la cantidad de aprobados, reprobados...de un X alumno.(Tseguimiento)
Todo bien esta parte y estan realcionados por el MasterSource...MasterFields.
Solo que me aparece los conteos y no se ven bien....
Por otra parte:
Código:
....
nombreDataModule.NombreQuery.SQL.Add('where nombre like "%Alonso%"');
...
En esta parte, en cuenta de Alonso, en vez de escribirla, quisiera seleccionar por medio de campo un Edit1 o un DBedit y me aparezca todos los datos del campo seleccionado, por decir todos aquellos que pertenezcan al pais "Peru" si selecciono el campo PAIS con la informacion PERU. Esta informacion que aparezca en un DBgrid.
gracias!
Publicado:
Lun Mar 29, 2010 2:14 pm
alonsojpd Administrador/Moderador
Registrado: Sep 16, 2003 Mensajes: 2687
Asunto:
Sizne escribió:
Por otra parte:
Código:
....
nombreDataModule.NombreQuery.SQL.Add('where nombre like "%Alonso%"');
...
En esta parte, en cuenta de Alonso, en vez de escribirla, quisiera seleccionar por medio de campo un Edit1 o un DBedit y me aparezca todos los datos del campo seleccionado, por decir todos aquellos que pertenezcan al pais "Peru" si selecciono el campo PAIS con la informacion PERU. Esta informacion que aparezca en un DBgrid.
gracias!
Para este caso que comentas, puedes usar parámetros, te explicamos cómo usarlos en el siguiente código de ejemplo:
Código:
dataModule.Query.Close;
dataModule.Query.SQL.Clear;
dataModule.Query.SQL.Add ('select * from nombretabla');
dataModule.Query.SQL.Add('where nombre like :pDato');
dataModule.Query.ParamByName('pDato').DataType := ftString;
dataModule.Query.ParamByName('pDato').AsString := "%" + nombreTedit.Text + "%";
dataModule.Query.Open;
Si utilizas el "ftString" para indicar el tipo de datos del parámetro (es muy recomendable) debes añadir al "Uses" del formulario la unidad "db".
Puede publicar nuevos temas en este foro No puede responder a temas en este foro No puede editar sus mensajes en este foro No puede borrar sus mensajes en este foro No puede votar en encuestas en este foro
Visita nuestro nuevo sitio web con programas y contenidos actualizados: Proyecto A