헤더, 아이템을 입력하면 생성 완료 시 송장문서번호 + 회계연도를 뱉어줌

 

알맞게 쇽쇽

그리고 나는 이거 생성할 때 자꾸 PO 레퍼런스된 걸 생성하라고 오류메세지가 떴었는데

알고보니 PO 생성 시 플래그 설정해줘야하는 게 있었던 걸로 기억한다.

입고, 송장은 PO 데이터를 기준으로 한다고 생각하면 될 것 같다.

그게 바로 이것!

 

완료 시 처리로직 이당.

정상적으로 생성되었다면 IV 생성 바피에서는 리턴값을 반환하지 않는다.

 

끗!

 

 

엑셀 업로드를 하면 데이터에 맞게 띄워진다

 

데이터는 헤더+아이템 구조로 받음.

그렇다면 그룹번호 별로 헤더내용은 중복이고 아이템 부분만 다르겟지?!

암튼 전체 데이터가 나오게된다면 생성하고 싶은 문서를 클릭 후 상단의 구매오더 생성을 클릭

그럼 PO 생성 BAPI 가 돌아감

내가 쓴 BAPI 는

'BAPI_PO_CREATE1'

입니다.

생성할 구매오더(=PO) 의 헤더와 아이템을 미리 채우고,

각각 파라미터의 x파라미터가 있는데 여기다가 X 값을 줘서 '해당 필드 내용에 적용 할게요 땅땅땅~' 하는 의미라고 생각하면 편하다.

아이템도 위와 같은 논리로 데이터 적용시켜주면 된다.

근데 !!!! 금액과 같은 경우는 통화키를 고려 안 하고 고대로 SAP 시스템에 저장되기 때문에 나중에 출력할 때 금액이 안 맞게 저장되는 경우가 있다. 그 부분만 고려해서 잘 변환해주면 됨여.

통화키에 맞춰서 금액 바꿔서 출력할때
맞춰진 금액을 도로 SAP 시스템에 저장할 때

이거슬. 쓰면. 되아요.

근데 지금과 같은 경우는

1400 & KRW 인데 통화 고려 안 하고 1400 & USD 로 저장해부려서, 나중에 나올때 14로 출력이 되는 슬픈 현상이 나오는 거임. 그라서. 이걸 통화키에 맞춰 한 번 더 변환을 해주았어요.

그럼 140000 인 채로 들어가니까 출력할 땐 1400이 되는 것.

 

아 그리고 생성할때 금액에 대한 조건도 설정해주어야한다잉

이 부분도 마찬가지.. 근데 의미를 잘 모르겠음... 음... 그렇다. 벌써 기억이 잘 안난다. 일단 기록

구매오더 생성이 완료 되었으면 바피는 문서번호를 뱉는다.

문서 처리 방법은 아래 로직을 확인해주세염

번호를 담는 변수의 상태에 따라서 처리를 하게 하는데

일단 저 BAPI_TRANSACTION_COMMIT 을 써야 실제 시스템에 문서 생성 결과가 적용 됨. 

더보기

FORM create_po  USING    pt_seldata LIKE gt_upload.

  DATAls_poheader LIKE bapimepoheader,
        ls_poheaderx LIKE bapimepoheaderx.

  DATAlv_po_number LIKE bapimepoheader-po_number.

  DATAlt_return TYPE TABLE OF bapiret2,
        ls_creturn TYPE bapiret2,
        ls_return LIKE LINE OF lt_return,

        lt_poitem LIKE TABLE OF bapimepoitem,
        lt_poitemx LIKE TABLE OF bapimepoitemx,

        lt_pocond   TYPE TABLE OF bapimepocond,
        ls_pocond   LIKE LINE OF lt_pocond,
        lt_pocondx TYPE TABLE OF bapimepocondx,
        ls_pocondx LIKE LINE OF lt_pocondx.

  DATAlv_stat TYPE char1,
        lv_err TYPE i.

  DATAls_seldata LIKE LINE OF pt_seldata,
        ls_savdata LIKE ls_seldata.

  " BAPI
  LOOP AT pt_seldata INTO ls_seldata.
    " PO HEADER 문서 설정
    IF ls_poheader IS INITIAL.
      PERFORM set_poheader USING ls_seldata CHANGING ls_poheader ls_poheaderx.
      MOVE-CORRESPONDING ls_seldata TO ls_savdata.
    ENDIF.

    " ITEM 문서 설정 - item & condition
    PERFORM set_po_item USING ls_seldata CHANGING lt_poitem lt_poitemx.
    PERFORM set_po_cond USING ls_seldata CHANGING lt_pocond lt_pocondx.

    CLEARls_seldata.

    AT END OF po_num.
      IF ls_poheader IS NOT INITIAL.
        " BAPI CREATE 실행
        PERFORM init_po_bapi USING     ls_poheader
                                       ls_poheaderx
                             CHANGING  lv_po_number
                                       lt_return
                                       lt_poitem
                                       lt_poitemx
                                       lt_pocond
                                       lt_pocondx.

        " 에러사항이 있다면 해당 내용으로 메세지 호출
        READ TABLE lt_return INTO ls_return WITH KEY type 'E' id '06'.
        IF ls_return-type 'E'.
          ls_savdata-exp_col icon_red_light.
          ls_savdata-msg ls_return-message.
          MODIFY gt_upload FROM ls_savdata TRANSPORTING exp_col msg WHERE po_num ls_savdata-po_num.
        ENDIF.

        " 만일 PO 번호가 생성되었다면 COMMIT
        IF lv_po_number IS NOT INITIAL.
          " COMMIT WORK
          CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
            EXPORTING
              wait   'X'
            IMPORTING
              return ls_creturn.

          IF sy-subrc 0.
            ls_savdata-exp_col icon_green_light.
            ls_savdata-ebeln lv_po_number.
            ls_savdata-msg '구매오더를 정상적으로 생성하였습니다.'.
            MODIFY gt_upload FROM ls_savdata TRANSPORTING ebeln exp_col msg WHERE po_num ls_savdata-po_num.
          ENDIF.
        ENDIF.
      ENDIF.
      REFRESHlt_return,  lt_poitem,  lt_poitemxlt_pocondlt_pocondx.
      CLEARls_returnls_poheaderls_poheaderxlv_po_number.
    ENDAT.
  ENDLOOP.

ENDFORM.                    " CREATE_PO

 

안녕!

이건 복잡버전보다 훨 간단함요.

왜냐!!!!!!!!!!

  1. 각 행을 한 줄의 문자열로 변환해서
  2. 클립보드를 사용해 엑셀에다 복붙할거기 때문!!!!

이전의 프로그램을 죅금 수정해봅시다.

오케이~ 레쓰고

여기선 string 타입 컴포넌트 하나만 갖고있는 인터널 테이블을 선언할 거심요.

데이터는 # 으로 구분할 것이요. 함 보시요

 

짜라란~

 

# 사이에 있는 애들이 각 셀에 들어갈 데이터다.

 

보여줄 데이터 취합 & 문자열로 형변환 및 조정 완료가 되었다면

인쟈 저번처럼 엑셀 창을 열어보자.

근데 이번에는 워크북 자체를 지정해준다고 해야하나... 활성화해준다고 해야하나.... 그 작업을 추가해야한다

그 후, 복사할 내역을 어디다가 붙여넣을 건지 셀을 선택해준당

그리고 아래와 같이 클립보드 메서드를 사용해서 인터널 테이블의 데이터를 클립보드에 복사할것이당

여기까지 작성하면 ctrl + c 되었다고 여기면 됨

정상적으로 복사 되었으면 lv_rc에 0 값이 들어감!

lv_rc 값을 기준으로 정상이라면 붙여넣기, 아니면 에러 메세지를 띄우게 했다.

자라란ㅠ

이렇게 복붙을 잘 사용하면 한꺼번에 빨리 내보낼 수 있지요! 

 

더보기

*&---------------------------------------------------------------------*
*& Report  ZOLEEXCEL_2024
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT zoleexcel_2024.

DATAgt_spfli TYPE TABLE OF spfli,
      gs_spfli TYPE spfli.

DATAgt_fields TYPE TABLE OF dd03m,
      gs_fields TYPE dd03m.

DATAgv_txt TYPE string.

SELECT-OPTIONSso_carr FOR gs_spfli-carrid.

INITIALIZATION.
  PERFORM get_fieldinfo.

START-OF-SELECTION.
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_spfli
    FROM spfli
    WHERE carrid IN so_carr.


  IF gt_spfli IS NOT INITIAL.
    gv_txt |총 { linesgt_spfli }건의 데이터를 내보냈습니다.|.
    PERFORM export_excel_simple" 간단!
    WRITE gv_txt.
  ENDIF.
*&---------------------------------------------------------------------*
*&      Form  ERROR_HANDLE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_SY_SUBRC  text
*----------------------------------------------------------------------*
FORM error_handle USING pv_subrc TYPE sy-subrc.
  IF pv_subrc <> 0.
    MESSAGE 'OLE 자동화 에러' TYPE 'W'.
    STOP.
  ENDIF.
ENDFORM.                    " ERROR_HANDLE
*&---------------------------------------------------------------------*
*&      Form  GET_FIELDINFO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_fieldinfo .
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_fields
    FROM dd03m
    WHERE tabname 'SPFLI'
     AND ddlanguage 3.
ENDFORM.                    " GET_FIELDINFO
*&---------------------------------------------------------------------*
*&      Form  EXPORT_EXCEL_SIMPLE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM export_excel_simple .
***********************클립보드용 데이터 만들기 ***********************
  DATAls_clip TYPE LENGTH 1000,
        lt_clip LIKE TABLE OF ls_clip.

  DATAdeli TYPE c.
  deli cl_abap_char_utilities=>horizontal_tab.

  FIELD-SYMBOLS<fs_field> .

* header
  LOOP AT gt_fields INTO gs_fields.
    IF gs_fields-fieldname 'MANDT'.
      CONTINUE.
    ENDIF.

    IF ls_clip IS INITIAL.
      ls_clip gs_fields-scrtext_l.
    ELSE.
      ls_clip ls_clip && deli && gs_fields-scrtext_l.
    ENDIF.
  ENDLOOP.
  APPEND ls_clip TO lt_clip.

  CLEAR ls_clip.
* Body
  LOOP AT gt_spfli INTO gs_spfli.
    LOOP AT gt_fields INTO gs_fields.
      IF gs_fields-fieldname 'MANDT'.
        CONTINUE.
      ENDIF.

      ASSIGN COMPONENT gs_fields-position OF STRUCTURE gs_spfli TO <fs_field>.
      IF ls_clip IS INITIAL.
        ls_clip <fs_field>.
      ELSE.
        ls_clip ls_clip && deli && <fs_field>.
      ENDIF.
    ENDLOOP.

    APPEND ls_clip TO lt_clip.
    CLEAR ls_clip.
  ENDLOOP.

  DATAlo_excel TYPE ole2_object,
        lo_cell TYPE ole2_object" 셀 객체 변수
        lo_books TYPE ole2_object,
        lo_book TYPE ole2_object.

* 엑셀 실행
  CREATE OBJECT lo_excel 'EXCEL.APPLICATION'.
  PERFORM error_handle USING sy-subrc.

  CALL METHOD OF
      lo_excel
      'WORKBOOKS' lo_books.
  PERFORM error_handle USING sy-subrc.

* add a new workbook
  CALL METHOD OF
      lo_books
      'ADD'    lo_books.
  PERFORM error_handle USING sy-subrc.

*  화면 DISPLAY 설정 (1을 설정하면 DISPLAY)
  SET PROPERTY OF lo_excel  'VISIBLE' 1.
  PERFORM error_handle USING sy-subrc.

  GET PROPERTY OF lo_excel 'ACTIVESHEET' lo_books.

*     엑셀 셀 선택
  CALL METHOD OF
      lo_books
      'CELLS'  lo_cell
    EXPORTING
      #1       1            " 행
      #2       1.           " 열

  CALL METHOD OF
      lo_cell
      'SELECT'.

**********************************************************************

  DATAlv_rc TYPE i.
* 테이블 내용 복사하기 - 클립보드
  CALL METHOD cl_gui_frontend_services=>clipboard_export
    EXPORTING
      no_auth_check        space
    IMPORTING
      data                 lt_clip
    CHANGING
      rc                   lv_rc
    EXCEPTIONS
      cntl_error           1
      error_no_gui         2
      not_supported_by_gui 3
      no_authority         4
      OTHERS               5.
  IF sy-subrc <> 0.
*   Implement suitable error handling here
  ENDIF.

**********************************************************************

 IF lv_rc 0.
  CALL METHOD OF
      lo_books
      'PASTE'.
 ELSE.
   MESSAGE 'ERROR' TYPE 'E'.
 ENDIF.


 FREE OBJECTlo_excello_celllo_booklo_books.


ENDFORM.                    " EXPORT_EXCEL_SIMPLE

 

안녕!

엑셀 다운로드는 업로드와 비슷한듯 다름

 

실제 엑셀을 다루는 것 처럼 코드를 짜야 하기 때문에.! (셀 선택 -> 작업(컬러, 폰트 등등) )

쉬운방법이 있고 복잡한 방법이 있는데 복잡한거 먼저 정리 해보겠다.

양 ... 양 양도 적으니 이거 한번 엑스퐅트 해볼께....

근데 그냥 한번 기분삼아 간단하게 프로그램을 짜봄

select options 값에 따라 출력시킬거고, 엑셀 다운로드는 저 export_excel 서브루틴에서 발생시킬것이다

 

엑셀은 ole2_object 타입의 변수를 선언해서 사용하고, 엑셀창, 폰트, 행, 열, 컬러 등등 전용 변수를 만들어두고 그때그때마다 쓴다.

주로 쓰이는 코드만 정리해보자면

  • CREATE OBJECT (변슈) 'EXCEL.APPLICATION'
  • SET PROPERTY OF (변수) '(속성명)' = (할당해줄 변수) / 값
  • CALL METHOD OF (변수) '(메서드명)' ( + 그 외 부가적인 파라미터값 )

가 있다.

그리고 오류를 핸들링하는 서브루틴을 하나 생성해준다.

FORM error_handle  USING pv_subrc TYPE sy-subrc.
  IF pv_subrc <> 0.
    MESSAGE 'OLE 자동화 에러' TYPE 'W'.
    STOP.
  ENDIF.
ENDFORM.                    " ERROR_HANDLE

 

일단 간단하게 엑셀 창만 열어보자!

엑셀 변수를 만들었다고 다 되는게 아니라 visible 속성을 설정해줘야함요

26건은 무시점여

실행해보면 이런 창이 뜬다. 그렇담 안의 작업창도 넣어줘야겟지?

크큭. 이렇게 워크북과 영역을 마련해주고 새로운 시트를 추가해주면 된다.

메서드를 보통 사용할 때는 lo_excel 객체의 workbooks 기능을 lo_books에 할당해준다 고 이해하면 될 것 같다.

그럼 일케나옴요! 우리가 알던 그 엑셀 창이다.

 

이제 내용을 적어보자. 처음에도 말했지만 엑셀에 직접 하나하나 적는 것 처럼 코드를 짜야한다. 우하하

칸 선택 -> 값 넣기 -> 그 옆 칸 선택 -> 값 넣기 반복해주는것이다

 

나는 DD03M 테이블에서 정보를 다 가져와야것따.!

그럼 해당 인터널 테이블에 관련 데이터 정보가 잘 올라왓을 것심.

데이터에 값을 넣기 위해서는!!!!!!!!!!!!!! 일단 아래와 같은 변수를 선언해주어야한다.

간단히 헤더정보를 입력하는 로직을 살펴보자면

  1. 'CELLS' 메서드를 통해 셀을 선택하고
  2. 'VALUE' 메서드를 통해 해당 셀에 값을 넣어준다.

구조로 움직임.

이게 다다! 엑셀파일에 직접 써주기 = 엑셀 파일로 내보내기

포맷은 항상 같고 전체 로직은 이러하다. 나는 클라이언트 번호는 적고싶지 않았기에. mandt는 제외하도록 코딩했다.

코드 마지막에는 항상 FREE 시켜주기 오호호!

 

프로그램을 시행하면 엑셀이 정상적으로 생성됨을 확인할 수 있다. 

근데 이 앙칼진게 문제가 뭐냐면.....

시간이 너무 오래걸려!!!!!!!!!!!!!!!!!!!!!!!!!!!!

 

그래서 해당 코드들은 인터널 테이블 데이터를 다 내보낼때보다는

특정 데이터를 소량으로 넣고자 할때 추천드립니다.

 

테두리, 컬러, 정렬 등 기능들이 더 있는데, 그건 간단 버전 글에서 마저 적어보겠다잉

 

 

전체 코드

더보기

REPORT zoleexcel_2024.

DATAgt_spfli TYPE TABLE OF spfli,
      gs_spfli TYPE spfli.

DATAgt_fields TYPE TABLE OF dd03m,
      gs_fields TYPE dd03m.

DATAgv_txt TYPE string.

SELECT-OPTIONSso_carr FOR gs_spfli-carrid.

INITIALIZATION.
  PERFORM get_fieldinfo.

START-OF-SELECTION.
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_spfli
    FROM spfli
    WHERE carrid IN so_carr.


  IF gt_spfli IS NOT INITIAL.
    gv_txt |총 { linesgt_spfli }건의 데이터를 내보냈습니다.|.
    PERFORM export_excel.
    WRITE gv_txt.
  ENDIF.
*&---------------------------------------------------------------------*
*&      Form  EXPORT_EXCEL
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM export_excel .
  DATAlv_col TYPE i" 선택 열 정보
        lv_row TYPE i" 선택 행 정보

  DATAlo_excel TYPE ole2_object,
        lo_cell TYPE ole2_object" 셀 객체 변수
        lo_books TYPE ole2_object,
        lo_book TYPE ole2_object.

  FIELD-SYMBOLS<fs_field>" 동적할당을 위한 필드심볼

* 엑셀 실행
  CREATE OBJECT lo_excel 'EXCEL.APPLICATION'.
  PERFORM error_handle USING sy-subrc.

*  화면 DISPLAY 설정 (1을 설정하면 DISPLAY)
  SET PROPERTY OF lo_excel  'VISIBLE' 1.
  PERFORM error_handle USING sy-subrc.

  CALL METHOD OF
      lo_excel
      'WORKBOOKS' lo_books.
  PERFORM error_handle USING sy-subrc.

* add a new workbook
  CALL METHOD OF
      lo_books
      'ADD'    lo_book.
  PERFORM error_handle USING sy-subrc.

******************엑셀 값 넣어주기*************************
  " HEADER
  LOOP AT gt_fields INTO gs_fields.
    IF gs_fields-fieldname 'MANDT'.
      CONTINUE" MANDT 생략
    ENDIF.
    lv_col gs_fields-position.
    SUBTRACT FROM lv_col.

*     엑셀 셀 선택
    CALL METHOD OF
        lo_excel
        'CELLS'  lo_cell
      EXPORTING
        #1       1            " 행
        #2       lv_col.      " 열

    SET PROPERTY OF lo_cell 'VALUE' gs_fields-scrtext_l.
  ENDLOOP.

  LOOP AT gt_spfli INTO gs_spfli.
    lv_row sy-tabix + 1.
    LOOP AT gt_fields INTO gs_fields.
      IF gs_fields-fieldname 'MANDT'.
        CONTINUE" MANDT 생략
      ENDIF.

      lv_col gs_fields-position.
      SUBTRACT FROM lv_col.

*     엑셀 셀 선택
      CALL METHOD OF
          lo_excel
          'CELLS'  lo_cell
        EXPORTING
          #1       lv_row            " 행
          #2       lv_col.           " 열

*     해당 셀에 값 넣기
      ASSIGN COMPONENT gs_fields-position OF STRUCTURE gs_spfli TO <fs_field>.
      SET PROPERTY OF lo_cell 'VALUE' <fs_field>.
    ENDLOOP.
  ENDLOOP.


  FREE OBJECT lo_excel.
  FREE OBJECT lo_book.
  FREE OBJECT lo_books.
  FREE OBJECT lo_cell.
ENDFORM.                    " EXPORT_EXCEL
*&---------------------------------------------------------------------*
*&      Form  ERROR_HANDLE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_SY_SUBRC  text
*----------------------------------------------------------------------*
FORM error_handle USING pv_subrc TYPE sy-subrc.
  IF pv_subrc <> 0.
    MESSAGE 'OLE 자동화 에러' TYPE 'W'.
    STOP.
  ENDIF.
ENDFORM.                    " ERROR_HANDLE
*&---------------------------------------------------------------------*
*&      Form  GET_FIELDINFO
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_fieldinfo .
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE gt_fields
    FROM dd03m
    WHERE tabname 'SPFLI'
     AND ddlanguage 3.
ENDFORM.                    " GET_FIELDINFO

안녕~!

엑셀파일의 내용을 ALV 로 출력하는 과정을 정리하려구 한다.

먼저 업로드를 위해서는 파일 경로를 불러오는 기능이 필요하다.

1. 파일 경로 불러오기(SEARCH HELP)

selection screen 만들어주기. 해당 파라미터 변수 이름은 pa_file 로 지정했따

그리고 f4 서치헬프 달아주기~!

나는 해당 메서드를 사용함요

엑셀 파일만 찾아서 오픈하게 기본 확장자와 필터를 모두 엑셀로맞췄다.

여기서 값을 가져온다면 lt_table에 경로와 lv_rc에 성공여부를 코드로 반환해줌요

잘 들어옴요 ^_^ 이제 경로를 불러왔으면 실행버튼으로 해당 엑셀 파일을 열어볼것이다

2. EXCEL 파일 읽어오기

초기값이면 읽어오는 서브루틴이 작동 못하게...! 막아쥬고 시작.

처음은 파일 기반 데이터를 채워주고(하이라이트 표시)

데이터를 정상적으로 alv용 itab 에 옮겨담았을 시(= 값이 존재할때) 부가정보(신호등, 텍스트 등등...)를 추가해준 후에 출력해주는 것이다

파일을 가져오기 위해서 필요한 변수들. 나머지는 형변환용 변수니까 참고만 하고 신경쓰지 마쇼잉!!

 

엑셀 데이터를 가져올 때 아밥 상에서는 모든 걸 문자형으로 가져오게됨

그리고 금액같은 경우는 코드를 거칠 때 통화 때문에 값이 달라지게 되는데 그것 또한 DB 저장 시 금액으로 재적용해줘야 할 때도 있고, 혹은 conversion exit 을 통해 하나씩 형변환을 해줘야할 때가 있음요

이때 사용할 수 있는게 뭐시냐!!

바로 DFIES 테이블 입니다.

2-1. 타입 정보 빼내기

글로벌 스트럭쳐/테이블 에 대하여 각 정보를 담아서 출력해주는 구조거든여.

그래서 로컬로 따로 선언하고 하나씩 바꿔줘도 좋지만~! 저는 글로벌 스트럭쳐를 선언해두고,

타입명을 기준으로 데이터를 조회해서 쓰고있음요

실제루다가. 이렇게 뜹니다. 여기서 필요한 정보를 사용하면 되아요

2-2. 엑셀 파일 데이터 빼내기

엑셀 파일은 아래 펑션을 사용하면 됩니다.(위 코드랑 이어짐)

엑셀 값은 이렇게 행 / 열 / 값 필드 구조로 가져오게 됩니다.

ex) (1)행 (1)열에는 (값) 이 들어가있다.

그러니 당연히 엑셀파일도 필드 순서대로 데이터를 넣어놔야겠죠?!

 

그리고... 그리고 이제 루프와 필드심볼을 이용해서 필드 하나하나에 값을 할당해주면 됩니다.

2-3. 필드에 값 할당해주기

루프 사용방법은 이러하다: 

1. 값이 들어있는 lt_intern을 기준으로 루프를 돌린다

2. 컬럼값을 이용하여 필드를 지정한다(by 필드심볼)

3. 컬럼값을 이용하여 lt_dfies의 정보를 읽어와서 형변환을 해준다

4. 필드에 해당 값을 할당해준다

4. 모든 필드에 대한 할당 작업이 끝나면 보여주고자 하는 work area 에 move-corresponding & itab append 해준다

꺄르르

중간중간 있는 부가적인 코드들은 다 타입 맞춰주기 위한 작업들임.

참고로 ls_data 는 순전히 글로벌 스트럭처 필드들만 존재하는 타입 변수고,

gs_upload는 글로벌에다가 필드명, 신호등 등 별도의 필드를 추가한 전혀 다른 구성의 스트럭쳐 변수다.

itab 상에서 move-corresponding 이 가능하면 그렇게 하시오.

 

참고로 !!!!

나만 그랬는진 모르겠지만 ... 환율 적용하는 부분에서 조금 머리아픈 이슈가 있었다.

이건 나중에 따로 적어볼 예정이지만 암튼 금액적인 부분에서도 뭔가 해줘야한다는거 ~

이렇게 해서 gt_upload 인터널 테이블에 데이터가 들어와있다면, 100번 스크린을 통해 화면을 보여주는거고

아니면 워닝 메세지를 띄우도록 설정 햇 따 ~!

결과는... 보여줄 수없지만 대충 이러하다.

만약 데이터 타입이 다르거나 누락된 필드가 존재한다면 '필드 누락:' 글자 뒤에 필드명을 나열하고,

코드는 정상인데 삭제되었거나 텍스트테이블에 조회되지 않는 코드라면 '유효하지 않은 데이터:' 글자 뒤에 리스트업하게 함.

 

이게 끝임 움캬!

계산기 프로그램 과제를 만드는데 소수타입은 무조건

3.3000 / 3.1520 처럼 자리수만큼 끝에 0이 붙어뿌린다.

 

근데 나는 진짜 계산기 프로그램처럼 결과값이  3.3 만 나오게 하고싶다,..!

저는 모듈풀로 만들었어요

 

일단 모든 결과값은 문자열로 나오게 합니다.

 

인풋은 숫자로, 아웃풋은 문자로 나오게 합니다.

 

입력값을 받기 위한 100번 스크린

일단 숫자타입 컴포넌트에 인풋값을 넣고 결과 계산

그 후에 연산기호 문자 세팅해둠

나눗셈의 경우 0 으로 나눌 때 예외처리(이때는 결과값 출력용 컴포넌트에 계산 불가 값을 넣어주기)

 

그리고 입력값, 결과값을 문자열 컴포넌트에 각각 넣어주기

글고 change_form서브뤁틴을 이용해서 포맷 맞춰주기!!

값이 계산 불가가 아닐때만 처리해주기

1. 부호를 앞으로 빼고,

2. . 을 기준으로 정수/소수 부분으로 나눠주기

3. 소수값ㅇ 0 이라면 그냥 전체 정수ㄱ부분만 출력시키기,

    아니라면 소수점 끝 0을 제거해주는 작업 시작

   -> 오른쪽 끝이 공백 혹은 0 인 경우 제거

4. 그 후 공백일 생길 시를 대비하여 CONDENSE NO-GAPS 사용.

그렇게하묜~? 

적용했을때
아닐때

끗!

받은 미니 과제 중에 기억에 남는 것 : 이진법 변환 Function Module 생성

음수는 계산 못하게 예외처리하라고 하셨지만 저는 그걸 잘못듣고 음수변환도 해버렸습니다

보시는 바와 같이 걍 대박 간단하게 10진수 -> 2진수 변환임...

아 근데 시작 전에 NOZERO 이름으로 0은 못하게 예외처리함

 

아시는 바와 같이 2진수는 0과 1로만 구성된 앙큼집합체라( 10 -> 1010 ) 이걸 숫자로 변환하고자 할때

변환 함수를 사용하면...~~!!

 

너무너무 좋지만~~!!!!!

 

쌩으로 코딩하라고 한다면 문자열을 이용해서 하나씩 추가해주는 수 밖에 생각이 나지 않습니다.

 

그래서

사용한 변수 목록들:

  • lv_left: i / 인풋값을 2로 나눈 나머지를 담을 변수
  • lv_cleft : numc1 / 인풋값의 나머지값의 문자형
  • lv_share: i / 인풋값을 2로 나눈 몫
  • lv_len: i / leading zero를 얼만큼 추가해줄지 결정할 변수
  • lv_add: i / 1 + 1 = 0 고려 할 변수 (다음 자리수에 1 넘김)
  • ls_num, lt_num : 0 또는 1 값을 담을 (numc1) 스트럭쳐와 인터널 테이블

어떻게 흘러가는 로직이냐미욘.

 

1. 사용자가 넣은 입력값(iv_decnum) 을 몫 변수에다가 할당, 근데 이제 절대값으로

    글케하면 음수 고려 어케하냐구요 ???

    그래서 변수 새로 선언 햇 짜 나 ~~!!!!!!

2. 그걸 계속 2로 나누면서 몫과 나머지를 각각의 변수에다가 저장

      2-1. 나머지의 경우 이를 인터널 테이블에 APPEND 해주고

      2-2. 몫의 경우는 2로 나눈 결과를 다시 재할당

 

몫이 0이 될때까지 2번을 계속 반복 (WHILE은 조건식이 거짓일 때 멈춘다)

 

만약 인풋값으로 10을 넣었다면 lt_num 인터널테이블에 데이터는

IDX VALUE
1 0
2 1
3 0
4 1

이리코롬. 들어갓을거씸

 

3. 그리고 음양수는 나중에 판단할거라 음수인 경우에는 1의 보수를 고려할거라서... 앞에 리딩제로를 넣어줄거임

일단 인터널 테이블의 행 개수(= 숫자개수)를 세어주고,  4로 나눈 나머지 값을 lv_len 에다가 넣어준다!!

 

ex. 이진변환 결과가 101 이라면,

lines( lt_num ) = 3

lv_len = 3 % 4 = 3

4. 그 후에 앞에 리딩제로를 붙여주면 댐ㅋㅋ 나는 넉넉하게 앞에 4 + a개 추가해줌

만약 나머지 결과(lv_len)가 4의 배수가 아니라면 8에서 나머지 값을 빼주면 되고(= 리딩제로 4개 + 부족한 리딩제로 개수만큼 채우기),

4의 배수면 4개만 추가해주면 댐

 

그 후 양수값이면 그대로 출력해주고~ 음수값이면 보수를 고려해서 처리해주면 대용!

(말이 어렵지 그냥 0 <-> 1 바꿔주고 맨 끝자리만 1 더해주면 됨요)

 

음수일 땐 필드심볼 사용해서 변경값 itab에 바로바로 반영시켯구

마무리 출력해줄때만 work area 썼음용. 왜냐구요? 그냥요..

 

계산이 완료되었으면 숫자 -> 문자로 형변환 후 CONCATENATE 키워드로 연결해주고 출력!

 

전체 코드

 

 

크아악

 

이제 레포트 프로그램에 펑션모듈을 직접 활용해봅시당

과제를 진행하다가

라디오 버튼이 클릭 될 때만 해당 인풋 모음이 보이도록 구현해야 하는데

일단 구현은 성공했으나 더블클릭을 해야 화면이 보이는 새드엔딩을 맞이했다.

방법을 찾던 중 발견한 바보같은 실수

!!라디오 버튼 뒤에 USER-COMMAND 를 붙여줘야 이벤트가 바로 실행이 된다는 것!!

라디오는 그룹으로 묶기 때문에 한 파라미터에만 적용시켜주면 되는 듯 하다.

ucomm 에 맞춰서 그룹에 따라 화면이 보이도록 코드도 아래와 같이 수정함

아직 많이 부족하다 야호~

1000 번대 스크린에 검색 조건 화면을 구성하고 싶을 때 아래 코드를 사용하면 된다

 

일단 모든 코드는

(1) SELECTION-SCREEN <>. 으로 나타내거나

 

(2) SELECTION-SCREEN BEGIN OF <>. 로 시작하여

     SELECTION-SCREEN END OF <>. 로 끝난다.

 

(1) 의 경우

  • SKIP (n)공백 행을 주고 싶을 때
  • ULINE선을 긋고싶을 때
  • POSITION - 위치 지정. 시작위치(길이) 구성으로 작성하면 됨! 
  • COMMENT TEXT-xxx FOR FIELD <> - 파라미터/라디오/체크박스에 대한 텍스트를 남기고 싶을 때
  • PUSHBUTTON <btn_txt> USER-COMMAND <code> - 버튼 생성용. 여기서 만든 펑션코드는 눌려질때마다 SSCRFIELDS-UCOMM에 담긴다!
  • FUNCTION KEY (n) - 상단의 어플리케이션 바에 버튼생성해줌. 이 또한 SSCRFIELDS-UCOMM에 담김 음하하.

스트럭쳐는 대충 요래 생김

(2) 의 경우는

  • BLOCK b01 : 블럭생성
  • BLOCK b01 WITH FRAME TITLE TEXT-xxx : 블럭 + 블럭 제목 생성
  • LINE : 파라미터들을 한 줄로 보여주고싶을때! 보통은 한 줄 씩 띄워주기떄문에 꼭 꼭 라인을 써줘야댐
                이런 경우는 위치 지정을 잘 해주어야 한다.

포지션은 보통 키워드 뒤에 작성해주면 된다.

예시:

 

Also, 파라미터를 체크박스나 라디오 버튼으로 만드려면 저렇게 PARAMETERS 키워드 선언하고 변수명 뒤에 적어주면 된다잉!

라디오버튼은 RADIOBUTTON GROUP <> 이고

체크박스는 AS CHECKBOX 혹은 USER-COMMAND <> 로 설정가능혀요.

 

끗!

 

 

SELECTION-SCREEN 화면에 나타나는 인풋필드, 박스 등을 조작하기 위해서는

SCREEN 스트럭쳐를 알어야 한다잉

보통은

  • NAME : 프로그램 상의 변수명을 기준으로 조작
  • GROUP 1234 : 그룹( TOP에 적는 MODIF ID 기준, 최대 3글자 ) 기준 조작
  • INPUT : 인풋필드 활성(1) / 비활성화(0) 여부 결정
  • OUTPUT : 출력 부분(ex. 문자) 활성(1) / 비활성화(0) 여부 결정
  • INVISIBLE : 인풋필드 영역글자 활성(1) / 비활성화(0) 여부 결정(ex. 비번칸)
  • ACTIVE : 화면에 해당 요소 보여주기(1) / 숨기기(0) 여부 결정

정도 쓰는 듯.

 

나는 화면에서 라디오버튼 클릭에 따라 해당 박스 화면만 나타나게 하고 싶었다.

요로코롬쓰. 따블클릭하면 쇽 사라짐

여기서는  INVISIBLE 이 아닌 ACTIVE를 사용해야겟지.

그러기 위해서는 MODIF ID를 이용하여 TOP 인클루드에 있는 파라미터들에게 group을 할당한다.

 

다 보여주면 너무 길어지니 일부만 보여주겠어요

참고로 CHECKBOX를 하고 싶다면 저렇게 한 자리 문자 타입 파라미터 선언 후 AS CHECKBOX 붙여주면 됨 하하

 

그리고 AT SELECTION-SCREEN OUTPUT(스크린상의 PBO모듈 역할)에서 아래와 같이 작업해 주기

스크린을 조작하고 싶을 땐 값을 확인하고 화면을 구성하는 해당 이벤트 블록에서 모든 코드가 이루어져야 한다.

SCREEN 은 테이블처럼 구성되기 때문에

LOOP를 돌아가면서 한 줄 한 줄 조건에 따라 값을 수정해 준다는 개념으로 다가가면 편할 듯.

 

끝~!

+ Recent posts