Sistema de Asistencia
#1
Escrito 12 abril 2013 - 03:27
#2
Escrito 12 abril 2013 - 03:47
Aqui tienes un programa de asistencia completo.
Trabaja con base de datoes access tambien.
Saludos
Archivos adjuntos
#3
Escrito 12 abril 2013 - 03:50
#4
Escrito 12 abril 2013 - 03:56
El programa toma la foto del empleado.
Necesitas un componente para ese fin.
Aqui lo dejo, solo instalalo y ya.
Saludos
Archivos adjuntos
#5
Escrito 12 abril 2013 - 04:52
Necesito calcular horas extras, dias trabajados e inasistencias... Pero la base de datos almacena hora y fecha como una variable datetime, por lo cual me toma todo el valor en un solo campo
Esta es la captura de la base de datos
con este codigo logro hacer un filtro de fecha y hora, ya que la hora la establezco en dtpicker
ADOQuery1.Active:= False; ADOQuery1.SQL.Text:= 'SELECT distinct * From V_Record'; ADOQuery1.SQL.Add('where (Checktime between :hora1 and :hora2)'); ADOQuery1CheckTime.DisplayFormat := 'dd/mm/yyyy'; ADOQuery1.Parameters.ParamByName('hora1').Value := FormatDateTime('dd,mm,yyyy', horaent1.Time); ADOQuery1.Parameters.ParamByName('hora2').Value := FormatDateTime('dd,mm,yyyy', horasal1.Time); ADOQuery1.Active:= True;
lo que quiero es mediante filtros separar hora de entrada y salida... a menos que exista otro metodo
#6
Escrito 12 abril 2013 - 05:15
Bueno, espero que me pueda explicar sobre mi humilde sugerencia y forma de ver las reglas del negocio.
Tienes en una tabla todas las asistencias, tanto entradas como salidas, salidas intermedias y entradas intermedias, porque puede que un empleado tenga un horario mixto de trabajar.
necesitas generar una tarjeta o kardex de asistencia por cada empleado de tal manera que te quede
empleado:
fecha dia. E S
dd/mm/aaaa hh:nn:SS hh:nn:ss
dd/mm/aaaa hh:nn:SS hh:nn:ss
dd/mm/aaaa hh:nn:SS hh:nn:ss
o en su defecto
empleado:
fecha dia. E SI EI S
dd/mm/aaaa hh:nn:ss hh:nn:ss hh:nn:ss hh:nn:ss
dd/mm/aaaa hh:nn:ss hh:nn:ss hh:nn:ss hh:nn:ss
dd/mm/aaaa hh:nn:ss hh:nn:ss hh:nn:ss hh:nn:ss
esto es correcto...?
si es asi
la solucion esta en el horario, turno, o configuración que tenga establecida el empleado, por un lado, o tomar las asistencias por pares. pero el problema es si el empleado se le olvido marcar alguna. es por eso que me voy mas por la primer opcion.
creas un filtro para traer la entrada, como es esto.
creas una consulta donde preguntes por la asistencia que se acerque mas a la hora de entrada, esto es manejando una tolerancia. hora de entrada + ó - tolerancia
creas un filtro para traer la salida, como es esto.
creas una consulta donde preguntes por la asistencia que se acerque mas a la hora de salida, esto es manejando una tolerancia. hora de salida + ó - tolerancia
espero haberme explicado y que mi comentario sea lo que esperas y si es así o si salieron mas dudas, con gusto puedo ayudarte.
#7
Escrito 12 abril 2013 - 05:24
#8
Escrito 12 abril 2013 - 05:34
#9
Escrito 13 abril 2013 - 07:10
#10
Escrito 15 abril 2013 - 08:05
Si no mal recuerdo cuando agregas el componente ClientDataSet desde el grupo "Data Access", en su propiedad FieldDefs defines los campos que vas a utilizar, una vez definidos, clic segundario sobre el componente (derecho) y clic sobre Create DataSet y listo ya esta funcionando tu ClientDataSet, ya lo puedes ligar a un TDataSource y a tus Datacontrols. lo manipulas como un TTable.
revisa este blog, es una maravilla, te dará mas pistas de como usar este componente, espero te sirva la ayuda.
http://delphiallimit...emoria-con.html
#11
Escrito 18 abril 2013 - 03:54
begin //Filtro por contenido del combobox //filtro Todos if ComboBox1.text = 'Todos' then begin ADOQuery1.Active:= False; ADOQuery1.SQL.Text:= 'SELECT * From V_Record'; ADOQuery1.SQL.Add('where (Checktime between :hora1 and :hora2)'); ADOQuery1CheckTime.DisplayFormat := 'hh:nn:ss'; //ADOQuery1.Parameters.ParamByName('nombre').Value := ComboBox1.Text; ADOQuery1.Parameters.ParamByName('hora1').Value := horaent1.datetime; ADOQuery1.Parameters.ParamByName('hora2').Value := horasal1.datetime; ADOQuery1.Active:= True; ADOQuery1.First; while not ADOQuery1.Eof do begin ClientDataSet1.Append; ClientDataSet1Legajo.Value := adoquery1userid.Value; ClientDataSet1Cedula.Value := adoquery1NativePlace.Value; ClientDataSet1Nombre.Value := adoquery1Name.Value; ClientDataSet1Fecha.Value := adoquery1Checktime.Value; ClientDataSet1HoraE.Value := adoquery1Checktime.Value; ADOQuery1.Next; end; end //Filtro por nombre else begin ADOQuery1.Active:= False; ADOQuery1.SQL.Text:= 'SELECT * From V_Record'; ADOQuery1.SQL.Add('where (Checktime between :hora1 and :hora2)and Name = :nombre'); ADOQuery1CheckTime.DisplayFormat := 'hh:nn:ss'; ADOQuery1.Parameters.ParamByName('nombre').Value := ComboBox1.Text; ADOQuery1.Parameters.ParamByName('hora1').Value := horaent1.datetime; ADOQuery1.Parameters.ParamByName('hora2').Value := horasal1.datetime; ADOQuery1.Active:= True; ADOQuery1.First; while not ADOQuery1.Eof do begin ClientDataSet1.Append; ClientDataSet1Legajo.Value := adoquery1userid.Value; ClientDataSet1Cedula.Value := adoquery1NativePlace.Value; ClientDataSet1Nombre.Value := adoquery1Name.Value; ClientDataSet1Fecha.Value := adoquery1Checktime.Value; ClientDataSet1HoraE.Value := adoquery1Checktime.Value; ADOQuery1.Next; end; end;
#12
Escrito 18 abril 2013 - 04:03
#13
Escrito 19 abril 2013 - 03:31
1) "Separar" fecha y hora desde la propia SQL y obtener dos campos distintos (más al respecto aquí http://www.firebirds...20-extract.html):
Select Extract(hour from MyField) as hora
En access parece que tienes algo similar llamado DatePart() "para campos calculados": http://msdn.microsof...(v=SQL.80).aspx
2) Usar el campo como float, y como la fecha va en la parte entera y la hora en la decimal, redondeando y esas cosas separas una cosa de otra, o si tienes funciones de redondeo y esas cosas, puedes filtrar por hora usando (date-round(date))
#14
Escrito 19 abril 2013 - 08:23
#15
Escrito 19 abril 2013 - 10:11
Gracias por el aporte, el detalle está en que necesito manejar los datos directamente de la base de datos que ya tengo establecida ya que esta se llena desde un equipo de registro de asistencia, es decir maneja la toma de asistencia a través de huella dactilar.
Necesito calcular horas extras, dias trabajados e inasistencias... Pero la base de datos almacena hora y fecha como una variable datetime, por lo cual me toma todo el valor en un solo campo
Esta es la captura de la base de datos
con este codigo logro hacer un filtro de fecha y hora, ya que la hora la establezco en dtpicker
delphi
ADOQuery1.Active:= False; ADOQuery1.SQL.Text:= 'SELECT distinct * From V_Record'; ADOQuery1.SQL.Add('where (Checktime between :hora1 and :hora2)'); ADOQuery1CheckTime.DisplayFormat := 'dd/mm/yyyy'; ADOQuery1.Parameters.ParamByName('hora1').Value := FormatDateTime('dd,mm,yyyy', horaent1.Time); ADOQuery1.Parameters.ParamByName('hora2').Value := FormatDateTime('dd,mm,yyyy', horasal1.Time); ADOQuery1.Active:= True;
lo que quiero es mediante filtros separar hora de entrada y salida... a menos que exista otro metodo
este es el formato de la tabla de donde extraigo los datos
la tabla resultante quedaría
en vez de checktime, seria fecha, horaentrada horasalida
en realidad ya la parte de separar fecha y hora lo solucione dando formato al query...
Es decir, ya tengo la fecha en un campo, la hora de entrada en otro campo, me hace falta una consulta para sacar la hora de salida... no se si me explico
#16
Escrito 19 abril 2013 - 12:22
Bueno, revisando el codigo que nos muestras, encuentro lo siguiente:
-El contenido de la Tquery lo pasas completo al ClientDataSet.
-Estoy entendiendo que en la consulta pides todas las "asistencias" de una misma fecha que estan entre la entrada y la salida. en lo ideal cada empleado tendrá un par de asistencias. ¿estamos de acuerdo?
-En vez de pasar "Todo" al TclientDataSet, analiza cada fecha-hora que encuentras de acuerdo a la configuracion que tengas del horario laboral, al "barrer" los registros de la consulta decidas, cual es entrada y cual es salida, de acuerdo a dicha configuración laboral.
-ahora que si lo quieres todo en la consulta puedes intentar hacer subconsultas para que te filtre la entrada y la salida. pero tienes que manejar un rango para la entrada y un rango para la salida
creas un filtro para traer la entrada, como es esto.
creas una consulta donde preguntes por la asistencia que se acerque mas a la hora de entrada, esto es manejando una tolerancia. hora de entrada + ó - tolerancia
creas un filtro para traer la salida, como es esto.
creas una consulta donde preguntes por la asistencia que se acerque mas a la hora de salida, esto es manejando una tolerancia. hora de salida + ó - tolerancia
por ejemplo Un Empleado que su jornada laboral empieza a las 8 AM y termina 5 PM no quiere decir que todos los dias va a llegar en punto, sobre todo que los registros se guardan hasta en milisegundos, no puedes preguntar si entro exactamente a esa hora, ni tampoco puedes "separar" la hora de entrada porque daría lo mismo entrar 8:01 que 8:59.
mejor toma un rango. manejas un rango de tolerancia para entrar antes de la hora asignada como entrada, y un rango despues, para tomarla como un retado. es decir, 15 minutos antes y 15 minutos despues por ejemplo.
entonces ya en tu consulta agregas una subconsulta para la entrada y Otra para la salida
SELECT V_Record.* , (SELECT MIN(Checktime) FROM V_Record WHERE Checktime between :hora1 and :hora2) as ENTRADA, (SELECT MAX(Checktime) FROM V_Record WHERE Checktime between :hora3 and :hora4) as SALIDA
From V_Record
WHERE
Checktime = :FECHA
El min en la entrada es para que tome la primera del dia y el Max es para que tome la ultima del dia en la salida. ya teniendo esto puedes pasarlo directamente al DBgrid o al clientdataset por si quieres hacer otro proceso.
esta es una forma burda de solucionarlo. ya que el control de asistencias es complejo ya que hay otras "circunstancias" que necesitas contemplar y controlar, retardos, inasistencias, permisos, si al usuario se le olvidó marcar alguna, tolerancias, en fin.
espero que haya sido clara mi idea, y te pueda servir
#17
Escrito 19 abril 2013 - 05:41
Por ejemplo si quieres recuperar solo la hora del campo CHECKTIME harías algo así:
SELECT HOUR(CHECKTIME) FROM TU_TABLA
WHERE
/*TUS CONDICIONES*/
Si quieres recuperar solo los minutos del campo CHECKTIME harías algo así:
SELECT MINUTE(CHECKTIME) FROM TU_TABLA
WHERE
/*TUS CONDICIONES*/
Si quieres recuperar solo los segundos del campo CHECKTIME harías algo así:
SELECT SECOND(CHECKTIME) FROM TU_TABLA
WHERE
/*TUS CONDICIONES*/
Si quieres recuperar solo el mes del campo CHECKTIME harías algo así:
SELECT MONTH(CHECKTIME) FROM TU_TABLA
WHERE
/*TUS CONDICIONES*/
Si quieres recuperar solo el día del campo CHECKTIME harías algo así:
SELECT DAY(CHECKTIME) FROM TU_TABLA
WHERE
/*TUS CONDICIONES*/
Si quieres recuperar solo el año del campo CHECKTIME harías algo así:
SELECT YEAR(CHECKTIME) FROM TU_TABLA
WHERE
/*TUS CONDICIONES*/
Como es lógico también puedes usar estas funciones dentro de las condiciones de tus consultas, por ejemplo, a la siguiente consulta le pasas los parámetros de fecha y horas que quieras obtener:
SELECT * FROM V_RECORD WHERE
(CHECKTIME = :FECHA) AND
(HOUR(CHECKTIME) BETWEEN :HORA1 AND :HORA2)
Saludos.