************************************************************************
* Program Name      :  ZSDR025
* Descriptions      :  外掛表格資料上傳 有权限限制
* Updates Tables    :
* Input  Parameters :
* Output Parameters :
* Return Codes      :
* Special Logic     :
* Includes          :
************************************************************************
* Modification Log
************************************************************************
*   Date     Ver. Programmer   Descriptions
* ---------- ---- ------------ -------------------------------------------
* 2013/11/29      ALICE        New Create
*
************************************************************************
REPORT zsdr025 NO STANDARD PAGE HEADING
                MESSAGE-ID 00
                LINE-SIZE  500
                LINE-COUNT 65.

CLASS lcl_report DEFINITION.
  PUBLIC SECTION.
    DATA: t_data  TYPE STANDARD TABLE OF anep,  " Output dat
          r_bukrs TYPE RANGE OF anep-bukrs,
          r_gjahr TYPE RANGE OF  anep-gjahr.  " Select Option
    METHODS:
      get_data,
      generate_output.
ENDCLASS.                    "lcl_report DEFINITION

TABLES:zsdt015,dd03l,sscrfields.

TYPE-POOLS : abap.
FIELD-SYMBOLS: <dyn_table>  TYPE STANDARD TABLE,
               <dyn_wa>,
               <dyn_field>,
               <dyn_table2> TYPE STANDARD TABLE,
               <dyn_wa2>,
               <dyn_field2>.
DATA: dy_table  TYPE REF TO data,
      dy_table2 TYPE REF TO data,
      dy_line   TYPE REF TO data,
      dy_line2  TYPE REF TO data,
      xfc       TYPE lvc_s_fcat,
      xfc2      TYPE lvc_s_fcat,
      ifc       TYPE lvc_t_fcat,
      ifc2      TYPE lvc_t_fcat.
DATA:gt_tablefield LIKE TABLE OF dd03l WITH HEADER LINE.

DATA: BEGIN OF t_line OCCURS 0,
        text(3000) TYPE c,
      END OF t_line.



* 定义ALV相关
*--> ALV
TYPE-POOLS: slis, icon, truxs.
DATA: wa_layout   TYPE slis_layout_alv,
      wa_setting  TYPE lvc_s_glay,
      gt_fieldcat TYPE slis_t_fieldcat_alv,
      wa_fieldcat TYPE slis_fieldcat_alv.
DATA: wa_layout_ord   TYPE slis_layout_alv,
      wa_setting_ord  TYPE lvc_s_glay,
      gt_fieldcat_ord TYPE slis_t_fieldcat_alv,
      wa_fieldcat_ord TYPE slis_fieldcat_alv.

DATA:BEGIN OF gt_tab OCCURS 0,
       tabname TYPE dd02t-tabname, "字母
       ddtext  TYPE dd02t-ddtext,
     END OF gt_tab.

FIELD-SYMBOLS:<gt_table> TYPE STANDARD TABLE,
              <g_wa>,
              <g_comp>,
              <g_field>,
              <g_comp_f>.

DATA: gt_table     TYPE REF TO data,
      gt_structure TYPE lvc_t_fcat.


DATA: lo_report TYPE REF TO lcl_report.
DATA: w_bukrs TYPE anep-bukrs,
      w_gjahr TYPE anep-gjahr.

TYPES: BEGIN OF t_dd03l,
         tabname    LIKE dd03l-tabname, "Table Name
         fieldname  LIKE dd03l-fieldname, "Field Name
         keyflag    LIKE dd03l-keyflag, "Key Flag
         rollname   LIKE dd03l-rollname, "Roll Name
         position   LIKE dd03l-position, "Position
         ddtext(30), "Description
       END OF t_dd03l,
       BEGIN OF t_fields.
    INCLUDE STRUCTURE dd03l.
TYPES: END OF t_fields.
TYPES : BEGIN OF t_tabs. "To hold the table names
    INCLUDE STRUCTURE rsdstabs.
TYPES : END OF t_tabs.
TYPES : BEGIN OF t_flds. "To hold the field names
    INCLUDE STRUCTURE rsdsfields.
TYPES : END OF t_flds.
TYPES : BEGIN OF t_fname, "To hold the field names
          fld LIKE dd03l-fieldname,
        END OF t_fname.

*----------------------------------------------------------------------
DATA : it_dd03l  TYPE TABLE OF t_dd03l, "To hold the field names
       it_tabs   TYPE TABLE OF t_tabs, "To hold the table names
       it_flds   TYPE TABLE OF t_flds, "To hold the field names
       it_temp   TYPE TABLE OF t_flds, "Temp. table to hold field names
       it_fields TYPE TABLE OF t_fields, "To hold the field names
       it_cat    TYPE TABLE OF lvc_s_fcat, "To hold Field Catalog
       it_fname  TYPE TABLE OF t_fname.

DATA: d_ref     TYPE REF TO data , "Data reference
      wa_dd03l  LIKE LINE OF it_dd03l, "Workarea for IT_DD03L
      wa_tabs   LIKE LINE OF it_tabs, "Workarea for IT_TABS
      wa_flds   LIKE LINE OF it_flds, "Workarea for IT_FLDS
      wa_temp   LIKE LINE OF it_temp, "Workarea for IT_TEMP
      wa_fields LIKE LINE OF it_fields, "Workarea for IT_FIELDS
      wa_cat    LIKE LINE OF it_cat , "Workarea for IT_CAT
      wa_fname  LIKE LINE OF it_fname. "Workarea for IT_FNAME

DATA: gx_texpr         TYPE rsds_texpr, "Variable to hold Expression
      gx_twhere        TYPE rsds_twhere, "Variable to hold Where Clause
      gv_selid         LIKE rsdynsel-selid, "Variable to hold Selid
      gv_actnum        LIKE sy-tfill, "Variable to hold no of fields
      gv_title         LIKE sy-title, "Variable to hold Title
      gv_where_cl(100) TYPE c, "Variable to hold Where clause
      gv_tbname        LIKE dd03l-tabname,
      gv_temp.

DATA: ref_grid TYPE REF TO cl_gui_alv_grid,
      ls_stbl  TYPE lvc_s_stbl.

CONSTANTS: gc_i     TYPE c VALUE 'I',
           gc_eq(2) TYPE c VALUE 'EQ'.


SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.
*  SELECTION-SCREEN BEGIN OF LINE.
*      "查询table内容
*      PARAMETERS: c_sel RADIOBUTTON GROUP up default 'X'.
*      SELECTION-SCREEN COMMENT (9) TEXT-001.
"修改table资料
PARAMETERS: c_up AS CHECKBOX .
*      SELECTION-SCREEN COMMENT (9) TEXT-002.



SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT (4) TEXT-003.
PARAMETERS: p_table TYPE dd02l-tabname OBLIGATORY.
SELECTION-SCREEN : PUSHBUTTON 45(8) p_btn USER-COMMAND clk1.
SELECTION-SCREEN END OF LINE.

PARAMETERS:p_fname LIKE rlgrap-filename DEFAULT 'c:\temp\tab.csv'
OBLIGATORY.

SELECT-OPTIONS:
s_selop FOR dd03l-fieldname NO-DISPLAY, "To hold fields for creating dyn. select-options
s_where FOR gv_where_cl NO-DISPLAY. "To hold where condition

SELECTION-SCREEN END OF BLOCK b1.


INITIALIZATION.
  p_btn = '查询或修改'(004).

* CREATE OBJECT lo_report.
* generate output
*  lo_report->generate_output( ).
** Start of Selection
*START-OF-SELECTION.
** Get data
**  lo_report->r_BUKRS = s_BUKRS[].
**  lo_report->r_GJAHR = s_GJAHR[].
**  lo_report->get_data( ).

AT SELECTION-SCREEN.
*--Select the fields of the input table
  PERFORM select_flds.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_table.
  PERFORM frm_help.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fname.
  CALL FUNCTION 'F4_FILENAME'
    IMPORTING
      file_name = p_fname.

START-OF-SELECTION.

END-OF-SELECTION.
* CALL SCREEN 1000.
*  PERFORM check_screen.
*  PERFORM get_structure.
*  PERFORM create_dynamic_itab.
************Creates a dyanamic internal table**********
*  PERFORM get_data.
*  PERFORM display_date.


*&---------------------------------------------------------------------*
*&      Form  get_structure
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_structure.

  DATA: idetails TYPE abap_compdescr_tab,
        xdetails TYPE abap_compdescr.
  DATA : ref_table_des TYPE REF TO cl_abap_structdescr.
  DATA : ef_is_unicode LIKE  /bdl/tasks-status.

* Check the system is UNICODE or NONUNICODE
  CALL FUNCTION '/BDL/CHECK_UNICODE'
    IMPORTING
      ef_is_unicode = ef_is_unicode.
* get the structure of the table.
  ref_table_des ?=
      cl_abap_typedescr=>describe_by_name( p_table ).
  idetails[] = ref_table_des->components[].

  wa_layout-colwidth_optimize = 'X'.
  wa_layout-box_fieldname    ='SEL'.

  xfc-tabname = p_table.
  xfc-fieldname =  'SEL'.
  xfc-datatype =  'C'.
  xfc-inttype = 'C'.
  xfc-intlen = '1'.
  xfc-decimals = '0'.
  APPEND xfc TO ifc.

  LOOP AT idetails INTO xdetails.
    CLEAR xfc.
    xfc-tabname = p_table.
    xfc-fieldname = xdetails-name .
    xfc-datatype = xdetails-type_kind.
    xfc-inttype = xdetails-type_kind.
    CASE xfc-datatype.
      WHEN 'C' OR 'D' OR 'N'.
        IF ef_is_unicode EQ 'X'.
          xfc-intlen = xdetails-length / 2. " Unicdoe
        ELSE.
          xfc-intlen = xdetails-length.     " nonunicode
        ENDIF.
      WHEN OTHERS.                          " For Type P
        xfc-intlen = xdetails-length.
    ENDCASE.
    xfc-decimals = xdetails-decimals.
    APPEND xfc TO ifc.
  ENDLOOP.


ENDFORM.                    "get_structure
*&---------------------------------------------------------------------*
*&      Form  create_dynamic_itab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM create_dynamic_itab.
* Create dynamic internal table and assign to FS
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      i_length_in_byte = 'X'
      it_fieldcatalog  = ifc
    IMPORTING
      ep_table         = dy_table.
  ASSIGN dy_table->* TO <dyn_table>.
* Create dynamic work area and assign to FS
  CREATE DATA dy_line LIKE LINE OF <dyn_table>.
  ASSIGN dy_line->* TO <dyn_wa>.

  ifc2[] = ifc[].

  DELETE ifc2 WHERE fieldname = 'SEL'.
  CALL METHOD cl_alv_table_create=>create_dynamic_table
    EXPORTING
      i_length_in_byte = 'X'
      it_fieldcatalog  = ifc2
    IMPORTING
      ep_table         = dy_table2.
  ASSIGN dy_table2->* TO <dyn_table2>.
* Create dynamic work area and assign to FS
  CREATE DATA dy_line2 LIKE LINE OF <dyn_table2>.
  ASSIGN dy_line2->* TO <dyn_wa2>.

ENDFORM.                    "create_dynamic_itab

*&---------------------------------------------------------------------*
*&      Form  get_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_data.
  DATA:g_p       TYPE p DECIMALS 3,
       g_c       TYPE c LENGTH 20,
       g_error   TYPE REF TO cx_root,
       g_message TYPE string.

* DATA:wa_structure type ref to cl_abap_structdescr.
  DATA:wa_structure TYPE lvc_s_fcat.
  DATA:l_new_line   TYPE REF TO data.
  CREATE DATA l_new_line LIKE LINE OF <dyn_table>.
  ASSIGN l_new_line->* TO <dyn_wa> .

  DATA : filename LIKE rlgrap-filename.

  DATA:l_text   TYPE string,
       itab     TYPE TABLE OF string,
       l2_index LIKE sy-tabix.

  filename = p_fname.

*  DATA: LT_UPLOAD  LIKE ALSMEX_TABLINE OCCURS 0 WITH HEADER LINE.
*--因為有超過長度50所以複製一個一樣的TABLE
*  DATA: lt_upload  LIKE zalsmex_tabline OCCURS 0 WITH HEADER LINE.

  DATA: l_index  TYPE i,
        l_num    TYPE i,
        l_number TYPE i.

  SELECT SINGLE *
  INTO  zsdt015
  FROM zsdt015
  WHERE usdid = sy-uname
   AND    table_name  = p_table.

  IF sy-subrc = 0 AND
      c_up = 'X' AND
      zsdt015-zupdate EQ 'N'.

    MESSAGE s001 WITH '此表只能做查询,不能做修改动作' DISPLAY LIKE 'E'.
    STOP.
  ENDIF.

  "批量上传档案
  IF c_up = 'X' AND p_table(1) = 'Z' .


    DATA: p_path TYPE string.
    p_path = filename.
    CALL FUNCTION 'GUI_UPLOAD'
      EXPORTING
        filename                = p_path
        filetype                = 'ASC'
*       HAS_FIELD_SEPARATOR     = 'X'
        codepage                = '8400'
      TABLES
        data_tab                = t_line
      EXCEPTIONS
        file_open_error         = 1
        file_read_error         = 2
        no_batch                = 3
        gui_refuse_filetransfer = 4
        invalid_type            = 5
        no_authority            = 6
        unknown_error           = 7
        bad_data_format         = 8
        header_not_allowed      = 9
        separator_not_allowed   = 10
        header_too_long         = 11
        unknown_dp_error        = 12
        access_denied           = 13
        dp_out_of_memory        = 14
        disk_full               = 15
        dp_timeout              = 16
        OTHERS                  = 17.
    IF sy-subrc <> 0.
      MESSAGE s000(zmsg) WITH '上傳失敗' DISPLAY LIKE 'E'.
      EXIT.
    ENDIF.
    IF t_line[] IS INITIAL.
      MESSAGE s000(zmsg) WITH '上傳檔案中無資料'
      DISPLAY LIKE 'E'.
      EXIT.
    ENDIF.



    DELETE t_line INDEX 1.

    LOOP AT t_line.
      l2_index = sy-tabix.
      SPLIT t_line-text AT ',' INTO TABLE itab.
      LOOP AT itab INTO l_text.
        l_index = sy-tabix.
        "检查表格是否包含客户端栏位,
        "①若存在且导入未写入客户端栏位值时,那么剔除客户端栏位
        "②若存在且导入写入客户端栏位值,那么不剔除客户端栏位
        "③若不存客户端栏位值,那么不剔除第一列数据
        IF l2_index = 1 AND l_index = 1.
          READ TABLE ifc2  INTO wa_structure WITH KEY fieldname = 'MANDT'.
          IF sy-subrc = 0 AND NOT
             ( l_text = 888 OR l_text = 200 OR
                l_text = 201 OR l_text = 202 OR
                l_text = 206 OR l_text = 230 OR
                l_text = 250 OR l_text = 280 ) .
            l_num = l_index + 1.
            l_number = '1'.
          ELSEIF sy-subrc <> 0 OR (
                      sy-subrc = 0 AND
                      ( l_text = 888 OR l_text = 200 OR
                        l_text = 201 OR l_text = 202 OR
                        l_text = 206 OR l_text = 230 OR
                        l_text = 250 OR l_text = 280 ) ).

            l_num = l_index.
            l_number = '0'.
          ENDIF.
        ELSE.
          l_num = l_index + l_number.
        ENDIF.

*--->第二筆是 MANDT所以都從第二筆開始
        READ TABLE ifc2  INTO wa_structure INDEX l_num.


        ASSIGN COMPONENT wa_structure-fieldname OF STRUCTURE
        <dyn_wa>  TO <dyn_field>.
        CONDENSE l_text.

        "检查非数值栏位是否包含非数字字符
        READ TABLE gt_tablefield WITH KEY
                           fieldname = wa_structure-fieldname.
        IF sy-subrc = 0 AND gt_tablefield-inttype <> 'C'.
          g_c = l_text.
          TRY .
              g_p = g_c .
            CATCH  cx_sy_conversion_no_number INTO g_error.
              g_message = g_error->get_longtext( ).

              MESSAGE s001 WITH g_message DISPLAY LIKE 'E'.
              STOP.
          ENDTRY.
        ENDIF.
        IF gt_tablefield-inttype = 'D' AND
            gt_tablefield-keyflag = 'X' AND
            gt_tablefield-fieldname = 'ERDAT'.
            zsdt015-zautom = 'Y'.

          l_text = sy-datum.
        ELSEIF gt_tablefield-inttype = 'T' AND
                   gt_tablefield-keyflag = 'X' AND
                   zsdt015-zautom = 'Y'.

          sy-uzeit = sy-uzeit + l2_index.
          l_text = sy-uzeit.
        ENDIF.
        <dyn_field> = l_text.
        "最后一行执行代码.
        AT LAST.
          APPEND <dyn_wa> TO <dyn_table>.
          CLEAR:<dyn_wa>.
        ENDAT.
      ENDLOOP.

    ENDLOOP.

*  清空需要导入的TABLE
    IF zsdt015-zddelete = 'Y'.
      DELETE FROM (p_table).
    ENDIF.

    CLEAR:<dyn_table2>[].
    MOVE-CORRESPONDING <dyn_table>[] TO <dyn_table2>[].
*select * from   (P_TABLE).
    "插入数据
    PERFORM write_out.

  ELSE.
    DATA: lv_where TYPE string.
    LOOP AT s_where.
      CONCATENATE lv_where s_where-low INTO lv_where SEPARATED BY space.
    ENDLOOP.

    SELECT * FROM (p_table)
    INTO CORRESPONDING FIELDS OF TABLE <dyn_table>
    WHERE (lv_where) .
  ENDIF.

ENDFORM.                    "get_data

**Write out data from table.
FORM write_out.
  DATA:l_suce TYPE i,
       l_str  TYPE c LENGTH 20,
       l_fail TYPE i,
       l_str1 TYPE c LENGTH 20.

  DATA:BEGIN OF lt_str OCCURS 0,
         str TYPE string,
         num TYPE c,
       END OF lt_str.

  CLEAR:l_suce,l_fail,lt_str[],lt_str,l_str,l_str1.

  LOOP AT <dyn_table2> INTO <dyn_wa2>.
    DO.
      ASSIGN COMPONENT  sy-index
         OF STRUCTURE <dyn_wa2> TO <dyn_field2>.
      IF sy-subrc <> 0.
        EXIT.
      ENDIF.
    ENDDO.

    INSERT (p_table) FROM <dyn_wa2>.
    IF sy-subrc <> 0.
      l_fail = l_fail + 1.

      lt_str-str = <dyn_wa2>.
      APPEND lt_str.
      CLEAR: lt_str.

    ELSE.
      l_suce = l_suce + 1.

    ENDIF.

    AT LAST.
      l_str  = l_suce.
      l_str1 = l_fail.

      CONCATENATE '成功' l_str  '筆,失敗' l_str1  ''
      INTO lt_str-str.
      lt_str-num = 'X'.
      APPEND lt_str.
      CLEAR: lt_str.
*      WRITE:/ '成功',L_SUCE ,'筆,失敗',L_FAIL, '筆'.
    ENDAT.

  ENDLOOP.

  SORT lt_str BY num DESCENDING.

ENDFORM.                    "write_out

*&---------------------------------------------------------------------*
*& Form DISPLAY_DATE
*&---------------------------------------------------------------------*
*& ALV显示
*&---------------------------------------------------------------------*

FORM  display_date.

**--> dynamic table structure and generate ALV fieldcat 构造fieldcat
  PERFORM create_structure.

  CLEAR:wa_layout.
  wa_layout-box_fieldname  = 'SEL'.  " 指定紀錄選取與否的欄位

**--> ALV Layout Setting
  wa_layout-colwidth_optimize = 'X'. " 最佳欄寬
  wa_layout-zebra = 'X'.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = sy-repid
      is_layout                = wa_layout
      it_fieldcat              = gt_fieldcat
      i_callback_pf_status_set = 'ALV_PF_STATUS'
      i_callback_user_command  = 'ALV_USER_COMMAND'
      i_save                   = 'A'
    TABLES
      t_outtab                 = <dyn_table>.

ENDFORM.

FORM alv_pf_status USING rt_extab TYPE slis_t_extab.
  SET  PF-STATUS  'STATUS_PRINT' .               "自定义按钮
ENDFORM.                    " ALV_PF_STATUS

FORM alv_user_command USING  in_ucomm LIKE  sy-ucomm
                         in_selfield TYPE slis_selfield.

  DATA:l_where       TYPE c LENGTH 12, "alv 选择数据条件
       l2_where      TYPE string , "主键条件
       l_field_value TYPE string, "栏位及值
       l_vlaue       TYPE string, "栏位值
       l_index       LIKE sy-tabix,
       l_datum       LIKE sy-datum. "日期

  FIELD-SYMBOLS:<f_fs1>,<f_out_wa>.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = ref_grid.
  CALL METHOD ref_grid->check_changed_data.

*--->核实权限
  SELECT SINGLE *
  INTO  zsdt015
  FROM zsdt015
  WHERE usdid = sy-uname
   AND    table_name  = p_table.

  IF  in_ucomm = '&UPDATE'
   AND zsdt015-zupdate <> 'Y'.

    MESSAGE s001 WITH '没有更改权限' DISPLAY LIKE 'E'.

    RETURN.

  ELSEIF in_ucomm = '&DELETE'
     AND zsdt015-zdelete <> 'Y'.

    MESSAGE s001 WITH '没有删除权限' DISPLAY LIKE 'E'.

    RETURN.

  ENDIF.

  READ TABLE <dyn_table> ASSIGNING <f_out_wa> WITH KEY ('SEL') = 'X'.
  IF sy-subrc <> 0.
    MESSAGE s001 WITH '请选择....需要更改或删除的数据' DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.

  CONCATENATE 'SEL' ' EQ '''  'X' '''' INTO l_where.

  CASE in_ucomm.
    WHEN '&UPDATE'.
*--->修改数据
      LOOP AT <dyn_table> ASSIGNING <f_out_wa> WHERE (l_where).
        CLEAR:l2_where,l_where,l_field_value.
        "栏位名称
        LOOP AT gt_tablefield.

          ASSIGN COMPONENT gt_tablefield-fieldname OF STRUCTURE
                                           <f_out_wa> TO <f_fs1>.
          l_vlaue = <f_fs1>.
          "主键栏位
          IF  gt_tablefield-keyflag = 'X'.
            IF l2_where IS INITIAL .
              CONCATENATE gt_tablefield-fieldname ' = '''
                                   l_vlaue ''''
              INTO l2_where.
            ELSE.
              CONCATENATE l2_where ' AND and'''
                                 gt_tablefield-fieldname ' = '''
                                  l_vlaue ''''
              INTO l2_where.
            ENDIF.

          ELSE.
            IF l_field_value IS INITIAL.
              CONCATENATE gt_tablefield-fieldname ' = '''
                                   l_vlaue ''''
              INTO l_field_value.
            ELSE.

              CONCATENATE l_field_value ' AND '''
                                    gt_tablefield-fieldname ' = '''
                                    l_vlaue ''''
              INTO l_field_value.

            ENDIF.

          ENDIF.
        ENDLOOP.
        REPLACE  ALL  OCCURRENCES  OF 'and''' IN  l2_where WITH  ''.
        REPLACE  ALL  OCCURRENCES  OF 'AND ''' IN  l_field_value WITH  ' ' .
        IF  l_field_value IS INITIAL.
          MESSAGE s001 WITH '不允许修改主键栏位' DISPLAY LIKE 'E'.
          RETURN.
        ENDIF.

        UPDATE (p_table) SET (l_field_value)  WHERE (l2_where).
      ENDLOOP.
      MESSAGE s001 WITH '更新成功!' DISPLAY LIKE 'S'.
    WHEN '&DELETE'.
*--->删除数据
      IF zsdt015-zdelday IS NOT INITIAL.
        CALL FUNCTION 'FIMA_DATE_CREATE'
          EXPORTING
            i_date             = sy-datum "输入日期
            i_flg_end_of_month = ' '
*           I_YEARS            = L_YEAR   "两年后的日期. 即输入日期的年加2所得日期,可为负数,表示前两年
*           I_MONTHS           = L_MONTH  "一个月后的日期.即输入日期的月加1所得日期,可为负数,表示前一个月
            i_days             = - zsdt015-zdelday "23天后的日期。可为负数
*           I_CALENDAR_DAYS    = 10      "10天后的日历。同I_DAYS参数。
*           I_SET_LAST_DAY_OF_MONTH = 'X'     "返回的日期为当前月份的最后一天
          IMPORTING
            e_date             = l_datum.   "返回的日期为当前月份的最后一天
      ENDIF.


      LOOP AT <dyn_table> ASSIGNING <f_out_wa> WHERE (l_where).
        l_index = sy-tabix.
        CLEAR:l2_where,l_where.
        "栏位名称
        LOOP AT gt_tablefield.

          ASSIGN COMPONENT gt_tablefield-fieldname OF STRUCTURE
                                           <f_out_wa> TO <f_fs1>.
          l_vlaue = <f_fs1>.

          IF  gt_tablefield-keyflag = 'X' AND
               gt_tablefield-inttype = 'D' AND
               gt_tablefield-fieldname = 'ERDAT' AND
               l_vlaue < l_datum.
            MESSAGE s001 WITH '删除失败!,日期版本已超出可删除范围内,请选择数据其他数据.'
            DISPLAY LIKE 'E'.
            RETURN.
          ENDIF.

          IF l2_where IS INITIAL .
            CONCATENATE gt_tablefield-fieldname ' = '''
                                  l_vlaue ''''
            INTO l2_where.
          ELSE.
            CONCATENATE l2_where
                               ' AND and'''
                               gt_tablefield-fieldname ' = '''
                                l_vlaue ''''
             INTO l2_where.
          ENDIF.

*          ENDIF.
        ENDLOOP.
        REPLACE  ALL  OCCURRENCES  OF 'and''' IN  l2_where WITH  ''.
        DELETE FROM (p_table)  WHERE (l2_where).

        DELETE <dyn_table> INDEX l_index.
        CONTINUE.
      ENDLOOP.

      MESSAGE s001 WITH '删除成功!' DISPLAY LIKE 'S'.

*-->刷新 Alv
*       in_selfield-refresh = 'X'.
      CALL METHOD ref_grid->refresh_table_display.
  ENDCASE.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_STRUCTURE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM create_structure.
  DATA: l_count TYPE i.

  LOOP AT gt_tablefield.
    ADD 1 TO l_count.
    IF  gt_tablefield-keyflag <> 'X'.
      wa_fieldcat-edit = 'X'.
    ENDIF.
    wa_fieldcat-col_pos    = l_count.
    wa_fieldcat-fieldname  = gt_tablefield-fieldname.
    wa_fieldcat-ref_fieldname = gt_tablefield-fieldname.
    wa_fieldcat-ref_tabname = gt_tablefield-tabname.
    APPEND wa_fieldcat TO  gt_fieldcat.CLEAR:wa_fieldcat.
  ENDLOOP.
ENDFORM.


FORM check_screen.
  CLEAR:gt_tablefield[].
  SELECT *
  FROM dd03l
  INTO  TABLE gt_tablefield
  WHERE dd03l~tabname EQ p_table.

  IF sy-subrc <> 0.
    MESSAGE s001 WITH '不存在' && p_table && '表请重新输入,或联系开发人员' DISPLAY LIKE 'E'.
    STOP.
  ENDIF.

  SELECT SINGLE zsdt015~table_name
   INTO zsdt015
   FROM zsdt015
   INNER JOIN dd02t ON dd02t~tabname = zsdt015~table_name
   WHERE sdate <= sy-datum
    AND    edate >= sy-datum
    AND    usdid = sy-uname
    AND zsdt015~table_name = p_table.

  IF sy-subrc <> 0.
    MESSAGE s001 WITH '很抱歉,您没有查询此表权限' DISPLAY LIKE 'E'.
    STOP.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*&      Form  FRM_HELP
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_help .


  SELECT zsdt015~table_name AS tabname dd02t~ddtext
  INTO TABLE gt_tab
  FROM zsdt015
  INNER JOIN dd02t ON dd02t~tabname = zsdt015~table_name
  WHERE sdate <= sy-datum
   AND    edate >= sy-datum
   AND    usdid = sy-uname.
  IF sy-subrc <> 0.
    MESSAGE s001 WITH '很抱歉,您没有查询或更改权限' DISPLAY LIKE 'E'.
    STOP.
  ENDIF.

  "调用展示函数
  CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
    EXPORTING
      retfield    = 'TABNAME'          "表格要显示的字段
      dynpprog    = sy-repid        "返回才程序
      dynpnr      = sy-dynnr        "屏幕
      dynprofield = 'P_TABLE'  "往页面回填值的地方
      value_org   = 'S'             "显示类型
    TABLES
      value_tab   = gt_tab.     "传进去的表格 帮助的内表
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.
CLASS lcl_report IMPLEMENTATION.
  METHOD get_data.
    SELECT * FROM anep
           INTO  TABLE t_data.
*           WHERE BUKRS IN s_BUKRS AND GJAHR IN S_GJAHR.
    IF sy-dbcnt IS INITIAL.
      MESSAGE s398(00) WITH 'No data selected'.
    ENDIF.
    EXPORT data = me->t_data TO MEMORY ID sy-cprog.
  ENDMETHOD.                    "get_data

  METHOD generate_output.
    DATA: lo_dock       TYPE REF TO cl_gui_docking_container,
          lo_cont       TYPE REF TO cl_gui_container,
          lt_fcat       TYPE lvc_t_fcat,
          gr_grid_d1001 TYPE REF TO cl_gui_alv_grid.
    IMPORT data = me->t_data FROM MEMORY ID sy-cprog.
    FREE MEMORY ID sy-cprog.
    CHECK me->t_data IS NOT INITIAL.
    CHECK lo_dock IS INITIAL.
    CREATE OBJECT lo_dock
      EXPORTING
        repid = sy-cprog
        dynnr = sy-dynnr
        ratio = 80
        side  = cl_gui_docking_container=>dock_at_bottom.
  ENDMETHOD.                    "generate_output
ENDCLASS.                    "lcl_report IMPLEMENTATION

*&---------------------------------------------------------------------
*& Form SELECT_FLDS
*&---------------------------------------------------------------------
* Select fields from the table
*----------------------------------------------------------------------
FORM select_flds .
  DATA: lv_txt TYPE string.
  CASE sscrfields-ucomm.
    WHEN 'CLK1'.
      lv_txt = 'Selection Paramters List'(008).
      SET PF-STATUS 'DIALOG'.
*      LEAVE TO LIST-PROCESSING AND RETURN TO SCREEN 0.
*      SUPPRESS DIALOG.
      MOVE lv_txt TO sy-title.
**--Get field names for given table
      SELECT tabname
             fieldname
             keyflag
             rollname
             position
        FROM dd03l
        INTO TABLE it_dd03l
       WHERE tabname EQ p_table
         AND fieldname NE 'MANDT'.
      IF sy-subrc = 0.
        SORT it_dd03l BY position.
        DELETE it_dd03l WHERE fieldname CP '.INCLU*'.
      ENDIF.
**--Get the description of the fields
      LOOP AT it_dd03l INTO wa_dd03l.
        IF NOT wa_dd03l-rollname IS INITIAL.
          SELECT SINGLE ddtext
          FROM dd04t
          INTO wa_dd03l-ddtext
          WHERE rollname EQ wa_dd03l-rollname
          AND ddlanguage = sy-langu
          AND as4local = 'A'.
          MODIFY it_dd03l FROM wa_dd03l.
        ELSE.
          SELECT SINGLE ddtext
          FROM dd03t
          INTO wa_dd03l-ddtext
          WHERE tabname EQ wa_dd03l-tabname
          AND ddlanguage = sy-langu
          AND as4local = 'A'
          AND fieldname = wa_dd03l-fieldname.
          MODIFY it_dd03l FROM wa_dd03l.
        ENDIF.
      ENDLOOP.

      MOVE 'S' TO wa_temp-type.
*    MOVE gv_tbname TO wa_temp-tablename.
      MOVE p_table TO wa_temp-tablename.
      CLEAR:sy-index.
      DO.
        sy-index = sy-index.
        READ TABLE it_dd03l INTO wa_dd03l INDEX sy-index.
        IF sy-subrc = 0.
          MOVE wa_dd03l-fieldname TO wa_temp-fieldname.
          APPEND wa_temp TO it_temp.
          CLEAR gv_temp.
        ELSE.
          EXIT.
        ENDIF.
      ENDDO.
      DESCRIBE TABLE it_temp.
      it_flds[] = it_temp[].
      CLEAR : it_temp, it_temp[].

      CLEAR : it_tabs, wa_tabs.
      wa_tabs-prim_tab = p_table.
      APPEND wa_tabs TO it_tabs.

      PERFORM set_values.

**--Generate Expression from Where clause
      CALL FUNCTION 'FREE_SELECTIONS_WHERE_2_EX'
        EXPORTING
          where_clauses        = gx_twhere
        IMPORTING
          expressions          = gx_texpr
        EXCEPTIONS
          incorrect_expression = 1
          OTHERS               = 2.

**--Display screen with the fields listed
      IF gv_selid IS NOT INITIAL.
        PERFORM call_screen.
      ENDIF.
      "执行按钮
    WHEN 'ONLI'.
      PERFORM check_screen.
      PERFORM get_structure.
      PERFORM create_dynamic_itab.
*  **********Creates a dyanamic internal table**********
      PERFORM get_data.
      PERFORM display_date.
  ENDCASE.

ENDFORM. " SELECT_FLDS

*&---------------------------------------------------------------------
*& Form SET_VALUES
*&---------------------------------------------------------------------
* Set the values to the select-options
*----------------------------------------------------------------------
FORM set_values.

*   gv_selid = 'DS000001'.
  CALL FUNCTION 'FREE_SELECTIONS_INIT'
    EXPORTING
      kind                     = 'T'
      expressions              = gx_texpr
    IMPORTING
      selection_id             = gv_selid
      number_of_active_fields  = gv_actnum
    TABLES
      tables_tab               = it_tabs
      fields_tab               = it_flds
    EXCEPTIONS
      fields_incomplete        = 01
      fields_no_join           = 02
      field_not_found          = 03
      no_tables                = 04
      table_not_found          = 05
      expression_not_supported = 06
      incorrect_expression     = 07
      illegal_kind             = 08
      area_not_found           = 09
      inconsistent_area        = 10
      kind_f_no_fields_left    = 11
      kind_f_no_fields         = 12
      too_many_fields          = 13.
ENDFORM. " SET_VALUES

FORM call_screen.
  DATA : wa_where LIKE LINE OF gx_twhere,
         lv_txt   TYPE string.
  lv_txt = 'Dynamic Selections Parameters for'(007).
  CONCATENATE lv_txt p_table
  INTO gv_title SEPARATED BY space.

*  SET PF-STATUS '0001'
  CALL FUNCTION 'FREE_SELECTIONS_DIALOG'
    EXPORTING
      selection_id            = gv_selid
      title                   = gv_title
      tree_visible            = ' '
*      status                  = '0001'
    IMPORTING
      where_clauses           = gx_twhere
      expressions             = gx_texpr
      number_of_active_fields = gv_actnum
    TABLES
      fields_tab              = it_flds
    EXCEPTIONS
      internal_error          = 01
      no_action               = 02
      no_fields_selected      = 03
      no_tables_selected      = 04
      selid_not_found         = 05.
  IF sy-subrc EQ 0.
    REFRESH: s_where, s_selop.
**--Populate the Where clause with selected values
    s_where-sign = gc_i.
    s_where-option = gc_eq.
    CLEAR wa_where.
    READ TABLE gx_twhere INDEX 1 INTO wa_where.
    LOOP AT wa_where-where_tab INTO s_where-low.
      APPEND s_where.
    ENDLOOP.
**--Populate all the fields
    s_selop-sign = gc_i.
    s_selop-option = gc_eq.
    CLEAR : wa_flds.
    LOOP AT it_flds INTO wa_flds.
      s_selop-low = wa_flds-fieldname.
      APPEND s_selop.
    ENDLOOP.
  ENDIF.

*  CALL SCREEN 1000.
ENDFORM. " CALL_SCREEN
*zsdt015 表结构

 

 


参考案例:http://t.zoukankan.com/datie-p-11433965.html

 点击查询或修改筛选界面

 执行的效果

posted on 2022-11-22 09:08  淡淡-祥  阅读(60)  评论(0编辑  收藏  举报