이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
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/community/web-dynpro-abap/floorplan-manager/blog/2013/09/19/using-fpm-applications-on-an-ipad

 

 

웹딘프로아밥과 FPM 은 데스크탑 어플리케이션 작성을 위해 설계되었습니다. 기술적으로는 FPM 어플리케이션은 태블릿이나 스마트폰처럼 모바일 환경에서도 사용 가능합니다. 그러나 많은 기능 제약이 있었습니다. 이제 SAP에도 변화가 생기고 있습니다. 노트 1853087을 적용하면 웹딘프로아밥/FPM 을 모바일 사파리 브라우저에서도 실행할 수 있습니다.

 

이 블로그에서는 모바일 장치에서 FPM 어플리케이션을 실행할때 사용할 수 있는 새로운 기능을 소개하겠습니다. 서버 버전이 NW 7.03/7.31 SP9 (+ 노트 1893651) 또는 NW 7.40 SP4 이상이면 가능합니다.

 

모바일과 데스크탑의 주요 차이점은 키보드와 마우스를 사용하지 않고 "터치"를 사용하는 방식 뿐만 아니라 화면의 크기가 데스크탑에 비해 매우 작다라는 특징이 있습니다. 그래서 보통 모바일 용 화면은 더 단순하게 만듭니다. 꼭 필요한 필드만 배치하고 자주 사용하지 않는 필드를 표시하지 않는다거나 기존의 복잡한 화면을 여러개의 단순한 화면으로 나누어 작은 화면에 잘 보이도록 배치하는 등의 방법을 사용합니다.

 

FPM의 configuration을 활용하면 이렇게 데스크탑/모바일의 화면을 별도로 가지는게 가능합니다. 이제부터 어떻게 만들고 enhance하고 adapt할 건지 소개하겠습니다. 기술적인 부분은 How to Create, Enhance, and Adapt Floorplan Manager Applications on SAP NetWeaver 7.31 를 참고하세요.

 

하지만 아직 한가지 문제는 남아있습니다:

 

만약 어플리케이션을 모바일용으로 adapt 하면 데스크탑 사용자들은 모바일에 맞춰 줄어든 기능을 함께 사용해야 하는 불편함을 감수 해야 합니다. 아니면 복사본을 만들어서 모바일용과 데스크탑용을 분리하여 운영 할 수 있습니다. 이런 경우 2개의 어플리케이션을 유지보수 해야 하고 각자 실행하는 어플리케이션이 달라지는 문제가 있습니다.

 

다행히 해결방법이 있습니다: 접속 장치의 종류를 인식하고 Context-Based Adaptations (CBA) 를 사용하는 것입니다. 무슨뜻이냐면 모바일용으로 복사가 아니라 단지 데스크탑용 대비 delta(변화량)만 관리하면 된다는 것입니다. FPM이 자동으로 장치의 종류를 인식하여 어플리케이션에 delta(변화량)를 적용해서 실행할 것인지 아닌지를 판단합니다. 이렇게 하면 하나의 어플리케이션만 유지보수 하면 됩니다. 사용자들은 동일한 어플리케이션을 사용하지만 접속 장치에 따라 모바일은 더 단순한 UI 를 보게 됩니다.

 

이 기술은 modification이 필요하지 않습니다. 그러므로 SAP 스탠다드 프로그램을 adpat 하는데에도 전혀 문제가 없습니다.

 

단계별 설명

이 블로그의 나머지 부분은 예제를 통해서 어떻게 작동하는지 설명하겠습니다. 예제는 SAP 스탠다드 어플리케이션이고 이를 단순화 시켜 adapt 하여 모바일로 접속하여 사용하는 것을 보여드리겠습니다. 예제 어플리케이션은 바로 FPM_DEMO_PLAYER 입니다. 이 어플리케이션은 엄청 단순합니다. 탭으로 구성된 2개의 리스트가 있습니다. 하나는 유명 축구 선수 목록이고 하나는 유명 테니스 선수 목록입니다. 선수를 선택 하게 되면 상세내역을 아래에 폼으로 보여줍니다.
FPM_DEMO_PLAYER.png

 

0. Adaptation Schema 만들기

이 준비 단계는 Netweaver 7.03/7.31 SP9 버전에서만 필요합니다. 높은 버전을 사용하고 있다면 이 단계를 건너띄고 스탠다드에 있는 스키마 FPM_DEVICE 를 사용하면 됩니다.
Context Based Adaptations(CBA)에는 어플리케이션이 무엇을 기준으로 adapt 할것인지 결정하는 adaptation scheme가 있습니다. 이번 예제에서는 1개의 기준(dimension)만 있으면 됩니다. 바로 장치 종류 (데스크탑, 테블릿, 스마트폰) 입니다.
adaptation scheme는 뷰클러스터 유지보수에서 정의합니다.
  1. 티코드 SM34로 이동합니다.
  2. 뷰클러스터 FPM_VC_ADAPT_SCHEMA를 입력하고 '유지보수' 버튼을 누릅니다.
  3. 새로운 스키마를 등록합니다. 이름은 ZDEVICE로 하겠습니다.
  4. 새로 만든 스키마를 선택하고 왼쪽 트리에서 Dimensions를 선택합니다.
  5. Dimension 하나를 추가 합니다. 이름은 DEVICE, 인덱스는 1, 타입은 FPM_DEVICE_TYPE
  6. 저장합니다.

 

1. CBA 활성화

첫번째 단계는 기존 데스크탑용 어플리케이션을 adapt 가능하도록 변경하는 것입니다. 장치 종류를 인식하여 분기할 수 있도록 하기 위함이죠.
  1. 티코드 FPM_WB 를 실행하여 FPM 워크벤치를 실행합니다. SAP GUI에서 실행한 경우 웹브라우저 새창으로 화면이 뜹니다.
  2. 화면에서 Context Based Adaptations 섹션에 있는 "Enable FPM Applications for Context-Based Adaptations" 링크를 찾아서 클릭합니다. FPM_WB.png
  3. 이제 CBA Enabler 가 실행됩니다. 우선 application configuration name에 변경할  어플리케이션을(FPM_DEMO_PLAYER) 입력합니다. 그리고 adaptation schema에 적용할 스키마를(ZDEVICE 또는 0단계 생략했다면 FPM_DEVICE) 입력합니다. 그리고 2개의 새로 만들 이름을(adapted application 과 adapted application configuration) 입력합니다. 2개의 이름은 아무렇게나 해도 되지만 2개를 동일하게 입력하기를 바랍니다. 예를들어 ZDEMO_PLAYER 를 입력하겠습니다. 이제 다 입력했으면 Next 버튼을 누릅니다.CBA Enabler Step 1.png
  4. 이제 CBA Enabler의 2번째 단계 화면에 들어왔습니다. 패키지와 transport request를 지정합니다. 여기서는 아무것도 변경할 필요없이 단지 Save 버튼만 눌러도 됩니다. 어플리케이션이 adapt 할 수 있는 준비가 되었습니다. 결과 화면에는 단순하게 링크 2개가 보입니다. CBA Enabler Step 3.png

어플리케이션을 adapt 하기 전에 좀전에 Save 버튼을 눌러서 어떤 변화가 생긴건지 설명해 주세요:

어플리케이션 FPM_DEMO_PLAYER 자체는 변경되지 않습니다. 대신 adpat 가능한 새로운 어플리케이션 (ZDEMO_PLAYER)으로 감싸는 형태로 만들었습니다. 이 새 어플리케이션은 원래 기능을 포함하고 있습니다.(복사가 아닙니다) 그리고 adapt 가능한 기능을 추가로 가지고 있습니다. 그러므로 새 어플리케이션을 실행(링크 Execute Application을 클릭)해도 기존 어플리케이션과 동일한 화면이 나타납니다.

이제 Configuration Editor를 (링크 Launch Configuration Editor를 클릭) 실행하도록 하겠습니다.

2. UI에 adapt 적용

앞에서 링크 Launch Configuration Editor를 클릭했다면 바로 FPM configuration editor ("FLUID")가 실행됩니다. 만약 CBA enabler를 닫아버려서 링크를 누를수 없다면, SE80에서 실행할 수 있습니다. 로컬 오브젝트로 이동합니다. 새로만든 FPM 어플리케이션 컨피규레이션 ZDEMO_PLAYER를 선택합니다. Start Configurator 버튼을 누르거나 단축키 F7을 누르세요. 웹브라우저에 Configurator가 나타날 겁니다. 링크 FPM_DEMO_PLAYER_OIF 를 눌러서 이동하세요.

툴바에는 추가 뷰를 볼 수 있는 3가지 버튼이 있습니다.

icon_buttons.png

 

이 중에서 왼쪽 첫번째 있는 버튼을 누르면 화면 상위 adaptation 패널이 열립니다. 이제 화면이 아래 그림처럼 보입니다:

FLUID.png

 

모바일용 새로운 adaptation을 추가 하기 위해서 Add 버튼을 누릅니다. 팝업 화면이 나타납니다. Applies to all values 체크 박스를 풉니다. Device Type 에는 TABLET을 선택합니다. Namespace에는 Z를 입력합니다.adatation popup.png

 

OK 버튼을 누르면 태블릿용 adaptation이 생성됩니다. 이제 이 adaptation에는 FPM configuration editor의 모든 기능을 사용하여 편집할 수 있습니다. 자유롭게 필요한 변경사항을 적용하세요.

편집을 끝내고 태블릿에서 어플리케이션을 실행하면 화면은 이런식으로 됩니다:

app on tablet.png

 

이런 화면을 보려고 우리가 무엇을 한건가요:

테니스 선수 뷰를 삭제하였습니다. 대신 상세(detail)뷰를 만들고 기존에 상세 폼을 이동시켰습니다.

툴바에서 Edit 와 Check 버튼을 제거했습니다.

목록 제거와 상세 폼의 제목을 제거하기 위해서 list configuration인 FPM_DEMO_PLAYER_LIST_FOOTBALL 와 form configuration인 FPM_DEMO_PLAYER_FORM_FOOTBALL에 adaptation을 생성했습니다. 앞서 adaptation을 만드는 작업과 동일한 방법으로 하면 됩니다.

이 모든 작업은 FPM configuration editor 에서 스탠다드 수정없이 모두 가능합니다. 그리고 변경한 내용은 오직 태블릿으로 접속할때만 나타납니다. 만약 데스크탑에서 실행한다면 어플리케이션에는 아무 변화도 없을 것입니다.

요약

웹딘프로아밥과 FPM은 모바일 장치를 위해 설계된것은 아닙니다. 모바일 사용자의 완벽한 요구사항을 만족하기 위해서 FPM은 좋은 선택이 아닙니다. 그러나 이미 만들어둔 FPM 어플리케이션을 모바일 장치에서도 사용할 수 있도록 하는 대안이 될 수 있습니다. 이 방법(adaptation)의 장점은 다음과 같습니다:

  • 데스크탑 어플리케이션에 전혀 영향이 없습니다.
  • 모바일용 adaptation은 원본에서 변경된 것만 가지고 있습니다. 그러므로 원본에 버그 수정이나 기능 향상이 있다면 모바일에도 동일하게 적용이 됩니다.
  • 다른 UI를 가지고 있지만 실행하는 어플리케이션은 여전히 동일하고 비지니스 로직에는 전혀 변화가 없습니다.
  • 이런 adaptation을 작성하는데 작업량이 적습니다. (빠른 개발)

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
http://scn.sap.com/community/web-dynpro-abap/floorplan-manager/blog/2013/09/19/using-fpm-applications-on-an-ipad

 

부모님이 강제로 가입해주신 소중한 새누리당이다.

 

문자 메시지 폭탄이라는 말이 딱 맞다.

수신거부도 소용없다. 그들은 안심번호다 처리기간이 걸린다 등등 각종 핑계를 대면서 수신거부를 안해준다.

문자 메시지가 너무 많이 와서 일상생활에 지장이 있을 정도다.

이제 그만 받고 싶다.

 

새누리당 탈퇴를 하는 방법을 알려 드립니다.

전화를 걸어 탈퇴 한다고 하면 여러번 돌려돌려 같은말 반복하는 일을 3번정도 하면 알려줍니다.

전화 걸지 마시고 아래 방법대로 하시면 됩니다.

 

지역별 새누리당 홈페이지에 접속합니다. 서울시당을 예로 보여 드립니다.

소개 > 당원가입 안내 로 들어가면 탈당 신고서와 당비해지요청서가 있습니다. 둘다 작성하여 팩스로 보내면 됩니다.

http://seoul.saenuriparty.kr/bbs/s_1_3.php

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
http://scn.sap.com/community/web-dynpro-abap/floorplan-manager/blog/2014/10/28/team-fpm--instance-styling-in-fpm

 

 

Christian Guenther

** Team FPM ** - FPM에서 CSS 스타일 적용하기

Posted by Christian Guenther in Floorplan Manager for Web Dynpro ABAP on Oct 28, 2014 1:18:09 PM

새로운 기능 Instance Styling (서버 버전이 SAP_UI 7.40 SP 10 이후 가능)으로 이제 FPM의 각 UI 엘리먼트별로 CSS 스타일을 적용할 수 있습니다. 이 블로그에서 어떻게 FPM에서 CSS 스타일을 적용하는지 예제를 통해 살펴보겠습니다.

FPM의 Instance Styling은 웹딘프로아밥에 새로 추가된 Instance Styling 을 기반으로 하고있습니다. 웹딘프로아밥과는 다르게 FPM 개발시에는 직접 UI 엘리먼트에 직접 접근하지 못합니다. FPM이 내부적으로 UI 엘리먼트를 그립니다. GUIBB에 필드를 추가하고, 버튼을 그리고, 페이지를 추가하고, 페이지에 섹션을 추가하고, 등등 FPM에서 개발한 내용은 FPM에 의해서 웹딘프로아밥 UI 엘리먼트가 그려집니다.

우리(FPM팀)는 FLUID(= FPM configuration editor)의 많은 엔티티에 새로운 어트리뷰트( Style, Label Style, ...)를 추가 했습니다. 여기에 여러분이 CSS 스타일 정보를 입력하면 FPM이 내부적으로 웹딘프로아밥 UI 엘리먼트를 그릴때 Instance Style로 변환하여서 연결해줍니다.

다음 섹션에서 이 기능을 어떻게 사용하는지 예제를 통해 살펴보겠습니다. 이 예제는 스탠다드 데모 어플리케이션 /BOBF/EPM_FPM_SADL_PD 를 변경하겠습니다. 다른 FPM 어플리케이션에도 적용할 수 있습니다.

이 어플리케이션을 실행하고 검색을 하면 아래 그림처럼 화면이 표시됩니다.

p1.png

 

툴바 버튼에 스타일 적용하기


"Switch to Filter Page" 버튼에 스타일을 적용해보겠습니다. configuration editor 를 열어서 이 버튼을 선택하세요.

p2.png

네비게이션 패널에서 "Search EPM Products" 페이지를 선택합니다. 프리뷰 또는 툴바 스키마에서 "Switch to Filter Page" 버튼을 선택합니다. Style 속성에 다음 값을 넣으세요.

borderRadius:30px;backgroundColor:#7D9847;

 

저장을 하고 어플리케이션을 다시 실행해보세요. 이제 버튼에 둥근모서리가 있고 배경색이 변경된 것을 확인할 수 있습니다.

p3.png

 

버튼 위로 마우스를 올려보세요. hover background 와 font color 가 기존과 다르게 (우리가 "hoverBackgroundColor" 와 "hoverFontColor"를 변경하지 않았는데) 자동으로 변경되었습니다.

이제 "hoverBackgroundColor"를 지정하여 변화를 살펴보겠습니다. 다음 내용을 입력합니다.

borderRadius:30px;backgroundColor:#7D9847;hoverBackgroundColor:blue;

결과는 이렇게 됩니다:

p4.png

 

왜 이런지 설명을 드리겠습니다. 하나의 스타일을 변경하면 관련된 다른 스타일이 자동으로 보기 좋게 맞춰서 변경됩니다. 이번 예제에서 원래의 "hoverFontColor"는 검정색이고 "hoverBackgroundColor"는 밝은 회색이였습니다. 배경색을 어두운 색상으로 변경하였기 때문에 기존 밝은 회색은 hover background color로 적절하지 않습니다. 그래서 이 속성은 어두운 녹색으로 자동 조정됩니다. 마우스를 올렸을때 어두운 녹색 배경에서 폰트색상으로 검정색은 읽기 어려우므로 hover font color 도 흰색으로 자동 조정됩니다. 다음으로 우리는 "hoverBackgroundColor"를 스타일에 추가하여 파란색으로 변경해 보았습니다. 이렇게 스타일에 추가한 값은 자동 조정된 값을 무시하고 대신(override) 적용됩니다. 그러면 hover font color 가 자동으로 조정되는데 파란색 배경에 맞춰 읽기 좋도록 역시 하얀색으로 조정되었습니다.

배경 그림 추가하기

배경 그림을 넣고 싶다는 요청사항은 자주 있는 편입니다. 스타일에 "backgroundImage" 속성을 사용하면 가능합니다.

배경 그림으로 사용될 이미지파일은 반드시 URL로 접근 가능해야 합니다. 이번 예제에서는 MIME 저장소에 이미지파일을 업로드 하고 그 URL을 사용했습니다.

이미지파일을 페이지의 배경 그림으로 넣어보겠습니다. configuration editor 를 열어서 페이지를 선택하고 Style 속성에 다음 값을 넣으세요.

backgroundImage:<Url to Image>;

p5.png

 

어플리케이션을 다시 실행해보면 아래와 같이 보일겁니다.

p6.png

 

요약

각 UI 엘리먼트에 Instance Styling 을 적용하여 CSS로 모양을 꾸밀 수 있습니다. 스탠다드 데모 WDR_TEST_CUSTOM_STYLES를 제공하므로 이를 통해 개략적인 스타일링 적용법을 살펴볼 수 있습니다.

Instance Styling 적용시 주의사항은 남용하면 안되고 꼭 필요할 때만 사용해 주세요. 해당 UI 엘리먼트가 특별하고 다른 UI 엘리먼트와 구분되어 보여야 할때 사용하는 것입니다. 단지 나는 동그란 모서리를 가진 버튼이 좋다는 이유로 모든 버튼에 Instance Styling을 적용하는 것은 좋지 않습니다. 다른 모양으로 표시하여 구분될 필요가 있는 경우에만 적용하세요. 만약 모든 버튼에 동그란 모서리를 적용하고 싶다면 차라리 테마 에디터를 이용하는게 좋습니다.

 

 

 

이글은 아래 링크의 원본 글에 대한 한글 번역 입니다
http://scn.sap.com/community/web-dynpro-abap/floorplan-manager/blog/2014/10/28/team-fpm--instance-styling-in-fpm

SE80 목록에 안보이는 프로그램이 있다면

rebuild object list

 

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

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

 

+ Recent posts