Etiquetas

20121107

ABAP Tips: Calcular días hábiles entre dos fechas

Esta es una función bastante interesante que permite obtener la cantidad de días hábiles y no hábiles entre dos fechas, donde se contabilizan aparte los sábados, domingos y festivos según el calendario SAP (transacción SCAL).
Cortesía de @AleMadriaza


FUNCTION z_tv_08_dias_habiles.
*"----------------------------------------------------------------------
*"*"Interfase local
*"  IMPORTING
*"     VALUE(I_FECHA_INI) TYPE  BEGDA
*"     VALUE(I_FECHA_FIN) TYPE  ENDDA
*"  EXPORTING
*"     VALUE(E_DIAS_HABILES) TYPE  I
*"     VALUE(E_DIAS_NO_HABILES) TYPE  I
*"     VALUE(E_RETURN) TYPE  BAPIRET2
*"----------------------------------------------------------------------


  DATA: lv_datediff   TYPE p,
        lv_timediff   TYPE p,
        lv_earliest   TYPE c,
        lv_feriado    TYPE i.

  DATA: lv_fecha_ent  TYPE sy-datum,
        lv_fecha_sal  TYPE sy-datum.



**********************************************************************
*                               INICIO                               *
**********************************************************************

* Validamos que las fechas sean correctas
  IF i_fecha_ini > i_fecha_fin.
    e_return-type     = 'E'.
    e_return-message  = text-e20. " La fecha de inicio no puede ser mayor que la fecha de fin.
    EXIT.
  ENDIF.


  CLEAR:  lv_feriado.


  lv_fecha_ent = i_fecha_ini.

  CALL FUNCTION 'SD_DATETIME_DIFFERENCE'
    EXPORTING
      date1            = i_fecha_ini
      time1            = sy-uzeit
      date2            = i_fecha_fin
      time2            = sy-uzeit
    IMPORTING
      datediff         = lv_datediff
      timediff         = lv_timediff
      earliest         = lv_earliest
    EXCEPTIONS
      invalid_datetime = 1
      OTHERS           = 2.

  lv_datediff   = lv_datediff   + 1.  " Para que incluya la última fecha
  lv_fecha_ent  = lv_fecha_ent  - 1.  " Para que incluya la fecha inicial


  DO lv_datediff TIMES.

    CLEAR: lv_fecha_sal.

    lv_fecha_ent = lv_fecha_ent + 1.

    CALL FUNCTION 'DATE_CONVERT_TO_FACTORYDATE'
      EXPORTING
        correct_option               = '+'
        date                         = lv_fecha_ent
        factory_calendar_id          = 'CL'
      IMPORTING
        date                         = lv_fecha_sal
      EXCEPTIONS
        calendar_buffer_not_loadable = 1
        correct_option_invalid       = 2
        date_after_range             = 3
        date_before_range            = 4
        date_invalid                 = 5
        factory_calendar_not_found   = 6
        OTHERS                       = 7.

    IF lv_fecha_ent NE lv_fecha_sal.
      lv_feriado = lv_feriado + 1.
    ENDIF.

  ENDDO.

  e_dias_no_habiles = lv_feriado.
  e_dias_habiles    = lv_datediff - lv_feriado.

  e_return-type     = 'S'.

ENDFUNCTION.