타임존이 시스템(서버) 기준:

날짜: SY-DATUM

시간: SY-UZEIT

타임존: 펑션 호출 GET_SYSTEM_TIMEZONE 또는 테이블 TTZCU

 

 

타임존이 사용자(로컬) 기준:

날짜: SY-DATLO

시간: SY-TIMLO

타임존: SY-ZONLO

 

 

타임존이 UTC(세계표준시) 기준:

날짜: GET TIME STAMP FIELD lv_ts. lv_ts(8)

시간: GET TIME STAMP FIELD lv_ts. lv_ts+8(6)

타임존: UTC

 

 

타임존이 다른 경우의 변환 로직:

CONVERT DATE lv_date_from TIME lv_time_from INTO TIME STAMP lv_ts TIME ZONE lv_tz_from.
CONVERT TIME STAMP lv_ts TIME ZONE lv_tz_to INTO DATE lv_date_to TIME lv_time_to.

 

 

타임존에 대한 이해가 필요한 경우 아래 글 참고:

https://boy0.tistory.com/181

 

ABAP TIMESTAMP 총정리

타임스탬프로 사용되는 타입은 두가지가 있습니다. TIMESTAMP : 15자리 YYYYMMDDhhmmss TIMESTAMPL : 21자리 YYYYMMDDhhmmss.ssssss 주로 사용하는 15자리 TIMESTAMP 를 기준으로 설명하겠습니다. 예를 들어 인천 에서

boy0.tistory.com

 

'ABAP' 카테고리의 다른 글

abap으로 open API (RESTful) 호출하기  (1) 2023.12.20
abap으로 ZIP 압축하기  (0) 2023.10.17
search help exit 총정리  (0) 2023.04.25
FUNCTION ZADD_1_ALPHANUM  (0) 2022.12.20
ABAP TIMESTAMP 총정리  (0) 2021.12.27

RESTful API 호출하는 예제 프로그램.

*&---------------------------------------------------------------------*
*& Report ZRESTFUL_API
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zrestful_api.

PARAMETERS: p_string TYPE string.

TYPES: BEGIN OF ts_req,
         BEGIN OF argument,
           type     TYPE string,
           question TYPE string,
         END OF argument,
       END OF ts_req,
       BEGIN OF ts_res_irinfo,
         wiki_title TYPE string,
         sent       TYPE string,
         url        TYPE string,
       END OF ts_res_irinfo,
       BEGIN OF ts_res_answerinfo,
         rank       TYPE i,
         answer     TYPE string,
         confidence TYPE i,
         url        TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
       END OF ts_res_answerinfo,
       BEGIN OF ts_res,
         result TYPE string,
         BEGIN OF return_object,
           BEGIN OF wikiinfo,
             irinfo     TYPE STANDARD TABLE OF ts_res_irinfo WITH DEFAULT KEY,
             answerinfo TYPE STANDARD TABLE OF ts_res_answerinfo WITH DEFAULT KEY,
           END OF wikiinfo,
         END OF return_object,
       END OF ts_res.

DATA: lv_url      TYPE string,
      ls_req      TYPE ts_req,
      lv_req_json TYPE string,
      lo_client   TYPE REF TO if_http_client,
      lv_message  TYPE string,
      lv_res_json TYPE string,
      ls_res      TYPE ts_res.

* 위키백과 QA API
* https://aiopen.etri.re.kr/guide/WikiQA
lv_url = |http://aiopen.etri.re.kr:8000/WikiQA|.
ls_req-argument-type = 'hybridqa'.
ls_req-argument-question = p_string.

"REQ to json
/ui2/cl_json=>serialize(
  EXPORTING
    data             = ls_req             " Data to serialize
    pretty_name      = /ui2/cl_json=>pretty_mode-low_case      " Pretty Print property names
  RECEIVING
    r_json           = lv_req_json           " JSON string
).

"HTTP create
cl_http_client=>create_by_url(
  EXPORTING
    url                    = lv_url             " URL
  IMPORTING
    client                 = lo_client          " HTTP Client Abstraction
  EXCEPTIONS
    argument_not_found     = 1               " Communication parameter (host or service) not available
    plugin_not_active      = 2               " HTTP/HTTPS communication not available
    internal_error         = 3               " Internal error (e.g. name too long)
    pse_not_found          = 4               " PSE not found
    pse_not_distrib        = 5               " PSE not distributed
    pse_errors             = 6               " General PSE error
    OTHERS                 = 7
).
IF sy-subrc <> 0.
  MESSAGE 'HTTP error' TYPE 'E'.
  RETURN.
ENDIF.

" HTTP request
lo_client->request->set_method(
    method = if_http_request=>co_request_method_post
).
lo_client->request->set_header_field(
  EXPORTING
    name  = 'Content-Type'
    value = 'application/json'
).
lo_client->request->set_header_field(
  EXPORTING
    name  = 'Authorization'
    value = 'cfd006b6-7766-42ca-88fc-3cd1e1c357f7'
).
lo_client->request->set_cdata(
  EXPORTING
    data   = lv_req_json
).

"HTTP send
lo_client->send(
  EXCEPTIONS
    http_communication_failure = 1                  " Communication Error
    http_invalid_state         = 2                  " Invalid state
    http_processing_failed     = 3                  " Error when processing method
    http_invalid_timeout       = 4                  " Invalid Time Entry
    OTHERS                     = 5
).
IF sy-subrc <> 0.
  lo_client->get_last_error(
    IMPORTING
      message        = lv_message
  ).
  MESSAGE lv_message TYPE 'E'.
  RETURN.
ENDIF.

"HTTP receive
lo_client->receive(
  EXCEPTIONS
    http_communication_failure = 1 " Communication Error
    http_invalid_state         = 2 " Invalid state
    http_processing_failed     = 3 " Error when processing method
    OTHERS                     = 4
).
IF sy-subrc <> 0.
  lo_client->get_last_error(
    IMPORTING
      message        = lv_message
  ).
  MESSAGE lv_message TYPE 'E'.
  RETURN.
ENDIF.

"HTTP response
IF lo_client->response IS NOT INITIAL.
  lv_res_json = lo_client->response->get_cdata( ).
ENDIF.

"json to RES
/ui2/cl_json=>deserialize(
  EXPORTING
    json             = lv_res_json             " JSON string
  CHANGING
    data             = ls_res             " Data to serialize
).
*BREAK-POINT.

IF ls_res-return_object-wikiinfo-answerinfo IS NOT INITIAL.
  cl_demo_output=>display( ls_res-return_object-wikiinfo-answerinfo[ 1 ]-answer ).
ENDIF.

'ABAP' 카테고리의 다른 글

SY-DATUM 과 SY-DATLO 차이  (0) 2024.01.04
abap으로 ZIP 압축하기  (0) 2023.10.17
search help exit 총정리  (0) 2023.04.25
FUNCTION ZADD_1_ALPHANUM  (0) 2022.12.20
ABAP TIMESTAMP 총정리  (0) 2021.12.27

ZIP 압축하는 예제 프로그램.

*&---------------------------------------------------------------------*
*& Report ZZIP
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zzip.

DATA: lt_file_table TYPE filetable,
      ls_file_table TYPE file_table,
      lv_rc         TYPE i,
      lv_filename   TYPE string,
      lv_path       TYPE string,
      lv_fullpath   TYPE string,
      lv_filelength TYPE i,
      lt_temptable  TYPE w3mimetabtype,
      lv_xstring    TYPE xstring,
      lo_zip        TYPE REF TO cl_abap_zip.

cl_gui_frontend_services=>file_open_dialog(
  EXPORTING
*    window_title            =                  " Title Of File Open Dialog
*    default_extension       =                  " Default Extension
*    default_filename        =                  " Default File Name
*    file_filter             =                  " File Extension Filter String
*    with_encoding           =                  " File Encoding
*    initial_directory       =                  " Initial Directory
    multiselection          = abap_true                 " Multiple selections poss.
  CHANGING
    file_table              = lt_file_table                 " Table Holding Selected Files
    rc                      = lv_rc                 " Return Code, Number of Files or -1 If Error Occurred
*    user_action             =                  " User Action (See Class Constants ACTION_OK, ACTION_CANCEL)
*    file_encoding           =
  EXCEPTIONS
    file_open_dialog_failed = 1                " "Open File" dialog failed
    cntl_error              = 2                " Control error
    error_no_gui            = 3                " No GUI available
    not_supported_by_gui    = 4                " GUI does not support this
    OTHERS                  = 5
).
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

CHECK: lt_file_table IS NOT INITIAL.
CREATE OBJECT lo_zip.
lo_zip->support_unicode_names = abap_true.

LOOP AT lt_file_table INTO ls_file_table.
  CLEAR: lv_filename, lv_filelength, lt_temptable, lv_xstring.

  lv_filename = ls_file_table-filename.
  cl_gui_frontend_services=>gui_upload(
    EXPORTING
      filename                = lv_filename            " Name of file
      filetype                = 'BIN'            " File Type (ASCII, Binary)
*      has_field_separator     = space            " Columns Separated by Tabs in Case of ASCII Upload
*      header_length           = 0                " Length of Header for Binary Data
*      read_by_line            = 'X'              " File Written Line-By-Line to the Internal Table
*      dat_mode                = space            " Numeric and date fields are in DAT format in WS_DOWNLOAD
*      codepage                =                  " Character Representation for Output
*      ignore_cerr             = abap_true        " Ignore character set conversion errors?
*      replacement             = '#'              " Replacement Character for Non-Convertible Characters
*      virus_scan_profile      =                  " Virus Scan Profile
    IMPORTING
      filelength              = lv_filelength                  " File Length
*      header                  =                  " File Header in Case of Binary Upload
    CHANGING
      data_tab                = lt_temptable                 " Transfer table for file contents
*      isscanperformed         = space            " File already scanned
    EXCEPTIONS
      file_open_error         = 1                " File does not exist and cannot be opened
      file_read_error         = 2                " Error when reading file
      no_batch                = 3                " Cannot execute front-end function in background
      gui_refuse_filetransfer = 4                " Incorrect front end or error on front end
      invalid_type            = 5                " Incorrect parameter FILETYPE
      no_authority            = 6                " No upload authorization
      unknown_error           = 7                " Unknown error
      bad_data_format         = 8                " Cannot Interpret Data in File
      header_not_allowed      = 9                " Invalid header
      separator_not_allowed   = 10               " Invalid separator
      header_too_long         = 11               " Header information currently restricted to 1023 bytes
      unknown_dp_error        = 12               " Error when calling data provider
      access_denied           = 13               " Access to file denied.
      dp_out_of_memory        = 14               " Not enough memory in data provider
      disk_full               = 15               " Storage medium is full.
      dp_timeout              = 16               " Data provider timeout
      not_supported_by_gui    = 17               " GUI does not support this
      error_no_gui            = 18               " GUI not available
      OTHERS                  = 19
  ).
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
    EXPORTING
      input_length = lv_filelength
*     first_line   = 0
*     last_line    = 0
    IMPORTING
      buffer       = lv_xstring
    TABLES
      binary_tab   = lt_temptable
    EXCEPTIONS
      failed       = 1
      OTHERS       = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  CALL FUNCTION 'SO_SPLIT_FILE_AND_PATH'
    EXPORTING
      full_name     = ls_file_table-filename
    IMPORTING
      stripped_name = lv_filename
    EXCEPTIONS
      x_error       = 1
      OTHERS        = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  lo_zip->add(
    EXPORTING
      name           = lv_filename
      content        = lv_xstring
*      compress_level = 6                " Level of Compression
  ).

ENDLOOP.

lv_xstring = lo_zip->save( ).

CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
  EXPORTING
    buffer        = lv_xstring
  IMPORTING
    output_length = lv_filelength
  TABLES
    binary_tab    = lt_temptable.

cl_gui_frontend_services=>file_save_dialog(
  EXPORTING
*    window_title              =                  " Window Title
    default_extension         = 'ZIP'                 " Default Extension
    default_file_name         = 'a.zip'                 " Default File Name
*    with_encoding             =
    file_filter               = 'ZIP(*.ZIP)|*.ZIP'                 " File Type Filter Table
*    initial_directory         =                  " Initial Directory
*    prompt_on_overwrite       = 'X'
  CHANGING
    filename                  = lv_filename                 " File Name to Save
    path                      = lv_path                 " Path to File
    fullpath                  = lv_fullpath                 " Path + File Name
*    user_action               =                  " User Action (C Class Const ACTION_OK, ACTION_OVERWRITE etc)
*    file_encoding             =
  EXCEPTIONS
    cntl_error                = 1                " Control error
    error_no_gui              = 2                " No GUI available
    not_supported_by_gui      = 3                " GUI does not support this
    invalid_default_file_name = 4                " Invalid default file name
    OTHERS                    = 5
).
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

cl_gui_frontend_services=>gui_download(
  EXPORTING
    bin_filesize              = lv_filelength                     " File length for binary files
    filename                  = lv_fullpath                     " Name of file
    filetype                  = 'BIN'                " File type (ASCII, binary ...)
*    append                    = space                " Character Field of Length 1
*    write_field_separator     = space                " Separate Columns by Tabs in Case of ASCII Download
*    header                    = '00'                 " Byte Chain Written to Beginning of File in Binary Mode
*    trunc_trailing_blanks     = space                " Do not Write Blank at the End of Char Fields
*    write_lf                  = 'X'                  " Insert CR/LF at End of Line in Case of Char Download
*    col_select                = space                " Copy Only Selected Columns of the Table
*    col_select_mask           = space                " Vector Containing an 'X' for the Column To Be Copied
*    dat_mode                  = space                " Numeric and date fields are in DAT format in WS_DOWNLOAD
*    confirm_overwrite         = space                " Overwrite File Only After Confirmation
*    no_auth_check             = space                " Switch off Check for Access Rights
*    codepage                  =                      " Character Representation for Output
*    ignore_cerr               = abap_true            " Ignore character set conversion errors?
*    replacement               = '#'                  " Replacement Character for Non-Convertible Characters
*    write_bom                 = space                " If set, writes a Unicode byte order mark
*    trunc_trailing_blanks_eol = 'X'                  " Remove Trailing Blanks in Last Column
*    wk1_n_format              = space
*    wk1_n_size                = space
*    wk1_t_format              = space
*    wk1_t_size                = space
*    show_transfer_status      = 'X'                  " Enables suppression of transfer status message
*    fieldnames                =                      " Table Field Names
*    write_lf_after_last_line  = 'X'                  " Writes a CR/LF after final data record
*    virus_scan_profile        = '/SCET/GUI_DOWNLOAD' " Virus Scan Profile
*  IMPORTING
*    filelength                =                      " Number of bytes transferred
  CHANGING
    data_tab                  = lt_temptable                     " Transfer table
  EXCEPTIONS
    file_write_error          = 1                    " Cannot write to file
    no_batch                  = 2                    " Cannot execute front-end function in background
    gui_refuse_filetransfer   = 3                    " Incorrect Front End
    invalid_type              = 4                    " Invalid value for parameter FILETYPE
    no_authority              = 5                    " No Download Authorization
    unknown_error             = 6                    " Unknown error
    header_not_allowed        = 7                    " Invalid header
    separator_not_allowed     = 8                    " Invalid separator
    filesize_not_allowed      = 9                    " Invalid file size
    header_too_long           = 10                   " Header information currently restricted to 1023 bytes
    dp_error_create           = 11                   " Cannot create DataProvider
    dp_error_send             = 12                   " Error Sending Data with DataProvider
    dp_error_write            = 13                   " Error Writing Data with DataProvider
    unknown_dp_error          = 14                   " Error when calling data provider
    access_denied             = 15                   " Access to file denied.
    dp_out_of_memory          = 16                   " Not enough memory in data provider
    disk_full                 = 17                   " Storage medium is full.
    dp_timeout                = 18                   " Data provider timeout
    file_not_found            = 19                   " Could not find file
    dataprovider_exception    = 20                   " General Exception Error in DataProvider
    control_flush_error       = 21                   " Error in Control Framework
    not_supported_by_gui      = 22                   " GUI does not support this
    error_no_gui              = 23                   " GUI not available
    OTHERS                    = 24
).
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

'ABAP' 카테고리의 다른 글

SY-DATUM 과 SY-DATLO 차이  (0) 2024.01.04
abap으로 open API (RESTful) 호출하기  (1) 2023.12.20
search help exit 총정리  (0) 2023.04.25
FUNCTION ZADD_1_ALPHANUM  (0) 2022.12.20
ABAP TIMESTAMP 총정리  (0) 2021.12.27

알 수 없는 이유로 데이터가 꼬여서 덤프 에러 Exception condition "NO_KEY" triggered 발생하곤 합니다.

가비지 데이터 정리 프로그램 만들어 보았습니다.

 

코드:

 

*&---------------------------------------------------------------------*
*& Report ZMDP_ADJUST_STAGING
*&---------------------------------------------------------------------*
*& MDG staging table 가비지 데이터 삭제 처리 프로그램
*&---------------------------------------------------------------------*
REPORT zmdp_adjust_staging LINE-SIZE 250.

DATA : lt_message           TYPE usmd_t_message,
       ls_message           TYPE usmd_s_message,
       lt_model             TYPE TABLE OF usmd_model,
       lv_model             TYPE usmd_model,
       lo_model_gen_adapter TYPE REF TO if_usmd_model_gen_adapter,
       ls_log_phys_name     TYPE if_usmd_model_gen_adapter=>s_log_phys_name,
       lt_log_phys_name     TYPE if_usmd_model_gen_adapter=>t_log_phys_name,
       lv_entity            TYPE string,
       lv_select            TYPE string,
       lv_table             TYPE string,
       lv_key_field         TYPE string,
*       lt_range_key_value   TYPE RANGE OF usmd_tech_key,
       lt_key_value         TYPE TABLE OF usmd_tech_key,
       lv_key_value         TYPE usmd_tech_key,
       lv_usmd_value        TYPE usmd_value,
       lt_cr                TYPE TABLE OF usmd_crequest,
       lv_cr                TYPE usmd_crequest,
       lt_usmd1213          TYPE TABLE OF usmd1213,
       ls_usmd1213          TYPE usmd1213,
       lv_flag_del          TYPE flag,
       lv_where             TYPE string,
       lv_key_json          TYPE string,
       lr_data              TYPE REF TO data,
       lv_error             TYPE char1,
       lv_index             TYPE i.

FIELD-SYMBOLS: <lt_data> TYPE tabel,
               <ls_data> TYPE data,
               <lv_data> TYPE data.

*--------------------------------------------------------------------*
" 모델 검색
SELECT-OPTIONS so_model FOR lv_model MATCHCODE OBJECT zmdph_model.



*--------------------------------------------------------------------*
START-OF-SELECTION.

*--------------------------------------
  " 활성 상태의 모델정보 검색
  SELECT usmd_model
    INTO TABLE lt_model
    FROM usmd001c
   WHERE usmd_model IN so_model
     AND usmd_objstat = 'A'.
  "
  IF sy-subrc NE 0.
    " 레코드 검색 실패
    MESSAGE s000(oo) WITH 'Data not found.' DISPLAY LIKE 'E'.
    " 작업 종료
    STOP.
  ENDIF.

*--------------------------------------
  " 모델별 작업
  LOOP AT lt_model INTO lv_model.
    "
    WRITE:/ ' *** ' , lv_model COLOR 7, ' *** '.

    "*----------------------------
    " 모델 정보로 활성된 테이블 정보 검색
    CALL METHOD cl_usmd_adapter_provider=>get_model_generation_adapter
      EXPORTING
        i_usmd_model         = lv_model
      IMPORTING
        eo_model_gen_adapter = lo_model_gen_adapter
        et_message           = lt_message.

    CLEAR lv_error.
    "
    LOOP AT lt_message TRANSPORTING NO FIELDS WHERE msgty CA 'AEX'.
      "*----------------------------
      " 오륲 메세지 처리
      MESSAGE ID ls_message-msgid TYPE 'S' NUMBER ls_message-msgno DISPLAY LIKE ls_message-msgty
        WITH ls_message-msgv1 ls_message-msgv2 ls_message-msgv3 ls_message-msgv4.
      " 오류 발생
      lv_error = abap_true.
    ENDLOOP.

    "*----------------------------
    " 오류 없을시 작업 진행
    CHECK lv_error IS INITIAL.

    "*----------------------------
    " 활성 테이블 정보 검색
    CALL METHOD lo_model_gen_adapter->get_generated_objects
      EXPORTING
        if_mdf_hry_tab   = abap_false
      IMPORTING
        et_message       = lt_message
        et_log_phys_name = lt_log_phys_name.    " 활성 테이블 정보

    "*----------------------------
    "
    LOOP AT lt_log_phys_name INTO ls_log_phys_name.

      CASE ls_log_phys_name-sub_kind.
        WHEN usmd1_cs_tabl_kind-check.
          "
          lv_entity    = ls_log_phys_name-entity.
          lv_table     = ls_log_phys_name-phys_name.
          lv_key_field = 'USMDK' && lv_model && lv_entity.

          "
          WRITE:/ '*', lv_entity, lv_table.

          TRY .
              "*----------------------------
              " 테이블 키 밸류 검색
              SELECT (lv_key_field)
                FROM (lv_table)
                INTO TABLE @lt_key_value.
            CATCH cx_sy_dynamic_osql_semantics.
              CONTINUE.
          ENDTRY.

          "*----------------------------
          " 키 중복 제거
          SORT lt_key_value.
          DELETE ADJACENT DUPLICATES FROM lt_key_value.

          "*----------------------------
          " 키 밸류별 작업
          LOOP AT lt_key_value INTO lv_key_value.
            "
            CLEAR: lv_flag_del.
            "
            lv_usmd_value = lv_key_value.

            " 키에 매핑된 Change Request 정보 검색
            SELECT usmd_crequest
              INTO TABLE lt_cr
              FROM usmd1213
             WHERE usmd_entity     = lv_entity
               AND usmd_entity_obj = lv_entity
               AND usmd_value      = lv_usmd_value.
            IF sy-subrc <> 0.
              " 삭제 대상 설정
              lv_flag_del = abap_true.
            ENDIF.

            " Change Request 별 상태 검색
            LOOP AT lt_cr INTO lv_cr.
              SELECT SINGLE mandt
                INTO sy-mandt
                FROM usmd120c
               WHERE usmd_crequest = lv_cr
                 AND usmd_creq_status NOT IN (usmd0_cs_crequest_status-finally_approved,  " 05: 승인완료
                                              usmd0_cs_crequest_status-finally_rejected). " 06: 반려완료.
              IF sy-subrc <> 0.
                " 삭제 대상 설정
                lv_flag_del = abap_true.
                " 루프 종료
                EXIT.
              ENDIF.
            ENDLOOP. " LOOP AT lt_cr INTO lv_cr.

            "*----------------------------
            " 삭제 대상인 경우
            IF lv_flag_del EQ abap_true.
              "
              lv_where = |{ lv_key_field } = lv_key_value|.

*              lv_table = lt_log_phys_name[ entity   = lv_entity
*                                           sub_kind = usmd1_cs_tabl_kind-map ]-phys_name.
              READ TABLE lt_log_phys_name INTO ls_log_phys_name
               WITH KEY entity = lv_entity sub_kind = usmd1_cs_tabl_kind-map.
              lv_table = ls_log_phys_name-phys_name.
              "
              CREATE DATA lr_data TYPE (lv_table).
              ASSIGN lr_data->* TO <ls_data>.
              "
              lv_key_json = lv_usmd_value.
              SELECT SINGLE * INTO <ls_data>
                FROM (lv_table)
               WHERE (lv_where).
              "
              lv_key_json = /ui2/cl_json=>serialize( <ls_data> ).
              "
              WRITE:/ lv_key_json.

              "*----------------------------
              " 테이블별 레코드 삭제
              " 엔티티별 매핑 테이블이 아닌 테이블에 대해 작업
              LOOP AT lt_log_phys_name INTO ls_log_phys_name
                                      WHERE kind     = 'TABL'
                                        AND entity   = lv_entity
                                        AND sub_kind <> usmd1_cs_tabl_kind-map.
                "*----------------------------
                " 테이블 아이디 설정
                lv_table = ls_log_phys_name-phys_name.
                "*----------------------------
                " 테이블 레코드 삭제 처리
                DELETE FROM (lv_table) WHERE (lv_where).
              ENDLOOP.
            ENDIF.
          ENDLOOP. " LOOP AT lt_key_value INTO lv_key_value.


        WHEN usmd1_cs_tabl_kind-map.
          "
          lv_entity    = ls_log_phys_name-entity.
          lv_table     = ls_log_phys_name-phys_name.
          lv_key_field = 'USMDK' && lv_model && lv_entity.

          "
          WRITE:/ '*', lv_entity, lv_table, 'USMD1213'.

          TRY .
              "*----------------------------
              " 테이블 키 밸류 검색
*              lv_select = |'I' AS SIGN, 'EQ' AS OPTION, { lv_key_field } AS LOW|.
              lv_select = lv_key_field.
              SELECT (lv_select)
                FROM (lv_table)
*                INTO TABLE @lt_range_key_value.
                INTO TABLE @lt_key_value.
              SORT lt_key_value.
            CATCH cx_sy_dynamic_osql_semantics.
              CONTINUE.
          ENDTRY.

          " 키에 매핑 안된 Change Request 정보 검색
          SELECT *
            INTO TABLE lt_usmd1213
            FROM usmd1213
           WHERE usmd_entity     = lv_entity
             AND usmd_entity_obj = lv_entity.
*             AND usmd_value      NOT IN lt_range_key_value.

          LOOP AT lt_usmd1213 INTO ls_usmd1213.
            READ TABLE lt_key_value TRANSPORTING NO FIELDS WITH KEY table_line = ls_usmd1213-usmd_value BINARY SEARCH.
            IF sy-subrc EQ 0.
              DELETE lt_usmd1213.
            ELSE.
              lv_key_json = /ui2/cl_json=>serialize( ls_usmd1213 ).
              WRITE:/ lv_key_json.
            ENDIF.
          ENDLOOP.

          DELETE usmd1213 FROM TABLE lt_usmd1213.

        WHEN OTHERS.
      ENDCASE.

    ENDLOOP. " LOOP AT lt_log_phys_name INTO ls_log_phys_name

  ENDLOOP. " LOOP AT lt_model INTO lv_model.

*--------------------------------------
  " 커밋
  COMMIT WORK.

'ABAP > MDG 기준정보' 카테고리의 다른 글

ZCL_MDP_READ_HELPER  (0) 2021.12.15
MDG BP 생성/수정 CR 만드는 로직  (0) 2021.12.15

취미로 개발중인 프로그램...

https://github.com/boy0korea/abap2json

 

GitHub - boy0korea/abap2json: abap2json is convertor to export abap table data to json format

abap2json is convertor to export abap table data to json format - GitHub - boy0korea/abap2json: abap2json is convertor to export abap table data to json format

github.com

abap2xlsx 를 패러디 하여 abap2json 으로 이름을 지었습니다.

테이블 내용을 json 포맷으로 저장합니다.

개발서버-품질서버-운영서버 간에 데이터를 복사할때도 사용할 수 있습니다.

(서버간 데이터 복사는 RFC 펑션으로 전달되며 전송에 json 포맷이 사용됩니다)

 

파일 생성 예

 

프로그램 ZABAP2JSON

Import ZIP

가져오기 (*.json.zip)

Comapre ZIP

비교 (*.json.zip)

Export Table

내보내기 테이블 단위 TABLE.datetime.json.zip

Export Package

내보내기 패키지 단위 *.json.zip

Comapre Table

서버간 테이블 내용 비교

Copy Table

서버간 테이블 내용 복사

DDIC 서치 헬프 만드는 방법에는 3가지가 있습니다.

  • Selection Method 에 테이블 입력
  • Search Help Exit 에 펑션 입력
  • Selection Method와 Search Help Exit 둘다 입력

 

테이블을 입력해서 만드는건 가장 기초적인 작성법이니 쉽게 아실테고 Exit 펑션을 입력하여 만드는 방법이 난이도가 상당히 있습니다.

 

개발을 시작하는 방법은 우선 펑션모듈 F4IF_SHLP_EXIT_EXAMPLE 을 복사하여 펑션모듈을 하나 만듭니다.

이 펑션에는 파라미터 4개가 있습니다. 이중 CALLCONTROL 과 SHLP 이 두 파라미터를 이용합니다.

exit 펑션은 CALLCONTROL-STEP 값이 변경되면서 여러번 호출 됩니다.

F4IF_SHLP_EXIT_EXAMPLE에 각 CALLCONTROL-STEP 에 따른 설명이 들어 있으니 참고 하시기 바랍니다.

보통은 SELECT와 DISP 일때만 처리합니다.

 

SHLP-SELOPT : 검색조건 range. SELECT step 에서 변경 하면 화면에 반영됩니다. DISP step 에서는 변경 못합니다.

SHLP-FIELDDESCR : 필드 명세. 예를 들어 필드 헤더 텍스트는 SCRTEXT_* 에 값을 변경하면 됩니다.

SHLP-FIELDPROP: 필드 속성. 서치헬프 파라미터 부분에 설정한 내용을 변경 할 수 있습니다. 예를 들어 표시 순서는 SHLPLISPOS 에 값을 변경하면 됩니다. 

CALLCONTROL-STEP : step 조건. 예를 들어 값을 EXIT로 변경하면 서치헬프가 종료 됩니다. 자동으로 값을 리턴하는 방법도 있는데 RETURN 으로 변경하고 F4UT_PARAMETER_RESULTS_PUT 펑션을 이용하여 결과 값을 넘겨주면 됩니다.

CALLCONTROL-SORTOFF : 'X'로 값을 주면 자동 정렬 끄기. 내맘대로 정렬 할 수 있습니다.

CALLCONTROL-MAXRECORDS : 최대 결과 수

CALLCONTROL-MAXEXCEED : 검색 결과가 최대 결과 수 초과 여부

CALLCONTROL-TOP_SHLP : Collective search help 의 경우 지금 선택된 Elementary search help

 

복잡한 코딩 예는 아래 프로젝트를 참고하시기 바랍니다.

https://github.com/boy0korea/ALL_ROUND_SEARCH_HELP

 

GitHub - boy0korea/ALL_ROUND_SEARCH_HELP: All Round Search Help

All Round Search Help. Contribute to boy0korea/ALL_ROUND_SEARCH_HELP development by creating an account on GitHub.

github.com

 

 

간단한 예제 코드는 이렇습니다.

FUNCTION zmdp_hr_exit_usr_tel.
*"--------------------------------------------------------------------
*"*"Local Interface:
*"  TABLES
*"      SHLP_TAB TYPE  SHLP_DESCT
*"      RECORD_TAB STRUCTURE  SEAHLPRES
*"  CHANGING
*"     VALUE(SHLP) TYPE  SHLP_DESCR
*"     VALUE(CALLCONTROL) LIKE  DDSHF4CTRL STRUCTURE  DDSHF4CTRL
*"--------------------------------------------------------------------
  TYPES:
    BEGIN OF lty_stru_list,
*   add fields for the selection list here
      tel TYPE zmdpt_m_usr-tel,
    END OF lty_stru_list.
  DATA: lt_select_list TYPE STANDARD TABLE OF lty_stru_list,
        ls_select_list LIKE LINE OF lt_select_list,
        ls_selopt      TYPE ddshselopt,
        lv_keydate     TYPE datum,
        lt_range_tel   TYPE RANGE OF zmdpt_m_usr-tel,
        ls_range_tel   LIKE LINE OF lt_range_tel.

  CHECK: callcontrol-step EQ 'SELECT'.

  LOOP AT shlp-selopt INTO ls_selopt.
    CASE ls_selopt-shlpfield.
      WHEN 'TEL'.
        MOVE-CORRESPONDING ls_selopt TO ls_range_tel.
        REPLACE ALL OCCURRENCES OF REGEX '[^[:digit:]*+]' IN ls_range_tel-low WITH ''.
        REPLACE ALL OCCURRENCES OF REGEX '[^[:digit:]*+]' IN ls_range_tel-high WITH ''.
        APPEND ls_range_tel TO lt_range_tel.
      WHEN 'KEYDATE'.
        lv_keydate = ls_selopt-low.
    ENDCASE.
  ENDLOOP.

  IF lv_keydate IS INITIAL.
    lv_keydate = sy-datum.
    CLEAR: ls_selopt.
    ls_selopt-shlpfield = 'KEYDATE'.
    ls_selopt-sign = 'I'.
    ls_selopt-option = 'EQ'.
    ls_selopt-low = lv_keydate.
    APPEND ls_selopt TO shlp-selopt.
  ENDIF.


  SELECT DISTINCT tel
    INTO TABLE lt_select_list
    FROM zmdpt_m_usr
    WHERE tel_mc IN lt_range_tel
      AND begda <= lv_keydate
      AND endda >= lv_keydate.
  CHECK: lt_select_list IS NOT INITIAL.

  callcontrol-maxexceed = abap_false.
  IF callcontrol-maxrecords IS NOT INITIAL AND
     lines( lt_select_list ) > callcontrol-maxrecords.
    DELETE lt_select_list FROM callcontrol-maxrecords + 1.
    callcontrol-maxexceed = abap_true.
  ENDIF.

* map
  CALL FUNCTION 'F4UT_RESULTS_MAP'
    TABLES
      shlp_tab    = shlp_tab
      record_tab  = record_tab
      source_tab  = lt_select_list
    CHANGING
      shlp        = shlp
      callcontrol = callcontrol.

  callcontrol-step = 'DISP'.


ENDFUNCTION.

'ABAP' 카테고리의 다른 글

abap으로 open API (RESTful) 호출하기  (1) 2023.12.20
abap으로 ZIP 압축하기  (0) 2023.10.17
FUNCTION ZADD_1_ALPHANUM  (0) 2022.12.20
ABAP TIMESTAMP 총정리  (0) 2021.12.27
abap2xlsx  (0) 2021.05.07

숫자와 영문자 순번 증가

10+26개 = 36진법

FUNCTION ZADD_1_ALPHANUM.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IV_SKIP_CHAR) TYPE  CLIKE OPTIONAL
*"     REFERENCE(IV_OFFSET) TYPE  I DEFAULT -1
*"  CHANGING
*"     REFERENCE(CV_DATA) TYPE  CLIKE
*"----------------------------------------------------------------------
* 이 구현은 ECATT_INCREASE_ALPHANUM_ID 를 참고 하였습니다.
* overflow가 발생하면 000...0 으로 다시 돌아갑니다.
* 자리수가 자동으로 늘어나면서 앞에 1이 붙지는 않습니다.

  CONSTANTS: lc_trans TYPE char72 VALUE '0112233445566778899AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ0'.
  DATA: lv_c      TYPE char1,
        lv_offset TYPE i.

  IF iv_offset < 0.

    lv_offset = strlen( cv_data ) - 1.    " 마지막 글자 위치.
    CALL FUNCTION 'ZADD_1_ALPHANUM'
      EXPORTING
        iv_skip_char = iv_skip_char
        iv_offset    = lv_offset
      CHANGING
        cv_data      = cv_data.

  ELSE.

    lv_c = cv_data+iv_offset(1).
    TRANSLATE cv_data+iv_offset(1) USING lc_trans.

    IF cv_data+iv_offset(1) EQ '0'.
*   자리수 올림은 재귀 호출로 처리한다.
      lv_offset = iv_offset - 1.    " 앞 글자 위치.
      IF lv_offset >= 0.
        CALL FUNCTION 'ZADD_1_ALPHANUM'
          EXPORTING
            iv_skip_char = iv_skip_char
            iv_offset    = lv_offset
          CHANGING
            cv_data      = cv_data.
      ENDIF.
    ENDIF.

    IF iv_skip_char IS NOT INITIAL AND
       cv_data+iv_offset(1) CA iv_skip_char.
      CALL FUNCTION 'ZADD_1_ALPHANUM'
        EXPORTING
          iv_skip_char = iv_skip_char
          iv_offset    = iv_offset
        CHANGING
          cv_data      = cv_data.
    ENDIF.
  ENDIF.

ENDFUNCTION.

'ABAP' 카테고리의 다른 글

abap으로 ZIP 압축하기  (0) 2023.10.17
search help exit 총정리  (0) 2023.04.25
ABAP TIMESTAMP 총정리  (0) 2021.12.27
abap2xlsx  (0) 2021.05.07
KR_POSTCODE : 한국주소입력  (0) 2021.03.31

웹딘프로 layout에 HTML_FRAGMENT를 하나 그려줍니다.

WDDOMODIFYVIEW 메소드에서

IF first_time EQ abap_true. 으로 한번만 실행되도록 하고

HTML_FRAGMENT 엘리먼트의 html 속성에 HTML tag를 하나 넣겠습니다.

<img src="/sap/public/bc/ur/nw5/1x1.gif" style="display: none;" onload="alert('script test');" />

ABAP 코드는 이렇습니다.

CAST cl_wd_html_fragment( io_view->get_element( 'HTML_FRAGMENT' ) )->set_html(
  `<img src="/sap/public/bc/ur/nw5/1x1.gif" style="display: none;" onload="alert('script test');" />`
).

내용을 설명드리겠습니다.

IMG tag를 이용해서 onload 시점에 실행할 JavaScript를 넣으면 됩니다. 예를 들어 아래 테스트 코드를 넣어 봤습니다.

alert('script test');

IMG의 onload가 실행되는 시점은 웹브라우저가 화면을 그리고 src 속성의 파일을 읽어와서야 실행됩니다. 매우 나중에 실행되는 타이밍입니다.

 

 

좀 더 복잡한 스크립트가 들어간 예제를 보여드리겠습니다.

파일 업로드 팝업인데 팝업이 뜨면 웹딘프로의 파일업로드 엘리먼트를 클릭하지 않아도 자동으로 클릭해서 파일 선택 창이 나오고 파일을 선택하면 자동으로 팝업의 OK 버튼을 눌러 닫힙니다.

CAST cl_wd_html_fragment( io_view->get_element( 'HTML_FRAGMENT' ) )->set_html(
  `<img src="/sap/public/bc/ur/nw5/1x1.gif" style="display: none;" ` &&
  `onload="` &&
  `var el = this;` &&
  `while( !el.classList.contains('lsPopupWindow') ) {` &&                 " popup div
  `  el = el.parentElement;` &&
  `}` &&
  `var file = el.querySelector('input[type=file]');` &&                   " file input box
  `var ok = el.querySelector('.urPWFooterBottomLine .lsButton');` &&      " ok button
  `file.oninput = function() { UCF_JsUtil.delayedCall( 200, ok, 'click' ); };` &&
  `file.click();` &&
  `" />`
).

IMG tag를 이용한 onload에 스크립트 넣기 방식은 동일합니다. JavaScript만 가져와서 보겠습니다.

var el = this;
while( !el.classList.contains('lsPopupWindow') ) {
  el = el.parentElement;
}
var file = el.querySelector('input[type=file]');
var ok = el.querySelector('.urPWFooterBottomLine .lsButton');
file.oninput = function() { UCF_JsUtil.delayedCall( 200, ok, 'click' ); };
file.click();

처음 4줄은 el 변수에 lsPopupWindow 이라는 class 속성을 가진 엘리먼트를 찾습니다. (웹딘프로 팝업의 태두리입니다)

5번째줄은 file 변수에 input tag의 type 속성이 file인 엘리먼트를 찾습니다. (웹딘프로 FILE_UPLOAD 엘리먼트에 해당합니다)

6번째줄은 ok 변수에 urPWFooterBottomLine 이라는 class 속성을 가진 엘리먼트 아래에 lsButton 이라는 class 속성을 가진 엘리먼트를 찾습니다. (웹딘프로 팝업의 아래쪽 OK 버튼에 해당합니다)

7번째줄은 파일 업로드 엘리먼트에 oninput 시점에 200ms 딜레이를 주고나서 OK 버튼을 click 하라는 뜻입니다. (이것은 파일 선택후 자동으로 팝업을 닫기 위한 코드 입니다)

8번째줄은 파일 업로드 엘리먼트를 click 하라는 뜻입니다. (파일 선택 창이 열립니다)

 

이 코드는 아래 프로젝트에 포함되어 있습니다.

https://github.com/boy0korea/ABAP2XLSX_HELPER

 

GitHub - boy0korea/ABAP2XLSX_HELPER: abap2xlsx helper

abap2xlsx helper. Contribute to boy0korea/ABAP2XLSX_HELPER development by creating an account on GitHub.

github.com

 

 

사용법은 보통 이런식으로...

/scmtms/cl_tor_helper_common=>get_tor_data(
  EXPORTING
    it_root_key      = lt_root_key
  IMPORTING
    et_all_items     = lt_all_items
).

실행되는건 아래 코드와 같은 내용입니다.

DATA(lo_srv_mgr) = /bobf/cl_tra_serv_mgr_factory=>get_service_manager( /scmtms/if_tor_c=>sc_bo_key ).
lo_srv_mgr->retrieve_by_association(
  EXPORTING
    iv_node_key       = /scmtms/if_tor_c=>sc_node-root
    it_key            = lt_root_key
    iv_association    = /scmtms/if_tor_c=>sc_association-root-item_tr
    iv_fill_data      = abap_true
  IMPORTING
    et_data           = lt_all_items
).

 

실용적인 코드 템플릿 >

DATA:
LT_ROOT_KEY TYPE /BOBF/T_FRW_KEY,
LT_ROOT	TYPE /SCMTMS/T_TOR_ROOT_K,
LT_ALL_ITEMS TYPE /SCMTMS/T_TOR_ITEM_TR_K,
LT_STOP	TYPE /SCMTMS/T_TOR_STOP_K,
LT_STOP_SUCC_ALL TYPE /SCMTMS/T_TOR_STOP_SUCC_K,
LT_DOC_REFERENCE TYPE /SCMTMS/T_TOR_DOCREF_K,
LT_EXEC TYPE /SCMTMS/T_TOR_EXEC_K,
LT_PARTY TYPE /SCMTMS/T_TOR_PARTY_K,

FIELD-SYMBOLS:
<LS_ROOT> TYPE /SCMTMS/S_TOR_ROOT_K,
<LS_ITEM> TYPE /SCMTMS/S_TOR_ITEM_TR_K,
<LS_STOP> TYPE /SCMTMS/S_TOR_STOP_K,
<LS_STOP_SUCC> TYPE /SCMTMS/S_TOR_STOP_SUCC_K,
<LS_DOC_REFERENCE> TYPE /SCMTMS/S_TOR_DOCREF_K,
<LS_EXEC> TYPE /SCMTMS/S_TOR_EXEC_K,
<LS_PARTY> TYPE /SCMTMS/S_TOR_PARTY_K,

" Invalidate cache
/bobf/cl_tra_trans_mgr_factory=>get_transaction_manager( )->cleanup( ).

" Get TOR data
/scmtms/cl_tor_helper_common=>get_tor_data(
  EXPORTING
    it_root_key      = lt_root_key
  IMPORTING
    et_root          = lt_root
    et_all_items     = lt_all_items
    et_stop          = lt_stop
    et_stop_succ_all = lt_stop_succ_all
    et_doc_reference = lt_doc_reference
    et_exec          = lt_exec
    et_party         = lt_party
).

 

/SCMTMS/T_TOR_ITEM_TR_K에 Secondary Key 가 여러개 있습니다.
Internal Table 의 Secondary Key 는 마치 DB Index 와 비슷한 역할을 하여 검색 속도를 빠르게 해줍니다.
차이점은 Secondary Key 가 여러개 있어도 Insert 속도에 영향을 주지 않습니다.
Secondary Key 의 Indexing 생성 시기는 최초 사용시 입니다. 사용하지 않는 Secondary Key 는 Indexing 하지 않습니다.


" ITEM_CAT = 'AVR' (차량)
READ TABLE lt_all_items ASSIGNING <ls_item> WITH KEY root_itmcat COMPONENTS root_key = <ls_root>-key item_cat = 'AVR'.

" ITEM_CAT = 'DRI' (드라이버)
READ TABLE lt_all_items ASSIGNING <ls_item> WITH KEY root_itmcat COMPONENTS root_key = <ls_root>-key item_cat = 'DRI'.

" ITEM_CAT = 'PRD' (제품)
LOOP AT lt_all_items ASSIGNING <ls_item> USING KEY root_itmcat WHERE <ls_root>-key item_cat = 'PRD'.

이렇게 Secondary Key 를 사용할때는 READ TABLE ... WITH KEY , LOOP AT ... USING KEY 구문을 쓰면 됩니다.

Item 노드 뿐만이 아니라 다른 노드에 대한 인터널 테이블도 모두 Secondary Key가 많이 있으니 찾아보고 활용해 보세요.

'ABAP > TM 물류운송관리' 카테고리의 다른 글

/SCMTMS/CL_UI_NAVIGATION=>START_NAVIGATION  (0) 2022.05.19

아래 예는 Yesterday, Today, Tommorow 를 입력하는 코드 입니다.

ev_search_criteria_changed = abap_true.
CLEAR: ls_fpm_search_criteria.
ls_fpm_search_criteria-search_attribute = 'DATE_FIELDNAME'.
ls_fpm_search_criteria-sign = if_fpm_guibb_search=>gc_sign-include_search_criteria.
ls_fpm_search_criteria-operator = if_fpm_guibb_search=>gc_operators-is.
ls_fpm_search_criteria-low = 'FPM_RD_FPM_DATE_YESTERDAY'.
APPEND ls_fpm_search_criteria TO ct_fpm_search_criteria.
ls_fpm_search_criteria-operator = if_fpm_guibb_search=>gc_operators-is.
ls_fpm_search_criteria-low = 'FPM_RD_FPM_DATE_TODAY'.
APPEND ls_fpm_search_criteria TO ct_fpm_search_criteria.
ls_fpm_search_criteria-operator = if_fpm_guibb_search=>gc_operators-is.
ls_fpm_search_criteria-low = 'FPM_RD_FPM_DATE_TOMORROW'.
APPEND ls_fpm_search_criteria TO ct_fpm_search_criteria.

 

FPM_RD_FPM_DATE_TODAY 라는 특별한 값을 주면 Today로 나타 납니다.

FPM_RD_ 와 FPM_DATE_TODAY 를 붙인 값입니다.

CL_FPM_SEARCH_UIBB_SELOPT->SET_SO_REL_DATES 에서 상수 GC_PREFIX_REL_DATE = 'FPM_RD_'

CL_FPM_DATE_DEFAULT_TOKEN_PROV->IF_FPM_TOKEN_PROVIDER~RESOLVE_TOKEN 에서 상수 GC_TOKEN_TODAY = 'FPM_DATE_TODAY'

 

relative date의 장점은 variant로 저장한 것을 불러 오더라도 저장할때의 고정된 날짜가 아니라 항상 날짜를 다시 계산 한다는 점입니다.

+ Recent posts