Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   Procedimiento que me muestre total de horas (https://www.clubdelphi.com/foros/showthread.php?t=83451)

novato_erick 20-06-2013 00:28:14

Procedimiento que me muestre total de horas
 
Hola Chicos:

nuestro amigo Chogo creó este procedimiento almacenado en Firebird el cual trae consulta por parámetro de un máximo de 15 días pero necesito realizar la suma de horas el cual están en el campo de HORA y no se como implementarlo me da muchos errores alguna idea como implementarlo?

Código SQL [-]
CREATE PROCEDURE CALCULOMARCACIONES(
  INICIO DATE,
  FINAL DATE,
  CODIGO INTEGER)
RETURNS(
  ID_EMPLEADOS INTEGER,
  FECHA DATE,
  NUM_DIA SMALLINT,
  DIA VARCHAR(30) CHARACTER SET NONE COLLATE NONE,
  ENTRADA0 TIMESTAMP,
  SALIDA0 TIMESTAMP,
  ENTRADA1 TIMESTAMP,
  SALIDA1 TIMESTAMP,
  ENTRADA2 TIMESTAMP,
  SALIDA2 TIMESTAMP,
  FALTA VARCHAR(1) CHARACTER SET NONE COLLATE NONE,
  HORASORDINARIAS DECIMAL(12, 2),
  HORASEXTRAS DECIMAL(12, 2))
AS
DECLARE VARIABLE FILA INTEGER;
DECLARE VARIABLE COLUMNA SMALLINT;
DECLARE VARIABLE XFECHAHORA TIMESTAMP;
DECLARE VARIABLE HORASORDEXTRA VARCHAR(20);
DECLARE VARIABLE MINUTOSAHORA VARCHAR(20);
BEGIN

  FOR
 
   SELECT
                    TMARCACIONES.ID_EMPLEADOS
                    -->LINEA.LINEA
                    FROM
                    TMARCACIONES                    
                      -->INNER JOIN LINEA ON (MARCACIONES_RELOJ.IDLINEA = LINEA.IDLINEA)
                    WHERE
                    TMARCACIONES.FECHA BETWEEN :INICIO AND :FINAL AND TMARCACIONES.ID_EMPLEADOS = :CODIGO
                    GROUP BY
                    TMARCACIONES.ID_EMPLEADOS
                    -->LINEA.LINEA
                    ORDER BY
                    -->LINEA.LINEA,
                    TMARCACIONES.ID_EMPLEADOS
  
        INTO
            :ID_EMPLEADOS-->,                       
             DO 
  BEGIN
       /*ESTE CICLO CREA 7 REGISTROS, ES UN REGISTRO DE POR CADA DIA DE LA SEMANA*/
       Fila=1;
       FECHA = INICIO;
       WHILE (Fila<>16) DO
       BEGIN 
               NUM_DIA=FILA;
               COLUMNA=0;
               
               ENTRADA0=NULL;
               SALIDA0=NULL;
               
               ENTRADA1=NULL;
               SALIDA1=NULL;
               
               ENTRADA2=NULL;
               SALIDA2=NULL;
               
               HORASORDINARIAS=NULL;
               HORASEXTRAS=NULL;
               
               FOR 
                       SELECT 
                          M.HORA 
                       FROM 
                          TMARCACIONES M
                       WHERE 
                           M.ID_EMPLEADOS = :ID_EMPLEADOS AND  M.FECHA = :FECHA
                       ORDER BY
                             m.HORA
                       INTO 
                             :XFECHAHORA                            
                       
               DO
               BEGIN
                   /* AQUI CONSULTAS LAS MARCACIONES DE UN EMPLEADO EN UNA SOLA FECHA */     
                        
                   IF (COLUMNA = 0) THEN
                   ENTRADA0=XFECHAHORA;
                        
                   IF (COLUMNA = 1) THEN
                   SALIDA0=XFECHAHORA;

                   IF (COLUMNA = 2) THEN
                   ENTRADA1=XFECHAHORA;
                   
                   IF (COLUMNA = 3) THEN
                   SALIDA1=XFECHAHORA;                   

                   IF (COLUMNA = 4) THEN
                   ENTRADA2=XFECHAHORA;
                  
                   IF (COLUMNA = 5) THEN
                   SALIDA2=XFECHAHORA;
                   
                   IF (COLUMNA = 6) THEN
                   HORASORDINARIAS=XFECHAHORA;  
                   
                   COLUMNA = COLUMNA + 1;
               END 
              
              IF (ENTRADA0 IS NULL) THEN FALTA = 'X'; ELSE FALTA='';  
       
                SUSPEND;
              FECHA = INICIO + FILA;
              Fila = Fila + 1;
              
       END       
       /* Procedure body */
  END
END;


Saludos

novato_erick

Casimiro Notevi 20-06-2013 11:24:40

Creo que estaría más claro que nos dijeras los campos de la tabla, lo que tienen cada uno y lo que quieres hacer.

novato_erick 20-06-2013 19:30:31

Hola casimiro

Tengo una tabla con la siguiente estructura:

Código SQL [-]
CREATE TABLE TMARCACIONES (
  ID_MARCAS INTEGER NOT NULL,
  ID_EMPLEADOS INTEGER NOT NULL,
  HORA TIMESTAMP DEFAULT 'NOW' NOT NULL,
  FECHA DATE DEFAULT 'NOW');


ALTER TABLE TMARCACIONES ADD PRIMARY KEY (ID_MARCAS);


SET TERM ^ ;

CREATE TRIGGER BI_TMARCACIONES_ID_MARCAS FOR TMARCACIONES
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (NEW.ID_MARCAS IS NULL) THEN
      NEW.ID_MARCAS = GEN_ID(TMARCACIONES_ID_MARCAS_GEN, 1);
END^

SET TERM ; ^

De las marcaciones calcular las horas laboradas ejemplo:

Cita:

ID_EMPLEADO----ENTRADA0----------------SALIDA0--------------------ENTRADA1--------------------SALIDA1---------------FALTA---HORASORDINARIAS--HORASMATUTINA--ALMUERZO--HORASTARDE
1--------------2013-02-07 9:20:59------2013-02-07 12:00:09-------2013-02-07 13:00:59-------2013-02-07 18:20:40---------NULL----------7.40--------------2.20--------------1----------5.20
1--------------2013-02-07 9:28:12------2013-02-07 12:10:10-------2013-02-07 13:10:11-------2013-02-07 18:29:21---------NULL----------7.49--------------2.30--------------1----------5.20

Saludos


novato_erick

novato_erick 09-08-2014 22:18:18

Hola Chicos hace un año coloqué este pos en la que mi intensión era extraer en una tabla llamada TMARCACIONES el total de horas laboradas en un día por colaborador en el que al final nunca terminé dicho procedimiento. Bueno como soy persona de no dejar las cosas a medio palo creo que insistiré en tratar de dejar este procedimiento para seguir el proyecto que tenia en mente para un programa de asistencia tomando referencias de multiples hilos en este mismo foro.

Al final espero poder lograr con su ayuda chicos el resultado esperado.

muestro a continuación lo que he estado haciendo hace un par de horas:
Código SQL [-]
BEGIN

  FOR
 
   SELECT
                    TMARCACIONES.ID_EMPLEADOS
                    
                    FROM
                    TMARCACIONES                    
                    
                    WHERE
                    CAST(TMARCACIONES.HORA AS DATE) BETWEEN :INICIO AND :FINAL AND TMARCACIONES.ID_EMPLEADOS = :CODIGO
                    GROUP BY
                    TMARCACIONES.ID_EMPLEADOS
                    
                    ORDER BY
                    
                    TMARCACIONES.ID_EMPLEADOS
  
        INTO
            :ID_EMPLEADOS                       
             DO 
  BEGIN
       /*ESTE CICLO CREA 7 REGISTROS, ES UN REGISTRO DE POR CADA DIA DE LA SEMANA*/
       Fila=1;
       FECHA = INICIO;
        WHILE (Fila<>16) DO 
       BEGIN 
               NUM_DIA=FILA;
               COLUMNA=0;
               
               ENTRADA0=NULL;
               SALIDA0=NULL;
               
               ENTRADA1=NULL;
               SALIDA1=NULL;
               
               ENTRADA2=NULL;
               SALIDA2=NULL;
               
               ENTRADA0ENTERO=NULL;
               SALIDA0ENTERO=NULL;
               
               HORASORDINARIAS=0;
              -->> HORASEXTRAS=NULL;
               ALMUERZO0=NULL;
               ALMUERZO0ENTRADA=NULL;
               ALMUERZO0SALIDA=NULL;
               
               ENTRADA1ENTERO=NULL;
               SALIDA1ENTERO=NULL;
               
               MINUTOENTRADA0 = NULL;
               MINUTOSALIDA0 = NULL;
               
               MINUTOENTRADA1 = NULL;
               MINUTOSALIDA1 = NULL;
               
               TOTALMINUTOSMANIANA = NULL;
               TOTALMINUTOSTARDE = NULL;
               
               TOTALMINUTOS =NULL;
               TOTALHORASMINUTOS =NULL;
               
               TOTALMINUTOSENTEROS = NULL;
               RESULTADOTOTALMINUTOS =NULL;
               
               TOTALHORASMINUTOS = NULL;
               TOTALMINUTOS = NULL;
               
               TOTALHORAS = NULL;
               TOTALMINUTOSORDINARIO = NULL;
               
               
               FOR 
                       SELECT 
                          M.HORA 
                       FROM 
                          TMARCACIONES M
                       WHERE 
                           M.ID_EMPLEADOS = :ID_EMPLEADOS AND CAST(M.HORA AS DATE) = :FECHA
                       ORDER BY
                             m.HORA
                       INTO 
                             :XFECHAHORA                            
                       
               DO
               BEGIN
                   /* AQUI CONSULTAS LAS MARCACIONES DE UN EMPLEADO EN UNA SOLA FECHA */     
                        
                   IF (COLUMNA = 0) THEN
                   begin
                   ENTRADA0 = XFECHAHORA;
                   ENTRADA0ENTERO = EXTRACT(HOUR from ENTRADA0);
                   MINUTOENTRADA0 = EXTRACT(MINUTE FROM ENTRADA0);
                   end
                  /*AQUI CONOCEMOS EN VALOR ENTERO LA HORA DE ENTRADA Y MINUTOS */      
                   IF (COLUMNA = 1) THEN
                   begin
                   SALIDA0 = XFECHAHORA;
                   SALIDA0ENTERO = EXTRACT(HOUR from SALIDA0);
                   MINUTOSALIDA0 =EXTRACT(MINUTE FROM SALIDA0);
                   ALMUERZO0SALIDA = SALIDA0ENTERO;
                   end
                   
                   IF (COLUMNA = 2) THEN
                   begin
                     ENTRADA1= XFECHAHORA;
                     ENTRADA1ENTERO = EXTRACT(HOUR FROM ENTRADA1);
                     ALMUERZO0ENTRADA = ENTRADA1ENTERO;
                     MINUTOENTRADA1 = EXTRACT(MINUTE FROM ENTRADA1);
                   end
                   
                   IF (COLUMNA = 3) THEN
                   begin
                   SALIDA1 = XFECHAHORA;
                   SALIDA1ENTERO = EXTRACT(HOUR FROM SALIDA1);
                   MINUTOSALIDA1 = EXTRACT(MINUTE FROM SALIDA1);
                   end
                          
                   IF (COLUMNA = 4) THEN
                   ENTRADA2 = XFECHAHORA;
                  
                   IF (COLUMNA = 5) THEN
                   SALIDA2 = XFECHAHORA;
                   
                                                                           
                   COLUMNA = COLUMNA + 1;
                   
               END 
              
              IF (ENTRADA0 IS NULL) THEN FALTA = 'X'; ELSE FALTA='';  
             /*CALCULOS DE HORAS EN EL PROSEDIMIENTO*/
             HORASMANIANA = SALIDA0ENTERO - ENTRADA0ENTERO;
             ALMUERZO0 = ALMUERZO0ENTRADA - ALMUERZO0SALIDA; 
             HORASTARDE = SALIDA1ENTERO - ENTRADA1ENTERO; 
             HORASORDINARIAS = HORASMANIANA + HORASTARDE;
             TOTALMINUTOSMANIANA = MINUTOENTRADA0 + MINUTOSALIDA0;
             TOTALMINUTOSTARDE = MINUTOSALIDA1 + MINUTOSALIDA1;
             TOTALMINUTOSORDINARIO = TOTALMINUTOSMANIANA + TOTALMINUTOSTARDE; 
            
             TOTALMINUTOS = CAST(TOTALMINUTOSORDINARIO AS DECIMAL(12,2)) /60.00; 
                              
             /*DESCOMPONEMOS EL RESULTADO PARA SACAR LOS MINUTOS EN VALOR ENTERO Y DECIMALES*/
             TOTALMINUTOSENTEROS = TRUNC(TOTALMINUTOS, 0);
             RESULTADOTOTALMINUTOS = CAST(TOTALMINUTOS AS INTEGER) - TOTALMINUTOS;
            
             RESULTADOTOTALMINUTOS = RESULTADOTOTALMINUTOS * 60.00 /100;
             TOTALHORASMINUTOS = TOTALMINUTOSENTEROS + RESULTADOTOTALMINUTOS;
             /*OBTENEMOS EL RESULTADO DEl TOTAL DE HORAS EN EL D;*/
             TOTALHORAS = TOTALHORASMINUTOS + HORASORDINARIAS;
              SUSPEND;
              FECHA = INICIO + FILA;
              Fila = Fila + 1;
              
       END       
       /* Procedure body */
  END
END

al principio del post está la tabla que es utilizada con sus campos y las variables que he estado aumentando para realizar este prosedimiento.

en fin como me comentó nuestro amigo y gran colaborador casimiro:
Cita:

Creo que estaría más claro que nos dijeras los campos de la tabla, lo que tienen cada uno y lo que quieres hacer.
como en esta parte se me ocurrío fue utilizar la funcion EXTRACT(HOUR), EXTRACT(MINUTE), para tener valores en la cual al final podia utilizar dentro de las variables y realizar sumas y restas pertinente.

en fin creí que lo había logrado sin embargo me apareció esto:

Código SQL [-]
             TOTALMINUTOS = CAST(TOTALMINUTOSORDINARIO AS DECIMAL(12,2)) /60.00; 
                              
             /*DESCOMPONEMOS EL RESULTADO PARA SACAR LOS MINUTOS EN VALOR ENTERO Y DECIMALES*/
             TOTALMINUTOSENTEROS = TRUNC(TOTALMINUTOS, 0);
             RESULTADOTOTALMINUTOS = CAST(TOTALMINUTOS AS INTEGER) - TOTALMINUTOS;

            /*Seria esto mas o menos : mi total de TOTALMINUTOSORDINARIOS = 78 /60 = 1.30
Trato de sacar el TOTALMINUTOSENTEROS EL 1 para dejar el .30 PARA RESTAR EL TOTALMINUTOS = 1.30 y multiplicar por 60.00 dividiéndolo */
/*entre 100 ara obtener este valor: 0.18 pero me manda -18 claramente aquí afecta la REGLA DE LOS SIGNOS:*/

"más por más = más"
"menos por menos = más"
"más por menos = menos"
"menos por más = menos"

en si eso me ocurre cuando mi TOTALMINUTOSORDINARIOS tiene menos de 99 pero si es más de 100 no ocurre el resultado es correcto/

Creo que dí a explicar...


Saludos

novato_erick 12-08-2014 23:28:09

Hola... Bueno después de todo buscando y buscando varios link dentro del mismo clubdelphi al final hice esto:

Código SQL [-]
              IF (ENTRADA0 IS NULL) THEN FALTA = 'X'; ELSE FALTA='';  
             /*CALCULOS DE HORAS EN EL PROSEDIMIENTO*/
             HORADIA = DATEDIFF(MINUTE, ENTRADA0, SALIDA1) / 60.00 -
             DATEDIFF(MINUTE, SALIDA0, ENTRADA1)/60.00;
             /*SUMAR TIEMPO DE ALMUERZO*/
             HORAALMUERZO = DATEDIFF(MINUTE, SALIDA0, ENTRADA1)/ 60.00;
             /*EXTRAEMOS LOS MINUTOS DE LAS HORAS DEL DIA*/
             MINUTOSDIA = TRUNC(HORADIA, 0);
             /*RESTAMOS LOS ENTEROS CONTRA LOS DECIMALES PARA DEJAR LOS DECIMALES*/
             HORASDIACONVER = HORADIA - MINUTOSDIA;
             /*MULTIPLICAMOS LOS DECIMALES PARA OPENER MINUTOS EJEMPLO .50 * 60.00 = 30.00 MINUTOS REDONDEANDO*/
             MINUTOSDIASCONVER =  ROUND(HORASDIACONVER * 60.00);
             /*DIVIDIMOS LO REDONDEADO /100 PARA OBTENER EL 30 DE ENTERO A 0.30 EN DECIMAL*/
             MINUTOSDIASCONVER =  MINUTOSDIASCONVER /100;
             /*SUMAMOS AL FINAL LAS HORAS ENTERAS CON LOS MINUTOS PARA EL TOTAL DE HORAS CON MINUTOS TRABAJADA EN EL DIA*/
             HORATOTALDIA = MINUTOSDIA + MINUTOSDIASCONVER;

en fin logre el objetivo...

Saludos

novato_erick


La franja horaria es GMT +2. Ahora son las 17:01:41.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi