MD61计划独立需求导入BAPI【按日维度/动态模板/动态字段】

实现按照选择屏幕输入区间下载动态模板,根据上传模板中实际日期列名,创建对应日期的计划独立需求。

下载效果:

 上传效果:

完整代码如下,稍加修改可直接复用:

*&---------------------------------------------------------------------*
*& Form FRM_GET_COMP
*&---------------------------------------------------------------------*
*& 获取字段结构列表
*&---------------------------------------------------------------------*
FORM FRM_GET_COMP USING     US_DATA
                  CHANGING  CT_COMP TYPE ABAP_COMPDESCR_TAB.
  DATA:
    LO_DESCR_REF TYPE REF TO CL_ABAP_TYPEDESCR,
    LO_STRUC     TYPE REF TO CL_ABAP_STRUCTDESCR.

  CALL METHOD CL_ABAP_STRUCTDESCR=>DESCRIBE_BY_DATA
    EXPORTING
      P_DATA      = US_DATA
    RECEIVING
      P_DESCR_REF = LO_DESCR_REF.

  LO_STRUC ?= LO_DESCR_REF.

  CT_COMP = LO_STRUC->COMPONENTS.
ENDFORM.
*&---------------------------------------------------------------------*
*& Report ZPPR005
*&---------------------------------------------------------------------*
*& 计划独立需求导入
*&---------------------------------------------------------------------*
REPORT ZPPR005.
TABLES:PBIM,SSCRFIELDS.

TYPES:
  BEGIN OF TY_PBIM,
    MATNR TYPE PBIM-MATNR,                        "物料
    WERKS TYPE PBIM-WERKS,                        "工厂
    BEDAE TYPE PBIM-BEDAE,                        "需求类型
    VERSB TYPE PBIM-VERSB,                        "版本
    PBDNR TYPE PBIM-PBDNR,                        "需求计划
  END OF TY_PBIM,
  TY_TAB_PBIM TYPE STANDARD TABLE OF TY_PBIM,

  BEGIN OF TY_MARA,
    MATNR TYPE MARA-MATNR,                        "物料
    MEINS TYPE MARA-MEINS,                        "基本计量单位
  END OF TY_MARA,
  TY_TAB_MARA TYPE STANDARD TABLE OF TY_MARA.

DATA:
  GT_PBIM     TYPE TY_TAB_PBIM,
  GS_PBIM     TYPE TY_PBIM,
  GT_MARA     TYPE TY_TAB_MARA,
  GT_FIELDCAT TYPE LVC_T_FCAT,
  GS_FIELDCAT TYPE LVC_S_FCAT,
  GS_FUNCTXT  TYPE SMP_DYNTXT.                     "菜单制作器

FIELD-SYMBOLS:
  <FS_TAB_UPLOAD> TYPE STANDARD TABLE,
  <FS_UPLOAD>     TYPE ANY,
  <FS_TAB_ALV>    TYPE STANDARD TABLE,
  <FS_ALV>        TYPE ANY.

*OLE使用相关参数定义
DATA:
  MYEXCEL     TYPE OLE2_OBJECT,
  MYSHEET     TYPE OLE2_OBJECT,
  MYSHEETNAME TYPE OLE2_OBJECT,
  MYCELL      TYPE OLE2_OBJECT,
  MYWORKBOOK  TYPE OLE2_OBJECT,
  MYRANGE     TYPE OLE2_OBJECT.

SELECTION-SCREEN BEGIN OF BLOCK B1  WITH FRAME TITLE TEXT-001.
  PARAMETERS:
    P_FILE TYPE RLGRAP-FILENAME OBLIGATORY MEMORY ID Z1 MODIF ID M1.
  SELECT-OPTIONS:
    S_DATUM FOR PBIM-DATLP MODIF ID M2 NO-EXTENSION.
SELECTION-SCREEN END OF BLOCK B1.
SELECTION-SCREEN BEGIN OF BLOCK B2  WITH FRAME TITLE TEXT-003.
  PARAMETERS:
    P_RB1 RADIOBUTTON GROUP R1 DEFAULT 'X' USER-COMMAND CREATE,    "计划独立需求模板下载
    P_RB2 RADIOBUTTON GROUP R1.                                    "计划独立需求导入
SELECTION-SCREEN END OF BLOCK B2.

INITIALIZATION.
* 初始化屏幕文本描述
  PERFORM FRM_INITIAL_DESC.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_FILE.
* 导入文件搜索帮助
  PERFORM FRM_CALL_F4 CHANGING P_FILE.

AT SELECTION-SCREEN OUTPUT.
* 动态更新屏幕
  PERFORM FRM_CHANGE_SCREEN.

AT SELECTION-SCREEN.

START-OF-SELECTION.
* 执行开始
  PERFORM FRM_PROCESS_MAIN.

*&---------------------------------------------------------------------*
*& Form FRM_INITIAL_DESC
*&---------------------------------------------------------------------*
*& 初始化屏幕文本描述
*&---------------------------------------------------------------------*
FORM FRM_INITIAL_DESC .
  GS_FUNCTXT-ICON_ID = ICON_EXPORT.
  GS_FUNCTXT-QUICKINFO = TEXT-002.                "下载生产版本导入模板
  GS_FUNCTXT-ICON_TEXT = TEXT-002.                "下载生产版本导入模板
  SSCRFIELDS-FUNCTXT_01 = GS_FUNCTXT.

* 默认模板日期区间为未来两个月
  S_DATUM-SIGN   = 'I'.
  S_DATUM-OPTION = 'EQ'.
  S_DATUM-LOW    = SY-DATUM.

  CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
    EXPORTING
      DATE      = SY-DATUM
      DAYS      = 0
      MONTHS    = 2
      SIGNUM    = '+'
      YEARS     = 0
    IMPORTING
      CALC_DATE = S_DATUM-HIGH.
  APPEND S_DATUM.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_call_f4
*&---------------------------------------------------------------------*
*& 导入文件搜索帮助
*&---------------------------------------------------------------------*
FORM FRM_CALL_F4 CHANGING CV_FILE TYPE RLGRAP-FILENAME.
  CALL FUNCTION 'F4_FILENAME'
    IMPORTING
      FILE_NAME = CV_FILE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CHANGE_SCREEN
*&---------------------------------------------------------------------*
*& 动态更新屏幕
*&---------------------------------------------------------------------*
FORM FRM_CHANGE_SCREEN .
  IF P_RB1 = 'X'.
    LOOP AT SCREEN.
      IF SCREEN-GROUP1 = 'M1'.
        SCREEN-ACTIVE = 0.
      ENDIF.
      MODIFY SCREEN.
    ENDLOOP.
  ELSE.
    LOOP AT SCREEN.
      IF SCREEN-GROUP1 = 'M2'.
        SCREEN-ACTIVE = 0.
      ENDIF.
      IF SCREEN-NAME = 'P_FILE'.
        SCREEN-REQUIRED = 2.
      ENDIF.
      MODIFY SCREEN.
    ENDLOOP.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DOWNLOAD_TEMPLATE
*&---------------------------------------------------------------------*
*& 下载模板
*&---------------------------------------------------------------------*
FORM FRM_DOWNLOAD_TEMPLATE .
  DATA:
    LV_FULLPATH TYPE STRING,
    LV_PATH     TYPE STRING.

* 获取模板保存路径
  PERFORM FRM_GET_FULLPATH CHANGING LV_FULLPATH
                                    LV_PATH.
* 路径为空则退出
  IF LV_FULLPATH IS INITIAL.
*   已取消下载!
    MESSAGE S028(ZMSG01).
    LEAVE LIST-PROCESSING.
  ENDIF.

* 使用OLE下载动态模板
  PERFORM FRM_CRT_EXCEL2 USING LV_FULLPATH
                               LV_PATH.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_PROCESS_MAIN
*&---------------------------------------------------------------------*
*& 执行开始
*&---------------------------------------------------------------------*
FORM FRM_PROCESS_MAIN .
  CASE ABAP_ON.
*   计划独立需求模板下载
    WHEN P_RB1.
*     下载模板
      PERFORM FRM_DOWNLOAD_TEMPLATE.
*   计划独立需求导入
    WHEN P_RB2.
*     创建上传模板动态内表
      PERFORM FRM_CREATE_UPLOAD_TAB.

*     导入计划独立需求数据
      PERFORM FRM_UPLOAD_FILE.

*     处理导入数据
      PERFORM FRM_PROCESS_DATA.

*     展示ALV
      PERFORM FRM_DISPLAY_ALV.
    WHEN OTHERS.
  ENDCASE.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_UPLOAD_FILE
*&---------------------------------------------------------------------*
*& 导入计划独立需求数据
*&---------------------------------------------------------------------*
FORM FRM_UPLOAD_FILE .
  DATA:
    LT_RAW_DATA TYPE TRUXS_T_TEXT_DATA.

  IF P_FILE IS INITIAL.
*     请选择导入文件!
    MESSAGE S035(ZMSG01) DISPLAY LIKE 'E'.
    LEAVE LIST-PROCESSING.
  ENDIF.

* 导入文件数据
  CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP'
    EXPORTING
*     I_FIELD_SEPERATOR    =
*     I_LINE_HEADER        = 'X'
      I_TAB_RAW_DATA       = LT_RAW_DATA
      I_FILENAME           = P_FILE
*     I_STEP               = 1
    TABLES
      I_TAB_CONVERTED_DATA = <FS_TAB_UPLOAD>
    EXCEPTIONS
      CONVERSION_FAILED    = 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'.
    LEAVE LIST-PROCESSING.
  ELSE.
    IF LINES( <FS_TAB_UPLOAD> ) = 1.
*     文件内容为空,请检查!
      MESSAGE S029(ZMSG01) DISPLAY LIKE 'E'.
      LEAVE LIST-PROCESSING.
    ENDIF.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_PROCESS_DATA
*&---------------------------------------------------------------------*
*& 处理导入数据
*&---------------------------------------------------------------------*
FORM FRM_PROCESS_DATA .
* 构建动态ALV
  PERFORM FRM_CREATE_DYN_ALV.

* 数据映射
  PERFORM FRM_MAPPING_DATA.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY_ALV
*&---------------------------------------------------------------------*
*& 展示ALV
*&---------------------------------------------------------------------*
FORM FRM_DISPLAY_ALV .
  DATA:
    LS_LAYOUT    TYPE LVC_S_LAYO,
    LT_FIELDCAT  TYPE LVC_T_FCAT,
    LT_EXCLUDING TYPE SLIS_T_EXTAB,
    LT_EVENT     TYPE SLIS_T_EVENT,
    LS_EVENT     TYPE SLIS_ALV_EVENT,
    LS_DDVAL     TYPE LVC_S_DROP.

* 设置布局控制
  LS_LAYOUT-ZEBRA      = 'X'.                     "颜色间隔
  LS_LAYOUT-SEL_MODE   = 'D'.                     "选择模式
  LS_LAYOUT-CWIDTH_OPT = 'X'.                     "列宽自适应
  LS_LAYOUT-STYLEFNAME = 'STYLE'.                 "控制字段
  LS_LAYOUT-BOX_FNAME  = 'CBOX'.                  "选择框字段

* 追加事件
  LS_EVENT-NAME = 'DATA_CHANGED'.
  LS_EVENT-FORM = 'FRM_ALV_DATA_CHANGED'.
  APPEND LS_EVENT TO LT_EVENT.

* 展示ALV
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      I_CALLBACK_PROGRAM       = SY-REPID
      I_CALLBACK_PF_STATUS_SET = 'FRM_STATUS_SET'
      I_CALLBACK_USER_COMMAND  = 'FRM_USER_COMMAND'
      IS_LAYOUT_LVC            = LS_LAYOUT
      IT_FIELDCAT_LVC          = GT_FIELDCAT
      IT_EXCLUDING             = LT_EXCLUDING
      I_SAVE                   = 'A'
      IT_EVENTS                = LT_EVENT
    TABLES
      T_OUTTAB                 = <FS_TAB_ALV>
    EXCEPTIONS
      PROGRAM_ERROR            = 1
      OTHERS                   = 2.

  IF SY-SUBRC <> 0.
* Implement suitable error handling here
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ALV_DATA_CHANGED
*&---------------------------------------------------------------------*
*& 数据更改事件
*&---------------------------------------------------------------------*
*&      --> ER_DATA_CHANGED      数据更改监控实例对象
*&---------------------------------------------------------------------*
FORM FRM_ALV_DATA_CHANGED USING ER_DATA_CHANGED TYPE REF TO CL_ALV_CHANGED_DATA_PROTOCOL.
* 手动触发PBO事件,以达到刷新列宽自适应效果
  CALL FUNCTION 'SAPGUI_SET_FUNCTIONCODE'
    EXPORTING
      FUNCTIONCODE           = 'REFRESH'
    EXCEPTIONS
      FUNCTION_NOT_SUPPORTED = 1
      OTHERS                 = 2.

  IF SY-SUBRC <> 0.
* Implement suitable error handling here
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_STATUS_SET
*&---------------------------------------------------------------------*
*& GUI状态栏设置
*&---------------------------------------------------------------------*
*&      --> RT_EXTAB      排除按钮
*&---------------------------------------------------------------------*
FORM FRM_STATUS_SET USING RT_EXTAB TYPE SLIS_T_EXTAB.
  DATA:
    LS_EXTAB TYPE SLIS_EXTAB.

  SET PF-STATUS 'STATUS' EXCLUDING RT_EXTAB.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_USER_COMMAND
*&---------------------------------------------------------------------*
*& 用户按钮事件响应
*&---------------------------------------------------------------------*
*&      --> R_UCOMM      事件码
*&      --> RS_SELFIELD  操作数据字段信息
*&---------------------------------------------------------------------*
FORM FRM_USER_COMMAND USING R_UCOMM     LIKE SY-UCOMM
                            RS_SELFIELD TYPE SLIS_SELFIELD.

  DATA:
    LO_GRID    TYPE REF TO CL_GUI_ALV_GRID,
    LS_STABLE  TYPE LVC_S_STBL,
    LV_VALID   TYPE CHAR1,
    LS_LAYOUT  TYPE LVC_S_LAYO,
    LV_REFRESH TYPE CHAR1.

  LS_STABLE-ROW = 'X'.
  LS_STABLE-COL = 'X'.

* 获取当前屏幕实例对象
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      E_GRID = LO_GRID.

* 将EDIT数据更新回内表GT_RESULT中.
  CALL METHOD LO_GRID->CHECK_CHANGED_DATA
    IMPORTING
      E_VALID   = LV_VALID
    CHANGING
      C_REFRESH = LV_REFRESH.

  CASE R_UCOMM.
*   双击
    WHEN '&IC1'.

*   保存
    WHEN 'SAVE'.
*     创建计划独立需求
      PERFORM FRM_CREATE_MD61.
    WHEN OTHERS.
  ENDCASE.

  CALL METHOD LO_GRID->GET_FRONTEND_LAYOUT
    IMPORTING
      ES_LAYOUT = LS_LAYOUT.

  LS_LAYOUT-CWIDTH_OPT = 'X'.

* 设置列宽自适应
  CALL METHOD LO_GRID->SET_FRONTEND_LAYOUT
    EXPORTING
      IS_LAYOUT = LS_LAYOUT.

* 刷新ALV
  CALL METHOD LO_GRID->REFRESH_TABLE_DISPLAY
    EXPORTING
      IS_STABLE = LS_STABLE
    EXCEPTIONS
      FINISHED  = 1
      OTHERS    = 2.

  IF SY-SUBRC <> 0.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CREATE_MD61
*&---------------------------------------------------------------------*
*& 创建计划独立需求
*&---------------------------------------------------------------------*
FORM FRM_CREATE_MD61 .
  DATA:
    LS_REQ_ITEM      TYPE BAPISITEMR,
    LT_REQ_SCHE_ITEM TYPE FSH_BAPISSHDIN_T,
    LS_REQ_SCHE_ITEM TYPE BAPISSHDIN,
    LT_RETURN        TYPE TAB_BAPIRET1,
    LT_COMPONENTS    TYPE ABAP_COMPDESCR_TAB,
    LV_VERVS         TYPE PBIM-VERVS,
    LV_SELNUM        TYPE I.

* 获取字段结构列表
  PERFORM FRM_GET_COMP(ZCUSTOM_FORM)
    USING <FS_ALV>
    CHANGING LT_COMPONENTS IF FOUND.

  LOOP AT <FS_TAB_ALV> INTO <FS_ALV>.
    ASSIGN COMPONENT 'CBOX'    OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_CBOX>).    "选择框
    ASSIGN COMPONENT 'MESSAGE' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_MESSAGE>). "消息
    ASSIGN COMPONENT 'ICON'    OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_ICON>).    "状态灯

    IF <FS_CBOX> <> 'X' OR <FS_ICON> = ICON_LED_GREEN.
      CONTINUE.
    ENDIF.

    ADD 1 TO LV_SELNUM.

    ASSIGN COMPONENT 'MATNR' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_MATNR>)."物料
    ASSIGN COMPONENT 'WERKS' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_WERKS>)."工厂
    ASSIGN COMPONENT 'VERSB' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_VERSB>)."版本
    ASSIGN COMPONENT 'PBDNR' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_PBDNR>)."需求计划
    ASSIGN COMPONENT 'VERVS' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_VERVS>)."激活

    READ TABLE GT_MARA INTO DATA(LS_MARA)
      WITH KEY MATNR = <FS_MATNR>
        BINARY SEARCH.

*   BAPI明细填充
    LOOP AT LT_COMPONENTS INTO DATA(LS_COMPOMENTS) FROM 9.
      ASSIGN COMPONENT LS_COMPOMENTS-NAME OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_PLNMG>).
      IF <FS_PLNMG> IS NOT INITIAL.
        LS_REQ_SCHE_ITEM-DATE_TYPE = '1'.                    "日期类型(日, 星期, 月, 间隔 )
        LS_REQ_SCHE_ITEM-REQ_DATE  = LS_COMPOMENTS-NAME+1(8)."计划行日期
        LS_REQ_SCHE_ITEM-REQ_QTY   = <FS_PLNMG>.             "计划数量
        LS_REQ_SCHE_ITEM-UNIT      = LS_MARA-MEINS.          "基本计量单位
        APPEND LS_REQ_SCHE_ITEM TO LT_REQ_SCHE_ITEM.
        CLEAR LS_REQ_SCHE_ITEM.
      ENDIF.
    ENDLOOP.

    READ TABLE GT_PBIM INTO DATA(LS_PBIM)
      WITH KEY MATNR = <FS_MATNR>
               WERKS = <FS_WERKS>
               VERSB = <FS_VERSB>
               PBDNR = <FS_PBDNR>
               BINARY SEARCH.
*   创建
    IF SY-SUBRC <> 0.
      LS_REQ_ITEM-MATERIAL   = <FS_MATNR>.        "物料
      LS_REQ_ITEM-PLANT      = <FS_WERKS>.        "工厂
      LS_REQ_ITEM-REQU_TYPE  = 'VSF'.             "需求类型
      LS_REQ_ITEM-VERSION    = <FS_VERSB>.        "版本
      LS_REQ_ITEM-REQ_NUMBER = <FS_PBDNR>.        "需求计划
      LS_REQ_ITEM-VERS_ACTIV = <FS_VERVS>.        "激活

*     独立需求计划创建
      CALL FUNCTION 'BAPI_REQUIREMENTS_CREATE'
        EXPORTING
          REQUIREMENTS_ITEM        = LS_REQ_ITEM
          DO_COMMIT                = 'X'
        TABLES
          REQUIREMENTS_SCHEDULE_IN = LT_REQ_SCHE_ITEM
          RETURN                   = LT_RETURN.
*   变更
    ELSE.
      LV_VERVS = <FS_VERVS>.

*     独立需求计划变更
      CALL FUNCTION 'BAPI_REQUIREMENTS_CHANGE'
        EXPORTING
          MATERIAL_LONG            = LS_PBIM-MATNR "物料
          PLANT                    = LS_PBIM-WERKS "工厂
          REQUIREMENTSTYPE         = 'VSF'         "需求类型
          VERSION                  = LS_PBIM-VERSB "版本
          REQMTSPLANNUMBER         = LS_PBIM-PBDNR "需求计划
          VERS_ACTIV               = LV_VERVS      "激活
          DO_COMMIT                = 'X'
          UPDATE_MODE              = 'X'
          DELETE_OLD               = 'X'
        TABLES
          REQUIREMENTS_SCHEDULE_IN = LT_REQ_SCHE_ITEM
          RETURN                   = LT_RETURN.
    ENDIF.

    LOOP AT LT_RETURN INTO DATA(LS_RETURN) WHERE TYPE CA 'EAX'.
      IF <FS_MESSAGE> IS INITIAL.
        <FS_MESSAGE> = LS_RETURN-MESSAGE.
      ELSE.
        <FS_MESSAGE> = <FS_MESSAGE> && ';' && LS_RETURN-MESSAGE.
      ENDIF.
    ENDLOOP.

    IF SY-SUBRC <> 0.
      CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
        EXPORTING
          WAIT = 'X'.

      <FS_ICON>    = ICON_LED_GREEN.              "绿灯
*     独立需求计划创建成功!
      MESSAGE S165(ZMSG01) INTO <FS_MESSAGE>.
    ELSE.
      <FS_ICON>    = ICON_LED_RED.                "红灯
    ENDIF.

    MODIFY <FS_TAB_ALV> FROM <FS_ALV>.

    CLEAR:
      LT_REQ_SCHE_ITEM,
      LT_RETURN,
      LS_MARA,
      LV_VERVS,
      LS_PBIM.
  ENDLOOP.

  IF LV_SELNUM = 0.
*   请至少选择一行数据!
    MESSAGE S041(ZMSG01) DISPLAY LIKE 'E'.
    RETURN.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_GET_FULLPATH
*&---------------------------------------------------------------------*
*& 获取模板保存路径
*&---------------------------------------------------------------------*
*&      <-- CV_FULLPATH    完整路径
*&      <-- CV_PATH        文件路径
*&---------------------------------------------------------------------*
FORM FRM_GET_FULLPATH  CHANGING CV_FULLPATH
                                CV_PATH.
  DATA:
    LV_INIT_PATH  TYPE STRING,
    LV_INIT_FNAME TYPE STRING,
    LV_PATH       TYPE STRING,
    LV_FILENAME   TYPE STRING,
    LV_FULLPATH   TYPE STRING.

* 初始名称(计划独立需求导入模板.XLSX)
  CONCATENATE TEXT-010
              S_DATUM-LOW
              '~'
              S_DATUM-HIGH
               '.xlsx'
         INTO LV_INIT_FNAME.

* 获取桌面路径
  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 SY-SUBRC <> 0.
    EXIT.
  ENDIF.

* 用户选择名称、路径
  CALL METHOD CL_GUI_FRONTEND_SERVICES=>FILE_SAVE_DIALOG
    EXPORTING
      DEFAULT_FILE_NAME    = LV_INIT_FNAME
      FILE_FILTER          = CL_GUI_FRONTEND_SERVICES=>FILETYPE_EXCEL
      INITIAL_DIRECTORY    = LV_INIT_PATH
      PROMPT_ON_OVERWRITE  = 'X'
    CHANGING
      FILENAME             = LV_FILENAME
      PATH                 = LV_PATH
      FULLPATH             = LV_FULLPATH
*     USER_ACTION          =
*     FILE_ENCODING        =
    EXCEPTIONS
      CNTL_ERROR           = 1
      ERROR_NO_GUI         = 2
      NOT_SUPPORTED_BY_GUI = 3
      OTHERS               = 4.
  IF SY-SUBRC = 0.
    CV_FULLPATH = LV_FULLPATH.
    CV_PATH     = LV_PATH.
  ENDIF.
ENDFORM.                    " FRM_GET_FULLPATH
*&---------------------------------------------------------------------*
*& Form FRM_CRT_EXCEL2
*&---------------------------------------------------------------------*
*& 使用OLE下载动态模板
*&---------------------------------------------------------------------*
*&      --> LV_FULLPATH
*&      --> LV_PATH
*&---------------------------------------------------------------------*
FORM FRM_CRT_EXCEL2  USING UV_FULLPATH
                           UV_PATH.
* 下载模版文件
  PERFORM FRM_DOWNLOAD_FROM_SERVER USING UV_FULLPATH.

* 打开excel
  PERFORM FRM_OPEN_EXCEL USING UV_FULLPATH.

* 动态填充数据
  PERFORM FRM_FILL_SHEET .

* 保存文件
  CALL METHOD OF MYWORKBOOK 'SAVE'.

* 关闭文件
  CALL METHOD OF MYWORKBOOK 'CLOSE'.

* 退出excel
  CALL METHOD OF MYEXCEL 'QUIT'.

* 释放对象
  FREE OBJECT MYSHEET.
  FREE OBJECT MYWORKBOOK.
  FREE OBJECT MYEXCEL.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DOWNLOAD_FROM_SERVER
*&---------------------------------------------------------------------*
*& 下载模版文件
*&---------------------------------------------------------------------*
*&      --> UV_FULLPATH
*&---------------------------------------------------------------------*
FORM FRM_DOWNLOAD_FROM_SERVER  USING UV_FULLPATH.
  DATA:
    LV_MOD      TYPE WWWDATA-OBJID,               "模板对象名
    LS_OBJECT   TYPE WWWDATATAB,                  "模板对象
    LV_FULLPATH TYPE LOCALFILE,                   "完整路径
    LV_RC       TYPE SY-SUBRC.                    "返回码

  LV_MOD      = 'ZPPR005_TEMP'.
  LV_FULLPATH = UV_FULLPATH.

* 查询下载模板
  SELECT SINGLE
         RELID
         OBJID
    FROM WWWDATA
    INTO CORRESPONDING FIELDS OF LS_OBJECT
   WHERE SRTF2 = '0'
     AND OBJID = LV_MOD.                          "smw0对象名称

  IF SY-SUBRC <> 0 OR LS_OBJECT-OBJID = SPACE .
*   模板文件&1不存在,请先使用SMW0进行上传!
    MESSAGE S025(ZMSG01) WITH LV_MOD DISPLAY LIKE 'E'.
    LEAVE LIST-PROCESSING.
  ENDIF.

* 下载模板
  CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
    EXPORTING
      KEY         = LS_OBJECT
      DESTINATION = LV_FULLPATH
    IMPORTING
      RC          = LV_RC.

  IF LV_RC <> 0.
*   模板文件&1下载失败,请联系开发人员!
    MESSAGE S026(ZMSG01) WITH LV_MOD DISPLAY LIKE 'E'.
    LEAVE LIST-PROCESSING.
  ENDIF.

* 下载成功!
  MESSAGE S027(ZMSG01).
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_OPEN_EXCEL
*&---------------------------------------------------------------------*
*& 打开excel
*&---------------------------------------------------------------------*
*&      --> UV_FULLPATH
*&---------------------------------------------------------------------*
FORM FRM_OPEN_EXCEL  USING UV_FULLPATH.
* 打开excel应用
  CREATE OBJECT MYEXCEL 'EXCEL.APPLICATION'.

  SET PROPERTY OF MYEXCEL 'VISIBLE' = 0 .         "0代表后台运行,1代表前台运行

* 获取工作簿。
  CALL METHOD OF MYEXCEL 'WORKBOOKS' = MYWORKBOOK.

* 打开工作簿
  CALL METHOD OF MYWORKBOOK 'OPEN'
    EXPORTING
      #1 = UV_FULLPATH.

* 设置活动的工作簿。
  GET PROPERTY OF MYEXCEL 'ACTIVEWORKBOOK' = MYWORKBOOK.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_FILL_SHEET
*&---------------------------------------------------------------------*
*& 动态填充数据
*&---------------------------------------------------------------------*
FORM FRM_FILL_SHEET .
  DATA:
    LV_DAYS      TYPE TFMATAGE,
    LV_DATE      TYPE DATUM,
    LV_FIELDNAME TYPE CHAR12,
    LT_TITLE     TYPE STANDARD TABLE OF CHAR2000,
    LS_TITLE     LIKE LINE OF LT_TITLE,
    LV_RC        TYPE I.

* 设置sheet页名称
  CALL METHOD OF MYEXCEL 'WORKSHEETS' = MYSHEET
    EXPORTING
    #1 = TEXT-010.                                "计划独立需求导入模板

  CALL METHOD OF MYSHEET 'ACTIVATE'.

* 获取日期区间天数
  CALL FUNCTION 'FIMA_DAYS_AND_MONTHS_AND_YEARS'
    EXPORTING
      I_DATE_FROM = S_DATUM-LOW
      I_DATE_TO   = S_DATUM-HIGH
    IMPORTING
      E_DAYS      = LV_DAYS.

  LV_DATE = S_DATUM-LOW.

  DO LV_DAYS + 1 TIMES.
    WRITE LV_DATE TO LV_FIELDNAME USING EDIT MASK '____/__/__'.

    IF LS_TITLE IS INITIAL.
      LS_TITLE = LV_FIELDNAME.
    ELSE.
      CONCATENATE LS_TITLE
                  LV_FIELDNAME
             INTO LS_TITLE
        SEPARATED BY CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB.
    ENDIF.

    LV_DATE = LV_DATE + 1.
  ENDDO.

  APPEND LS_TITLE TO LT_TITLE.

* 将内容复制进粘贴板
  CALL METHOD CL_GUI_FRONTEND_SERVICES=>CLIPBOARD_EXPORT
    IMPORTING
      DATA                 = LT_TITLE
    CHANGING
      RC                   = LV_RC
    EXCEPTIONS
      CNTL_ERROR           = 1
      ERROR_NO_GUI         = 2
      NOT_SUPPORTED_BY_GUI = 3
      OTHERS               = 4.

  CALL METHOD OF MYEXCEL 'CELLS' = MYCELL
    EXPORTING
      #1 = 1                                      "行
      #2 = 6.                                     "列

* 内容粘贴
  CALL METHOD OF MYCELL 'PASTESPECIAL'.

* 选中范围
  CALL METHOD OF MYEXCEL 'RANGE' = MYRANGE
    EXPORTING
      #1 = 'F1'                                   "开始单元格
      #2 = 'EO1'.                                 "结束单元格

* 更改列宽
  SET PROPERTY OF MYRANGE 'COLUMNWIDTH' = '12'.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CREATE_UPLOAD_TAB
*&---------------------------------------------------------------------*
*& 创建上传模板动态内表
*&---------------------------------------------------------------------*
FORM FRM_CREATE_UPLOAD_TAB .
  DATA:
    LT_COMPONENTS TYPE ABAP_COMPONENT_TAB,
    LO_STRUC      TYPE REF TO CL_ABAP_STRUCTDESCR,
    LO_TABLE      TYPE REF TO CL_ABAP_TABLEDESCR,
    LO_WS         TYPE REF TO DATA,
    LO_TAB        TYPE REF TO DATA,
    LV_INDEX      TYPE I,
    LV_FNAME      TYPE STRING.

* 添加模板固定列:物料
  PERFORM FRM_CHANGE_COMP USING 'MATNR'
                                'CHAR30'
                       CHANGING LT_COMPONENTS.
* 添加模板固定列:工厂
  PERFORM FRM_CHANGE_COMP USING 'WERKS'
                                'CHAR30'
                       CHANGING LT_COMPONENTS.
* 添加模板固定列:版本
  PERFORM FRM_CHANGE_COMP USING 'VERSB'
                                'CHAR30'
                      CHANGING LT_COMPONENTS.
* 添加模板固定列:需求计划
  PERFORM FRM_CHANGE_COMP USING 'PBDNR'
                                'CHAR30'
                       CHANGING LT_COMPONENTS.
* 添加模板固定列:激活标识
  PERFORM FRM_CHANGE_COMP USING 'VERVS'
                                'CHAR30'
                       CHANGING LT_COMPONENTS.

* 添加动态列(预留一年天数)
  DO 365 TIMES.
    ADD 1 TO LV_INDEX.
    LV_FNAME = |FIELD{ LV_INDEX }|.

*   添加动态列:需求数量
    PERFORM FRM_CHANGE_COMP USING LV_FNAME
                                  'CHAR30'
                         CHANGING LT_COMPONENTS.
  ENDDO.

  TRY.
*     获取工作区类型
      CALL METHOD CL_ABAP_STRUCTDESCR=>CREATE
        EXPORTING
          P_COMPONENTS = LT_COMPONENTS
        RECEIVING
          P_RESULT     = LO_STRUC.
    CATCH CX_SY_STRUCT_CREATION.
  ENDTRY.

  TRY.
*     获取表类型
      CALL METHOD CL_ABAP_TABLEDESCR=>CREATE
        EXPORTING
          P_LINE_TYPE = LO_STRUC
        RECEIVING
          P_RESULT    = LO_TABLE.
    CATCH CX_SY_TABLE_CREATION.
  ENDTRY.

  CREATE DATA LO_TAB TYPE HANDLE LO_TABLE.
  CREATE DATA LO_WS  TYPE HANDLE LO_STRUC.

  ASSIGN LO_TAB->* TO <FS_TAB_UPLOAD>.
  ASSIGN LO_WS->* TO <FS_UPLOAD>.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CHANGE_COMP
*&---------------------------------------------------------------------*
*& 添加动态字段
*&---------------------------------------------------------------------*
*&      --> UV_FNAME
*&      --> UV_REF_FIELD
*&      <-- CT_COMPONENTS
*&---------------------------------------------------------------------*
FORM FRM_CHANGE_COMP  USING    VALUE(UV_FNAME)
                               VALUE(UV_REF_FIELD)
                      CHANGING CT_COMPONENTS TYPE ABAP_COMPONENT_TAB.
  DATA:
    LO_TYPE       TYPE REF TO CL_ABAP_TYPEDESCR,
    LS_COMPOMENTS TYPE ABAP_COMPONENTDESCR.

  LS_COMPOMENTS-NAME = UV_FNAME.

  CALL METHOD CL_ABAP_DATADESCR=>DESCRIBE_BY_NAME
    EXPORTING
      P_NAME         = UV_REF_FIELD
    RECEIVING
      P_DESCR_REF    = LO_TYPE
    EXCEPTIONS
      TYPE_NOT_FOUND = 1
      OTHERS         = 2.

  LS_COMPOMENTS-TYPE ?= LO_TYPE.
  APPEND LS_COMPOMENTS TO CT_COMPONENTS.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_CREATE_DYN_ALV
*&---------------------------------------------------------------------*
*& 构建动态ALV
*&---------------------------------------------------------------------*
FORM FRM_CREATE_DYN_ALV .
  DATA:
    LO_TAB       TYPE REF TO DATA,
    LO_WS        TYPE REF TO DATA,
    LV_INDEX     TYPE I,
    LV_DATEFNAME TYPE CHAR9,
    LT_SPLIT     TYPE STANDARD TABLE OF STRING,
    LV_YEAR      TYPE N LENGTH 4,
    LV_MONTH     TYPE N LENGTH 2,
    LV_DAY       TYPE N LENGTH 2,
    LV_COL_POS   TYPE LVC_COLPOS.

  CLEAR <FS_UPLOAD>.
  READ TABLE <FS_TAB_UPLOAD> INTO <FS_UPLOAD> INDEX 1.

* 设置字段控制(固定列部分)
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      I_STRUCTURE_NAME       = 'ZSPP_ALV_STRUC_003'
      I_BYPASSING_BUFFER     = 'X'
    CHANGING
      CT_FIELDCAT            = GT_FIELDCAT
    EXCEPTIONS
      INCONSISTENT_INTERFACE = 1
      PROGRAM_ERROR          = 2
      OTHERS                 = 3.

  READ TABLE GT_FIELDCAT ASSIGNING FIELD-SYMBOL(<FS_FIELDCAT>)  "选择框
    WITH KEY FIELDNAME = 'CBOX'.
  IF SY-SUBRC = 0.
    <FS_FIELDCAT>-NO_OUT = 'X'.
    <FS_FIELDCAT>-TECH   = 'X'.
  ENDIF.

* 从第6列开始为动态列
  LV_INDEX = 6.
  LV_COL_POS = LINES( GT_FIELDCAT ).

  DO.
    ASSIGN COMPONENT LV_INDEX OF STRUCTURE <FS_UPLOAD> TO FIELD-SYMBOL(<FS_FIELD>).
    IF <FS_FIELD> IS NOT INITIAL.
      SPLIT <FS_FIELD> AT '/' INTO TABLE LT_SPLIT.
      READ TABLE LT_SPLIT INTO DATA(LS_SPLIT) INDEX 1.
      LV_YEAR = LS_SPLIT.
      READ TABLE LT_SPLIT INTO LS_SPLIT INDEX 2.
      LV_MONTH = LS_SPLIT.
      READ TABLE LT_SPLIT INTO LS_SPLIT INDEX 3.
      LV_DAY = LS_SPLIT.

      LV_DATEFNAME = |D{ LV_YEAR }{ LV_MONTH }{ LV_DAY }|.
      ADD 1 TO LV_COL_POS.

*     添加数量字段
      PERFORM FRM_ADD_FIELDCAT USING <FS_FIELD>
                                     LV_DATEFNAME
                                     'PBED'
                                     'PLNMG'
                                     LV_COL_POS.
      ADD 1 TO LV_INDEX.
    ELSE.
      EXIT.
    ENDIF.
    CLEAR:
      LT_SPLIT.
  ENDDO.

  CALL METHOD CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE
    EXPORTING
      IT_FIELDCATALOG           = GT_FIELDCAT
    IMPORTING
      EP_TABLE                  = LO_TAB
    EXCEPTIONS
      GENERATE_SUBPOOL_DIR_FULL = 1
      OTHERS                    = 2.

  ASSIGN LO_TAB->* TO <FS_TAB_ALV>.
  CREATE DATA LO_WS LIKE LINE OF <FS_TAB_ALV>.
  ASSIGN LO_WS->* TO <FS_ALV>.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_MAPPING_DATA
*&---------------------------------------------------------------------*
*& 数据映射
*&---------------------------------------------------------------------*
FORM FRM_MAPPING_DATA .
  DATA:
    LV_INDEX_FILE TYPE I,
    LV_INDEX_ALV  TYPE I,
    LT_PBIM       TYPE TY_TAB_PBIM,
    LS_PBIM       TYPE TY_PBIM,
    LV_VERSB      TYPE VERSB.

  LOOP AT <FS_TAB_UPLOAD> INTO <FS_UPLOAD> FROM 2.
    ASSIGN COMPONENT 'MATNR' OF STRUCTURE <FS_UPLOAD> TO FIELD-SYMBOL(<FS_FIELD>).
    ASSIGN COMPONENT 'MATNR' OF STRUCTURE <FS_ALV> TO FIELD-SYMBOL(<FS_ALV_FIELD>).
    CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
      EXPORTING
        INPUT        = <FS_FIELD>
      IMPORTING
        OUTPUT       = <FS_ALV_FIELD>             "物料
      EXCEPTIONS
        LENGTH_ERROR = 1
        OTHERS       = 2.
    LS_PBIM-MATNR = <FS_ALV_FIELD>.

    ASSIGN COMPONENT 'WERKS' OF STRUCTURE <FS_UPLOAD> TO <FS_FIELD>.
    ASSIGN COMPONENT 'WERKS' OF STRUCTURE <FS_ALV> TO <FS_ALV_FIELD>.
    <FS_ALV_FIELD> = <FS_FIELD>.                  "工厂
    LS_PBIM-WERKS = <FS_FIELD>.

    ASSIGN COMPONENT 'VERSB' OF STRUCTURE <FS_UPLOAD> TO <FS_FIELD>.
    ASSIGN COMPONENT 'VERSB' OF STRUCTURE <FS_ALV> TO <FS_ALV_FIELD>.
    LV_VERSB = |{ <FS_FIELD> ALPHA = IN }|.
    <FS_ALV_FIELD> = LV_VERSB.                    "版本
    LS_PBIM-VERSB = LV_VERSB.

    ASSIGN COMPONENT 'PBDNR' OF STRUCTURE <FS_UPLOAD> TO <FS_FIELD>.
    ASSIGN COMPONENT 'PBDNR' OF STRUCTURE <FS_ALV> TO <FS_ALV_FIELD>.
    <FS_ALV_FIELD> = <FS_FIELD>.                  "需求计划
    LS_PBIM-PBDNR = <FS_FIELD>.

    ASSIGN COMPONENT 'VERVS' OF STRUCTURE <FS_UPLOAD> TO <FS_FIELD>.
    ASSIGN COMPONENT 'VERVS' OF STRUCTURE <FS_ALV> TO <FS_ALV_FIELD>.
    <FS_ALV_FIELD> = <FS_FIELD>.                  "激活标识

*   从第6列开始为动态列(文件)
    LV_INDEX_FILE = 6.

*   从第9列开始为动态列(ALV)
    LV_INDEX_ALV  = 9.

    DO.
      ASSIGN COMPONENT LV_INDEX_FILE OF STRUCTURE <FS_UPLOAD> TO <FS_FIELD>.
      IF <FS_FIELD> IS ASSIGNED.
        ASSIGN COMPONENT LV_INDEX_ALV OF STRUCTURE <FS_ALV> TO <FS_ALV_FIELD>.
        <FS_ALV_FIELD> = <FS_FIELD>.
        ADD 1 TO LV_INDEX_FILE.
        ADD 1 TO LV_INDEX_ALV.
      ELSE.
        EXIT.
      ENDIF.
      UNASSIGN <FS_FIELD>.
    ENDDO.

    APPEND <FS_ALV> TO <FS_TAB_ALV>.
    APPEND LS_PBIM TO LT_PBIM.
    CLEAR:
      <FS_ALV>,
      LS_PBIM.
  ENDLOOP.

* 获取已存在的独立需求计划
  SELECT MATNR                                    "物料
         WERKS                                    "工厂
         BEDAE                                    "需求类型
         VERSB                                    "版本
         PBDNR                                    "需求计划
    INTO TABLE GT_PBIM
    FROM PBIM
     FOR ALL ENTRIES IN LT_PBIM
   WHERE MATNR = LT_PBIM-MATNR
     AND WERKS = LT_PBIM-WERKS
     AND BEDAE = 'VSF'
     AND VERSB = LT_PBIM-VERSB
     AND PBDNR = LT_PBIM-PBDNR
     AND LOEVR <> 'D'.

* 获取物料基本单位
  SELECT MATNR
         MEINS
    INTO TABLE GT_MARA
    FROM MARA
     FOR ALL ENTRIES IN LT_PBIM
   WHERE MATNR = LT_PBIM-MATNR.

  SORT GT_PBIM BY MATNR ASCENDING
                  WERKS ASCENDING
                  BEDAE ASCENDING
                  VERSB ASCENDING
                  PBDNR ASCENDING.
  SORT GT_MARA BY MATNR ASCENDING.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_ADD_FIELDCAT
*&---------------------------------------------------------------------*
*& 添加数量字段
*&---------------------------------------------------------------------*
*&      --> UV_FIELDDESC   字段描述
*&      --> UV_FIELDNAME   字段名
*&      --> UV_REF_TABLE   参考表
*&      --> UV_REF_FIELD   参考字段
*&      --> UV_COLPOS      列位置
*&---------------------------------------------------------------------*
FORM FRM_ADD_FIELDCAT  USING    UV_FIELDDESC
                                UV_FIELDNAME
                                VALUE(UV_REF_TABLE)
                                VALUE(UV_REF_FIELD)
                                UV_COLPOS.

  GS_FIELDCAT-FIELDNAME = UV_FIELDNAME.
  GS_FIELDCAT-COL_POS   = UV_COLPOS.
  GS_FIELDCAT-REPTEXT   = UV_FIELDDESC.
  GS_FIELDCAT-SCRTEXT_L = UV_FIELDDESC.
  GS_FIELDCAT-SCRTEXT_M = UV_FIELDDESC.
  GS_FIELDCAT-SCRTEXT_S = UV_FIELDDESC.
  GS_FIELDCAT-REF_TABLE = UV_REF_TABLE.
  GS_FIELDCAT-REF_FIELD = UV_REF_FIELD.
  APPEND GS_FIELDCAT TO GT_FIELDCAT.
  CLEAR GS_FIELDCAT.
ENDFORM.

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DeveloperMrMeng

觉得有用的佛系投币哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值