【SAP Abap】SAP ABAP开发常用FORM集

ABAP 0 次阅读
【SAP Abap】SAP ABAP开发常用FORM集
*&---------------------------------------------------------------------*
*&  包括                YZ_ZLL_FORMS
*&---------------------------------------------------------------------*

TYPES:    abap_bool.
CONSTANTS:
          abap_true   TYPE abap_bool VALUE 'X',
          abap_false  TYPE abap_bool VALUE ''.

CONSTANTS:gc_green    TYPE icon       VALUE '@5B@',
          gc_red      TYPE icon       VALUE '@5C@',
          gc_yellow   TYPE icon       VALUE '@5D@'.

************************************************************************
*       宏定义:增加Range表行
*       &1:Range对象,&2:sign,&3:option,&4:low,&5:high
************************************************************************
DEFINE zmac_range_add_item.
  &1-sign = &2.
  &1-option = &3.
  &1-low = &4.
  if &4 is not initial.
    &1-high = &5.
  endif.
  append &1.
  clear  &1.
END-OF-DEFINITION.

************************************************************************
*                             系统消息相关
************************************************************************

************************************************************************
*       宏定义:显示系统消息
************************************************************************
DEFINE zmac_show_sys_msg.
  message id sy-msgid type sy-msgty number sy-msgno
  with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
END-OF-DEFINITION.


*       过程:获取系统消息
FORM zfrm_get_sys_msg CHANGING fc_msg.
  CALL FUNCTION 'MESSAGE_TEXT_BUILD'
    EXPORTING
      msgid               = sy-msgid
      msgnr               = sy-msgno
      msgv1               = sy-msgv1
      msgv2               = sy-msgv2
      msgv3               = sy-msgv3
      msgv4               = sy-msgv4
    IMPORTING
      message_text_output = fc_msg.
ENDFORM.                    "frm_get_system_message

*       过程:获取BAPI返回消息
FORM zfrm_get_bapi_ret_msg USING fs_return TYPE bapiret2 CHANGING fc_msg.
  CALL FUNCTION 'MESSAGE_TEXT_BUILD'
    EXPORTING
      msgid               = fs_return-id
      msgnr               = fs_return-number
      msgv1               = fs_return-message_v1
      msgv2               = fs_return-message_v2
      msgv3               = fs_return-message_v3
      msgv4               = fs_return-message_v4
    IMPORTING
      message_text_output = fc_msg.
ENDFORM.                    "frm_get_return_message


* 状态栏,显示进度信息
FORM zfrm_gui_progress USING value(fv_text) TYPE string.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      text = fv_text.
ENDFORM.                    "FRM_GUI_PROGRESS

* 状态栏,显示进度信息
FORM zfrm_gui_progress_percent USING value(fv_text) value(fv_percent).
  "p_text = '数据处理中,请稍后......'.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      percentage = fv_percent                               " 0-100之间
      text       = fv_text.
ENDFORM.                    "FM_GUI_PROGRESS_IND



************************************************************************
*                             数据转换相关
************************************************************************


*      通用转换
FORM zfrm_convert USING p_type p_put input CHANGING output.
  DATA: lv_function_name  TYPE rs38l_fnam.
*  FUNCTIONAME = |CONVERSION_EXIT_{ P_TYPE }_{ P_PUT }|.
  CONCATENATE 'CONVERSION_EXIT_'  p_type p_put INTO lv_function_name.
  CONDENSE lv_function_name NO-GAPS.
  CALL FUNCTION lv_function_name
    EXPORTING
      input  = input
    IMPORTING
      output = output.
ENDFORM.                    "zfrm_convert

*       编号去前置零
FORM zfrm_code_no_lzero CHANGING fc_code.
* 方式一:函数转换
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
    EXPORTING
      input  = fc_code
    IMPORTING
      output = fc_code.

** 方式二:新语法,显示转换(不改变值内容)
*  FC_CODE = |{ FC_CODE ALPHA = OUT }|.
ENDFORM.                " CONVERSION_EXIT_ALPHA_OUTPut

*       编号加前置零
FORM zfrm_code_with_lzero CHANGING fc_code.
* 方式一:函数转换
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = fc_code
    IMPORTING
      output = fc_code.

** 方式二:新语法,显示转换(不改变值内容)
*  FC_CODE = |{ FC_CODE ALPHA = IN }|.
ENDFORM.                    "ZFRM_CODE_WITH_LZERO

*       编号前置零处理:+前置0,-前置0
FORM zfrm_code_deal_lzero USING value(fu_flag) CHANGING fc_code .
  CASE fu_flag .
    WHEN '+'.
      PERFORM zfrm_code_with_lzero CHANGING fc_code.
    WHEN '-'.
      PERFORM zfrm_code_no_lzero CHANGING fc_code.
  ENDCASE.
ENDFORM.                    "ZFRM_CODE_DEAL_LZERO

*       物料号去前置零
FORM zfrm_matnr_no_lzero CHANGING fc_matnr.
  CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
    EXPORTING
      input        = fc_matnr
    IMPORTING
      output       = fc_matnr
    EXCEPTIONS
      length_error = 1
      OTHERS       = 2.
  IF sy-subrc <> 0.
  ENDIF.
ENDFORM.                " CONVERSION_EXIT_ALPHA_OUTPut

*       物料号加前置零
FORM zfrm_matnr_with_lzero CHANGING fc_matnr.
  CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
    EXPORTING
      input        = fc_matnr
    IMPORTING
      output       = fc_matnr
    EXCEPTIONS
      length_error = 1
      OTHERS       = 2.
  IF sy-subrc <> 0.
  ENDIF.
ENDFORM.                    "ZFRM_MATNR_WITH_LZERO

*       物料号前置零处理:+前置0,-前置0
FORM zfrm_matnr_deal_lzero USING value(fu_flag) CHANGING fc_matnr .
  CASE fu_flag .
    WHEN '+'.
      PERFORM zfrm_matnr_with_lzero CHANGING fc_matnr.
    WHEN '-'.
      PERFORM zfrm_matnr_no_lzero CHANGING fc_matnr.
  ENDCASE.
ENDFORM.                    "ZFRM_MATNR_DEAL_LZERO

*       内外部单位转换(转显示值)
FORM zfrm_unit_output USING value(fu_unit) CHANGING fc_unit.
  CALL FUNCTION 'CONVERSION_EXIT_CUNIT_OUTPUT'
    EXPORTING
      input    = fu_unit
      language = sy-langu
    IMPORTING
      output   = fc_unit.
ENDFORM.                " CONVERSION_EXIT_CUINT_OUTPut

*       内外部单位转换(转内部值)
FORM zfrm_unit_input USING fu_unit CHANGING fc_unit.
  CALL FUNCTION 'CONVERSION_EXIT_CUNIT_INPUT'
    EXPORTING
      input    = fu_unit
      language = sy-langu
    IMPORTING
      output   = fc_unit.
ENDFORM.                " CONVERSION_EXIT_CUINT_OUTPut



***************************字符串处理******************************************

*   拼接字符串,对 fc_msg_con 追加 fv_symbol fv_message
FORM zfrm_concatenate_with_symbol  USING  value(fv_message)
                                          value(fv_symbol)
                                    CHANGING value(fc_msg_con).
  IF fc_msg_con IS INITIAL.
    fc_msg_con = fv_message.
  ELSE.
    CONCATENATE fc_msg_con fv_message INTO fc_msg_con SEPARATED BY fv_symbol.
  ENDIF.
ENDFORM.                    "FM_CONCARENATE_MESSAGE


************************************************************************
*                             数值相关
************************************************************************

*       数字去尾0,负号前置
FORM zfrm_num_nozero USING value(fv_input) CHANGING fc_output.
  DATA: l_inp TYPE string,
        l_len TYPE i.
  MOVE fv_input TO l_inp.
  CONDENSE l_inp.
  l_len = STRLEN( l_inp ).
  l_len = l_len - 1.
  IF l_inp+l_len = '-'.   "最后一位
    l_inp = l_inp(l_len). "取最后一位之前的
    CONCATENATE '-' l_inp INTO l_inp. "负号前置
  ENDIF.
  SHIFT l_inp RIGHT DELETING TRAILING '0'.
  SHIFT l_inp RIGHT DELETING TRAILING '.'.
  CONDENSE l_inp.
  fc_output = l_inp.
ENDFORM.                    "zfrm_num_nozero

*       数字去尾0,去+号,并指定负号位置
*       入参:fv_input,输入的数字;fv_loc,负号的未知,L-左置,其他-右置
FORM zfrm_num_nozero_ex  USING value(fv_input) value(fv_loc)
                      CHANGING fc_output.
  DATA: lv_input  TYPE string,
        lv_num   TYPE string,
        lv_num1  TYPE string,
        lv_num2  TYPE string,
        lv_minus TYPE c.

  lv_input = fv_input.
  CONDENSE lv_input NO-GAPS.
  SPLIT lv_input AT '.' INTO lv_num1 lv_num2.
  REPLACE ALL OCCURRENCES OF '+' IN lv_num2 WITH ''.  " 去正号
  REPLACE ALL OCCURRENCES OF '-' IN lv_num2 WITH ''.
  IF sy-subrc = 0.
    lv_minus = '-'.
  ENDIF.
  SHIFT lv_num2 RIGHT DELETING TRAILING '0'.                " 小数部分去尾0
  CONDENSE lv_num2.
  CONCATENATE lv_num1 '.' lv_num2 INTO lv_num.
  SHIFT lv_num RIGHT DELETING TRAILING '.'.     " 整数去小数点
  IF lv_num  = '0'.
    CLEAR: lv_num.
  ELSE.
    IF lv_minus IS NOT INITIAL.
      TRANSLATE fv_loc TO LOWER CASE.
      IF fv_loc = 'l'.
        CONCATENATE lv_minus lv_num INTO lv_num.
      ELSE.
        CONCATENATE lv_num lv_minus INTO lv_num.
      ENDIF.
    ENDIF.
    CONDENSE lv_num NO-GAPS.
  ENDIF.
  fc_output = lv_num.
ENDFORM.                    "zfrm_num_nozero_ex


*& 四舍五入(不准确)
FORM zfrm_rounding_decimals USING value(fv_data)        " 传入小数
                                  value(fv_dec) TYPE i  " 保留小数位数
                            CHANGING  fc_data .           " 结果

  DATA: lv_data TYPE p DECIMALS 10.

  CALL FUNCTION 'HR_NZ_ROUNDING_DECIMALS'
    EXPORTING
      value_in                 = fv_data
      conv_dec                 = fv_dec
    IMPORTING
      value_out                = lv_data
    EXCEPTIONS
      no_rounding_required     = 1
      decimals_greater_than_10 = 2
      rounding_error           = 3
      OTHERS                   = 4.
  IF sy-subrc <> 0.
*MESSAGE ID SY-MSGID TYPE 'W'  NUMBER SY-MSGNO
*          WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4 .
  ENDIF
  .
                                                            " 去尾0
  PERFORM zfrm_num_nozero USING lv_data CHANGING fc_data.
ENDFORM.                    "FM_ROUNDING_DECIMALS

*&---------------------------------------------------------------------*
*& Form FM_FLTP_TO_CHAR
*& 科学计数法FLTP 转为 字符串CHAR
*&---------------------------------------------------------------------*
FORM zfrm_fltp_to_char USING value(fv_input)                                 " 输入float数
                              value(fv_digits) "TYPE cha_class_data-stellen    " 截取小数位数 ≤ 16
                      CHANGING fc_output .

  DATA:lv_input TYPE cha_class_data-sollwert.
  DATA:lv_digits TYPE cha_class_data-stellen.
  DATA:lv_field TYPE cha_class_view-sollwert.
  lv_input = fv_input.
  lv_digits = fv_digits.
  CALL FUNCTION 'QSS0_FLTP_TO_CHAR_CONVERSION'
    EXPORTING
      i_number_of_digits       = lv_digits
      i_fltp_value             = lv_input
      i_value_not_initial_flag = 'X'
      i_screen_fieldlength     = 16
    IMPORTING
      e_char_field             = lv_field.
  fc_output = lv_field.
ENDFORM.                    "FM_FLTP_TO_CHAR


***************************字符串检查**************************************

* 通用正则检查器
FORM zfrm_check_regexp  USING value(fv_pattern)
                              value(fv_num_str)
                        CHANGING fc_subrc TYPE sy-subrc.    " 0-是,非0-否
  IF cl_abap_matcher=>matches(
      pattern = fv_pattern
      text = fv_num_str
    ) = 'X'.
    fc_subrc = 0.
  ELSE.
    fc_subrc = 1.
  ENDIF.
ENDFORM.                    "zfrm_regexp_check

* 检查字符串是否是数量
FORM zfrm_check_num USING value(fv_num_str)
                     CHANGING fc_subrc TYPE sy-subrc.  " 0-是数字,非0-不是数字

  " 存在负号的数量,将负号前置
  DATA: l_inp TYPE string,
        l_len TYPE i.
  MOVE fv_num_str TO l_inp.
  CONDENSE l_inp.
  l_len = STRLEN( l_inp ).
  l_len = l_len - 1.
  IF l_inp+l_len = '-'.   "最后一位
    l_inp = l_inp(l_len). "取最后一位之前的
    CONCATENATE '-' l_inp INTO l_inp. "负号前置
  ENDIF.

  " 利用正则表单时,检查字符串
  PERFORM zfrm_check_regexp USING '^(-?[1-9]\d*(\.\d*[1-9])?)|(-?0\.\d*[1-9])$' l_inp
                            CHANGING fc_subrc.
ENDFORM.                    "zfrm_check_num

*&---------------------------------------------------------------------*
*& 检查数字(纯数字,不包括小数点、正负号)
*&---------------------------------------------------------------------*
FORM zfrm_check_digit USING value(fv_digit_str)  " 输入字符串
                      CHANGING fc_subrc TYPE sy-subrc.  " 0-是数字,非0-不是数字
  DATA: lv_type TYPE dd01v-datatype.
  CALL FUNCTION 'NUMERIC_CHECK'
    EXPORTING
      string_in = fv_digit_str
    IMPORTING
      htype     = lv_type.
  IF lv_type EQ 'NUMC'.
    fc_subrc = 0.
  ELSE.
    fc_subrc = 1.
  ENDIF.
ENDFORM.                    "FM_NUMBER_CHECK

*&---------------------------------------------------------------------*
*& 检验日期
*&---------------------------------------------------------------------*
FORM zfrm_check_date  USING value(fv_date_str)  " 输入字符串
                      CHANGING fc_subrc TYPE sy-subrc.  " 0-是日期,非0-不是日期
  DATA: lv_date TYPE sy-datum.
  lv_date = fv_date_str.
  IF STRLEN( fv_date_str ) NE 8 OR lv_date IS INITIAL.
    fc_subrc = 1.
  ELSE.
    CALL FUNCTION 'DATE_CHECK_PLAUSIBILITY'
      EXPORTING
        date                      = lv_date
      EXCEPTIONS
        plausibility_check_failed = 1
        OTHERS                    = 2.
    fc_subrc = sy-subrc.
  ENDIF.
ENDFORM.                    "FM_DATE_CHECK



************************************************************************
*                             日期相关
************************************************************************

*     特定于用户的日期显示格式,用于BDC输入
FORM zfrm_date_output USING value(fv_date) CHANGING fc_date.
  CALL FUNCTION 'CONVERT_DATE_TO_EXTERNAL'
    EXPORTING
      date_internal = fv_date
    IMPORTING
      date_external = fc_date.
ENDFORM.                    "zfrm_date_output

************************************************************************
*       获取制定类型期间的第一天
*       FU_TYPE:仅限yy-年度、mm-月份、wk-周、qrt-季度
************************************************************************
FORM zfrm_get_first_day USING value(fu_type) TYPE c
                       CHANGING fc_date     TYPE datum.

  TRANSLATE fu_type TO LOWER CASE.
  CHECK fu_type = 'yy' OR fu_type = 'mm'
     OR fu_type = 'wk' OR fu_type = 'qrt'.

  IF fc_date IS INITIAL.
    fc_date = sy-datum.
  ENDIF.
  CASE fu_type.
    WHEN 'yy'.
      fc_date+4(4) = '0101'.
    WHEN 'mm'.
      fc_date+6(2) = '01'.
    WHEN 'wk'.
      DATA: lv_week TYPE scal-week.
      CALL FUNCTION 'DATE_GET_WEEK'
        EXPORTING
          date = fc_date
        IMPORTING
          week = lv_week.   " 获取周数

      CALL FUNCTION 'WEEK_GET_FIRST_DAY'
        EXPORTING
          week = lv_week
        IMPORTING
          date = fc_date.   " 获取周一

    WHEN 'qrt'.
      DATA: lv_quarter TYPE i,
            lv_year(4) TYPE n,
            lv_month TYPE i.
      lv_year = fc_date(4).
      lv_month = fc_date+4(2).
      lv_quarter = lv_month / 3 .  " 获取第几季度

      CALL FUNCTION 'HR_99S_GET_DATES_QUARTER'
        EXPORTING
          im_quarter       = lv_quarter
          im_year          = lv_year
       IMPORTING
         ex_begda         = fc_date
*         EX_ENDDA         =
                .

    WHEN OTHERS.
  ENDCASE.

ENDFORM.                    "zfrm_get_first_day

************************************************************************
*       获取制定类型期间的最后一天
*       FU_TYPE:仅限yy-年度、mm-月份、wk-周、qrt-季度
************************************************************************
FORM zfrm_get_last_day USING value(fu_type) TYPE c
                       CHANGING fc_date     TYPE datum.

  TRANSLATE fu_type TO LOWER CASE.
  CHECK fu_type = 'yy' OR fu_type = 'mm'
     OR fu_type = 'wk' OR fu_type = 'qrt'.

  IF fc_date IS INITIAL.
    fc_date = sy-datum.
  ENDIF.
  CASE fu_type.
    WHEN 'yy'.
      fc_date+4(4) = '1231'.        " 年底

    WHEN 'mm'.
*      CALL FUNCTION 'BKK_GET_MONTH_LASTDAY'    " 传统闰年算法
*        EXPORTING
*          i_date = fc_date
*        IMPORTING
*          e_date = fc_date.    " 月末
      CALL FUNCTION 'LAST_DAY_OF_MONTHS'
        EXPORTING
          day_in            = fc_date
        IMPORTING
          last_day_of_month = fc_date. " 月末

    WHEN 'wk'.
      DATA: lv_week TYPE scal-week.
      CALL FUNCTION 'DATE_GET_WEEK'
        EXPORTING
          date = fc_date
        IMPORTING
          week = lv_week.   " 获取周数

      CALL FUNCTION 'WEEK_GET_FIRST_DAY'
        EXPORTING
          week = lv_week
        IMPORTING
          date = fc_date.   " 获取周一

      fc_date = fc_date + 6.              " 获取周末

    WHEN 'qrt'.
      DATA: lv_quarter TYPE i,
            lv_year(4) TYPE n,
            lv_month TYPE i.
      lv_year = fc_date(4).
      lv_month = fc_date+4(2).
      lv_quarter = lv_month / 3 .  " 获取第几季度

      CALL FUNCTION 'HR_99S_GET_DATES_QUARTER'
        EXPORTING
          im_quarter       = lv_quarter
          im_year          = lv_year
       IMPORTING
*         EX_BEGDA         =
         ex_endda         = fc_date
                .

    WHEN OTHERS.
  ENDCASE.

ENDFORM.                    "zfrm_get_last_day

************************************************************************
*       日期加减,单独针对年/月/日加减
*       入参1:FU_TYPE,类型,仅限YY、MM、DD,或yy、mm、dd
*       入参2:FU_NUM,间隔数,正数表示日期增加,负数表示日期减少
************************************************************************
FORM zfrm_date_add  USING value(fu_type)  TYPE c
                          value(fu_num)   TYPE i
                    CHANGING fc_date      TYPE p0001-begda.

  DATA: lv_days   TYPE t5a4a-dlydy VALUE IS INITIAL,
        lv_months TYPE t5a4a-dlymo VALUE IS INITIAL,
        lv_years  TYPE t5a4a-dlyyr VALUE IS INITIAL,
        lv_sign   TYPE c.

  IF fu_num = 0.
    RETURN.
  ELSEIF fu_num > 0.
    lv_sign = '+'.
  ELSE.
    lv_sign = '-'.
  ENDIF.

  TRANSLATE fu_type TO LOWER CASE.
  CASE fu_type.
    WHEN 'yy'.
      lv_years = ABS( fu_num ).
    WHEN 'mm'.
      lv_months = ABS( fu_num ).
    WHEN 'dd'.
      lv_days = ABS( fu_num ).
    WHEN OTHERS.

  ENDCASE.

  IF fc_date IS INITIAL.
    fc_date = sy-datum.
  ENDIF.

  CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
    EXPORTING
      date      = fc_date
      days      = lv_days
      months    = lv_months
      signum    = lv_sign
      years     = lv_years
    IMPORTING
      calc_date = fc_date.
ENDFORM.                    "ZFRM_DATE_ADD

************************************************************************
*       日期加减,年月日同时加/减
*       入参1:FU_SIGN,仅限'+'、'-'
*       入参2:FU_DAYS,间隔天数
*       入参3:FU_MONTHS,间隔月数
*       入参4:FU_YEARS,间隔年数
************************************************************************
FORM zfrm_date_add_ex  USING value(fu_sign)   TYPE c
                             value(fu_days)   TYPE t5a4a-dlydy
                             value(fu_months) TYPE t5a4a-dlymo
                             value(fu_years)  TYPE t5a4a-dlyyr
                       CHANGING fc_date       TYPE p0001-begda.

  CHECK ( fu_sign = '+' OR fu_sign = '-' ).
  CHECK fu_days > 0 AND fu_months > 0 AND fu_years > 0.

  IF fc_date IS INITIAL.
    fc_date = sy-datum.
  ENDIF.

  CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
    EXPORTING
      date      = fc_date
      days      = fu_days
      months    = fu_months
      signum    = fu_sign
      years     = fu_years
    IMPORTING
      calc_date = fc_date.
ENDFORM.                    "ZFRM_DATE_ADD_EX

************************************************************************
*       时间加减,时分秒同时加/减
*       入参1:FV_SIGN,仅限'+'、'-'
*       入参2:fv_sec,间隔秒数
*       入参3:fv_min,间隔分钟数
*       入参4:fv_hour,间隔小时数
************************************************************************
FORM zfrm_time_add USING value(fv_sign)
                         value(fv_sec)  TYPE i
                         value(fv_min)  TYPE i
                         value(fv_hour) TYPE i
                   CHANGING fc_time     TYPE sy-uzeit.

  CHECK ( fv_sign = '+' OR fv_sign = '-' )
    AND fv_sec GE 0 AND fv_min GE 0 AND fv_hour GE 0.

  IF fc_time IS INITIAL.
    fc_time = sy-uzeit.
  ENDIF.

  IF fv_sign = '-'.
    fc_time = fc_time - fv_sec - fv_min * 60 - fv_hour * 60 * 60.
  ELSE.
    fc_time = fc_time + fv_sec + fv_min * 60 + fv_hour * 60 * 60.
  ENDIF.
ENDFORM.                    "zfrm_time_add


************************************************************************
*       获取时戳
*       入参1:fv_date,当前日期
*       入参2:fv_time,当前时间
************************************************************************
FORM zfrm_get_timestamp USING value(fv_date) TYPE sy-datum
                              value(fv_time) TYPE sy-uzeit
                        CHANGING fc_timestamp TYPE tzntstmps.
  CONVERT DATE fv_date TIME fv_time
             INTO TIME STAMP fc_timestamp
                  TIME ZONE  sy-zonlo.
ENDFORM.                    "zfrm_get_timestamp
************************************************************************
*       获取 UUID
************************************************************************
FORM zfrm_get_guid CHANGING fc_guid TYPE sysuuid_c.         "char32.
  "方法一:函数获取
  CALL FUNCTION 'SYSTEM_UUID_C_CREATE'
    IMPORTING
      uuid = fc_guid.

  " 方法二:类方法获取,仅S4支持
*  TRY.
*      CALL METHOD cl_system_uuid=>if_system_uuid_static~create_uuid_c32
*      RECEIVING
*      uuid = fc_guid.
*    CATCH cx_uuid_error .
*  ENDTRY.
ENDFORM.                    "gen_uuid


************************************************************************
*                             表维护
************************************************************************

* 打开SE11的数据查看界面
FORM zfrm_show_table USING value(fv_tablename).
  DATA lf_tablename TYPE databrowse-tablename.
  lf_tablename = fv_tablename.
  CALL FUNCTION 'RS_TABLE_LIST_CREATE'
    EXPORTING
      table_name         = lf_tablename
    EXCEPTIONS
      table_is_structure = 01
      table_not_exists   = 02.
ENDFORM.                    " FRM_SELECT_LOG

* 打开SM30表维护功能
FORM zfrm_maintenance_sm30 USING value(fv_tabname) TYPE dd02v-tabname .
  CALL FUNCTION 'VIEW_MAINTENANCE_CALL'
    EXPORTING
      action                       = 'U'
      view_name                    = fv_tabname
      no_warning_for_clientindep   = 'X'
    EXCEPTIONS
      client_reference             = 1
      foreign_lock                 = 2
      invalid_action               = 3
      no_clientindependent_auth    = 4
      no_database_function         = 5
      no_editor_function           = 6
      no_show_auth                 = 7
      no_tvdir_entry               = 8
      no_upd_auth                  = 9
      only_show_allowed            = 10
      system_failure               = 11
      unknown_field_in_dba_sellist = 12
      view_not_found               = 13
      maintenance_prohibited       = 14
      OTHERS                       = 15.
  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.                    "zFRM_MAINTENANCE_SM30

* 打开SE16N表维护功能
FORM zfrm_maintenance_se16n  USING value(fv_tabname).
  CALL FUNCTION 'SE16N_INTERFACE'
    EXPORTING
      i_tab       = fv_tabname
      i_edit      = 'X'
      i_sapedit   = 'X'
*     I_NO_TXT    = ' '
      i_max_lines = ''
    EXCEPTIONS
      no_values   = 1
      OTHERS      = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.
ENDFORM.                    "zFRM_MAINTENANCE_SE16N


************************************************************************
*                             显示程序代码
************************************************************************
*       显示 Report 程序源码
FORM zfrm_show_report_code USING value(fv_pname).
  TRANSLATE fv_pname TO UPPER CASE.
  DATA ls_trdir TYPE trdir.
  SELECT SINGLE * INTO ls_trdir FROM trdir WHERE name = fv_pname .
  IF sy-subrc = 0 .
    CALL FUNCTION 'EDITOR_PROGRAM'
      EXPORTING
        display = 'X'
        program = fv_pname
      EXCEPTIONS
        OTHERS  = 1.
  ENDIF.
ENDFORM.                    "zfrm_show_report_code

*       显示 Function 函数源码
FORM zfrm_show_function_code USING value(fv_pname).
  TRANSLATE fv_pname TO UPPER CASE.
  DATA ls_tfdir TYPE tfdir.
  SELECT SINGLE * INTO ls_tfdir FROM tfdir WHERE funcname = fv_pname .
  IF sy-subrc = 0 .
    SHIFT ls_tfdir-pname BY 3 PLACES.
    CONCATENATE ls_tfdir-pname 'U' ls_tfdir-include INTO ls_tfdir-pname.

    CALL FUNCTION 'EDITOR_PROGRAM'
      EXPORTING
        display = 'X'
        program = ls_tfdir-pname
      EXCEPTIONS
        OTHERS  = 1.
  ENDIF.
ENDFORM.                    "zfrm_show_function_code


************************************************************************
*                             BCD录屏相关
************************************************************************

* BDC录屏-屏幕
FORM zfrm_bdc_dynpro  TABLES pt_bdc STRUCTURE bdcdata
                       USING fv_program  fv_dynpro.
  pt_bdc-program  = fv_program.
  pt_bdc-dynpro   = fv_dynpro.
  pt_bdc-dynbegin = 'X'.
  APPEND pt_bdc.
  CLEAR  pt_bdc.
ENDFORM.                    "frm_bdc_dynpro

* BDC录屏-字段
FORM zfrm_bdc_field TABLES pt_bdc STRUCTURE bdcdata
                     USING fv_name fv_value.
  pt_bdc-fnam = fv_name.
  pt_bdc-fval = fv_value.
  APPEND pt_bdc.
  CLEAR pt_bdc.
ENDFORM.                    "frm_bdc_field

*&---------------------------------------------------------------------*
*&      Form  frm_bdc_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_VALUE1   text
*      -->P_VALUE2   text
*      -->P_VALUE3   text
*      -->FC_BDCDATA text
*      -->OF         text
*      -->BDCDATA    text
*----------------------------------------------------------------------*
FORM frm_bdc_data USING p_value1 TYPE any
                         p_value2 TYPE any
                         p_value3 TYPE any
                   CHANGING fc_bdcdata TYPE STANDARD TABLE of bdcdata.
  DATA:lw_bdcdata TYPE bdcdata.
  IF p_value1 EQ 'D'.
    lw_bdcdata-program = p_value2.
    lw_bdcdata-dynpro  = p_value3.
    lw_bdcdata-dynbegin = 'X'.
    APPEND lw_bdcdata TO fc_bdcdata.
  ELSEIF p_value1 EQ 'F'.
    lw_bdcdata-fnam = p_value2.
    lw_bdcdata-fval = p_value3.
    CONDENSE lw_bdcdata-fval.
    APPEND lw_bdcdata TO fc_bdcdata.
  ENDIF.
ENDFORM.                    "frm_bdc_data

*& 调用TCode
FORM frm_call_transaction
                        TABLES ft_bdcdata STRUCTURE bdcdata
                               ft_message  STRUCTURE bdcmsgcoll
                        USING  value(code)
                        CHANGING value(p_status)
                                 value(p_message).

  DATA: lv_message(255),
        l_message(100) TYPE c,
        lw_message     TYPE bdcmsgcoll.
  DATA:opt  TYPE ctu_params.                       " 屏幕主变量
*  CLEAR: IT_MESSAGE[].

  opt-dismode  = 'N'.  " 录屏常量:处理方式,后台的处理
*  OPT-DISMODE = 'A'.  " 录屏常量:前台
  opt-updmode  = 'S'.  " 录屏常量:更新方式,同步
  opt-racommit = 'X'.  " 录屏常量:是否在录屏结束后,一次性提交

  CALL TRANSACTION code USING ft_bdcdata
                 OPTIONS FROM opt
                MESSAGES INTO ft_message.
  CLEAR:lv_message.
  LOOP AT ft_message INTO lw_message WHERE msgtyp CA 'EA'.
    CLEAR l_message.
    ROLLBACK WORK.
    MESSAGE ID     lw_message-msgid
            TYPE   lw_message-msgtyp
            NUMBER lw_message-msgnr
            INTO   l_message
            WITH   lw_message-msgv1 lw_message-msgv2
                   lw_message-msgv3 lw_message-msgv4.
    CONCATENATE l_message lv_message INTO lv_message SEPARATED BY ','.
    IF p_message IS INITIAL.
      p_message = l_message.
    ELSE.
      CONCATENATE p_message ';' l_message INTO p_message.
    ENDIF.
    p_status = '0'.
  ENDLOOP.
  IF lv_message IS INITIAL.
    p_status = '1'.
    COMMIT WORK .
  ENDIF.

  REFRESH ft_bdcdata.
ENDFORM.                    "FRM_CALL_TRANSACTION


************************************************************************
*                          SMARTFORMS相关
************************************************************************

* 根据Smartforms表单名称,获取对应function module名称
FORM zfrm_sf_get_function   USING value(fv_sfname) TYPE tdsfname
                           CHANGING fc_fm_name TYPE rs38l_fnam.
  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname           = fv_sfname
    IMPORTING
      fm_name            = fc_fm_name
    EXCEPTIONS
      no_form            = 1
      no_function_module = 2
      OTHERS             = 3.
  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.                    "zfrm_get_function_name

* Smartforms打印设置
FORM zfrm_sf_open_control.

  DATA: ls_control TYPE ssfctrlop,
        ls_output_opt TYPE ssfcompop.

  ls_control-langu = sy-langu.
  ls_control-no_open = 'X'.
  ls_control-no_close = 'X'.

  ls_output_opt-tdnewid = 'X'.
  ls_output_opt-tdimmed = 'X'.
  ls_output_opt-tddelete = 'X'.

  CALL FUNCTION 'SSF_OPEN'
    EXPORTING
      output_options     = ls_output_opt
      control_parameters = ls_control
    EXCEPTIONS
      formatting_error   = 1
      internal_error     = 2
      send_error         = 3
      user_canceled      = 4
      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.

ENDFORM.                    "zfrm_smartforms_open

* Smartforms关闭
FORM zfrm_sf_close.

  DATA: ls_job_info TYPE ssfcrescl.

  CALL FUNCTION 'SSF_CLOSE'
    IMPORTING
      job_output_info  = ls_job_info
    EXCEPTIONS
      formatting_error = 1
      internal_error   = 2
      send_error       = 3
      OTHERS           = 4.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE 'E' NUMBER sy-msgno
           WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

  IF ls_job_info-outputdone = 'X'.
    MESSAGE s208(00) WITH '打印成功'.
  ELSE.
    MESSAGE s208(00) WITH '打印失败' DISPLAY LIKE 'E'.  " 显示报错信息,但是不终止程序
  ENDIF.

ENDFORM.                    "zfrm_smartforms_close


************************************************************************
*                          加密长文本读取
************************************************************************

FORM zfrm_read_long_text USING fv_tdobject TYPE thead-tdobject
                          fv_tdname TYPE thead-tdname
                          fv_tdid TYPE thead-tdid
*                          fv_tdspras TYPE sy-langu
                    CHANGING fc_zlongtext.

  DATA:lt_lines TYPE TABLE OF tline WITH HEADER LINE.
  DATA: lv_tdname TYPE thead-tdname.
  lv_tdname = fv_tdname.

  "STXH  抬头项目文本  透明表
  SELECT  COUNT( * ) FROM  stxh "SINGLE  * INTO @DATA(ls_stxh)
    WHERE tdobject  =  fv_tdobject
      AND tdname    =  fv_tdname
      AND tdid      =  fv_tdid
      AND tdspras   =  sy-langu.
  IF  sy-subrc  =  0.   "如果存在,则读取文本
    CALL FUNCTION 'READ_TEXT'
      EXPORTING
*       CLIENT                  = SY-MANDT
        id                      = fv_tdid
        language                = sy-langu
        name                    = lv_tdname
        object                  = fv_tdobject
*       ARCHIVE_HANDLE          = 0
*       LOCAL_CAT               = '  '
*       IMPORTING
*       HEADER                  =
*       OLD_LINE_COUNTER        =
      TABLES
        lines                   = lt_lines
      EXCEPTIONS
        id                      = 1
        language                = 2
        name                    = 3
        not_found               = 4
        object                  = 5
        reference_check         = 6
        wrong_access_to_archive = 7
        OTHERS                  = 8.
    IF  sy-subrc  =  0.
      CLEAR  fc_zlongtext.
      LOOP AT lt_lines.
        CONCATENATE fc_zlongtext lt_lines-tdline INTO fc_zlongtext  SEPARATED BY space.    "解决回车事件  space
        CONDENSE fc_zlongtext.
        CLEAR lt_lines.
      ENDLOOP.
    ENDIF.
  ENDIF.
ENDFORM.                    "ZFRM_READ_TEXT


*&---------------------------------------------------------------------*
*&      Form  fm_creat_long_text
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->PR_TLINT     text
*      -->PR_FID       text
*      -->PR_LANG      text
*      -->PR_TDNAME    text
*      -->PR_TDOBJECT  text
*      -->PC_MESSAGE   text
*----------------------------------------------------------------------*
FORM fm_creat_long_text TABLES pr_tlint STRUCTURE tline
                    USING pr_fid TYPE thead-tdid
                          pr_lang TYPE thead-tdspras
                          pr_tdname TYPE thead-tdname
                          pr_tdobject TYPE thead-tdobject
                 CHANGING pc_message TYPE string .

  CALL FUNCTION 'CREATE_TEXT'
    EXPORTING
      fid       = pr_fid
      flanguage = pr_lang
      fname     = pr_tdname
      fobject   = pr_tdobject
*     SAVE_DIRECT       = 'X'
*     FFORMAT   =
    TABLES
      flines    = pr_tlint[]
    EXCEPTIONS
      no_init   = 1
      no_save   = 2
      OTHERS    = 3.
  IF sy-subrc <> 0.
    CALL FUNCTION 'MESSAGE_TEXT_BUILD'
      EXPORTING
        msgid               = sy-msgid
        msgnr               = sy-msgno
        msgv1               = sy-msgv1
        msgv2               = sy-msgv2
        msgv3               = sy-msgv3
        msgv4               = sy-msgv4
      IMPORTING
        message_text_output = pc_message.
  ENDIF.

ENDFORM.                    "FM_CREAT_TEXT

************************************************************************
*       状态文本读取
************************************************************************
FORM fm_status_text  USING    pa_object TYPE jest-objnr
                              pa_spras TYPE sy-langu
                     CHANGING pa_stonr
                              pa_line.

  DATA:lv_user  TYPE bsvx-sttxt,
       lv_stonr TYPE tj30-stonr,
       lv_line  TYPE bsvx-sttxt,
       lv_stsma TYPE jsto-stsma.

  CALL FUNCTION 'STATUS_TEXT_EDIT'
    EXPORTING
      client           = sy-mandt
*     FLG_USER_STAT    = ' '
      objnr            = pa_object
      only_active      = 'X'
      spras            = pa_spras
*     BYPASS_BUFFER    = ' '
    IMPORTING
*     ANW_STAT_EXISTING       =
*     E_STSMA          =
      line             = lv_line
      user_line        = lv_user
      stonr            = lv_stonr
    EXCEPTIONS
      object_not_found = 1
      OTHERS           = 2.
  IF sy-subrc <> 0.
*    MESSAGE ID SY-MSGID TYPE 'S' NUMBER SY-MSGNO
*           WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4 DISPLAY LIKE 'E'.
  ENDIF.
  pa_stonr = lv_stonr .
  pa_line = lv_line.

ENDFORM.                    "FM_STATUS_TEXT



************************************************************************
*                          文件操作相关
************************************************************************

* 获取单个本地文件路径(文档导入前提)
FORM zfrm_get_file_path  CHANGING fc_file." TYPE rlgrap-filename.
  DATA: lv_file TYPE rlgrap-filename.
  CALL FUNCTION 'WS_FILENAME_GET'
    EXPORTING
      mask             = ',*.*,'
      mode             = 'O'
      title            = '打开文件'
    IMPORTING
      filename         = lv_file
    EXCEPTIONS
      inv_winsys       = 1
      no_batch         = 2
      selection_cancel = 3
      selection_error  = 4
      OTHERS           = 5.
  IF sy-subrc = 0 AND lv_file IS NOT INITIAL.
    fc_file = lv_file.
  ENDIF.
ENDFORM.                    "zfrm_file_path

* 获取多个本地文件路径(如何传出文件列表)
FORM zfrm_get_file_path_mult CHANGING ft_files TYPE filetable  " 文件列表
                                      fc_file_count TYPE i.    " 文件数
  CALL METHOD cl_gui_frontend_services=>file_open_dialog
  EXPORTING
*     WINDOW_TITLE            =
*     DEFAULT_EXTENSION       =
*     DEFAULT_FILENAME        =
*     file_filter             =
*     WITH_ENCODING           =
*     INITIAL_DIRECTORY       =
    multiselection          = 'X'
  CHANGING
    file_table              = ft_files
    rc                      = fc_file_count
*     USER_ACTION             =
*     FILE_ENCODING           =
  EXCEPTIONS
    file_open_dialog_failed = 1
    cntl_error              = 2
    error_no_gui            = 3
    not_supported_by_gui    = 4
    OTHERS                  = 5.
  IF fc_file_count EQ 0.
    MESSAGE s001(00) WITH '请选择要上传的文件' DISPLAY LIKE 'E'.
  ENDIF.
ENDFORM.                    "zfrm_get_file_path_mult

* 检查文件是否存在
FORM zfrm_file_exists USING value(fv_filename_with_full_path)
                      CHANGING fc_exists TYPE abap_bool.
  DATA: lv_return TYPE abap_bool.
  CALL METHOD cl_gui_frontend_services=>file_exist
    EXPORTING
      file                 = fv_filename_with_full_path
    RECEIVING
      result               = fc_exists  "X-存在,非X-不存在
    EXCEPTIONS
      cntl_error           = 1
      error_no_gui         = 2
      wrong_parameter      = 3
      not_supported_by_gui = 4
      OTHERS               = 5.
ENDFORM.                    "zfrm_file_exists

* 获取本地Excel文件路径(数据导入的第一步)
FORM zfrm_get_excel_path  CHANGING fc_file." TYPE rlgrap-filename.
  DATA: lv_file TYPE rlgrap-filename.
  CALL FUNCTION 'WS_FILENAME_GET'
    EXPORTING
      mask             = ',EXECL2007(*.XLSX),*.XLSX,EXECL2003(*.XLS),*.XLS,'
      mode             = 'O'
      title            = '打开文件'
    IMPORTING
      filename         = lv_file
    EXCEPTIONS
      inv_winsys       = 1
      no_batch         = 2
      selection_cancel = 3
      selection_error  = 4
      OTHERS           = 5.
  IF sy-subrc = 0 AND lv_file IS NOT INITIAL.
    fc_file = lv_file.
  ENDIF.
ENDFORM.                    "frm_EXECL_HELP

* (系统标准函数)将Excel数据导入内存
FORM zfrm_upload_excel_sys  USING value(fv_file) value(fv_row1) value(fv_row2)
                                                  value(fv_col1) value(fv_col2)
                            CHANGING ft_excel TYPE STANDARD TABLE.
  DATA:lv_filename TYPE rlgrap-filename.
  DATA: lt_line TYPE TABLE OF alsmex_tabline.
  CHECK NOT fv_file IS INITIAL.
  lv_filename = fv_file.
  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
    EXPORTING
      filename                = lv_filename
      i_begin_col             = fv_col1
      i_begin_row             = fv_row1
      i_end_col               = fv_col2
      i_end_row               = fv_row2
    TABLES
      intern                  = lt_line
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.
  IF sy-subrc <> 0.
    MESSAGE s001(00) WITH '获取EXCEL数据失败'  DISPLAY LIKE 'E'.
  ELSE.
    ft_excel = lt_line.
  ENDIF.
ENDFORM.                    "FM_UPLOAD_EXCEL

* (系统标准函数)将内存Excel数据导入对应内表
FORM zfrm_excel_to_itab_sys TABLES ft_excel STRUCTURE alsmex_tabline  "zalsmex_tabline_line
                               ft_itab.   " 泛型内表
  FIELD-SYMBOLS: <fs>.
  CLEAR: ft_itab, ft_itab[].
  IF ft_excel[] IS NOT INITIAL.
    LOOP AT ft_excel.
      "赋地址值:对应 fs_itab 中的 ft_excel-col 列
      ASSIGN COMPONENT ft_excel-col OF STRUCTURE ft_itab TO <fs>.
      CLEAR <fs>.   "清内容值
      IF ft_excel-value IS NOT INITIAL.
        CONDENSE  ft_excel-value.
        TRANSLATE ft_excel-value TO UPPER CASE.
        MOVE ft_excel-value TO <fs>.    "赋内容值
      ENDIF.
      AT END OF row.    "每当row值的最后一行(即遍历完excel一行的所有列之后执行)
        APPEND ft_itab. "将读取的行数据,保存到内表中
        CLEAR ft_itab.
      ENDAT.
    ENDLOOP.
  ENDIF.
ENDFORM.                    "zfrm_excel_to_itab_sys

* 将Excel数据导入内存(数据导入的第二步,需要第一步获取的文件路径)
* 依赖自定义的函数中定义的类型 zsexcel_tabline
FORM zfrm_upload_excel TABLES ft_excel STRUCTURE zsexcel_tabline  "zalsmex_tabline_line
                       USING value(fv_file) value(fv_row1) value(fv_row2)
                             value(fv_col1) value(fv_col2).

  CHECK NOT fv_file IS INITIAL.
*  check fv_row1 ge 1 and fv_row1 le 1048576.    " 不大于最大行
*  check fv_row2 ge 1 and fv_row2 le 1048576.    " 不大于最大行
*  check fv_col1 ge 1 and fv_col1 le 16384.      " 不大于最大列
*  check fv_col2 ge 1 and fv_col2 le 16384.      " 不大于最大列

*  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'   " 系统的,行列在9999以内,值50字符
*  CALL FUNCTION 'ZALSM_EXCEL_TO_INTERNAL_TABLE'  " 增强的,行列在99999以内,值2046字符
  CALL FUNCTION 'ZFMBC_EXCEL_TO_INTERNAL_TABLE'   "
    EXPORTING
      filename                = fv_file
      i_begin_row             = fv_row1
      i_end_row               = fv_row2
      i_begin_col             = fv_col1
      i_end_col               = fv_col2
*      SHEET_NAME              = 'Sheet1' "页签名称,不指定则默认第一个页签
    TABLES
      intern                  = ft_excel[]
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.
  IF sy-subrc <> 0.
    MESSAGE '导入失败' TYPE 'E'.
    STOP.
  ENDIF.
  IF ft_excel[] IS INITIAL.
    MESSAGE '导入数据空' TYPE 'I'.
    LEAVE PROGRAM.
  ENDIF.

ENDFORM.                    "frm_upload_pblic

* 将内存Excel数据导入对应内表(数据导入的第三步)
* 依赖自定义的函数中定义的类型 zsexcel_tabline
FORM zfrm_excel_to_itab TABLES ft_excel STRUCTURE zsexcel_tabline  "zalsmex_tabline_line
                               ft_itab.   " 泛型内表
  FIELD-SYMBOLS: <fs>.
  CLEAR: ft_itab, ft_itab[].
  IF ft_excel[] IS NOT INITIAL.
    LOOP AT ft_excel.
      "赋地址值:对应 fs_itab 中的 ft_excel-col 列
      ASSIGN COMPONENT ft_excel-col OF STRUCTURE ft_itab TO <fs>.
      CLEAR <fs>.   "清内容值
      IF ft_excel-value IS NOT INITIAL.
        CONDENSE  ft_excel-value.
        TRANSLATE ft_excel-value TO UPPER CASE.
        MOVE ft_excel-value TO <fs>.    "赋内容值
      ENDIF.
      AT END OF row.    "每当row值的最后一行(即遍历完excel一行的所有列之后执行)
        APPEND ft_itab. "将读取的行数据,保存到内表中
        CLEAR ft_itab.
      ENDAT.
    ENDLOOP.
  ENDIF.
ENDFORM.                    "zfrm_excel_to_itab

* 导入模板文件下载(SMW0)
FORM zfrm_download_template USING value(p_template) value(p_objid).
  DATA: lv_fname TYPE string,
        lv_title TYPE string,
        lv_path  TYPE string VALUE 'D:/',
        lv_fpath TYPE string VALUE 'D:/',
        lv_desc  TYPE rlgrap-filename.
  DATA: ls_wdatb   LIKE wwwdatatab.
  DATA: lv_subrc   TYPE sy-subrc.

  "首先检查文件是否存在
  SELECT SINGLE relid objid   "ZSD_JZJ
  FROM wwwdata
  INTO CORRESPONDING FIELDS OF ls_wdatb
  WHERE srtf2 = 0
    AND relid = 'MI'
    AND objid = p_objid.
*    IF sy-subrc <> 0 OR ls_wdatb-objid IS INITIAL.
*      MESSAGE '没有获得模板数据' TYPE 'E'.
*    ENDIF.
  IF ls_wdatb IS INITIAL.
    MESSAGE '文件不存在!' TYPE 'E'.
  ELSE.
    lv_fname = p_template.
    CONCATENATE p_template '下载' INTO lv_title.

    "获取桌面路径(无效,未取到桌面路径)
*    DATA: lv_init_path TYPE string.
*    CALL METHOD cl_gui_frontend_services=>get_desktop_directory
*      CHANGING
*        desktop_directory    = lv_init_path
*      EXCEPTIONS
*        cntl_error           = 1
*        error_no_gui         = 2
*        not_supported_by_gui = 3
*        OTHERS               = 4.
*    IF lv_init_path IS INITIAL.
*      lv_init_path = 'D:\'.
*    ENDIF.
    "获取保存路径及文件名
    CALL METHOD cl_gui_frontend_services=>file_save_dialog
      EXPORTING
        window_title         = lv_title
        default_extension    = 'xlsx'
        default_file_name    = lv_fname
        initial_directory    = 'D:\'
*        file_filter          = 'Excel文件(*.xlsx)|*.xlsx|全部文件 (*.*)|*.*|'
        prompt_on_overwrite  = 'X'
      CHANGING
        filename             = lv_fname
        path                 = lv_path
        fullpath             = lv_fpath
      EXCEPTIONS
        cntl_error           = 1
        error_no_gui         = 2
        not_supported_by_gui = 3
        OTHERS               = 4.
    IF sy-subrc <> 0.
      MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
      WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
*   没有选择路径
*    IF lf_fullpath = ''.
*      MESSAGE  '请选择正确的路径!' TYPE 'E'.
    ELSE.
      IF lv_fpath IS NOT INITIAL.
        lv_desc = lv_fpath.   "类型转换
        CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
          EXPORTING
            key         = ls_wdatb
            destination = lv_desc
          IMPORTING
            rc          = lv_subrc.
        IF lv_subrc NE 0.
          MESSAGE '下载失败!' TYPE 'E'.
        ELSE.
          MESSAGE '下载成功' TYPE 'S'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.
ENDFORM.                    "frm_download_public


************************************************************************
*                          对话框相关
************************************************************************

* 确认对话框
FORM zfrm_simple_comfirm USING fv_question CHANGING fc_answer.
  CALL FUNCTION 'POPUP_TO_CONFIRM'
    EXPORTING
     titlebar                    = '请您确认 '
*     DIAGNOSE_OBJECT             = ' '
      text_question               = fv_question
     text_button_1               = '是'
*     ICON_BUTTON_1               = ' '
     text_button_2               = '否'
*     ICON_BUTTON_2               = ' '
*     DEFAULT_BUTTON              = '1'   " 默认选中按钮:1、2、A
*     DISPLAY_CANCEL_BUTTON       = 'X'    " 是否显示取消按钮:'X' ''
*     USERDEFINED_F1_HELP         = ' '
*     START_COLUMN                = 25
*     START_ROW                   = 6
*     POPUP_TYPE                  =
*     IV_QUICKINFO_BUTTON_1       = ' '
*     IV_QUICKINFO_BUTTON_2       = ' '
   IMPORTING
     answer                      = fc_answer
*   TABLES
*     PARAMETER                   =
   EXCEPTIONS
     text_not_found              = 1
     OTHERS                      = 2
            .
  IF sy-subrc <> 0.
*   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*           WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
ENDFORM.                    "zfrm_simple_comfirm

* 值输入对话框
FORM zfrm_input_value TABLES ft_sval STRUCTURE sval " 返回值:在 lt_sval-value 里
                      USING value(fv_title)
                      CHANGING fc_returncode.       " 返回码:确认:空,取消:A

* 入参示例
*DATA : lt_sval TYPE  TABLE  OF  sval,
*       ls_sval LIKE  LINE  OF  lt_sval.
*DATA:l_returncode TYPE string .
*
*"物料
*CLEAR ls_sval .
*ls_sval-tabname = 'MARA' .  "表名
*ls_sval-fieldname = 'MATNR' . "字段名
*ls_sval-field_obl = 'X' .          "是否为必填
*APPEND ls_sval TO lt_sval.
*
*"过账日期
*CLEAR ls_sval .
*ls_sval-tabname = 'BKPF' .  "表名
*ls_sval-fieldname = 'BUDAT' . "字段名
*ls_sval-field_obl = 'X' .          "是否为必填
*APPEND ls_sval TO lt_sval.
*
*"如果是金额的话要把参考表和参考字段也写进来,然后隐藏,不然金额的输入框是不能输入的
*CLEAR ls_sval .
*ls_sval-tabname = 'BSIS'.
*ls_sval-fieldname = 'WRBTR'.
*APPEND ls_sval TO lt_sval.
*
*"货币
*CLEAR ls_sval .
*ls_sval-tabname = 'BSIS'.
*ls_sval-fieldname = 'WAERS'.
**ls_sval-field_attr = '04'.   "隐藏货币字段
*APPEND ls_sval TO lt_sval.

*PERFORM tfrm_input_value TABLES lt_sval USING '请输入值' CHANGING l_returncode.
*write:/ 'wait'.

  CALL FUNCTION 'POPUP_GET_VALUES'
    EXPORTING
*   NO_VALUE_CHECK  = ' '
      popup_title     = fv_title
*   START_COLUMN    = '5'
*   START_ROW       = '5'
    IMPORTING
      returncode      = fc_returncode  " 返回码:确认:空,取消:A
    TABLES
      fields          = ft_sval       " 返回值:在 lt_sval-value 里
    EXCEPTIONS
      error_in_fields = 1
      OTHERS          = 2.
ENDFORM.                    "zfrm_input_value



***************************ALV 相关处理*******************************************
*       设置字段目录
FORM zfrm_field_lvc TABLES ft_fieldcat_lvc STRUCTURE lvc_s_fcat  " 返回字段目录及设置
                    USING pv_fieldname TYPE lvc_rfname
                          pv_ref_table TYPE lvc_rfname
                          pv_ref_field TYPE lvc_tname
                          pv_cfieldname TYPE lvc_cfname
                          pv_qfieldname TYPE lvc_qfname
                          pv_text TYPE string
                          pv_edit TYPE c
                          pv_nozero TYPE c
                          pv_f4 TYPE c
                          pv_no_out TYPE c
                          pv_outputlen TYPE i.

  DATA:ls_fieldcat_lvc TYPE lvc_s_fcat.
  CLEAR ls_fieldcat_lvc.
  ls_fieldcat_lvc-fieldname = pv_fieldname.
  ls_fieldcat_lvc-ref_table = pv_ref_table.
  ls_fieldcat_lvc-ref_field = pv_ref_field.
  ls_fieldcat_lvc-cfieldname = pv_cfieldname.
  ls_fieldcat_lvc-qfieldname = pv_qfieldname.
  ls_fieldcat_lvc-colddictxt = 'L'.
  ls_fieldcat_lvc-scrtext_l = pv_text.
  ls_fieldcat_lvc-edit = pv_edit.
  ls_fieldcat_lvc-no_zero = pv_nozero.
  ls_fieldcat_lvc-f4availabl = pv_f4.
  ls_fieldcat_lvc-no_out = pv_no_out.
  ls_fieldcat_lvc-outputlen = pv_outputlen.

  IF ls_fieldcat_lvc-fieldname = 'SEL'
    OR ls_fieldcat_lvc-fieldname = 'BOX'.
    ls_fieldcat_lvc-checkbox = 'X'.
    ls_fieldcat_lvc-fix_column = 'X'.
  ENDIF.

  APPEND ls_fieldcat_lvc TO ft_fieldcat_lvc.
ENDFORM.                       "FRM_FIELD_LVC