SAP/ABAP

Excel DATEVALUE to DATE conversion

Denise 2014. 8. 29. 22:22

1. 엑셀 upload시 셀서식에 의해 데이터가 변형되는것을 방지 할때 사용. 
2. 용도 : 엑셀의 날짜값을 raw data로 받아 날짜로 변환.

FUNCTION zcp_excel_date_from_serial.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     REFERENCE(IV_DAYS) TYPE  CHAR08
*"  EXPORTING
*"     REFERENCE(EV_DATE) TYPE  DATS
*"----------------------------------------------------------------------

  DATA : lv_years    TYPE char04,
         lv_month(2) TYPE n,
         lv_date(2)  TYPE n,
         lv_days     TYPE i,
         lv_remain   TYPE i,
         lv_lunar    TYPE i, " 윤년 횟수.
         lv_base     TYPE i. " 기준년도

*---  for Excel Bug 1900.02.29
  IF iv_days GE 60 AND iv_days LT 367.
    lv_days = iv_days - 1.
    lv_base = 1900.
  ELSEIF iv_days GE 367.
    lv_days = iv_days - 366.
    lv_base = 1901.
    PERFORM calc_number USING    lv_days '/' '365.2425'
                        CHANGING lv_years.
  ELSE.
    lv_base = 1900.
    lv_days = iv_days.
  ENDIF.

  PERFORM get_leap_days USING    lv_years lv_base
                        CHANGING lv_lunar.

  lv_remain = lv_days
            - ( ( lv_years  * 365 ) + lv_lunar ) .

  lv_years = lv_years + lv_base.

  IF lv_remain EQ 0.
    lv_years = lv_years - 1 .
    lv_month = 12.
    lv_date  = 31.
  ELSE.

    CLEAR: lv_days.
    DO 12 TIMES.

      PERFORM get_mon_days USING    sy-index
                                    lv_years
                           CHANGING lv_days.

      IF lv_remain LE lv_days.
        IF lv_remain LT lv_days.
          lv_month = sy-index.
          lv_date  = lv_remain.
        ELSEIF lv_remain EQ lv_days.
          lv_month = sy-index.
          lv_date  = lv_days.
        ENDIF.
        EXIT.

      ELSE.
        lv_remain = lv_remain - lv_days.
      ENDIF.
    ENDDO.
  ENDIF.

  CONCATENATE lv_years lv_month lv_date
         INTO ev_date.

ENDFUNCTION.
*&---------------------------------------------------------------------*
*&      Form  CALC_NUMBER
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_NUM1  text
*      -->P_OPER  text
*      -->P_NUM2  text
*      <--P_RESULT  text
*----------------------------------------------------------------------*
FORM calc_number  USING    pv_num1
                           pv_oper
                           pv_num2
                  CHANGING pv_result.

  DATA : lv_str   TYPE char100,
         lv_num1  TYPE char100,
         lv_num2  TYPE char100,
         lv_value TYPE f,
         lv_int   TYPE i.

  IF pv_num1 EQ 0.
    pv_result = 0.
    EXIT.
  ENDIF.

  lv_num1 = pv_num1.
  lv_num2 = pv_num2.
  CONDENSE : lv_num1, lv_num2.

  CONCATENATE lv_num1 pv_oper lv_num2
         INTO lv_str SEPARATED BY space.
  CONDENSE lv_str.

  CALL FUNCTION 'EVAL_FORMULA'
    EXPORTING
      degrees                 = ' '
      formula                 = lv_str
      program                 = ' '
      routine                 = ' '
      unit_of_measure         = ' '
      no_existence_check      = ' '
    IMPORTING
      value                   = lv_value
    EXCEPTIONS
      division_by_zero        = 1
      exp_error               = 2
      formula_table_not_valid = 3
      invalid_expression      = 4
      invalid_value           = 5
      log_error               = 6
      parameter_error         = 7
      sqrt_error              = 8
      units_not_valid         = 9
      missing_parameter       = 10
      OTHERS                  = 11.

*--- 소수점 없으면 덤프 ;;
  lv_int = lv_value.

  IF lv_int NE lv_value.
    CALL FUNCTION 'FIMA_NUMERICAL_VALUE_ROUND'
      EXPORTING
        i_rtype     = '-'
        i_runit     = 1
        i_value     = lv_value
      IMPORTING
        e_value_rnd = pv_result.
  ELSE.
    pv_result = lv_int.
  ENDIF.

ENDFORM.                    " CALC_NUMBER
*&---------------------------------------------------------------------*
*&      Form  GET_MON_DAYS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_INDEX  text
*      <--P_DAYS  text
*----------------------------------------------------------------------*
FORM get_mon_days  USING    pv_index
                            pv_year
                   CHANGING pv_days.
  CLEAR : pv_days.

  DATA : lv_lunar1 TYPE i,
         lv_lunar2 TYPE i,
         lv_lunar3 TYPE i.

  lv_lunar1 = pv_year MOD 4 .
  lv_lunar2 = pv_year MOD 100 .
  lv_lunar3 = pv_year MOD 400 .

  CASE sy-index.
    WHEN 1 OR 3 OR 5 OR 7 OR 8 OR 10 OR 12.
      pv_days = 31.
    WHEN 2.
      IF ( pv_year MOD 4 ) EQ 0
         AND (
               ( pv_year MOD 100 ) NE 0
             OR
               ( pv_year MOD 400 ) EQ 0
              ).
        pv_days = 29.
      ELSE.
      pv_days = 28.
      ENDIF.
    WHEN OTHERS.
      pv_days = 30.
  ENDCASE.

ENDFORM.                    " GET_MON_DAYS
*&---------------------------------------------------------------------*
*&      Form  GET_LEAP_DAYS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_YEAR  text
*      <--P_DAYS  text
*----------------------------------------------------------------------*
FORM get_leap_days  USING    pv_year pv_base
                    CHANGING pv_days.

  DATA : lv_year  TYPE i,
         lv_value TYPE i,
         lv_days  TYPE i.

  CLEAR : pv_days.
  lv_year = pv_year + pv_base - 1.
  PERFORM calc_number USING    lv_year '/' 4
                      CHANGING lv_value.
  pv_days = pv_days + lv_value.

  PERFORM calc_number USING    lv_year '/' 100
                      CHANGING lv_value.
  pv_days = pv_days - lv_value.

  PERFORM calc_number USING    lv_year '/' 400
                      CHANGING lv_value.
  pv_days = pv_days + lv_value.


  PERFORM calc_number USING    pv_base '/' 4
                      CHANGING lv_value.
  lv_days = lv_days + lv_value.

  PERFORM calc_number USING    pv_base '/' 100
                      CHANGING lv_value.
  lv_days = lv_days - lv_value.

  PERFORM calc_number USING    pv_base '/' 400
                      CHANGING lv_value.
  lv_days = lv_days + lv_value.

  pv_days = pv_days - lv_days.

ENDFORM.                    " GET_LEAP_DAYS 



'SAP > ABAP' 카테고리의 다른 글

Function for Stock  (0) 2014.09.19
Get Structure/Table sub-components  (0) 2014.09.12
excel download ( OLE based )  (0) 2014.02.18
[Macro] Range 선언  (0) 2014.02.18
Chartset 변경.  (0) 2014.01.15