ABAP 批导模板(项目+WBS)

该ABAP程序用于读取Excel文件中的项目和WBS元素数据,进行数据验证,然后在ALV表格中展示。程序包括Excel文件上传、数据读取、字段映射、ALV控制台配置以及项目和WBS元素的创建或更新操作。
摘要由CSDN通过智能技术生成
********************************************************************
* 事务代码:                                                *
* 程序名称:                                                *
* 程序目的:                                       *
* 设 计 人:                                                  *
* 开 发 人:                                                  *
* 设计时间:2022-09-26                                             *
* 程序类型: ABAP/4 程序 ,批导程序                                 *
* 应用类型: FI                                                     *
* 描    述:                                        *
*(修改日志)--------------------------------------------------------*
*                                                                  *
* 日志号   修改人  修改时间       修改说明              传输号码   *
*  ----    ----    ------         -----------
********************************************************************

REPORT zfib002.

*----------------------------------------------------------------------*
* 数据库表声明/Database Table Declaration
*----------------------------------------------------------------------*
TABLES: sscrfields. " 选择屏幕上的字段

*&---------------------------------------------------------------------*
*&  ALV TYPE/ALV 类型定义
*&---------------------------------------------------------------------*
*&---ALV数据组,类型池
TYPE-POOLS:slis,
           vrm.

*----------------------------------------------------------------------*
* 结构声明类型/Structure Type Declaration
*----------------------------------------------------------------------*
*&--- 全局结构体与内表声明
*&---Excel导入数据
TYPES:BEGIN OF ty_excel,

        light     TYPE  c LENGTH 4,     " 信号灯
        msg       TYPE  string    ,    " 导入结果

        " 项目
        vbukr     TYPE proj-vbukr     , " 项目的公司代码
        werks     TYPE proj-werks     , " 工厂
        pspnr     TYPE proj-pspid     , " 项目定义
        post1     TYPE proj-post1     , " 项目描述
        profl     TYPE proj-profl     , " 项目参数文件
        plfaz     TYPE proj-plfaz     , " 项目计划开始日期
        plsez     TYPE proj-plsez     , " 项目计划完成日期

        " WBS元素
        level     TYPE c LENGTH 1     , " 层级
        posid1    TYPE prps-posid     , " 一层WBS
        posid2    TYPE prps-posid     , " 二层WBS
        posid3    TYPE prps-posid     , " 三层WBS
        prart     TYPE prps-prart     , " WBS类型
        post2     TYPE prps-post1     , " WBS描述
        poski     TYPE prps-poski     , " 短标识

      END OF ty_excel.

*----------------------------------------------------------------------*
* CONSTANTS/(全局)常量                                               *
*----------------------------------------------------------------------*

*----------------------------------------------------------------------*
* 全局变量定义/Global variable definition
*----------------------------------------------------------------------*
*&---全局内表定义
DATA:gt_excel  TYPE STANDARD TABLE OF ty_excel.   " Excel导入表

*&---全局结构定义
DATA:gs_excel  TYPE ty_excel.           " Excel导入结构

*&---------------------------------------------------------------------*
*& 字段串定义/Field-symbols                                            *
*&---------------------------------------------------------------------*
FIELD-SYMBOLS:<fs_excel>  TYPE ty_excel.

*&---------------------------------------------------------------------*
*&  ALV TYPE/ALV 类型定义
*&---------------------------------------------------------------------*
*&---ALV数据组,类型池
TYPE-POOLS:slis,
           vrm.

DATA:gt_fieldcat TYPE STANDARD TABLE OF lvc_s_fcat, " ALV 控制: 字段目录
     gs_fieldcat TYPE lvc_s_fcat,          " ALV 控制: 字段目录
     gs_layout   TYPE lvc_s_layo.          " ALV 控制: 布局结构
DATA:gs_functxt  TYPE smp_dyntxt .

*----------------------------------------------------------------------*
* Excel 导入所需传入与接收参数定义                                          *
*----------------------------------------------------------------------*
DATA: gv_filepath TYPE string.                          " 保存文件路径

FIELD-SYMBOLS: <fs_unit> LIKE  alsmex_tabline.          " Excel 单元格
FIELD-SYMBOLS: <fs_value> TYPE any.

DATA: gv_lines LIKE sy-index VALUE 2.                   " Excel 数据的行数
DATA: gv_index LIKE sy-index VALUE 1.                   " Message 表的序号
DATA: gv_sign TYPE c.                                   " Excel 一行是否写入成功的标志
DATA: gv_succ LIKE sy-index.                            " 成功更新条数
DATA: gv_fail TYPE i VALUE 0.                           " 失败的行数
DATA: gv_flag TYPE char1.                               " 标记
DATA: gt_xlstmp TYPE alsmex_tabline OCCURS 0.           " 保存 Excel 中读取的记录
DATA: gs_xlstmp TYPE alsmex_tabline.           " 保存 Excel 中读取的记录

*&---------------------------------------------------------------------*
*&  Macro 宏定义
*&---------------------------------------------------------------------*
DEFINE mcr_set_catalog.
  gs_fieldcat-fieldname  = &1. " 字段技术名称
  gs_fieldcat-coltext    = &2. " 显示名称
  gs_fieldcat-ref_table  = &3. " 参照表
  gs_fieldcat-ref_field  = &4. " 参照表字段
  gs_fieldcat-qfieldname = &5. " 参考计量单位的字段名称
  gs_fieldcat-key        = &6. " key 值
  gs_fieldcat-edit       = &7. " 可编辑

  APPEND gs_fieldcat TO gt_fieldcat.
  CLEAR  gs_fieldcat.
END-OF-DEFINITION.

*&---------------------------------------------------------------------*
*& SELECTION SCREEN/选择屏幕                                            *
*&---------------------------------------------------------------------*
*&--- 选择屏幕块
SELECTION-SCREEN BEGIN OF BLOCK block0 WITH FRAME TITLE TEXT-101. " 上传文件

SELECTION-SCREEN: FUNCTION KEY 1. "菜单栏下载模板

PARAMETERS: p_fname LIKE rlgrap-filename.    " 输入文件路径

SELECTION-SCREEN END OF BLOCK block0.

*&---------------------------------------------------------------------*
*& INITIALIZATION/选择屏幕前初始化                                     *
*&---------------------------------------------------------------------*
INITIALIZATION.
*&---设置选择屏幕菜单栏按钮--下载模板
  gs_functxt = VALUE #(
    icon_id = icon_export
    quickinfo = TEXT-001 " 下载模板
    icon_text = TEXT-001 " 下载模板
  ).
  sscrfields-functxt_01 = gs_functxt.

*&---------------------------------------------------------------------*
*& at selection-screen/选择屏幕开始                                    *
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN.
  CASE sy-ucomm.
    WHEN 'FC01'.  " 下载模板
      PERFORM frm_download_template.
    WHEN OTHERS.
  ENDCASE.

*&---------------------------------------------------------------------*
*& AT SELECTION-SCREEN ON VALUE-REQUEST/F4 Search Help                 *
*&---------------------------------------------------------------------*
*&--- 上传文件 F4 路径帮助
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_fname.
  CALL FUNCTION 'F4_FILENAME'
    EXPORTING
      program_name  = sy-cprog
      dynpro_number = sy-dynnr
    IMPORTING
      file_name     = p_fname.

  CLEAR gv_filepath.
  gv_filepath = p_fname.
  " 判断是否为 XLS文件
  SEARCH  gv_filepath  FOR '.xls'.
  IF sy-subrc <> 0.
    MESSAGE s006(zfico01) DISPLAY LIKE 'E'. " 上传文件类型错误,请选择XLS文件
    STOP.
  ENDIF.

*&---------------------------------------------------------------------*
*& START-OF-SELECTION/开始选择屏幕                                       *
*&---------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM frm_check_excel.       " Excel 是否上传校验

*&---------------------------------------------------------------------*
*& END-OF-SELECTION/结束选择屏幕(程序结束处理,输出等)                     *
*&---------------------------------------------------------------------*
END-OF-SELECTION.
  IF gt_excel IS NOT INITIAL.
    PERFORM frm_display_data.    " ALV 数据展示
  ELSE.
    MESSAGE s007(zfico01) DISPLAY LIKE 'E'. " 导入文件为空,请检查
  ENDIF.

*&---------------------------------------------------------------------*
*& Form FRM_CHECK_EXCEL
*&---------------------------------------------------------------------*
*& Excel 是否上传校验
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_check_excel .
  DATA lv_flag(1).
  IF p_fname IS INITIAL.
    MESSAGE s008(zfico01) DISPLAY LIKE 'E'. " 文件路径不能为空
    LEAVE LIST-PROCESSING.
  ENDIF.

  PERFORM frm_read_excel. " 读取 Excel 文件数据
*  PERFORM frm_read_excel_new. " 读取 Excel 文件数据
ENDFORM.                    " FRM_CHECK_EXCEL

*&---------------------------------------------------------------------*
*& Form FRM_READ_EXCEL
*&---------------------------------------------------------------------*
*& 读取 Excel 文件数据
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_read_excel .
  DATA lv_value(255) TYPE c.
  DATA lv_flag       TYPE char1.
  DATA lv_count      LIKE sy-subrc.
  DATA lv_message    TYPE string.

  REFRESH gt_xlstmp.
  " 读取 EXCEL 文件数据
  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
    EXPORTING
      filename                = p_fname
      i_begin_col             = 1
      i_begin_row             = 2         "	从第 4 行开始 读取
      i_end_col               = 14         " 结束列
      i_end_row               = 65536     " 结束行
    TABLES
      intern                  = gt_xlstmp " 存储读取的记录 行、列、值
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.
  IF sy-subrc <> 0 .
    MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno DISPLAY LIKE sy-msgty
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    STOP.
  ENDIF.

*&--- 将读取到的记录存储到 gt_excel 内表中
  CLEAR gt_excel.
  SORT gt_xlstmp BY row col .
  " 循环赋值
  LOOP AT gt_xlstmp ASSIGNING <fs_unit>.
    ASSIGN COMPONENT <fs_unit>-col  OF STRUCTURE <fs_unit> TO <fs_value> .
    lv_value = <fs_unit>-value .
    CONDENSE lv_value.
    CASE <fs_unit>-col. " 判断当前列,并赋值到对应技术字段
      WHEN 1.
        gs_excel-vbukr  = lv_value. " 项目公司代码
      WHEN 2.
        gs_excel-werks  = lv_value. " 工厂
      WHEN 3.
        gs_excel-pspnr  = lv_value. " 项目定义
      WHEN 4.
        gs_excel-post1  = lv_value. " 短描述
      WHEN 5.
        gs_excel-profl  = lv_value. " 项目参数文件
      WHEN 6.
        CALL FUNCTION 'CONVERT_DATE_TO_INTERNAL'
          EXPORTING
            date_external = lv_value "当前用户日期格式:YYYY.MM.DD
          IMPORTING
            date_internal = lv_value.
        gs_excel-plfaz  = lv_value. " 项目计划开始日期
      WHEN 7.
        CALL FUNCTION 'CONVERT_DATE_TO_INTERNAL'
          EXPORTING
            date_external = lv_value "当前用户日期格式:YYYY.MM.DD
          IMPORTING
            date_internal = lv_value.
        gs_excel-plsez  = lv_value. " 项目计划结束日期
      WHEN 8.
        gs_excel-level  = lv_value. " 层级
      WHEN 9.
        gs_excel-posid1 = lv_value. " 一层WBS
      WHEN 10.
        gs_excel-posid2 = lv_value. " 二层WBS
      WHEN 11.
        gs_excel-posid3 = lv_value. " 三层WBS
      WHEN 12.
        gs_excel-prart  = lv_value. " WBS类型
      WHEN 13.
        gs_excel-post2  = lv_value. " WBS描述
      WHEN 14.
        gs_excel-poski  = lv_value. " 短标识

    ENDCASE.
    AT END OF row.
      gs_excel-light = icon_light_out. " 熄灯
      APPEND gs_excel TO gt_excel.
      CLEAR gs_excel.
    ENDAT.
  ENDLOOP.

  SORT gt_excel BY pspnr.

ENDFORM.                    " FRM_READ_EXCEL

*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY_DATA
*&---------------------------------------------------------------------*
*& ALV 展示数据
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_display_data .
  PERFORM frm_build_fieldcat.   " 配置 ALV 字段目录
  PERFORM frm_build_layout.     " 构建 ALV 布局样式

*&--- 调用 ALV 展示数据
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'FRM_PF_STATUS'
      i_callback_user_command  = 'FRM_USER_COMMAND'
      is_layout_lvc            = gs_layout
      it_fieldcat_lvc          = gt_fieldcat
      i_save                   = 'A'            " 标准保存模式
    TABLES
      t_outtab                 = gt_excel        " 内表数据
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno DISPLAY LIKE sy-msgty
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.                    " FRM_DISPLAY_DATA

*&---------------------------------------------------------------------*
*& Form FRM_PF_STATUS
*&---------------------------------------------------------------------*
*& ALV 工具栏状态
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_pf_status USING ps_extab TYPE slis_t_extab.
  SET PF-STATUS 'STATUS_1000'.
ENDFORM. " FRM_PF_STATUS

*&---------------------------------------------------------------------*
*&      Form  frm_user_command
*&---------------------------------------------------------------------*
*       菜单栏事件
*----------------------------------------------------------------------*
*  -->  pv_ucomm        触发的功能码
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_user_command USING pv_ucomm LIKE sy-ucomm  "user_command
                            pv_selfield TYPE slis_selfield.

  DATA: lr_grid TYPE REF TO cl_gui_alv_grid.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid = lr_grid.

  CALL METHOD lr_grid->check_changed_data. "将更新后的数据传到alv所对应的内表

  pv_selfield-refresh = 'X'. "刷新数据

  CASE pv_ucomm.
    WHEN 'IMPORT'.
      PERFORM frm_value_check.
      PERFORM frm_import.
  ENDCASE.

ENDFORM.                  " FRM_USER_COMMAND

*&---------------------------------------------------------------------*
*& Form frm_import
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_import .

  DATA: lt_head TYPE STANDARD TABLE OF ty_excel.

  " 筛选项目
  lt_head = gt_excel.
  SORT lt_head BY pspnr.
  DELETE ADJACENT DUPLICATES FROM lt_head COMPARING pspnr.

  SELECT
    pspid
  FROM proj
  FOR ALL ENTRIES IN @gt_excel
  WHERE
    pspid = @gt_excel-pspnr
  INTO TABLE @DATA(lt_proj).
  SORT lt_proj BY pspid.

  " 项目导入
  LOOP AT lt_head INTO gs_excel WHERE light = icon_light_out. " 导入熄灯项目

    READ TABLE lt_proj TRANSPORTING NO FIELDS WITH KEY gs_excel-pspnr BINARY SEARCH.
    IF sy-subrc = 0. " 项目已创建
      gs_excel-light = icon_yellow_light.  " 黄灯
      gs_excel-msg   = TEXT-m01.  " 项目已创建;
      MODIFY gt_excel FROM gs_excel TRANSPORTING light msg WHERE pspnr = gs_excel-pspnr.
    ELSE. " 项目未创建
      PERFORM frm_porj_create.
      MODIFY gt_excel FROM gs_excel TRANSPORTING light msg WHERE pspnr = gs_excel-pspnr.
      CLEAR gs_excel.
    ENDIF.

  ENDLOOP.

  " WBS导入
  PERFORM frm_wbs_create.

  " 检查是否有导入失败行项目
  SORT gt_excel BY light.
  READ TABLE gt_excel TRANSPORTING NO FIELDS WITH KEY light = icon_red_light.
  IF sy-subrc = 0.
    MESSAGE s012(zfico01) DISPLAY LIKE 'E'. " 存在导入失败的行项目,请检查数据
  ENDIF.
  SORT gt_excel BY pspnr level light.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form frm_download_template
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_download_template .
  DATA: lv_filename    TYPE string,
        lv_fullpath    TYPE string,
        lv_path        TYPE string,
        lv_objid       TYPE wwwdatatab-objid,
        ls_objdata     TYPE wwwdatatab,
        lv_destination TYPE rlgrap-filename,
        lv_rc          TYPE i.

  lv_objid    = 'ZFIB008'.
  lv_filename = TEXT-002 && '.xls'. " 项目&WBS元素批导模板

  SELECT SINGLE relid objid INTO CORRESPONDING FIELDS OF ls_objdata
  FROM wwwdata
  WHERE srtf2 = 0 AND relid = 'MI' AND objid = lv_objid.
  IF sy-subrc <> 0.
    MESSAGE e009(zfico01). " 模板不存在,请联系管理员导入
  ENDIF.

  CALL METHOD cl_gui_frontend_services=>file_save_dialog
    EXPORTING
      default_extension = 'XLS'
      default_file_name = lv_filename
      file_filter       = 'EXCEL'
    CHANGING
      filename          = lv_filename
      path              = lv_path
      fullpath          = lv_fullpath
    EXCEPTIONS
      OTHERS            = 1.
  IF lv_fullpath = ''.
    MESSAGE e010(zfico01). " 没有选择文件
  ENDIF.

  IF strlen( lv_fullpath ) > 128.
    MESSAGE s011(zfico01) DISPLAY LIKE 'E'. " 文件名长度超过128位,请重新选择文件
    STOP.
  ENDIF.

  lv_destination = lv_fullpath.
  CALL FUNCTION 'DOWNLOAD_WEB_OBJECT'
    EXPORTING
      key         = ls_objdata
      destination = lv_destination
    IMPORTING
      rc          = lv_rc.
  IF lv_rc <> 0.
    MESSAGE e007(zfico01). " 导入文件为空,请检查
  ENDIF.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_BUILD_FIELDCAT
*&---------------------------------------------------------------------*
*& 配置 ALV 字段目录
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_build_fieldcat .
  mcr_set_catalog:  'LIGHT'     TEXT-a01  ''        'LIGHT'      ''  'X'  '', " 信号灯
                    'MSG'       TEXT-a02  ''        'MSG'        ''  'X'  '', " 导入结果
                    'VBUKR'     TEXT-a03  'PROJ'    'VBUKR'      ''  ''   '', " 项目的公司代码
                    'WERKS'     TEXT-a04  'PROJ'    'WERKS'      ''  ''   '', " 工厂
                    'PSPNR'     TEXT-a05  'PROJ'    'PSPID'      ''  ''   '', " 项目定义
                    'POST1'     TEXT-a06  'PROJ'    'POST1'      ''  ''   '', " 项目描述
                    'PROFL'     TEXT-a07  'PROJ'    'PROFL'      ''  ''   '', " 项目参数文件
                    'PLFAZ'     TEXT-a08  'PROJ'    'PLFAZ'      ''  ''   '', " 项目计划开始日期
                    'PLSEZ'     TEXT-a09  'PROJ'    'PLSEZ'      ''  ''   '', " 项目计划完成日期
                    'LEVEL'     TEXT-a15  ''        ''           ''  ''   '', " 层级
                    'POSID1'    TEXT-a19  'PRPS'    'POSID'      ''  ''   '', " 一层WBS
                    'POSID2'    TEXT-a10  'PRPS'    'POSID'      ''  ''   '', " 二层WBS
                    'POSID3'    TEXT-a11  'PRPS'    'POSID'      ''  ''   '', " 三层WBS
                    'PRART'     TEXT-a12  'PRPS'    'PRART'      ''  ''   '', " WBS类型
                    'POST2'     TEXT-a13  'PRPS'    'POST1'      ''  ''   '', " WBS描述
                    'POSKI'     TEXT-a14  'PRPS'    'POSKI'      ''  ''   ''. " 短标识


ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_BUILD_LAYOUT
*&---------------------------------------------------------------------*
*& 构建 ALV 样式布局
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_build_layout .
  CLEAR: gs_layout.
  gs_layout = VALUE #( zebra = 'X'             " ALV 控制: 可选行颜色 (带) - 斑马条纹 - 美观
                       cwidth_opt = 'X'        " 自动调整ALVL列宽
                       no_toolbar = 'X' ).     " ALV 控制: 隐藏工具栏
ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_PORJ_CREATE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_porj_create .
  DATA:
    lv_seqno(6)               TYPE n VALUE '000000',
    lt_message                TYPE TABLE OF bapi_meth_message,
    ls_message                TYPE bapi_meth_message,
    ls_return                 TYPE bapireturn1,
    lt_method_project         TYPE TABLE OF bapi_method_project,
    ls_method_project         TYPE bapi_method_project,
    ls_project_definition     LIKE bapi_project_definition,
    ls_project_definition_upd LIKE bapi_project_definition_up.

  "项目定义
  ls_project_definition-project_definition = gs_excel-pspnr.   "项目定义
  ls_project_definition-description        = gs_excel-post1.   "描述
  ls_project_definition-project_profile    = gs_excel-profl.   "项目参数文件
  ls_project_definition-comp_code          = gs_excel-vbukr.   "项目的公司代码
  ls_project_definition-plant              = gs_excel-werks.   "工厂
  ls_project_definition-start              = gs_excel-plfaz.   "项目计划开始日期
  ls_project_definition-finish             = gs_excel-plsez.   "项目计划完成日期

  "项目定义(更新字段)
  ls_project_definition_upd-project_definition = 'X'.   "项目定义
  ls_project_definition_upd-description        = 'X'.   "描述
  ls_project_definition_upd-project_profile    = 'X'.   "项目参数文件
  ls_project_definition_upd-comp_code          = 'X'.   "项目的公司代码
  ls_project_definition_upd-plant              = 'X'.   "工厂
  ls_project_definition_upd-start              = 'X'.   "项目计划开始日期
  ls_project_definition_upd-finish             = 'X'.   "项目计划完成日期

  "项目处理方法创建
  lv_seqno = lv_seqno + 1.
  ls_method_project-refnumber  = lv_seqno.                     "参考号
  ls_method_project-objecttype = co1_type-project_definition.  "对象类型
  ls_method_project-method     = co1_meth-create.              "项目创建
  ls_method_project-objectkey  = gs_excel-pspnr.               "项目定义
  APPEND ls_method_project TO lt_method_project.
  CLEAR ls_method_project.


  "项目处理方法保存
  ls_method_project-method = co1_meth-save.
  APPEND ls_method_project TO lt_method_project.
  CLEAR: ls_method_project.

*  SET UPDATE TASK LOCAL.    "同步执行项目创建
  CALL FUNCTION 'BAPI_PROJECT_MAINTAIN'
    EXPORTING
      i_project_definition     = ls_project_definition
      i_project_definition_upd = ls_project_definition_upd
    IMPORTING
      return                   = ls_return
    TABLES
      i_method_project         = lt_method_project
      e_message_table          = lt_message.

  "回写至ALV每行导入结果
  IF ls_return-type EQ 'E' OR ls_return EQ 'A'. " 项目创建失败

    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

    " 更新消息
    LOOP AT lt_message INTO ls_message.
      gs_excel-msg = gs_excel-msg && ls_message-message_text && ';'.
    ENDLOOP.
    gs_excel-light   = icon_red_light.  " 红灯

  ELSE.

    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        wait = 'X'.

    " 更新日志信息
    gs_excel-msg      = TEXT-m02. " 项目创建成功;
    gs_excel-light    = icon_green_light. " 绿灯

  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_WBS_CREATE
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_wbs_create .

  DATA: lv_tabix TYPE i,
        lt_head  TYPE STANDARD TABLE OF ty_excel.

  DATA:
    lv_project     TYPE bapi_bus2001_new-project_definition,
    lt_wbs_import  TYPE STANDARD TABLE OF bapi_bus2054_new,
    ls_wbs_import  LIKE LINE OF lt_wbs_import,
    lt_wbs_element TYPE STANDARD TABLE OF bapi_bus2054_detail,
    ls_wbs_element LIKE LINE OF lt_wbs_element,
    lt_return      TYPE STANDARD TABLE OF bapiret2,
    ls_return      LIKE LINE OF lt_return.

  DATA:
    lv_seqno(6)               TYPE n VALUE '000000',
    lt_message                TYPE TABLE OF bapi_meth_message,
    ls_message                TYPE bapi_meth_message,
    ls_return1                TYPE bapireturn1,
    lt_method_project         TYPE TABLE OF bapi_method_project,
    ls_method_project         TYPE bapi_method_project,
    ls_project_definition     LIKE bapi_project_definition,
    ls_project_definition_upd LIKE bapi_project_definition_up,
    lt_wbs_update TYPE STANDARD TABLE OF BAPI_WBS_ELEMENT,
    lt_wbs_updatex TYPE STANDARD TABLE OF BAPI_WBS_ELEMENT_UPDATE,
    ls_wbs_update             LIKE BAPI_WBS_ELEMENT,
    ls_wbs_updatex            LIKE BAPI_WBS_ELEMENT_UPDATE.

  " 筛选项目
  lt_head = gt_excel.
  SORT lt_head BY pspnr level light.
  DELETE ADJACENT DUPLICATES FROM lt_head COMPARING pspnr level.
  DELETE lt_head WHERE light = icon_red_light.
  SORT gt_excel BY pspnr level posid3.

  LOOP AT lt_head INTO DATA(ls_head).
    CLEAR:lv_project,lt_wbs_element,lt_return.

    " 项目号
    lv_project = ls_head-pspnr.
    " 获取项目WBS信息
    CALL FUNCTION 'BAPI_BUS2054_GETDATA'
      EXPORTING
        i_project_definition = lv_project
      TABLES
        et_wbs_element       = lt_wbs_element
        et_return            = lt_return.

    " 按项目号,层级,依次创建WBS元素
    READ TABLE gt_excel TRANSPORTING NO FIELDS WITH KEY pspnr = ls_head-pspnr level = ls_head-level BINARY SEARCH.
    IF sy-subrc = 0.
      lv_tabix = sy-tabix.

      " 按层级汇总WBS元素
      CLEAR: lt_wbs_import,lt_method_project,lt_wbs_update,lt_wbs_updatex.
      LOOP AT gt_excel INTO gs_excel FROM lv_tabix.
        IF gs_excel-pspnr <> ls_head-pspnr OR gs_excel-level <> ls_head-level.
          EXIT.
        ENDIF.

        CLEAR ls_wbs_element.
        IF gs_excel-level = '1'.  " 第一层
          ls_wbs_import-wbs_element   = gs_excel-posid1. " WBS元素
        ELSEIF gs_excel-level = '2'. " 第二层
          ls_wbs_import-wbs_up        = gs_excel-posid1. " 上层元素
          ls_wbs_import-wbs_element   = gs_excel-posid1 && '/' && gs_excel-posid2. " WBS元素
        ELSEIF gs_excel-level = '3'. " 第三层
          ls_wbs_import-wbs_up        = gs_excel-posid1 && '/' && gs_excel-posid2. " 上层元素
          ls_wbs_import-wbs_element   = gs_excel-posid1 && '/' && gs_excel-posid2 && '/' && gs_excel-posid3. " WBS元素
        ENDIF.

        ls_wbs_import-description             = gs_excel-post2.  " WBS描述
        ls_wbs_import-PROJ_TYPE               = gs_excel-prart.  " WBS类型
        APPEND ls_wbs_import TO lt_wbs_import.

        " WBS创建后修改简明ID(WBS元素)
        ls_project_definition-project_definition = gs_excel-pspnr.   "项目定义
        ls_project_definition_upd-project_definition = 'X'.          "项目定义
        "项目处理方法更新
        lv_seqno = lv_seqno + 1.
        ls_method_project-refnumber  = lv_seqno.                     "参考号
        ls_method_project-objecttype = co1_type-wbs_element.         "对象类型
        ls_method_project-method     = co1_meth-update.              "项目更新
        ls_method_project-objectkey  = gs_excel-pspnr.               "项目定义
        APPEND ls_method_project TO lt_method_project.
        CLEAR ls_method_project.

        "项目处理方法保存
        ls_method_project-method = co1_meth-save.
        APPEND ls_method_project TO lt_method_project.
        CLEAR: ls_method_project.

        ls_wbs_update-wbs_element             = ls_wbs_import-wbs_element.
        ls_wbs_update-project_definition      = gs_excel-pspnr.
        ls_wbs_update-short_id                = gs_excel-poski.
        APPEND ls_wbs_update TO lt_wbs_update.

        ls_wbs_updatex-short_id               = 'X'.
        APPEND ls_wbs_updatex TO lt_wbs_updatex.

      ENDLOOP.

      " 初始化
      CHECK lt_wbs_import IS NOT INITIAL.
      REFRESH lt_return.
      CALL FUNCTION 'BAPI_PS_INITIALIZATION'.
      " 创建WBS

      CALL FUNCTION 'BAPI_BUS2054_CREATE_MULTI'
        EXPORTING
          i_project_definition = lv_project
        TABLES
          it_wbs_element       = lt_wbs_import
          et_return            = lt_return.
      SORT lt_return BY type message_v1 message_v2.
      READ TABLE lt_return TRANSPORTING NO FIELDS WITH KEY type = 'E' BINARY SEARCH.
      IF sy-subrc <> 0.

        CLEAR:lt_return.
        " 提交\
        SET UPDATE TASK LOCAL.    "同步执行WBS创建
        CALL FUNCTION 'BAPI_PS_PRECOMMIT'
          TABLES
            et_return = lt_return.
        READ TABLE lt_return TRANSPORTING NO FIELDS WITH KEY type = 'E' BINARY SEARCH.
        IF sy-subrc <> 0.
          CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.

          " 更新日志信息
          gs_excel-msg  = gs_excel-msg && TEXT-m03. " WBS创建成功
          gs_excel-light   = icon_green_light.
          MODIFY gt_excel FROM gs_excel TRANSPORTING msg light WHERE pspnr  = ls_head-pspnr AND level = ls_head-level.

*          " 更新简明ID(WBS元素)
*          SET UPDATE TASK LOCAL.    "同步执行WBS创建
*          CALL FUNCTION 'BAPI_PROJECT_MAINTAIN'
*            EXPORTING
*              i_project_definition     = ls_project_definition
*              i_project_definition_upd = ls_project_definition_upd
*            IMPORTING
*              return                   = ls_return1
*            TABLES
*              i_method_project         = lt_method_project
*              e_message_table          = lt_message
*              I_WBS_ELEMENT_TABLE          = lt_wbs_update
*              I_WBS_ELEMENT_TABLE_UPDATE   = lt_wbs_updatex.
*          IF ls_return1-type <> 'E'.
*            CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
*          ELSE.
*            CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
*          ENDIF.
        ELSE.

          CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          " 更新日志信息
          gs_excel-msg  = gs_excel-msg && TEXT-m04. " WBS创建失败
          gs_excel-light   = icon_red_light.

          LOOP AT lt_return INTO ls_return WHERE type = 'E'.
            gs_excel-msg = gs_excel-msg && ls_return-message.
          ENDLOOP.
          MODIFY gt_excel FROM gs_excel TRANSPORTING msg light WHERE pspnr  = ls_head-pspnr AND level = ls_head-level.
        ENDIF.

      ELSE.

        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
        " 更新日志信息
        gs_excel-msg  = gs_excel-msg && TEXT-m04. " WBS创建失败
        gs_excel-light   = icon_red_light.

        LOOP AT lt_return INTO ls_return WHERE type = 'E'.
          gs_excel-msg = gs_excel-msg && ls_return-message.
        ENDLOOP.
        MODIFY gt_excel FROM gs_excel TRANSPORTING msg light WHERE pspnr  = ls_head-pspnr AND level = ls_head-level.

      ENDIF.
    ENDIF.
  ENDLOOP.

  " 筛选项目
  lt_head = gt_excel.
  SORT lt_head BY pspnr level light.
  DELETE lt_head WHERE light = icon_red_light.
  DELETE ADJACENT DUPLICATES FROM lt_head COMPARING pspnr level.
  SORT gt_excel BY pspnr level posid3.

  LOOP AT lt_head INTO ls_head.
    CLEAR:lv_project,lt_wbs_element,lt_return.

    " 按项目号,层级,依次更新wbs元素短标识
    READ TABLE gt_excel TRANSPORTING NO FIELDS WITH KEY pspnr = ls_head-pspnr level = ls_head-level BINARY SEARCH.
    IF sy-subrc = 0.
      lv_tabix = sy-tabix.

      " 按层级汇总WBS元素
      CLEAR: lt_wbs_import,lt_method_project,lt_wbs_update,lt_wbs_updatex.
      lv_seqno = '000000'.
      LOOP AT gt_excel INTO gs_excel FROM lv_tabix.
        IF gs_excel-pspnr <> ls_head-pspnr OR gs_excel-level <> ls_head-level.
          EXIT.
        ENDIF.
        IF gs_excel-light = icon_red_light.
          CONTINUE.
        ENDIF.

        CLEAR ls_wbs_element.
        IF gs_excel-level = '1'.  " 第一层
          ls_wbs_import-wbs_element   = gs_excel-posid1. " WBS元素
        ELSEIF gs_excel-level = '2'. " 第二层
          ls_wbs_import-wbs_element   = gs_excel-posid1 && '/' && gs_excel-posid2. " WBS元素
        ELSEIF gs_excel-level = '3'. " 第三层
          ls_wbs_import-wbs_element   = gs_excel-posid1 && '/' && gs_excel-posid2 && '/' && gs_excel-posid3. " WBS元素
        ENDIF.

        " WBS创建后修改简明ID(WBS元素)
        ls_project_definition-project_definition = gs_excel-pspnr.   "项目定义
        ls_project_definition_upd-project_definition = 'X'.          "项目定义
        "项目处理方法更新
        lv_seqno = lv_seqno + 1.
        ls_method_project-refnumber  = lv_seqno.                     "参考号
        ls_method_project-objecttype = co1_type-wbs_element.         "对象类型
        ls_method_project-method     = co1_meth-update.              "项目更新
        ls_method_project-objectkey  = ls_wbs_import-wbs_element.    "项目定义
        APPEND ls_method_project TO lt_method_project.
        CLEAR ls_method_project.

        ls_wbs_update-wbs_element             = ls_wbs_import-wbs_element.
        ls_wbs_update-project_definition      = gs_excel-pspnr.
        ls_wbs_update-short_id                = gs_excel-poski.

        APPEND ls_wbs_update TO lt_wbs_update.

        ls_wbs_updatex-short_id               = 'X'.
        APPEND ls_wbs_updatex TO lt_wbs_updatex.

      ENDLOOP.

      "项目处理方法保存
      ls_method_project-method = co1_meth-save.
      APPEND ls_method_project TO lt_method_project.
      CLEAR: ls_method_project.

      " 初始化
      CHECK lt_wbs_update IS NOT INITIAL.
      REFRESH lt_return.
      " 更新简明ID(WBS元素)\
      CALL FUNCTION 'BAPI_PROJECT_MAINTAIN'
        EXPORTING
          i_project_definition     = ls_project_definition
          i_project_definition_upd = ls_project_definition_upd
        IMPORTING
          return                   = ls_return1
        TABLES
          i_method_project         = lt_method_project
          e_message_table          = lt_message
          I_WBS_ELEMENT_TABLE          = lt_wbs_update
          I_WBS_ELEMENT_TABLE_UPDATE   = lt_wbs_updatex.
      IF ls_return1-type <> 'E'.
        CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'.
      ELSE.
        CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
      ENDIF.

    ENDIF.
  ENDLOOP.


ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_VALUE_CHECK
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_value_check .

  SORT gt_excel BY pspnr level.
  LOOP AT gt_excel ASSIGNING <fs_excel>.
    IF <fs_excel>-level = '1'.
      IF <fs_excel>-posid1 IS INITIAL     OR
         <fs_excel>-posid2 IS NOT INITIAL OR
         <fs_excel>-posid3 IS NOT INITIAL.
        <fs_excel>-light = icon_red_light.
        <fs_excel>-msg   = TEXT-m06. " 请检查层级与WBS元素层级关系是否一致
      ENDIF.
    ELSEIF <fs_excel>-level = '2'.
      IF <fs_excel>-posid1 IS INITIAL     OR
         <fs_excel>-posid2 IS INITIAL     OR
         <fs_excel>-posid3 IS NOT INITIAL.
        <fs_excel>-light = icon_red_light.
        <fs_excel>-msg   = TEXT-m06. " 请检查层级与WBS元素层级关系是否一致
      ENDIF.
    ELSEIF <fs_excel>-level = '3'.
      IF <fs_excel>-posid1 IS INITIAL     OR
         <fs_excel>-posid2 IS INITIAL     OR
         <fs_excel>-posid3 IS INITIAL.
        <fs_excel>-light = icon_red_light.
        <fs_excel>-msg   = TEXT-m06. " 请检查层级与WBS元素层级关系是否一致
      ENDIF.
    ELSE.
      <fs_excel>-light = icon_red_light.
      <fs_excel>-msg   = TEXT-m05. " 层级只能为1,2,3其中一种
    ENDIF.
  ENDLOOP.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_READ_EXCEL_NEW
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_read_excel_new .

  DATA lv_value(255) TYPE c.
  DATA lv_flag       TYPE char1.
  DATA lv_count      LIKE sy-subrc.
  DATA lv_message    TYPE string.
  DATA lv_index      TYPE i.

  FIELD-SYMBOLS: <fs_value>.

  REFRESH gt_xlstmp.
  " 读取 EXCEL 文件数据
  CALL FUNCTION 'ALSM_EXCEL_TO_INTERNAL_TABLE'
    EXPORTING
      filename                = p_fname
      i_begin_col             = 1
      i_begin_row             = 2         "	从第 4 行开始 读取
      i_end_col               = 14         " 结束列
      i_end_row               = 65536     " 结束行
    TABLES
      intern                  = gt_xlstmp " 存储读取的记录 行、列、值
    EXCEPTIONS
      inconsistent_parameters = 1
      upload_ole              = 2
      OTHERS                  = 3.
  IF sy-subrc <> 0 .
    MESSAGE ID sy-msgid TYPE 'S' NUMBER sy-msgno DISPLAY LIKE sy-msgty
              WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    STOP.
  ENDIF.

  "将gt_xlstmp的数据遍历到gt_alv内表中
  "gt_xlstmp 中按行列的顺序将每个单元格值放在value中
  LOOP AT gt_xlstmp INTO gs_xlstmp.     " 按先行后列遍历每个单元格
    lv_index = gs_xlstmp-col. " 获取当前列数
    ASSIGN COMPONENT lv_index OF STRUCTURE gs_excel TO <fs_value>. " 将内表第index列的字段地址复制给指针<fs_value>
" 对特殊类型字段可以用case语句单独处理,比如单位字段或者需要加前导零的字段
" 用数字其实后期不好维护,中间插入字段就会导致index变更
*    CASE lv_index.
*    	WHEN 11. " 单位字段需要外码转内码
*        PERFORM frm_meins_in USING gs_xlstmp-value.
*    	WHEN 12. " 物料号需要加前导0
*        PERFORM frm_add_zero USING gs_xlstmp-value.
*    	WHEN 14. " wbs元素需要外码转内码
*        PERFORM frm_pspnr_in USING gs_xlstmp-value.
*    	WHEN 15. " 外部日期yyyy*MM*dd转内部yyyyMMdd才可导入
*        REPLACE ALL OCCURRENCES OF REGEX '[^0-9]' IN gs_xlstmp-value WITH ''.
*    	WHEN OTHERS.
*    ENDCASE.

    MOVE gs_xlstmp-value TO <fs_value>. " 将单元格值赋值给指向结构中字段的指针
    CLEAR gs_xlstmp.
    AT END OF row.  " 遍历至当行的最后一列时,将整行append至内表中
      APPEND gs_excel TO gt_excel.
      CLEAR gs_excel.
    ENDAT.
  ENDLOOP.
ENDFORM.

*&---------------------------------------------------------------------*
*& Form frm_meins_in
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> GS_OUT_MEINS
*&---------------------------------------------------------------------*
FORM frm_meins_in USING p1.

  CALL FUNCTION 'CONVERSION_EXIT_CUNIT_INPUT'
    EXPORTING
      input          = p1
      language       = sy-langu
    IMPORTING
      output         = p1
    EXCEPTIONS
      unit_not_found = 1
      OTHERS         = 2.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_ADD_ZERO
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> P1
*&---------------------------------------------------------------------*
FORM frm_add_zero USING p1.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = p1
    IMPORTING
      output = p1.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form frm_pspnr_in
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> GS_OUT_PS_PSP_PNR
*&---------------------------------------------------------------------*
FORM frm_pspnr_in USING p1.

  CALL FUNCTION 'CONVERSION_EXIT_ABPSP_INPUT'
    EXPORTING
      input     = p1
    IMPORTING
      output    = p1
    EXCEPTIONS
      not_found = 1
      OTHERS    = 2.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.

ENDFORM.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值