Somar intervalo de tempo/produção dos recursos | Período útil

    Caso de uso:

     

    • Necessário somar o tempo de inatividade dos recursos no período de produção útil, desconsiderando feriados nacionais e horário de almoço, e apresentar a quantidade de dias das ocorrências
    • Obs.: Cenário também serve para medir o tempo de trabalho de funcionários (H/H)

     

    Cenário atual:

    Capturar2.JPG

    Cenário desejado:

    Capturar2.JPG


    Solução:

     

    Via Script:


    TAB_PRODUCAO:
    Load
        RECURSO,
        Date(Date#(PARADO,'YYYYMMDDhhmm'),'DD/MM/YYYY hh:mm') As 'PARADO',
        Date(Date#(RETORNO,'YYYYMMDDhhmm'),'DD/MM/YYYY hh:mm') As 'RETORNO',
        Date(Floor(Date#(PARADO,'YYYYMMDDhhmm'))) As 'DATA_PARADO',
        Time(Frac(Date#(PARADO,'YYYYMMDDhhmm')),'hh:mm') As 'TEMPO_PARADO',    
        Date(Floor(Date#(RETORNO,'YYYYMMDDhhmm'))) As 'DATA_RETORNO',
        Time(Frac(Date#(RETORNO,'YYYYMMDDhhmm')),'hh:mm') As 'TEMPO_RETORNO'
    FROM [lib://QVD_XPTO/PRODUCAO.QVD](qvd);
    
    TAB_FERIADOS:
    Mapping LOAD
        Num(DATA) As DATA,
        FERIADO
    FROM [lib://QVD_XPTO/FERIADOS_NACIONAIS.QVD](qvd);
    
    Let vJORNADA_INI = Time#('07:30','hh:mm');
    Let vJORNADA_FIM = Time#('17:48','hh:mm');
    Let vJORNADA_ALM_INI = Time#('12:00','hh:mm');
    Let vJORNADA_ALM_FIM = Time#('13:30','hh:mm');
    Let vJORNADA_ALM = Time('$(vJORNADA_ALM_FIM)'-'$(vJORNADA_ALM_INI)','hh:mm');
    Let vJORNADA_TOTAL = Time('$(vJORNADA_FIM)'-'$(vJORNADA_INI)'-'$(vJORNADA_ALM)','hh:mm');
    
    TAB_INTERVADO_PARADO:
    Load
        RECURSO,
        Interval(Sum(INTERVALO),'hh:mm') As 'INTERVALO_PARADO', 
        Count(DIAS_PARADOS) As 'QTD_DIAS_OCORRÊNCIA'
    Group By RECURSO; 
    Load
        RECURSO,   
        Time(
        IF( Not Match(Num(WeekDay(DATA_PARADO + IterNo() -1)),0,6) and //not sab e dom?
            Not Len(ApplyMap('TAB_FERIADOS',(DATA_PARADO + IterNo() -1),null())) //not feriado?
           
            ,IF(DATA_PARADO=DATA_RETORNO, //mesmo dia?
                IF(TEMPO_RETORNO<'$(vJORNADA_INI)','$(vJORNADA_INI)', //antes do período de trabalho?
                   IF(TEMPO_RETORNO>'$(vJORNADA_FIM)','$(vJORNADA_FIM)', //depois do período de trabalho?
                      IF(TEMPO_RETORNO>='$(vJORNADA_ALM_INI)' AND TEMPO_RETORNO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_ALM_FIM)', //período de almoço?
                         TEMPO_RETORNO
                      )
                   )
                )       
                -
                IF(TEMPO_PARADO<'$(vJORNADA_INI)','$(vJORNADA_INI)', //antes do período de trabalho?
                   IF(TEMPO_PARADO>'$(vJORNADA_FIM)','$(vJORNADA_FIM)', //depois do período de trabalho?
                      IF(TEMPO_PARADO>='$(vJORNADA_ALM_INI)' AND TEMPO_PARADO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_ALM_FIM)', //período de almoço?
                         TEMPO_PARADO
                      )
                   )
                )
                -
                IF(TEMPO_PARADO<'$(vJORNADA_ALM_INI)' AND TEMPO_RETORNO>='$(vJORNADA_ALM_INI)', '$(vJORNADA_ALM)',0)        
    
            ,IF(IterNo()=1, //primeiro dia?
                IF(TEMPO_PARADO<'$(vJORNADA_INI)','$(vJORNADA_TOTAL)', //antes do período de trabalho?
                   IF(TEMPO_PARADO>'$(vJORNADA_FIM)',NULL(), //depois do período de trabalho?
                      IF(TEMPO_PARADO<'$(vJORNADA_ALM_INI)', '$(vJORNADA_FIM)'-TEMPO_PARADO-'$(vJORNADA_ALM)', //antes de meio dia?
                         IF(TEMPO_PARADO>='$(vJORNADA_ALM_INI)' AND TEMPO_PARADO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_FIM)'-'$(vJORNADA_ALM_FIM)', //período de almoço?
                            '$(vJORNADA_FIM)'-TEMPO_PARADO
                         )
                      )
                   )
                )
             
                ,IF(DATA_RETORNO = Date(DATA_PARADO + IterNo() -1), //último dia?
                    IF(TEMPO_RETORNO<'$(vJORNADA_INI)',Null(), //antes do período de trabalho?
                       IF(TEMPO_RETORNO>'$(vJORNADA_FIM)','$(vJORNADA_TOTAL)', //depois do período de trabalho?
                          IF(TEMPO_RETORNO<'$(vJORNADA_ALM_INI)', TEMPO_RETORNO-'$(vJORNADA_INI)', //antes de meio dia?
                             IF(TEMPO_RETORNO>='$(vJORNADA_ALM_INI)' AND TEMPO_RETORNO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_ALM_INI)'-'$(vJORNADA_INI)', //período de almoço?
                                TEMPO_RETORNO-'$(vJORNADA_INI)'-'$(vJORNADA_ALM)'
                             )
                          )
                       )
                    )
                ,'$(vJORNADA_TOTAL)'
                )
            )
        )
        ),'hh:mm') As 'INTERVALO',     
        Date(DATA_PARADO + IterNo() -1)  As 'DIAS_PARADOS'
    Resident TAB_PRODUCAO
    While DATA_PARADO + IterNo() -1 <= DATA_RETORNO;
    
    

     

    Modelo com Inline*:

     

    TAB_PRODUCAO:
    Load
        RECURSO,
        Date(Date#(PARADO,'YYYYMMDDhhmm'),'DD/MM/YYYY hh:mm') As 'PARADO',
        Date(Date#(RETORNO,'YYYYMMDDhhmm'),'DD/MM/YYYY hh:mm') As 'RETORNO',
        Date(Floor(Date#(PARADO,'YYYYMMDDhhmm'))) As 'DATA_PARADO',
        Time(Frac(Date#(PARADO,'YYYYMMDDhhmm')),'hh:mm') As 'TEMPO_PARADO',    
        Date(Floor(Date#(RETORNO,'YYYYMMDDhhmm'))) As 'DATA_RETORNO',
        Time(Frac(Date#(RETORNO,'YYYYMMDDhhmm')),'hh:mm') As 'TEMPO_RETORNO';
    LOAD *
    INLINE [
       RECURSO|PARADO|RETORNO
       MAQ1|201703211020|201703241130
       MAQ2|201704020830|201704031520
       MAQ3|201704120830|201704130830
       MAQ4|201704130600|201704170600
       MAQ5|201704130800|201704180800  
       MAQ6|201704131200|201704171200 
       MAQ7|201704131330|201704171330 
       MAQ8|201704131430|201704171430 
       MAQ9|201704131900|201704171900   
       MAQ10|201703130600|201703130800
       MAQ11|201703130600|201703131200
       MAQ12|201703130600|201703131500
       MAQ13|201703130600|201703132000
       MAQ14|201703131200|201703131330
       MAQ15|201703131200|201703131430
       MAQ16|201703132000|201703132300  
       MAQ17|201703132000|201705132300     
    ](delimiter is '|');
    
    TAB_FERIADOS:
    Mapping LOAD
        Num(DATA) As DATA,
        FERIADO;
    Load *
    INLINE [
       DATA|DIA DA SEMANA|FERIADO
       01/01/2017|domingo|Confraternização Universal
       27/02/2017|segunda-feira|Carnaval
       28/02/2017|terça-feira|Carnaval
       14/04/2017|sexta-feira|Paixão de Cristo
       21/04/2017|sexta-feira|Tiradentes
       01/05/2017|segunda-feira|Dia do Trabalho
       15/06/2017|quinta-feira|Corpus Christi
       07/09/2017|quinta-feira|Independência do Brasil
       12/10/2017|quinta-feira|Nossa Sr.a Aparecida - Padroeira do Brasil
       02/11/2017|quinta-feira|Finados
       15/11/2017|quarta-feira|Proclamação da República
       25/12/2017|segunda-feira|Natal
    ](delimiter is '|');
    
    Let vJORNADA_INI = Time#('07:30','hh:mm');
    Let vJORNADA_FIM = Time#('17:48','hh:mm');
    Let vJORNADA_ALM_INI = Time#('12:00','hh:mm');
    Let vJORNADA_ALM_FIM = Time#('13:30','hh:mm');
    Let vJORNADA_ALM = Time('$(vJORNADA_ALM_FIM)'-'$(vJORNADA_ALM_INI)','hh:mm');
    Let vJORNADA_TOTAL = Time('$(vJORNADA_FIM)'-'$(vJORNADA_INI)'-'$(vJORNADA_ALM)','hh:mm');
    
    TAB_INTERVADO_PARADO:
    Load
        RECURSO,
        Interval(Sum(INTERVALO),'hh:mm') As 'INTERVALO_PARADO', 
        Count(DIAS_PARADOS) As 'QTD_DIAS_OCORRÊNCIA'
    Group By RECURSO;
    Load
        RECURSO,   
        Time(
        IF( Not Match(Num(WeekDay(DATA_PARADO + IterNo() -1)),0,6) and //not sab e dom?
            Not Len(ApplyMap('TAB_FERIADOS',(DATA_PARADO + IterNo() -1),null())) //not feriado?
           
            ,IF(DATA_PARADO=DATA_RETORNO, //mesmo dia?
                IF(TEMPO_RETORNO<'$(vJORNADA_INI)','$(vJORNADA_INI)', //antes do período de trabalho?
                   IF(TEMPO_RETORNO>'$(vJORNADA_FIM)','$(vJORNADA_FIM)', //depois do período de trabalho?
                      IF(TEMPO_RETORNO>='$(vJORNADA_ALM_INI)' AND TEMPO_RETORNO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_ALM_FIM)', //período de almoço?
                         TEMPO_RETORNO
                      )
                   )
                )       
                -
                IF(TEMPO_PARADO<'$(vJORNADA_INI)','$(vJORNADA_INI)', //antes do período de trabalho?
                   IF(TEMPO_PARADO>'$(vJORNADA_FIM)','$(vJORNADA_FIM)', //depois do período de trabalho?
                      IF(TEMPO_PARADO>='$(vJORNADA_ALM_INI)' AND TEMPO_PARADO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_ALM_FIM)', //período de almoço?
                         TEMPO_PARADO
                      )
                   )
                )
                -
                IF(TEMPO_PARADO<'$(vJORNADA_ALM_INI)' AND TEMPO_RETORNO>='$(vJORNADA_ALM_INI)', '$(vJORNADA_ALM)',0)        
    
            ,IF(IterNo()=1, //primeiro dia?
                IF(TEMPO_PARADO<'$(vJORNADA_INI)','$(vJORNADA_TOTAL)', //antes do período de trabalho?
                   IF(TEMPO_PARADO>'$(vJORNADA_FIM)',NULL(), //depois do período de trabalho?
                      IF(TEMPO_PARADO<'$(vJORNADA_ALM_INI)', '$(vJORNADA_FIM)'-TEMPO_PARADO-'$(vJORNADA_ALM)', //antes de meio dia?
                         IF(TEMPO_PARADO>='$(vJORNADA_ALM_INI)' AND TEMPO_PARADO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_FIM)'-'$(vJORNADA_ALM_FIM)', //período de almoço?
                            '$(vJORNADA_FIM)'-TEMPO_PARADO
                         )
                      )
                   )
                )
             
                ,IF(DATA_RETORNO = Date(DATA_PARADO + IterNo() -1), //último dia?
                    IF(TEMPO_RETORNO<'$(vJORNADA_INI)',Null(), //antes do período de trabalho?
                       IF(TEMPO_RETORNO>'$(vJORNADA_FIM)','$(vJORNADA_TOTAL)', //depois do período de trabalho?
                          IF(TEMPO_RETORNO<'$(vJORNADA_ALM_INI)', TEMPO_RETORNO-'$(vJORNADA_INI)', //antes de meio dia?
                             IF(TEMPO_RETORNO>='$(vJORNADA_ALM_INI)' AND TEMPO_RETORNO<='$(vJORNADA_ALM_FIM)', '$(vJORNADA_ALM_INI)'-'$(vJORNADA_INI)', //período de almoço?
                                TEMPO_RETORNO-'$(vJORNADA_INI)'-'$(vJORNADA_ALM)'
                             )
                          )
                       )
                    )
                ,'$(vJORNADA_TOTAL)'
                )
            )
        )
        ),'hh:mm') As 'INTERVALO',     
        Date(DATA_PARADO + IterNo() -1)  As 'DIAS_PARADOS'
    Resident TAB_PRODUCAO
    While DATA_PARADO + IterNo() -1 <= DATA_RETORNO;
    
    

    * Só copiar e colar na aplicação para testar.