보통 뷰에서 view api 의 REQUEST_FOCUS 메소드를 호출하여 포커스를 지정합니다.

ALV에는 SET_FOCUS 라는 메소드가 있습니다.

그런데 SET_FOCUS를 실행해도 포커스 지정이 안되고 무시되는 경우가 있습니다.

 

노트 1399068 에 답이 있습니다.

 Note that the time in the Web Dynpro phase model at which you set the focus is relevant. If you set the focus very early in the phase model, the data may be changed and the focus lost in a subsequent phase. We recommend that you set the focus at the time WDDOPOSTPROCESSING.

다른 요인으로 인해 포커스가 다시 변경될수 있으니, 컴포넌트컨트롤러의 WDDOPOSTPROCESSING 메소드에서 포커스 지정하는 코드를 넣으라고 하네요.

그리고 서버 버전도 확인하시기 바랍니다.

 

Solution

  • SAP NetWeaver 7.00
    Import Basis Support Package 21.
  • SAP NetWeaver 7.01
    Import Basis Support Package 6.
  • SAP NetWeaver 7.02
    Import Basis Support Package 2.
  • SAP NetWeaver 7.10
    Import Basis Support Package 10.
  • SAP NetWeaver 7.11
    Import Basis Support Package 5.
  • SAP NetWeaver 7.20
    Import Basis Support Package 2.

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://scn.sap.com/community/web-dynpro-abap/blog/2013/12/13/step-by-step-to-create-ui-elements-and-context-node-attribute-in-the-runtime

 

 

 

Jerry Wang

웹딘프로아밥 실행중 동적으로 UI 엘리먼트와 컨텍스트 노트 어트리뷰트 만드는 방법

Posted by Jerry Wang in Web Dynpro ABAP on Dec 13, 2013 11:52:04 AM

clipboard1.png

 

1. 빈 group 을 하나 만듭니다. 동적으로 생성할 UI 엘리먼트를 담아둘 컨테이너입니다. layout은 RowLayout으로 지정합니다.

clipboard2.png

 

2. 빈 컨텍스트 노드를 하나 만듭니다. 이것 역시 동적으로 생성할 컨텍스트 어트리뷰트를 담아둘 컨테이너입니다.

clipboard3.png

 

3. 메소드 WDDOMODIFYVIEW 에서는 단지 view 변수를 저장합니다. view 변수는 나중에 버튼 클릭시 UI 엘리먼트를 조작하기 위해서 필요합니다.

 

method WDDOMODIFYVIEW .
  CHECK first_time = 'X'.
  wd_this->mr_view = view.
endmethod.

 

 

4. 뷰에 새 메소드를 하나 만듭니다.

3번째 줄에서 컨텍스트 노드 DYNAMIC에 대한 참조변수를 가져왔습니다. 노드 정보 오브젝트를 통해서 노드 어트리뷰트를 가져옵니다.

버튼을 클릭할때마다 매번 새로운 어트리뷰트를 만들 필요는 없습니다. 어트리뷰트가 이미 만들어져 있다면 만들지 않고 없다면 새로 만들어 줍니다.

clipboard5.png

 

5. Create 버튼에 대한 액션메소드 구현.

중복된 아이디로 UI 엘리먼트를 추가하는 문제를 피하기 위해서 처음에 빈 group 아래의 자식 UI 엘리먼트를 모두 삭제하는 구문이 필요합니다. 삭제하지 않고 중복된 아이디로 생성하면 런타임 에러가 납니다. 다음으로 label과 text view를 생성합니다. layout 값을 적절히 지정하여 각 label이 새로운 줄로 줄바꿈 되도록 합니다.

 

method ONACTIONCREATE .
  CONSTANTS: cv_label TYPE string VALUE 'LABEL',
             cv_field TYPE string VALUE 'FIELD',
             cv_bind_text TYPE string VALUE 'DYNAMIC.VALUE'.
  DATA: lv_count type i,
        lo_container type ref to cl_Wd_uielement_container.
  wd_context->get_attribute( EXPORTING name = 'NUMBER' IMPORTING value = lv_count ).
  CHECK lv_count > 0.
  create_context( lv_count ).
  DATA(lo_root) = wd_this->mr_view->get_element( 'DYNAMICUI' ).
  lo_container ?= lo_root.
  lo_container->remove_all_children( ).
  DO lv_count TIMES.
    data(lv_field_id) = cv_field && sy-index.
    data(lv_label_id) = cv_label && sy-index.
    data(lv_bind_path) = cv_bind_text && sy-index.
    DATA(lo_text_view) = cl_wd_text_view=>new_text_view( id = lv_field_id bind_text = lv_bind_path ).
    DATA(lo_label) = cl_wd_label=>new_label( id = lv_label_id label_for = lo_text_view->id text = lv_label_id ).
    CL_WD_ROW_HEAD_DATA=>new_row_head_data( element = lo_label ).
    cl_wd_row_data=>new_row_data( element = lo_text_view ).
    lo_container->add_child( the_child = lo_label ).
    lo_container->add_child( the_child = lo_text_view ).
  ENDDO.
endmethod.

 

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
https://scn.sap.com/community/web-dynpro-abap/blog/2013/12/13/step-by-step-to-create-ui-elements-and-context-node-attribute-in-the-runtime

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다

https://blogs.sap.com/2013/11/20/dynamic-ui-generation-in-web-dynpro-abap/

 

 

 

웹딘프로아밥에서 동적 UI 생성

이글은 웹딘프로아밥에서 동적으로 뷰를 생성하는 방법을 설명한 글입니다.

Author : Raj

Raj is an Application Developer focusing on Custom Development - particularly in the areas of ABAP ,WD4A , JAVA , APO , Enterprise services and PI Developer/consultant . He is also certified in ABAP and PI. FacebookTwitter

 

 

아우 씨* 이건 멍미!! 아래 그림의 웹딘프로아밥 뷰 레이아웃을 본 나의 첫 한마디 입니다.

실행 결과는 이렇습니다:

그날은 내가 처음으로 우리 멋진 팀장님으로 부터 동적 UI 생성에 대해서 전해들었습니다. 이런 이야기 입니다.

웹딘프로아밥에는 각 UI 엘리먼트 마다 클래스(예: CL_WD_CHECKBOX , CL_WD_CHECKBOX_GROUP, CL_WD_INPUT_FIELD 등)가 하나씩 있습니다. 이 클래스를 이용하면 뷰의 WDDOMODIFYVIEW 메소드에서 UI 엘리먼트를 뷰에 추가 할 수 있습니다.

간단한 예제로 뷰에 트레이 UI 엘리먼트를 만들어 보겠습니다.

 

예제 1:

뷰에 트레이 UI 엘리먼트 만들기.

정답:

티코드 SE80에서 웹딘프로아밥 컴포넌트를 하나 만듭니다. MAIN 뷰에 transparent container 아이디 TC_MAIN을 만들고 flow 레이아웃으로 지정합니다. ( 이렇게 transparent container를 만드는게 필수는 아니지만 transparent container가 있으면 나중에 뷰를 조정할때 도움이 됩니다. 그러므로 transparent container를 만들기를 추천합니다)

모든 동적 생성 UI 엘리먼트는 이 transparent container에 배치할 것입니다.

아래 소스코드를 뷰의 WDDOMODIFYVIEW 메소드에 입력하면 트레이 UI 엘리먼트가 준비됩니다.

method WDDOMODIFYVIEW .
 "Let's Create Tray
 data : lr_tray type REF TO cl_wd_tray.
 data : lr_caption TYPE REF TO cl_wd_caption.
 DATA : lr_container  TYPE REF TO cl_wd_uielement_container.
 data : lr_flow type ref to cl_wd_flow_data.
 data : lr_matrix_layout type REF TO cl_wd_matrix_layout.
 
 "As we are gonna put the tray in TC_MAIN ( the transperant container )
 "fetch it ...
 lr_container ?= view->get_element( 'TC_MAIN' ).
 
 "Create a Tray Object
 CALL METHOD CL_WD_TRAY=>NEW_TRAY
 EXPORTING
 ID      = 'TR_TRAY'
 WIDTH   = '100%'
 RECEIVING
 CONTROL = lr_tray.
 
 
 "Need to Assign the flow layout information for this Tray
 "As it is part if ROOTUIELEMENTCONTAINER ( with layout flow )
 lr_flow = cl_wd_flow_data=>new_flow_data( lr_tray ).
 
 lr_tray->set_layout_data( lr_flow ).
 "" add tray to container
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_tray.
 
 "' set layout of tray
 CALL METHOD cl_wd_matrix_layout=>new_matrix_layout
 EXPORTING
 container = lr_tray
 RECEIVING
 control   = lr_matrix_layout.
 
 CALL METHOD cl_wd_caption=>new_caption
 EXPORTING
 id      = 'CA_TRAY'
 text    = 'Yahoo... Here is my Tray (*_*)'
 RECEIVING
 control = lr_caption.
 
 "' set header for tray
 CALL METHOD lr_tray->set_header
 EXPORTING
 the_header = lr_caption.
 
 endmethod.

 

저장하고 활성화하고 실행합니다.

 

예제 2:

트레이 안에 input field 와 label 그리고 button을 추가합니다.

정답:

input field 의 Value 속성은 반드시 컨텍스트의 어트리뷰트가 바인딩 되어야 합니다. 그러므로 컨택스트 노드/어트리뷰트를 먼저 만들어야 합니다.

컴포넌트 컨트롤러에 RET_CC_CONTEXT 메소드를 만듭니다.

Exporting parameter : ER_CONTEXT  type ref to IF_WD_CONTEXT_NODE.

 

아래 소스 코드를 WDDOMODIFYVIEW 메소드에 입력하고 다시 실행해보세요. 만약 활성화할때 에러가 발생한다면 에러 메시지를 보고 스스로 해결하도록 합니다.

method WDDOMODIFYVIEW .
 "Let's Create Tray
 data : lr_tray type REF TO cl_wd_tray.
 data : lr_caption TYPE REF TO cl_wd_caption.
 DATA : lr_container  TYPE REF TO cl_wd_uielement_container.
 data : lr_flow type ref to cl_wd_flow_data.
 data : lr_matrix_layout type REF TO cl_wd_matrix_layout.
 
 "As we are gonna put the tray in TC_MAIN ( the transperant container )
 "fetch it ...
 lr_container ?= view->get_element( 'TC_MAIN' ).
 
 "Create a Tray Object
 CALL METHOD CL_WD_TRAY=>NEW_TRAY
 EXPORTING
 ID      = 'TR_TRAY'
 WIDTH   = '100%'
 RECEIVING
 CONTROL = lr_tray.
 
 
 "Need to Assign the flow layout information for this Tray
 "As it is part if ROOTUIELEMENTCONTAINER ( with layout flow )
 lr_flow = cl_wd_flow_data=>new_flow_data( lr_tray ).
 
 lr_tray->set_layout_data( lr_flow ).
 "" add tray to container
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_tray.
 
 "' set layout of tray
 CALL METHOD cl_wd_matrix_layout=>new_matrix_layout
 EXPORTING
 container = lr_tray
 RECEIVING
 control   = lr_matrix_layout.
 
 CALL METHOD cl_wd_caption=>new_caption
 EXPORTING
 id      = 'CA_TRAY'
 text    = 'Yahoo... Here is my Tray (*_*)'
 RECEIVING
 control = lr_caption.
 
 "' set header for tray
 CALL METHOD lr_tray->set_header
 EXPORTING
 the_header = lr_caption.
 
 
 "****************Create Input field ********************************
 "create Node And Element for input field
 "Part 1: stracture creation : with one field called name
 TYPE-POOLS:  abap.
 
 DATA :
 lt_components     TYPE abap_component_tab,
 lw_component      TYPE LINE OF abap_component_tab,
 lr_structdescr    type ref to CL_ABAP_STRUCTDESCR,
 lt_attribs TYPE  wdr_context_attr_info_map,
 ls_attribs like LINE OF lt_attribs.
 
 
 lw_component-name = 'NAME'.
 TRY.
 lw_component-type = cl_abap_elemdescr=>get_c(  p_length =  20 ).
 CATCH cx_sy_move_cast_error .
 ENDTRY.
 
 append lw_component to lt_components.
 
 lr_structdescr = cl_abap_structdescr=>create( lt_components ).
 "Part2 : Now Create a Node based on this Dynamic struct.
 
 DATA:
 lo_parent_node_info                TYPE REF TO if_wd_context_node_info,
 lo_child_node_info                 TYPE REF TO if_wd_context_node_info,
 *    lo_nd_gen_tab                      TYPE REF TO if_wd_context_node,
 lt_child_node_map                  TYPE wdr_context_child_info_map,
 comp_context type ref to if_wd_context_node.
 FIELD-SYMBOLS : <fs_stru>    TYPE any .
 *  DATA   dy_stru       TYPE REF TO data.
 
 wd_comp_controller->ret_cc_context(
 IMPORTING
 er_context = comp_context ).
 
 lo_parent_node_info = comp_context->get_node_info( ).
 lt_child_node_map = lo_parent_node_info->get_child_nodes( ).
 READ TABLE lt_child_node_map TRANSPORTING NO FIELDS WITH TABLE KEY name = 'ND_DETAIL'.
 IF sy-subrc = 0.
 " REMOVE_CHILD_NODE
 lo_parent_node_info->remove_child_node(  'ND_DETAIL' ).
 ENDIF.
 
 "" get attrib property
 LS_ATTRIBS-name = 'NAME'.
 insert ls_attribs into table lt_attribs.
 
 " create Node in Comp Controller
 CALL METHOD lo_parent_node_info->add_new_child_node
 EXPORTING
 name                         = 'ND_DETAIL'
 is_singleton                 = abap_true
 static_element_rtti          = lr_structdescr
 is_static                    = abap_true
 attributes                   = lt_attribs
 RECEIVING
 child_node_info              = lo_child_node_info.
 
 
 DATA lr_wa            TYPE REF TO data.
 data lo_child_node_detail TYPE ref to if_wd_context_node.
 FIELD-SYMBOLS <lfs_dyn> TYPE any.
 CREATE DATA lr_wa TYPE HANDLE lr_structdescr.
 ASSIGN lr_wa->* TO <lfs_dyn>.
 lo_child_node_detail = comp_context->get_child_node( name = 'ND_DETAIL' ).
 lo_child_node_detail->bind_structure( EXPORTING new_item =   <lfs_dyn> ).
 
 " Map that component controller node to View
 
 DATA: lo_node_info TYPE REF TO if_wd_context_node_info,
 lo_node TYPE REF TO if_wd_context_node,
 mapping_info TYPE wdr_context_mapping_info,
 lv_name TYPE string,
 lt_path TYPE wdr_ctx_element_path_segments.
 DATA map_path TYPE string.
 CLEAR lt_path.
 
 ""
 DATA:
 lr_child_node_info_view                 TYPE REF TO if_wd_context_node_info,
 lt_child_node_map_view                 TYPE wdr_context_child_info_map.
 lo_node_info  = WD_CONTEXT->get_node_info( ).
 lv_name = 'ND_DETAIL'.
 lt_child_node_map_view  = lo_node_info->get_child_nodes( ).
 READ TABLE lt_child_node_map TRANSPORTING NO FIELDS WITH TABLE KEY name = 'ND_DETAIL'.
 IF sy-subrc = 0.
 " REMOVE_CHILD_NODE
 lo_node = wd_context->get_child_node(  name = 'ND_DETAIL' ).
 lr_child_node_info_view = lo_node->get_node_info( ).
 RETURN.
 ELSE.
 ENDIF.
 
 CONCATENATE 'COMPONENTCONTROLLER.' lv_name INTO map_path.
 APPEND map_path TO lt_path.
 mapping_info-controller = 'COMPONENTCONTROLLER'. "conponent name
 mapping_info-path = lt_path. "Controller context node name
 "" create view node refering component node
 CALL METHOD lo_node_info->add_new_mapped_child_node
 EXPORTING
 child_name      = lv_name
 mapping_info    = mapping_info
 is_static       = abap_true
 RECEIVING
 child_node_info = lr_child_node_info_view.
 
 
 "Now Let's Create An input field along with the label and put it in Try
 "Bind the inout field with the Name element of ND_DETAIL Node we created
 
 DATA lr_input  TYPE REF TO cl_wd_input_field..
 DATA lr_matrix_data    TYPE REF TO cl_wd_matrix_data.
 DATA lr_matrix    TYPE REF TO cl_wd_matrix_head_data.
 DATA lv_lbl_id TYPE string.
 DATA lv_lbl_txt TYPE string.
 DATA lv_lbl_for TYPE string.
 DATA lr_label     TYPE REF TO cl_wd_label.
 DATA inp_id TYPE string.
 DATA lv_width TYPE string.
 CLEAR  : inp_id , lv_width.
 
 CALL METHOD cl_wd_input_field=>new_input_field
 EXPORTING
 bind_value             = 'ND_DETAIL.ND_DETAIL.NAME'
 id                     = 'IF_NAME'
 input_prompt           = 'Enter Name'
 RECEIVING
 control                = lr_input.
 
 "" create lbl for Input field
 CALL METHOD cl_wd_label=>new_label
 EXPORTING
 id        = 'LBL_NAME'
 label_for = 'IF_NAME'
 text      = 'Name'
 RECEIVING
 control   = lr_label. " CONTROL
 
 lr_matrix = cl_wd_matrix_head_data=>new_matrix_head_data( lr_label ).
 lr_label->set_layout_data( lr_matrix ).
 
 lr_matrix_data = cl_wd_matrix_data=>new_matrix_data( lr_input ).
 lr_input->set_layout_data( lr_matrix_data ).
 
 "Let's Add this couple to the Try
 
 "' get tray as container
 lr_container ?= view->get_element( 'TR_TRAY' ).
 
 
 "" add label and Input field to Tray
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_label.
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_input.
 
 "Now let's Create a button and add it to Tray
 data : lr_button type REF TO cl_wd_button.
 
 CALL METHOD CL_WD_BUTTON=>NEW_BUTTON
 EXPORTING
 IMAGE_SOURCE           = '~Icon/Search'
 on_action              = 'PROCESS_EVENT'
 ID                     = 'BTN_SEARCH'
 TEXT                   = 'Sumit'
 RECEIVING
 CONTROL                 = lr_button.
 
 "as we want this button to come on new line make it matrix head data
 
 lr_matrix = cl_wd_matrix_head_data=>new_matrix_head_data( lr_button ).
 lr_button->set_layout_data( lr_matrix ).
 
 "" add Button to Tray
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_button.
 
 endmethod.

 

저장하고 활성화하고 실행합니다.

 

덕후들을 위한 추가…

예제 3:

SEARCH 버튼을 누르면 팝업화면에 입력한 이름을 표시합니다.

힌트: Search 버튼에 바인딩된 액션 메소드 ONACTIONPROCESS_EVENT 를 구현해야 합니다.

하다가 문제가 있으면 댓글로 질문주세요 ..

해피 코딩….

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다

https://blogs.sap.com/2013/11/20/dynamic-ui-generation-in-web-dynpro-abap/

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다

http://scn.sap.com/docs/DOC-65405

 

 

웹딘프로 아밥에서 CSS 스타일 적용하기

서버 버전이 SAP_UI 740이상 SP 10 이상 이면 CSS를 사용할 수 있습니다. 이제 HTML Island를 사용하지 않고도 배경색상, 글자색상, 글자크기 등을 변경하여 UI를 아름답게 꾸밀 수 있습니다.

 

 

웹딘프로아밥에 CSS를 적용하려면 아래 단계를 진행하세요.

 

1.  적용할 CSS 스타일 속성(배경색상, 글자크기, 글자색상)을 if_wd_custom_style=>t_style_properties 타입에 맞게 이름과 값으로 정의합니다.

 

2.  메소드 IF_WD_CUSTOM_STYLE_MANAGER~CREATE_CUSTOM_STYLE를 호출합니다. 파라미터로 스타일 클래스 이름, 스타일 속성(단계1에서 정의한것), UI엘리먼트 등이 필요합니다.

 

3.  위에서 만들어진 IF_WD_CUSTOM_STYLE_MANAGER 타입의 인스턴스를 컴포넌트에 추가합니다. 이제 컴포넌트에서 스타일시트를 사용 할 수 있습니다.

 

4.  스타일시트 이름을 UI 속성 styleClassName에 입력합니다.

 

 

단계별 시나리오 예제:-

 

1. 웹딘프로아밥 컴포넌트를 새로 만듭니다.

 

     Create Component.png


 

 

2. 컴포넌트 컨트롤러의 메소드 탭에서 WDDOINIT 메소드에 아래 코드를 추가 합니다.

 

 

    

WDDOINIT
data(lo_custom_style_manager) = wd_this->wd_get_api( )->get_application( )->get_custom_style_manager( ).

  data lo_btn_style_properties type if_wd_custom_style=>t_style_properties.

    lo_btn_style_properties = value #( ( name = 'fontSize' value = '15px' )

                                       ( name = 'fontWeight' value = 'bold' )

                                       ( name = 'fontColor' value = 'RED' )

                                  ).

    data(lo_btn_custom_style) = lo_custom_style_manager->create_custom_style( style_class_name = 'myCustomButton'

                                                                        library_name     = 'STANDARD'

                                                                        element_type     = 'BUTTON'

                                                                        style_properties = lo_btn_style_properties ).

lo_custom_style_manager->add_custom_style( lo_btn_custom_style ).

    data lo_txt_vw_style_properties type if_wd_custom_style=>t_style_properties.

    lo_txt_vw_style_properties = value #( ( name = 'fontSize' value = '15px' )

                                          ( name = 'fontWeight' value = 'bold' )

                                          ( name = 'fontColor' value = 'rgb(95,95,95)' )

                                        ).

    data(lo_txt_custom_style) = lo_custom_style_manager->create_custom_style( style_class_name = 'myCustomTextView'

                                                                        library_name     = 'STANDARD'

                                                                        element_type     = 'TEXT_VIEW'

                                                                        style_properties = lo_txt_vw_style_properties ).

   lo_custom_style_manager->add_custom_style( lo_txt_custom_style ).

 

 

3. 뷰 탭으로 이동하여 transparent container를 하나 만들고 안에 button 하나와 text view 하나를 만듭니다. 만들어진 transparent container를 복사하여 하나 더 만듭니다. 이렇게 복사하는 이유는 일반 UI 와 CSS가 적용된 UI를 비교해 보기위해서 입니다. 아래그림처럼 만듭니다.

 

    View Layout.png

 

 

4. 복사한 transparent container아래 button 과 text view에 속성 styleClassName를 각각 아래 그림처럼 입력합니다. (속성에 들어가는 이름은 WDDOINIT 메소드에서 정의한 이름입니다).

button.pngtextView.png

 

 

5. 이제 어플리케이션을 만들고 실행합니다. CSS 적용된 결과를 보세요.

Output.png

 

 

 

스탠다드의 WDR_TEST_CUSTOM_STYLES 컴포넌트를 보면 이와 관련된 더 많은 예제를 볼 수 있습니다.

 

 

참고자료:

 

 

 

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다

http://scn.sap.com/docs/DOC-65405

 

 

보통은 lo_application->get_remote_address( ) 로 접속한 아이피를 알 수 있지만

여러 AP가 있는 환경에서는 로드밸런싱 장비가 중간에 있어서 그 장비 아이피가 나오는 경우가 있습니다.

그래서 그런 경우에도 원래 접속자의 IP를 알 수 있도록 펑션을 만들어 보았습니다.

웹딘에서도 되고 SAP GUI에서도 동작하도록  IF-ELSE 로 SAP GUI용 로직도 넣었습니다.

접속 로그 남기는데 활용하세요.

 

FUNCTION zget_ip_address.
*"---------------------------------------------------------------------- *"
*"Local interface:
*"  EXPORTING
*"     REFERENCE(EV_IP) TYPE  CSEQUENCE
*"----------------------------------------------------------------------
    DATA: lo_application   TYPE REF TO if_wd_application,
          ls_header_fields TYPE wdr_name_value,
          lv_ip            TYPE string.

    IF wdr_task=>application_name IS INITIAL.
      " SAP GUI
      CALL METHOD cl_gui_frontend_services=>get_ip_address
        RECEIVING
          ip_address           = lv_ip
        EXCEPTIONS
          cntl_error           = 1
          error_no_gui         = 2
          not_supported_by_gui = 3
          OTHERS               = 4.
    ELSE.
      " WD
      READ TABLE wdr_task=>client_window->if_wdr_client_info_object~header_fields INTO ls_header_fields
            WITH KEY name = 'x-forwarded-for'.
      IF sy-subrc = 0.
        " load balancer 통해서 접속한 경우.
        lv_ip = ls_header_fields-value.
      ELSE.
        " 직접 AP 로 접속한 경우.
        lo_application = wdr_task=>application->get_api( ).
        lv_ip = lo_application->get_remote_address( ).
      ENDIF.

    ENDIF.

    ev_ip = lv_ip.
ENDFUNCTION.

 

 

ABAP에서는 일반 공백이 무시되는 경우가 종종 있는데

웹딘프로아밥에서도 공백 여러개가 하나로 합쳐진다거나 단어 뒤에 공백을 추가로 넣고 싶은데 사라지는 등 문제가 발생합니다.

이럴때 필요한 유니코드 공백 문자

 

cl_abap_conv_in_ce=>uccp( '00A0' )

cl_abap_conv_in_ce=>uccp( '2000' )

cl_abap_conv_in_ce=>uccp( '3000' )

 

등... 위 코드에서 유니코드 값만 바꾸면 다른 유니코드 문자도 사용할 수 있는겁니다.

다양한 넓이의 유니코드 공백은 https://www.cs.tut.fi/~jkorpela/chars/spaces.html 여기서 찾아보세요.

2021-10-14 수정

abap2xlsx helper 를 만들었습니다. 더 쉽고 편리합니다.

https://boy0.tistory.com/173

 

abap2xlsx helper

취미로 개발중인 프로그램... https://github.com/boy0korea/ABAP2XLSX_HELPER ZCL_ABAP2XLSX_HELPER=>EXCEL_DOWNLOAD 인터널 테이블 내용을 엑셀 파일로 다운로드 합니다. ZCL_ABAP2XLSX_HELPER=>EXCEL_EMAIL 인..

boy0.tistory.com

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

안녕하세요.

 

ABAP2XLSX 를 활용한 엑셀 다운로드 입니다. (설치방법: http://boy0.tistory.com/95)

인터널 테이블을 넣으면 엑셀 파일 다운로드를 시작합니다.

옵션 파라미터 4개가 있는데,

IV_FOR_UPLOAD    : 나중에 업로드를 위한 다운로드 파일로 DATE와 TIME을 엑셀포맷이 아닌 일반문자로 바꿔줍니다.

IT_FIELD_CATALOG    : 필드 레이블을 변경할 수 있습니다. zcl_excel_common=>get_fieldcatalog( ) 호출하여 생성.

IV_FILENAME    : 파일명 (기본 export.xlsx)

IV_SHEET_TITLE    : 시트명 (기본 Export)

 

FUNCTION ZWD_EXCEL_DOWNLOAD.
*"--------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IV_FOR_UPLOAD) TYPE  FLAG OPTIONAL
*"     REFERENCE(IT_FIELD_CATALOG) TYPE  ZEXCEL_T_FIELDCATALOG
*"         OPTIONAL
*"     REFERENCE(IV_FILENAME) TYPE  CSEQUENCE OPTIONAL
*"     REFERENCE(IV_SHEET_TITLE) TYPE  CSEQUENCE OPTIONAL
*"     REFERENCE(IV_AUTO_COLUMN_WIDTH) TYPE  FLAG DEFAULT ABAP_TRUE
*"  EXPORTING
*"     REFERENCE(EV_ERROR_TEXT) TYPE  STRING
*"  TABLES
*"      IT_TABLE TYPE  TABLE
*"--------------------------------------------------------------------
* 오픈소스 abap2xlsx 설치가 필요합니다. http://www.abap2xlsx.org
  DATA: lo_excel             TYPE REF TO zcl_excel,
        lo_writer            TYPE REF TO zif_excel_writer,
        lo_worksheet         TYPE REF TO zcl_excel_worksheet,
        ls_table_settings    TYPE zexcel_s_table_settings,
        lt_field_catalog     TYPE zexcel_t_fieldcatalog,
        ls_field_catalog     TYPE zexcel_s_fieldcatalog,
        lv_xstring           TYPE xstring,
        lo_zcx_excel         TYPE REF TO zcx_excel,
        lv_sheet_title       TYPE zexcel_sheet_title,
        lv_filename_string   TYPE string,
        lv_filename_path     TYPE string,
        lv_filename_fullpath TYPE string,
        lv_bin_filesize      TYPE i,
        lt_temptable         TYPE w3mimetabtype,
        lv_index             TYPE i.
  CLEAR ev_error_text.

  TRY.

      " Creates active sheet
      CREATE OBJECT lo_excel.

      " Get active sheet
      IF iv_sheet_title IS NOT INITIAL.
        lv_sheet_title = iv_sheet_title.
      ELSE.
        lv_sheet_title = 'Export'.
      ENDIF.
      lo_worksheet = lo_excel->get_active_worksheet( ).
      lo_worksheet->set_title( ip_title = lv_sheet_title ).

      ls_table_settings-table_style       = zcl_excel_table=>builtinstyle_medium2.
      ls_table_settings-show_row_stripes  = abap_true.
      ls_table_settings-nofilters         = abap_true.

      IF it_field_catalog IS NOT INITIAL.
        lt_field_catalog = it_field_catalog.
        SORT lt_field_catalog BY position fieldname.
        LOOP AT lt_field_catalog INTO ls_field_catalog.
          lv_index = sy-tabix.
          IF ls_field_catalog-position <> lv_index.
            ls_field_catalog-position = lv_index.
            MODIFY lt_field_catalog FROM ls_field_catalog INDEX lv_index TRANSPORTING position.
          ENDIF.
        ENDLOOP.
      ELSE.
        lt_field_catalog = zcl_excel_common=>get_fieldcatalog( ip_table = it_table[] ).
      ENDIF.

      IF iv_for_upload EQ abap_true.
        ls_field_catalog-dynpfld = abap_true.
        MODIFY lt_field_catalog FROM ls_field_catalog TRANSPORTING dynpfld WHERE dynpfld EQ abap_false.
        ls_field_catalog-abap_type = 'C'.
        MODIFY lt_field_catalog FROM ls_field_catalog TRANSPORTING abap_type WHERE abap_type EQ 'D'.  "Date -> Char
        MODIFY lt_field_catalog FROM ls_field_catalog TRANSPORTING abap_type WHERE abap_type EQ 'T'.  "Time -> Char
      ENDIF.

      lo_worksheet->bind_table( ip_table          = it_table[]
                                it_field_catalog = lt_field_catalog
                                is_table_settings = ls_table_settings ).
*                                iv_no_header = iv_no_header
*                                iv_no_table_setting = iv_no_table_setting ).

      IF iv_auto_column_width EQ abap_true.
        LOOP AT lt_field_catalog INTO ls_field_catalog WHERE dynpfld = abap_true.
          lo_worksheet->set_column_width(
            EXPORTING
              ip_column         = zcl_excel_common=>convert_column2alpha( ls_field_catalog-position )
              ip_width_autosize = abap_true
          ).
        ENDLOOP.
      ENDIF.

      lo_worksheet->freeze_panes( ip_num_rows = 1 ). "freeze column headers when scrolling

*** Create output
      CREATE OBJECT lo_writer TYPE zcl_excel_writer_2007.
      lv_xstring = lo_writer->write_file( lo_excel ).


    CATCH zcx_excel INTO lo_zcx_excel.    " Exceptions for ABAP2XLSX
      ev_error_text = lo_zcx_excel->error.
      RETURN.
*      IF NOT MSG IS INITIAL.
**Raise exception message
*      ENDIF.
  ENDTRY.


  lv_filename_string = iv_filename.
  IF iv_filename IS INITIAL.
    lv_filename_string = |export_{ sy-datum }_{ sy-uzeit }.xlsx|.
  ENDIF.
  IF wdr_task=>application_name IS NOT INITIAL.
    CALL METHOD cl_wd_runtime_services=>attach_file_to_response
      EXPORTING
        i_filename  = lv_filename_string
        i_content   = lv_xstring
        i_mime_type = 'xlsx'
*       i_in_new_window = ABAP_FALSE
*       i_inplace   = ABAP_FALSE
      .
  ELSE.
    CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
      EXPORTING
        buffer        = lv_xstring
      IMPORTING
        output_length = lv_bin_filesize
      TABLES
        binary_tab    = lt_temptable.
    cl_gui_frontend_services=>file_save_dialog(
      EXPORTING
*        window_title              = window_title      " Window Title
*        default_extension         = default_extension " Default Extension
        default_file_name         = lv_filename_string " Default File Name
*        with_encoding             = with_encoding
        file_filter               = '*.xlsx'       " File Type Filter Table
*        initial_directory         = initial_directory " Initial Directory
*        prompt_on_overwrite       = 'X'
      CHANGING
        filename                  = lv_filename_string          " File Name to Save
        path                      = lv_filename_path              " Path to File
        fullpath                  = lv_filename_fullpath          " Path + File Name
*        user_action               = user_action       " User Action (C Class Const ACTION_OK, ACTION_OVERWRITE etc)
*        file_encoding             = file_encoding
      EXCEPTIONS
        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.
    IF lv_filename_fullpath IS NOT INITIAL.
      cl_gui_frontend_services=>gui_download(
         EXPORTING
           bin_filesize = lv_bin_filesize
           filename     = lv_filename_fullpath
           filetype     = 'BIN'
         CHANGING
           data_tab     = lt_temptable
         EXCEPTIONS
           file_write_error          = 1
           no_batch                  = 2
           gui_refuse_filetransfer   = 3
           invalid_type              = 4
           no_authority              = 5
           unknown_error             = 6
           header_not_allowed        = 7
           separator_not_allowed     = 8
           filesize_not_allowed      = 9
           header_too_long           = 10
           dp_error_create           = 11
           dp_error_send             = 12
           dp_error_write            = 13
           unknown_dp_error          = 14
           access_denied             = 15
           dp_out_of_memory          = 16
           disk_full                 = 17
           dp_timeout                = 18
           file_not_found            = 19
           dataprovider_exception    = 20
           control_flush_error       = 21
           not_supported_by_gui      = 22
           error_no_gui              = 23
           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.
    ENDIF.
  ENDIF.

ENDFUNCTION.

 

 

 

참고로 업로드 펑션은 여기 있습니다.

http://boy0.tistory.com/107

 

2021-10-14 수정

abap2xlsx helper 를 만들었습니다. 더 쉽고 편리합니다.

https://boy0.tistory.com/173

 

abap2xlsx helper

취미로 개발중인 프로그램... https://github.com/boy0korea/ABAP2XLSX_HELPER ZCL_ABAP2XLSX_HELPER=>EXCEL_DOWNLOAD 인터널 테이블 내용을 엑셀 파일로 다운로드 합니다. ZCL_ABAP2XLSX_HELPER=>EXCEL_EMAIL 인..

boy0.tistory.com

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

안녕하세요.

 

ABAP2XLSX 를 활용한 엑셀 업로드 입니다. (설치방법: http://boy0.tistory.com/95)

WDA용 엑셀 업로드 예제 프로그램은 http://boy0.tistory.com/106 에서 확인하시고,

이를 더 발전시켜서 모듈화 시켜서 사용하기 쉽게 펑션을 제작해 보았습니다.

엑셀 파일을 넣으면 인터널 테이블로 변환시켜 줍니다. 웹딘프로 아닌 일반 ABAP에도 사용가능합니다.

 

FUNCTION ZWD_EXCEL_UPLOAD.
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(IV_EXCEL) TYPE  XSTRING
*"     REFERENCE(IV_BEGIN_ROW) TYPE  I
*"     REFERENCE(IV_SHEET_NO) TYPE  INT1 DEFAULT 1
*"  EXPORTING
*"     REFERENCE(EV_ERROR_TEXT) TYPE  STRING
*"  TABLES
*"      ET_TABLE TYPE  TABLE
*"----------------------------------------------------------------------
* 오픈소스 abap2xlsx 설치가 필요합니다. http://www.abap2xlsx.org
  DATA: lv_xstring        TYPE xstring,
        lo_excel          TYPE REF TO zcl_excel,
        lo_reader         TYPE REF TO zif_excel_reader,
        lo_worksheet      TYPE REF TO zcl_excel_worksheet,
        lv_highest_column TYPE zexcel_cell_column,
        lv_highest_row    TYPE int4,
        lv_column         TYPE zexcel_cell_column,
        lv_col_str        TYPE zexcel_cell_column_alpha,
        lv_row            TYPE int4,
        lv_value          TYPE zexcel_cell_value,
        lv_date           TYPE datum,
        lv_time           TYPE uzeit,
        lv_char_col       TYPE string,
        lv_char_row       TYPE string,
        lv_style_guid     TYPE zexcel_cell_style,
        ls_stylemapping   TYPE zexcel_s_stylemapping,
        lo_root           TYPE REF TO cx_root,
        lo_zcx_excel      TYPE REF TO zcx_excel.
  FIELD-SYMBOLS: <lv_data> TYPE data.

  CLEAR:          ev_error_text, et_table[].

  lv_xstring = iv_excel.

  TRY.
      CREATE OBJECT lo_reader TYPE zcl_excel_reader_2007.
      lo_excel = lo_reader->load( lv_xstring  ). "Load data into reader
      lo_excel->set_active_sheet_index( iv_sheet_no ).
      lo_worksheet = lo_excel->get_active_worksheet( ).

      lv_highest_column = lo_worksheet->get_highest_column( ).
      lv_highest_row    = lo_worksheet->get_highest_row( ).
      lv_row = iv_begin_row.
      lv_column = 1.

      WHILE lv_row <= lv_highest_row.
        WHILE lv_column <= lv_highest_column.
          lv_col_str = zcl_excel_common=>convert_column2alpha( lv_column ).
          lo_worksheet->get_cell(
            EXPORTING
              ip_column = lv_col_str
              ip_row    = lv_row
            IMPORTING
              ep_value  = lv_value
              ep_guid   = lv_style_guid ).
*&---------------------------------------------------------------------*
*&■ Add : Excel Date style Conv
*&---------------------------------------------------------------------*
          IF lv_style_guid IS NOT INITIAL AND lv_value IS NOT INITIAL.
            " Read style attributes
            ls_stylemapping = lo_excel->get_style_to_guid( lv_style_guid ).
            CASE ls_stylemapping-complete_style-number_format-format_code.
              WHEN zcl_excel_style_number_format=>c_format_date_ddmmyyyy
                OR zcl_excel_style_number_format=>c_format_date_ddmmyyyydot
                OR zcl_excel_style_number_format=>c_format_date_dmminus
                OR zcl_excel_style_number_format=>c_format_date_dmyminus
                OR zcl_excel_style_number_format=>c_format_date_dmyslash
                OR zcl_excel_style_number_format=>c_format_date_myminus
                OR zcl_excel_style_number_format=>c_format_date_std
                OR zcl_excel_style_number_format=>c_format_date_xlsx14
                OR zcl_excel_style_number_format=>c_format_date_xlsx15
                OR zcl_excel_style_number_format=>c_format_date_xlsx16
                OR zcl_excel_style_number_format=>c_format_date_xlsx17
                OR zcl_excel_style_number_format=>c_format_date_xlsx22
                OR zcl_excel_style_number_format=>c_format_date_xlsx45
                OR zcl_excel_style_number_format=>c_format_date_xlsx46
                OR zcl_excel_style_number_format=>c_format_date_xlsx47
                OR zcl_excel_style_number_format=>c_format_date_yymmdd
                OR zcl_excel_style_number_format=>c_format_date_yymmddminus
                OR zcl_excel_style_number_format=>c_format_date_yymmddslash
                OR zcl_excel_style_number_format=>c_format_date_yyyymmdd
                OR zcl_excel_style_number_format=>c_format_date_yyyymmddminus
                OR zcl_excel_style_number_format=>c_format_date_yyyymmddslash.
                " Convert excel date to ABAP date
                lv_date = zcl_excel_common=>excel_string_to_date( lv_value ).
                lv_value = lv_date.
              WHEN zcl_excel_style_number_format=>c_format_date_time1
                OR zcl_excel_style_number_format=>c_format_date_time2
                OR zcl_excel_style_number_format=>c_format_date_time3
                OR zcl_excel_style_number_format=>c_format_date_time4
                OR zcl_excel_style_number_format=>c_format_date_time5
                OR zcl_excel_style_number_format=>c_format_date_time6
                OR zcl_excel_style_number_format=>c_format_date_time7
                OR zcl_excel_style_number_format=>c_format_date_time8
                OR 'h:mm:ss;@'.
                " Convert excel time to ABAP time
                lv_time = zcl_excel_common=>excel_string_to_time( lv_value ).
                lv_value = lv_time.
            ENDCASE.
          ENDIF.
*&---------------------------------------------------------------------*
          CONDENSE lv_value.
          IF lv_value IS NOT INITIAL.
            ASSIGN COMPONENT lv_column OF STRUCTURE et_table TO <lv_data>.
            IF sy-subrc <> 0.
              EXIT.
            ENDIF.
            <lv_data> = lv_value.
          ENDIF.
          lv_column = lv_column + 1.
        ENDWHILE.
        IF NOT et_table IS INITIAL .
          APPEND et_table.
        ENDIF.
        CLEAR et_table .
        lv_column = 1.
        lv_row    = lv_row + 1.
      ENDWHILE.
    CATCH cx_root INTO lo_root.    " Exceptions for ABAP2XLSX
      ev_error_text = lo_root->get_text( ).
      lv_char_col = lv_column. CONDENSE lv_char_col NO-GAPS.
      lv_char_row = lv_row.    CONDENSE lv_char_row NO-GAPS.
      ev_error_text = ev_error_text && '(Col:' && lv_char_col && ',Row:' && lv_char_row && ')'.
*      IF NOT MSG IS INITIAL.
**Raise exception message
*      ENDIF.
  ENDTRY.





ENDFUNCTION.

 

 

참고로 다운로드 펑션은 여기 있습니다.

http://boy0.tistory.com/108

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다 (+약간의 내용 추가)

https://scn.sap.com/community/web-dynpro-abap/blog/2012/04/05/upload-xlsx-file-in-webdynpro-abap-and-view-its-content

더 발전된 코드 웹딘프로아밥 XLSX 엑셀파일 업로드 펑션: https://boy0.tistory.com/107

 

웹딘프로아밥 XLSX 엑셀파일 업로드 예제

Posted by Ashish Shah in Web Dynpro ABAP on Apr 5, 2012 2:20:52 PM

Upload XLSX file in WebDynpro ABAP and view its content

 

웹딘프로아밥 게시판에는 엑셀 파일을 읽어서 그 내용을 화면에 테이블로 보여주기를 원하는 많은 글이 있습니다. 그런데 대부분은 답변이 없는 상태로 남아있죠. 그 이유는 스탠다드 기능만으로 바로 엑셀파일을 다룰 수 있는 방법이 없기 때문입니다.

 

새로운 해결 방법은 바로 ABAP2XLSX 프로젝트를 통해서 가능합니다!!!


준비:

  1. SAPlink 최신버전 설치 https://boy0.tistory.com/96
  2. SAPlink 플러그인 설치
  3. ABAP2XLSX 설치 https://boy0.tistory.com/95
  4. 샘플 데이터를 입력한 XLSX 엑셀파일
  5. (필수는 아님) 개선사항을 업데이트 받기위해 ABAP2XLS 와 SAPLINK 그룹에 가입하기
    https://cw.sdn.sap.com/cw/groups/saplink and https://cw.sdn.sap.com/cw/groups/abap2xlsx


파일업로드 UI 엘리먼트가 있는 웹딘프로아밥 만들기:

  1. 티코드 SE80에서 웹딘프로아밥 컴포넌트를 생성합니다.
  2. 뷰의 context 탭에서 "upload_content" 노드를 만들고 그 아래에 타입이 XSTRING인  "file_content" 어트리뷰트를 만듭니다.
  3. layout 탭에서 파일업로드 UI 엘리먼트를 추가 하고 data 속성에 XSTRING 어트리뷰트를 바인딩합니다. WD View.jpg
  4. 버튼을 추가하고 action: upload를 지정합니다.
  5. 아래 코드를 사용하여 엑셀 2007포맷의 .xlsx 파일을 읽을 수 있습니다.

 

Method OnActionUpload.
METHOD onactionupload .
DATA lo_nd_upload_content    TYPE REF TO if_wd_context_node.
DATA lo_el_upload_content    TYPE REF TO if_wd_context_element.
DATA ls_upload_content       TYPE wd_this->element_upload_content.
DATA: lo_componentcontroller  TYPE REF TO ig_componentcontroller,
lo_current_controller   TYPE REF TO if_wd_controller,
lo_view_controller      TYPE REF TO if_wd_view_controller,
lo_message_manager      TYPE REF TO if_wd_message_manager .
DATA: excel                   TYPE REF TO zcl_excel,
lo_excel_writer         TYPE REF TO zif_excel_writer,
  reader                  TYPE REF TO zif_excel_reader.
DATA: worksheet               TYPE REF TO zcl_excel_worksheet,
highest_column          TYPE zexcel_cell_column,
highest_row             TYPE int4,
column                  TYPE zexcel_cell_column VALUE 1,
col_str                 TYPE zexcel_cell_column_alpha,
row                     TYPE int4               VALUE 1,
value                   TYPE zexcel_cell_value.
DATA: ex                      TYPE REF TO zcx_excel,
msg                     TYPE string,
lv_highest_row          TYPE string,
lv_highest_column       TYPE string,
lv_rowdata              TYPE string,
lv_rownumber            TYPE string.

lo_current_controller ?= wd_this->wd_get_api( ).
lo_message_manager = lo_current_controller->get_message_manager( ).
lo_view_controller = wd_this->wd_get_api( ).

*   navigate from  to  via lead selection
lo_nd_upload_content = wd_context->get_child_node( name = wd_this->wdctx_upload_content ).

*   get element via lead selection
lo_el_upload_content = lo_nd_upload_content->get_element( ).

*   get all declared attributes
  lo_el_upload_content->get_static_attributes(
IMPORTING
static_attributes = ls_upload_content ).

TRY.
CREATE OBJECT reader TYPE zcl_excel_reader_2007.
excel = reader->load( ls_upload_content-file_content ).

worksheet = excel->get_active_worksheet( ).
highest_column = worksheet->get_highest_column( ).
MOVE highest_column TO lv_highest_column.
highest_row    = worksheet->get_highest_row( ).
MOVE highest_row TO lv_highest_row.
CONCATENATE 'Highest column: ' lv_highest_column  'Highest row: '  lv_highest_row INTO msg.
CALL METHOD lo_message_manager->report_message
EXPORTING
message_text = msg.

CLEAR lv_rowdata.

WHILE row <= highest_row.
WHILE column <= highest_column.
col_str = zcl_excel_common=>convert_column2alpha( column ).
worksheet->get_cell(
EXPORTING
ip_column = col_str
ip_row    = row
IMPORTING
ep_value = value
).
CONCATENATE lv_rowdata value INTO lv_rowdata SEPARATED BY space.
column       = column + 1.
ENDWHILE.
CLEAR msg.
MOVE row TO lv_rownumber.
CONCATENATE 'Row# ' lv_rownumber ' Data = ' lv_rowdata INTO msg.
CLEAR lv_rowdata.
CALL METHOD lo_message_manager->report_message
EXPORTING
message_text = msg.
column = 1.
row = row + 1.
ENDWHILE.

CATCHzcx_excel INTO ex.    ” Exceptions for ABAP2XLSX
CLEAR msg.
msg = ex->error.

*  report message
CALL METHOD lo_message_manager->report_message
EXPORTING
message_text = msg.

ENDTRY.
ENDMETHOD.

 

샘플 엑셀 파일 내용

Excel File.jpg

 

엑샐 파일을 업로드 하는 웹딘프로아밥 프로그램 예:

WDA Application.jpg


결과 :

WDA Application Output.jpg

 

행복하세요!!!!

관심있는 댓글 환영합니다.

 

 

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다 (+약간의 내용 추가)

https://scn.sap.com/community/web-dynpro-abap/blog/2012/04/05/upload-xlsx-file-in-webdynpro-abap-and-view-its-content

더 발전된 코드 웹딘프로아밥 XLSX 엑셀파일 업로드 펑션: https://boy0.tistory.com/107

+ Recent posts