ABAP的ALV报表开发

ALV相关概念

ALV是系统的一种网格的显示方式,这种方式带有汇总\排序\筛选等功能,ALV格式的数据是以单元格为单位显示,不象一般的写屏方式拷出来或是

导出成文件不同列的内容粘在一块,这种方式便于数据导出来放在电子表格里进行加工。
ALV即能显示简单表单(SIMPLE LIST)又能显示有序表单(SEQUENTIALLIST):

ALV实现方式:
ALV 可以通过两种方式实现:Two Approaches
Conventional (Using SAP Standard Function Modules).
Object Oriented (Using SAP Standard Classes and Methods).
以下我们要讲的为Function Modules方式。

ALV实现流程:
第一步:定义将要用到的表,即TALBES定义部分,然后定义TYPE-POOLS: SLIS.
第二步:定义数据类型或者内表的实体对象.
第三步:定义一些需要用到的变量.
第四步:定义自己的选择屏幕.
第五步:start-of-selection部分.
1)用一个子函数完成对ALV表单标题区域的赋值(i_list_comments).
2)用一个子函数完成自己所需要数据的抓取.
3)用一个子函数完成要显示列表的列名行(第一行)的相关赋值(i_fieldcat_alv)以及设置.
4)用一个子函数完成输出格式的设置(i_layout),比如双击一条记录是否弹出对话框啊?是用哪个功能键触发等等.
5)用一个子函数FORM DISPLAY_DATA来显示上面我们已经分别封装好的数据,需要调用两个常用的FUNCTION MODULE.

下面根据一个普通的例子来具体解释各步骤:



*&---------------------------------------------------------------------*

*& Report  ZHYALVREPORTDEMO2
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  ZHYALVREPORTDEMO2.
*第一步:添加TYPE-POOLS和所需要的TABLES
TYPE-POOLS:SLIS.

TABLES:ZHYUSERMAIN,ZHYUSERLINE.
*第二步:定义ALV报表的内表数据类型和内表,用来作为ALV报表的DATASOURCE
TYPES:BEGIN OF T_OUT,
  ID LIKE ZHYUSERMAIN-ID,
  NAME LIKE ZHYUSERMAIN-NAME,
  AGE LIKE ZHYUSERMAIN-AGE,
  ADDR LIKE ZHYUSERLINE-ADDR,
  SCHOOL LIKE ZHYUSERLINE-SCHOOL,
  END OF T_OUT.

DATA: IT_OUT TYPE STANDARD TABLE OF T_OUT WITH HEADER LINE,
      ST_OUT LIKE LINE OF IT_OUT.

*第三步:定义ALV报表的相关的参数

DATA:ST_LAYOUT TYPE SLIS_LAYOUT_ALV,"ALV报表的LAYOUT设置
     IT_EVENT TYPE SLIS_T_EVENT,"ALV的事件内表
     ST_EVENT LIKE LINE OF IT_EVENT,"ALV的单个事件对象
*     ST_EVENT TYPE SLIS_ALV_EVENT,
     IT_COMMENT TYPE SLIS_T_LISTHEADER,"存储表头信息的内表
     ST_COMMENT LIKE LINE OF IT_COMMENT,"存储单个表头信息
     IT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV,"存储ALV报表的COLUMNS信息的内表
     ST_FIELDCAT LIKE LINE OF IT_FIELDCAT,"单个COLUMN信息
*    ST_FIELDCAT TYPE SLIS_FIELDCAT_ALV,
     IT_SORT TYPE SLIS_T_SORTINFO_ALV,"保存排序列的信息
     ST_SORT LIKE LINE OF IT_SORT."单个SORT信息
*    ST_SORT TYPE SLIS_SORTINFO_ALV.

**1)SLIS_LAYOUT_ALV是一个类型,它用来定义ALV报表的整体属性例如:
*   *ST_LAYO-ZEBRA = 'X'.“显示成斑马纹样式
*   *ST_LAYO-DETAIL_POPUP = 'X'.“是否弹出详细信息窗口
*   *ST_LAYO-F2CODE = '&ETA'. “设置触发弹出详细信息窗口的功能码,这里是双击
*   *ST_LAYO-COLWIDTH_OPTIMIZE = 'X'. “优化列宽选项是否设置
*   *ST_LAYO-DETAIL_INITIAL_LINES  = 'X'.
*   *ST_LAYO -no_vline = 'X'.“这个用来设置列间隔线
*   *ST_LAYO -detail_titlebar = '详细内容'. “设置弹出窗口的标题栏
**2)SLIS_T_EVENT是一个取得事件的内表,通过函数REUSE_ALV_EVENTS_GET取得多个事件(包括操作页眉页脚的事件).
**3)SLIS_T_LISTHEADER操作页眉页脚的内表.
**4)SLIS_T_FIELDCAT_ALV操作ALV报表列的内表.
**5)SLIS_T_SORTINFO_ALV对显示数据排序的内表。

*第四步:定义自己的选择屏幕的查询条件包括PARAMETERS和SELECT-OPTIONS
SELECT-OPTIONS:S_ID FOR ZHYUSERMAIN-ID.

*在选择屏幕处做一些输入的条件的验证。
AT SELECTION-SCREEN.
  PERFORM FRM_CHECK_SDATA."调用验证子例程FRM_CHECK_SDATA


* 第五步:在START-OF-SELECTION部分调用以下子例程设置ALV报表所要使用到的相关参数
*即对第三步定义的一些ALV参数进行设置
*1:FRM_GET_DATA获得数据赋值给ALV数据源内表IT_OUT
*2:FRM_SET_LAYOUT设置ALV报表样式
*3:FRM_SET_EVENT设置ALV报表的事件
*4:FRM_SET_FIELDCAT设置ALV的列属性。
*5:FRM_SET_SORT设置ALV的排序属性。
*6:FRM_DISPLAY_ALV显示ALV报表。
START-OF-SELECTION.
  PERFORM FRM_GET_DATA.
  PERFORM FRM_SET_LAYOUT.
  PERFORM FRM_SET_EVENT.
  PERFORM FRM_SET_FIELDCAT.
  PERFORM FRM_SET_SORT.
  PERFORM FRM_DISPLAY_ALV.


*&---------------------------------------------------------------------*
*&      Form  FRM_CHECK_SDATA
*&---------------------------------------------------------------------*
*       判断录入参数的合法性
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_CHECK_SDATA .
*做一些判断
  IF S_ID-HIGH = 3.
    MESSAGE '用户ID不能等于3' TYPE 'E' .
    LEAVE TO LIST-PROCESSING.
  ENDIF.
ENDFORM.                    " FRM_CHECK_SDATA
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATA
*&---------------------------------------------------------------------*
*       取数据到内表中
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_GET_DATA .
  SELECT
    ZHYUSERMAIN~ID
    ZHYUSERMAIN~NAME
    ZHYUSERMAIN~AGE
    ZHYUSERLINE~ADDR
    ZHYUSERLINE~SCHOOL
    INTO CORRESPONDING FIELDS OF TABLE IT_OUT
  FROM ZHYUSERMAIN
  INNER JOIN ZHYUSERLINE ON ZHYUSERLINE~MAINID = ZHYUSERMAIN~ID.

  IF SY-SUBRC <> 0 .
    MESSAGE '读取数据进内表失败' TYPE 'E'.
    LEAVE LIST-PROCESSING.
  ENDIF.
ENDFORM.                    " FRM_GET_DATA
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_LAYOUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_SET_LAYOUT .
  CLEAR ST_LAYOUT.
  ST_LAYOUT-ZEBRA = 'X'.
  ST_LAYOUT-DETAIL_POPUP = 'X'.
  ST_LAYOUT-F2CODE = '&ETA'.
  ST_LAYOUT-COLWIDTH_OPTIMIZE = 'X'.
  ST_LAYOUT-DETAIL_INITIAL_LINES = 'X'.
ENDFORM.                    " FRM_SET_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_EVENT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_SET_EVENT .
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
    EXPORTING
      I_LIST_TYPE     = 0
    IMPORTING
      ET_EVENTS       = IT_EVENT
    EXCEPTIONS
      LIST_TYPE_WRONG = 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.
    LEAVE TO LIST-PROCESSING.
  ENDIF.

  READ TABLE IT_EVENT
  WITH KEY NAME = SLIS_EV_END_OF_LIST
  INTO ST_EVENT.

  IF SY-SUBRC = 0.
    ST_EVENT-FORM = 'ALV_END_OF_PAGE'."将页尾子程名称赋值给 ST_EVENT-FORM
    MODIFY IT_EVENT FROM ST_EVENT INDEX SY-TABIX.
  ENDIF.


  READ TABLE IT_EVENT
  WITH KEY NAME = SLIS_EV_TOP_OF_PAGE
  INTO ST_EVENT.

  IF SY-SUBRC = 0 .
    ST_EVENT-FORM = 'ALV_TOP_OF_PAGE'.
    MODIFY IT_EVENT FROM  ST_EVENT INDEX SY-TABIX.
  ENDIF.

ENDFORM.                    " FRM_SET_EVENT
*页眉处理子例程
FORM ALV_TOP_OF_PAGE.
  DATA:CONTXT TYPE SLIS_LISTHEADER-INFO.
  DATA:L,H TYPE STRING.
  MOVE S_ID-LOW TO L .
  MOVE S_ID-HIGH TO H.
  CONCATENATE L '~' H INTO CONTXT.
  REFRESH IT_COMMENT.
  PERFORM INSERT_IT_COMMENT USING:
        'H' SPACE '用户信息表',
        'S' 'ID' CONTXT.

  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
    EXPORTING
      IT_LIST_COMMENTARY = IT_COMMENT
      I_LOGO             = 'ENJOYSAP_LOGO'.

  IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    LEAVE TO LIST-PROCESSING.
  ENDIF.

ENDFORM.                    "ALV_TOP_OF_PAGE



*页脚处理子例程
FORM ALV_END_OF_PAGE.
  DATA:W_DATA TYPE SLIS_LISTHEADER-INFO.
  DATA:W_UNAME TYPE SLIS_LISTHEADER-INFO.
  DATA:Z_DATA TYPE STRING.
  CONCATENATE
    SY-DATUM+0(4)
    SY-DATUM+4(2)
    SY-DATUM+6(2)
    INTO W_DATA SEPARATED BY '/'.
  MOVE SY-UNAME TO W_UNAME.

  REFRESH IT_COMMENT.
  PERFORM INSERT_IT_COMMENT USING:
        'S' '用户名:' W_UNAME,
        'S' '时间:' W_DATA.

  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
    EXPORTING
      IT_LIST_COMMENTARY = IT_COMMENT
      I_END_OF_LIST_GRID = 'X'.

ENDFORM.                    "ALV_END_OF_PAGE

*&---------------------------------------------------------------------*
*&      Form  INSERT_IT_COMMENT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->TYP        text
*      -->KEY        text
*      -->INFO       text
*----------------------------------------------------------------------*
FORM INSERT_IT_COMMENT
  USING TYP TYPE SLIS_LISTHEADER-TYP
        KEY TYPE SLIS_LISTHEADER-KEY
        INFO TYPE SLIS_LISTHEADER-INFO.
  CLEAR ST_COMMENT.
  ST_COMMENT-TYP = TYP. "H=Header, S=Selection, A=Action供选择
  ST_COMMENT-KEY = KEY.
  ST_COMMENT-INFO = INFO.
  APPEND ST_COMMENT TO IT_COMMENT.
ENDFORM.                    "INSERT_IT_COMMENT
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_FIELDCAT
*&---------------------------------------------------------------------*
*       设置ALV报表列属性
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_SET_FIELDCAT .
  REFRESH IT_FIELDCAT.
  PERFORM INSERT_IT_FIELDCAT USING:
        0 'ID' 'ZHYUSERMAIN-ID' 'ID' SPACE,
        1 'NAME' 'ZHYUSERMAIN-NAME' '姓名' SPACE,
        2 'AGE' 'ZHYUSERMAIN-AGE' '年龄' SPACE,
        3 'ADDR' 'ZHYUSERMAIN-ADDR' '地址' SPACE,
        4 'SCHOOL' 'ZHYUSERMAIN-SCHOOL' '学校' SPACE.
ENDFORM.                    " FRM_SET_FIELDCAT

*&---------------------------------------------------------------------*
*&      Form  INSERT_IT_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->COL_POS        列序
*      -->FIELDNAME      绑定的内表列名
*      -->REF_FIELDNAME  录入时,帮助制作时指定表中参考列名称
*      -->SELTEXT_M      字段描述
*      -->EDIT           是否可编辑
*----------------------------------------------------------------------*
FORM INSERT_IT_FIELDCAT USING
      COL_POS TYPE SLIS_FIELDCAT_ALV-COL_POS
      FIELDNAME TYPE SLIS_FIELDCAT_ALV-FIELDNAME
      REF_FIELDNAME TYPE SLIS_FIELDCAT_ALV-REF_FIELDNAME
      SELTEXT_M TYPE SLIS_FIELDCAT_ALV-SELTEXT_M
      EDIT TYPE SLIS_FIELDCAT_ALV-EDIT.

  CLEAR ST_FIELDCAT.
  ST_FIELDCAT-COL_POS = COL_POS.
  ST_FIELDCAT-FIELDNAME = FIELDNAME.
  ST_FIELDCAT-REF_FIELDNAME = REF_FIELDNAME.
  ST_FIELDCAT-SELTEXT_M = SELTEXT_M.
  ST_FIELDCAT-EDIT = EDIT.
  APPEND ST_FIELDCAT TO IT_FIELDCAT.

ENDFORM.                    "INSERT_IT_FIELDCAT
*&---------------------------------------------------------------------*
*&      Form  FRM_SET_SORT
*&---------------------------------------------------------------------*
*       显示前页表数据的排序
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_SET_SORT .
  REFRESH IT_SORT.
  PERFORM INSERT_IT_SORT USING:
        2 'AGE' 'X',
        1 'ID' 'X'.
ENDFORM.                    " FRM_SET_SORT

FORM INSERT_IT_SORT USING
      SPOS TYPE SLIS_SORTINFO_ALV-SPOS
      FIELDNAME TYPE SLIS_SORTINFO_ALV-FIELDNAME
      UP TYPE SLIS_SORTINFO_ALV-UP.

  CLEAR ST_SORT.
  ST_SORT-SPOS = SPOS.
  ST_SORT-FIELDNAME = FIELDNAME.
  ST_SORT-UP = UP.
  APPEND ST_SORT TO IT_SORT.

ENDFORM.
*&---------------------------------------------------------------------*
*&      Form  FRM_DISPLAY_ALV
*&---------------------------------------------------------------------*
*       ALV报表的显示
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_DISPLAY_ALV .
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      I_INTERFACE_CHECK = SPACE
      I_CALLBACK_PROGRAM = SY-REPID
      IS_LAYOUT = ST_LAYOUT
      IT_FIELDCAT = IT_FIELDCAT
      IT_SORT = IT_SORT
      I_DEFAULT = 'X'
      I_SAVE = 'A'
      IT_EVENTS = IT_EVENT
    TABLES
      T_OUTTAB = IT_OUT
    EXCEPTIONS
      PROGRAM_ERROR = 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.                    " FRM_DISPLAY_ALV
<think>好的,我需要帮用户开发一个基于ABAP的SAP报表,涉及多个数据表和字段。首先,我需要理清用户提供的字段结构和对应的数据源表。用户提供的字段包括序号、项目号、生产订单、工作中心、物料编码、物料描述、订单数量、预算人工、实际人工、差异1、预算折旧、实际折旧、差异2、预算费用、实际费用、差异3。对应的数据库表有AFPO、CRHD、MAKT、PLPO、AFRU等。 首先,我需要确认每个字段对应的数据库表和字段是否正确。例如,项目号对应AFPO-PROJN,生产订单是AFPO-AUFNR,工作中心是CRHD-ARBPL,物料编码AFPO-MATNR,物料描述是MAKT-MAKTX,订单数量AFPO-PGMNG。预算人工来自PLPO-VGW01,实际人工是AFRU-ISM01,预算折旧PLPO-VGW02,实际折旧AFRU-ISM02,预算费用可能是另一个字段,实际费用是AFRU-ISM03,差异字段可能需要计算得出。 接下来需要考虑这些表之间的关联关系。AFPO是生产订单项目表,CRHD是工作中心表,MAKT是物料描述表,PLPO可能包含工艺路线数据,AFRU是生产订单确认数据。需要确定如何连接这些表,比如通过生产订单号(AUFNR)和项目号(PROJN)连接AFPO和AFRU,通过物料编码(MATNR)连接AFPO和MAKT,工作中心可能需要通过CRHD的ARBPL字段关联。 然后需要确定数据的选择屏幕参数,用户可能需要输入生产订单范围、项目号、工作中心、日期范围等。需要定义选择屏幕元素,如SELECT-OPTIONS和PARAMETERS。 在数据提取部分,需要编写SELECT语句从各个表中获取数据,并使用JOIN或FOR ALL ENTRIES来关联表。需要注意的是FOR ALL ENTRIES的效率问题,特别是当主表数据量大时。此外,处理差异计算时,可能需要计算实际与预算的差值,并处理可能的空值情况。 在ALV输出部分,需要定义字段目录,设置字段名称、列标题、输出长度等。可能还需要添加颜色标识,比如差异为负数时显示红色,正数为绿色。同时,添加合计行和排序功能,方便用户查看。 性能优化方面,考虑使用内表索引、合理使用JOIN和FOR ALL ENTRIES,避免嵌套循环。测试时需要验证数据的准确性,特别是关联字段是否正确,差异计算是否无误。 用户可能的深层需求是希望有一个清晰的报表来监控生产订单的成本差异,帮助财务或生产部门分析预算执行情况。因此,报表需要直观展示差异,并允许导出数据进一步分析。可能还需要考虑权限控制,确保只有授权用户可访问。 在开发过程中,需要注意ABAP的语法和SAP标准表的正确使用,避免修改标准表结构。同时,处理可能的数据不一致情况,比如某些字段为空时的处理方式,确保报表的稳定性和可靠性。</think>以下是为您设计的生产订单成本差异分析报表开发方案,采用ABAP语言实现: ```abAP REPORT zprod_cost_analysis. * 表结构定义 TYPES: BEGIN OF ty_output, seqno TYPE i, " 序号 projn TYPE afpo-projn, " 项目号 aufnr TYPE afpo-aufnr, " 生产订单 arbpl TYPE crhd-arbpl, " 工作中心 matnr TYPE afpo-matnr, " 物料编码 maktx TYPE makt-maktx, " 物料描述 pgmng TYPE afpo-pgmng, " 订单数量 vgw01 TYPE plpo-vgw01, " 预算人工 ism01 TYPE afru-ism01, " 实际人工 diff1(16), " 差异1 vgw02 TYPE plpo-vgw02, " 预算折旧 ism02 TYPE afru-ism02, " 实际折旧 diff2(16), " 差异2 vgw03 TYPE plpo-vgw03, " 预算费用 ism03 TYPE afru-ism03, " 实际费用 diff3(16), " 差异3 color TYPE lvc_t_scol, " 颜色标识 END OF ty_output. DATA: gt_output TYPE TABLE OF ty_output, gt_field TYPE lvc_t_fcat. * 选择屏幕定义 SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-001. SELECT-OPTIONS: s_aufnr FOR afpo-aufnr, " 生产订单 s_projn FOR afpo-projn, " 项目号 s_arbpl FOR crhd-arbpl, " 工作中心 s_matnr FOR afpo-matnr. " 物料 PARAMETERS: p_date TYPE budat DEFAULT sy-datum. " 过账日期 SELECTION-SCREEN END OF BLOCK b1. START-OF-SELECTION. PERFORM get_data. PERFORM process_data. PERFORM display_report. *&---------------------------------------------------------------------* *& Form GET_DATA *&---------------------------------------------------------------------* FORM get_data. DATA: lt_afpo TYPE TABLE OF afpo, lt_afru TYPE TABLE OF afru, lt_plpo TYPE TABLE OF plpo, lt_makt TYPE TABLE OF makt. " 获取生产订单基础数据 SELECT aufnr projn matnr pgmng INTO CORRESPONDING FIELDS OF TABLE lt_afpo FROM afpo WHERE aufnr IN s_aufnr AND projn IN s_projn AND matnr IN s_matnr. CHECK lt_afpo IS NOT INITIAL. " 获取工艺路线数据 SELECT plnkn vgw01 vgw02 vgw03 INTO CORRESPONDING FIELDS OF TABLE lt_plpo FROM plpo FOR ALL ENTRIES IN lt_afpo WHERE plnty = 'N' AND plnnr = lt_afpo-plnnr. " 获取确认数据 SELECT aufnr ism01 ism02 ism03 INTO CORRESPONDING FIELDS OF TABLE lt_afru FROM afru FOR ALL ENTRIES IN lt_afpo WHERE aufnr = lt_afpo-aufnr AND budat <= p_date. " 获取物料描述 SELECT matnr maktx INTO CORRESPONDING FIELDS OF TABLE lt_makt FROM makt FOR ALL ENTRIES IN lt_afpo WHERE matnr = lt_afpo-matnr AND spras = sy-langu. PERFORM build_output USING lt_afpo lt_plpo lt_afru lt_makt. ENDFORM. *&---------------------------------------------------------------------* *& Form BUILD_OUTPUT *&---------------------------------------------------------------------* FORM build_output USING lt_afpo TYPE tty_afpo lt_plpo TYPE tty_plpo lt_afru TYPE tty_afru lt_makt TYPE tty_makt. DATA: ls_output TYPE ty_output, lv_seqno TYPE i VALUE 1. LOOP AT lt_afpo ASSIGNING FIELD-SYMBOL(<afpo>). CLEAR ls_output. " 基础信息填充 ls_output-seqno = lv_seqno. ls_output-projn = <afpo>-projn. ls_output-aufnr = <afpo>-aufnr. ls_output-matnr = <afpo>-matnr. ls_output-pgmng = <afpo>-pgmng. " 物料描述 READ TABLE lt_makt ASSIGNING FIELD-SYMBOL(<makt>) WITH KEY matnr = <afpo>-matnr. IF sy-subrc = 0. ls_output-maktx = <makt>-maktx. ENDIF. " 预算数据 READ TABLE lt_plpo ASSIGNING FIELD-SYMBOL(<plpo>) WITH KEY plnnr = <afpo>-plnnr. IF sy-subrc = 0. ls_output-vgw01 = <plpo>-vgw01. ls_output-vgw02 = <plpo>-vgw02. ls_output-vgw03 = <plpo>-vgw03. ENDIF. " 实际数据 READ TABLE lt_afru ASSIGNING FIELD-SYMBOL(<afru>) WITH KEY aufnr = <afpo>-aufnr. IF sy-subrc = 0. ls_output-ism01 = <afru>-ism01. ls_output-ism02 = <afru>-ism02. ls_output-ism03 = <afru>-ism03. ENDIF. " 差异计算 ls_output-diff1 = ls_output-ism01 - ls_output-vgw01. ls_output-diff2 = ls_output-ism02 - ls_output-vgw02. ls_output-diff3 = ls_output-ism03 - ls_output-vgw03. " 颜色标识(红色:超支,绿色:节约) PERFORM set_color USING: 'DIFF1' ls_output-diff1, 'DIFF2' ls_output-diff2, 'DIFF3' ls_output-diff3 CHANGING ls_output-color. APPEND ls_output TO gt_output. lv_seqno = lv_seqno + 1. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form SET_COLOR *&---------------------------------------------------------------------* FORM set_color USING iv_fieldname TYPE string iv_value TYPE any CHANGING ct_color TYPE lvc_t_scol. DATA: ls_color TYPE lvc_s_scol. IF iv_value < 0. ls_color-fname = iv_fieldname. ls_color-color-col = 6. " 红色 ls_color-color-int = 1. APPEND ls_color TO ct_color. ELSEIF iv_value > 0. ls_color-fname = iv_fieldname. ls_color-color-col = 5. " 绿色 ls_color-color-int = 1. APPEND ls_color TO ct_color. ENDIF. ENDFORM. ``` **实现功能说明:** 1. **数据模型设计** - 使用`FOR ALL ENTRIES`高效关联多表数据 - 通过`AFPO`获取生产订单基础信息 - 从`PLPO`提取预算数据(人工、折旧、费用) - 通过`AFRU`获取实际消耗数据 - 关联`MAKT`表获取物料描述 2. **核心处理逻辑** - 自动序号生成(SEQNO字段) - 差异计算逻辑:实际值 - 预算值 - 智能颜色标识:超支(红色)、节约(绿色) - 容错处理:空值处理和数据缺失保护 3. **性能优化措施** - 使用`FOR ALL ENTRIES`代替多重嵌套循环 - 采用字段符号(Field Symbol)提升处理速度 - 数据分阶段加载(基础数据→关联数据) - 内存表合理设计避免冗余字段 4. **扩展功能支持** - 多语言支持(通过MAKT-SPRAS字段) - 日期范围过滤(BUDAT字段) - 灵活选择条件(生产订单、项目号等) - 支持ALV导出、排序、过滤等标准功能 **使用说明:** 1. 事务代码SE38创建程序 2. 复制上述代码到ABAP编辑器 3. 创建必要的类型定义(tty_afpo等) 4. 实现ALV显示逻辑(推荐使用CL_SALV_TABLE) 5. 添加权限检查(AUTHORITY-CHECK) 6. 增强功能建议: - 添加批次管理支持 - 集成成本中心分析 - 增加差异百分比计算 - 添加邮件自动发送功能 该报表可帮助生产管理部门实时监控订单执行成本,及时发现预算偏差,建议部署在SAP ECC或S/4HANA生产系统中使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值