10单据和报表,实践A2-ALV输出订单列表

图10-A2_1 ALV输出订单列表
图10-A2_2 查看销售订单

需求分析:

1、具体需求

本《ALV输出销售单据》有如下需求:

初始界面
订单列表显示

2、开发分析

要达成本实践目标,将需要使用ABAP的数据处理和界面设计技术,程序流程分析如下。

实践步骤:

本实践可以在ABAP工作台(SE80)完成所有工作,也可以通过不同的工具完成不同部分。

No 部分 说明 事务代码
1 建立程序 建立本实践的程序,设置程序基本信息。 SE38
2 GUI状态标题设计 设计GUI状态,增加相应的功能以接受用户的指令;设计GUI标题,以在程序运行时显示在界面的标题上。 SE41
3 屏幕设计 根据实践需求设计屏幕,并将相关元素添加到屏幕上。 SE51
4 代码编写 编写代码以进行变量定义、数据获取、输出数据到界面等。 SE38
4.1 对象定义 定义要使用的变量,以在程序执行过程中计算和存储临时值。
4.2 程序初始事件 通过START-OF-SELECTION执行程序初始事件。
4.3 屏幕100事件 对于屏幕100,数据输出到屏幕前的处理(PBO事件);以及在用户点击按钮后触发相应操作(PAI事件)。
4.4 子程序 根据程序执行的过程将部分代码封装为主程序,以实现代码重用、提高效率和提高代码可读性。

1、建立程序

与一般程序的建立过程一样,在程序编辑器初始界面输入程序名称后点击创建,设置类型和状态后,将进入程序编辑器界面,默认代码如下,不改动内容,保存后退出。

REPORT zu1002_order_output.

2、GUI状态标题设计

2.1、系统交付程序

使用程序编辑器(SE38),查看系统交付程序SAPLKKBL。

标准程序交付的ALV工具栏

复制状态栏到程序

2.2、建立状态

将标准GUI状态复制过来后,可以据此新建2个GUI状态栏。

1)GUI状态ALV_PF_STATUS

GUI状态编辑维护的界面如图。

各功能按钮的定义可参考下表完成,其他&开头的为标准GUI中所包含,直接输入即可。

2)GUI状态STAT2

GUI状态STAT2编辑维护的界面如图所示。

各功能按钮的定义可参考下表完成。

2.2、建立标题

重新执行“菜单设计器”,在初始界面中选择“标题列表”后点击创建,参考图9-39所示建立2个标题。

GUI标题列表

3、屏幕设计

在本实践中,有程序执行初始界面,还有点击“查看订单”后显示的订单明细界面,其中初始界面在程序中定义后自动生成,订单明细界面则需要设计,使用屏幕设计器(SE51),完成屏幕的设计。

1)屏幕属性
屏幕100的属性
2)屏幕格式设计

点击工具栏的“格式”后,在显示“屏幕绘制器”界面中添加屏幕元素,结果如图。

屏幕100的格式
3)屏幕元素清单

点击工具栏的“元素列表”按钮,将返回到屏幕定义的“元素清单”中,此处将列出界面中所包含的元素,以及各元素的具体属性,如图。

屏幕100包含的元素
4)屏幕逻辑流

点击“逻辑流”页签,逻辑流的代码如下。

PROCESS BEFORE OUTPUT.
  MODULE status_0100.
  LOOP AT orderdetail_tab INTO orderdetail_tab WITH CONTROL order_items.
  ENDLOOP.

PROCESS AFTER INPUT.
  MODULE USER_COMMAND_0100.
  LOOP AT orderdetail_tab.
  ENDLOOP.

在如上屏幕100的“逻辑流”PBO事件中,包含一个MODULE:status_0100,此MODULE在屏幕输出前执行,包括设置GUI、标题栏、变量初始值等,具体代码将在后续屏幕100的PBO事件代码中实现。

PAI事件中,也包含了1个MODULE:user_command_0100此MODULE是在屏幕100中点击按钮时的响应。

4、代码编写

完成如上步骤后,接下来通过程序编辑器(SE38)对代码的各部分进行编写。

4.1、对象定义

根据程序功能需求,定义的变量、内表、控件等对象如代码所列。

*****对象定义
TABLES:ztorders_h.
CONTROLS: order_items TYPE TABLEVIEW USING SCREEN 100.
DATA: ordersh_stru    TYPE zu1002_ordersh_stru,
      ordersh_tab     TYPE zu1002_ordersh_tab WITH HEADER LINE,
      gt_print_out    TYPE zu1002_ordersh_tab WITH HEADER LINE,
      orderdetail_tab TYPE zu1002_orderdetail_tab WITH HEADER LINE,
      report_id       TYPE sy-repid,
      ok_code         TYPE sy-ucomm.
TYPE-POOLS:slis.
DATA: it_fieldcat TYPE slis_t_fieldcat_alv WITH HEADER LINE,
      i_layout    TYPE slis_layout_alv.
*****选择屏幕
SELECTION-SCREEN BEGIN OF BLOCK b1  WITH FRAME TITLE TEXT-t01.
SELECT-OPTIONS: s_oid FOR ztorders_h-orderid,
              s_odate  FOR ztorders_h-orderdate,
              s_custid FOR ztorders_h-customerid,
              s_empid  FOR ztorders_h-employeeid.
SELECTION-SCREEN END OF BLOCK b1.
4.2、程序初始事件

在程序执行后,通过START-OF-SELECTION语句,进行数据的读取和ALV列表的显示。

*&----------------------------------------------------------------------*
*& START-OF-SELECTION
*&----------------------------------------------------------------------*
START-OF-SELECTION.
  report_id = sy-repid.
  PERFORM read_order.
  PERFORM show_alv.
4.3、屏幕100事件
1)PBO事件的MODULE

当屏幕100被调用的时候,首先触发屏幕的PBO事件,此事件包含的MODULE status_0100的代码如下。

*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       屏幕初始化
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'STAT2'.
  SET TITLEBAR 'TITLE02'.
ENDMODULE.

此代码首先设置GUI状态为STAT2,标题为TITLE02。

2)PAI事件的MODULE

当点击GUI状态对应图标时,将触发屏幕的PAI事件。user_command_0100是PAI中的MODULE,此MODULE是对按钮点击后的响应,代码如下。

*&---------------------------------------------------------------------*
*&      Module  USER_COMMAND_0100  INPUT
*&---------------------------------------------------------------------*
*       用户点击按钮后的响应
*----------------------------------------------------------------------*
MODULE user_command_0100 INPUT.
  CASE ok_code.
    WHEN 'EXIT'.
      LEAVE TO SCREEN 0 .
  ENDCASE.
ENDMODULE.
4.4、子程序

在程序中,多处用到了不同的子程序。

1)子程序read_order

是用以根据初始界面中输入的选择条件号,获得数据到内表。

*&---------------------------------------------------------------------*
*&      Form  READ_ORDER
*&---------------------------------------------------------------------*
*       读取订单数据
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM read_order .
  SELECT oh~orderid oh~customerid ct~customername ct~city oh~employeeid
    et~employeename oh~orderdate oh~shipdate oh~oamount
    INTO  CORRESPONDING FIELDS OF TABLE ordersh_tab
    FROM ztorders_h AS oh
    LEFT OUTER JOIN ztcustomer AS ct
                    ON ct~customerid = oh~customerid
    LEFT OUTER JOIN ztemployee AS et
                    ON et~employeeid = oh~employeeid
    WHERE oh~orderid IN s_oid
          AND oh~orderdate IN s_odate
          AND oh~customerid IN s_custid
          AND oh~employeeid IN s_empid.
  SORT ordersh_tab BY orderid.
ENDFORM.
2)子程序show_alv

是将获得的数据输出到ALV。

*&---------------------------------------------------------------------*
*&      Form  ALV_SHOW
*&---------------------------------------------------------------------*
*       显示ALV列表
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM show_alv .
  PERFORM prepare_alv_field.
  PERFORM layout_init.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       = report_id
      i_background_id          = 'ALV_BACKGROUND'
      i_callback_pf_status_set = 'SET_PF_STATUS'
      i_callback_user_command  = 'ALV_USER_COMMAND'
      is_layout                = i_layout
      i_save                   = 'A'
      it_fieldcat              = it_fieldcat[]
    TABLES
      t_outtab                 = ordersh_tab
    EXCEPTIONS
      program_error            = 1
      OTHERS                   = 2.
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.
ENDFORM.
3)子程序prepare_alv_field

则是确定ALV中输出的列。

*&---------------------------------------------------------------------*
*&      Form  PREPARE_ALV_FIELD
*&---------------------------------------------------------------------*
*       设置ALV字段格式
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM prepare_alv_field .
  "定义宏m_fieldcat
  DEFINE m_fieldcat.
    it_fieldcat-fieldname = &1.
    it_fieldcat-reptext_ddic = &2.
    it_fieldcat-col_pos = &3.
    it_fieldcat-checkbox = &4.
    it_fieldcat-edit = &5.
    APPEND it_fieldcat.
  END-OF-DEFINITION.
  "调用宏定义ALV字段
  m_fieldcat 'SEL'           '选择'      '010' 'X' 'X'.
  m_fieldcat 'ORDERID'       '订单编号'  '110' ' ' ' '.
  m_fieldcat 'CUSTOMERID'    '客户ID'    '210' ' ' ' '.
  m_fieldcat 'CUSTOMERNAME'  '客户名称'  '310' ' ' ' '.
  m_fieldcat 'CITY'          '城市'      '410' ' ' ' '.
  m_fieldcat 'EMPLOYEEID'    '雇员ID'    '510' ' ' ' '.
  m_fieldcat 'EMPLOYEENAME'  '雇员名称'  '610' ' ' ' '.
  m_fieldcat 'ORDERDATE'     '订单日期'  '710' ' ' ' '.
  m_fieldcat 'SHIPDATE'      '交货日期'  '810' ' ' ' '.
*  m_fieldcat 'OAMOUNT'       '金额'      '910' ' ' ' '.
ENDFORM.
4)子程序layout_init

则是将布局进行初始化,以自动根据列宽进行调整。

*&---------------------------------------------------------------------*
*&      Form  LAYOUT_INIT
*&---------------------------------------------------------------------*
*       ALV布局初始化
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM layout_init .
  CLEAR i_layout.
  i_layout-colwidth_optimize = 'X'.
ENDFORM.
5)子程序set_pf_status

用于设置ALV列表的GUI状态和标题。

*&---------------------------------------------------------------------*
*&      Form  SET_PF_STATUS
*&---------------------------------------------------------------------*
*       设置GUI状态标题
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM set_pf_status USING rt_extab TYPE slis_t_extab.
  SET PF-STATUS 'ALV_PF_STATUS'.
  SET TITLEBAR 'TITLE01'.
ENDFORM.
6)子程序alv_user_command

用于响应用户对ALV列表的操作。

*&---------------------------------------------------------------------*
*&      Form  ALV_USER_COMMAND
*&---------------------------------------------------------------------*
*       ALV列表指令
*----------------------------------------------------------------------*
*  -->  R_UCOMM        text
*  <--  RS_SELFIELD       text
*----------------------------------------------------------------------*
FORM alv_user_command USING r_ucomm LIKE sy-ucomm
rs_selfield TYPE slis_selfield.
  DATA: lr_grid TYPE REF TO cl_gui_alv_grid.
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
*     EXPORTING
*       IR_SALV_FULLSCREEN_ADAPTER       =
    IMPORTING
*     ET_EXCLUDING                     =
*     E_REPID                          =
*     E_CALLBACK_PROGRAM               =
*     E_CALLBACK_ROUTINE               =
      e_grid = lr_grid
*     ET_FIELDCAT_LVC                  =
*     ER_TRACE                         =
*     E_FLG_NO_HTML                    =
*     ES_LAYOUT_KKBLO                  =
*     ES_SEL_HIDE                      =
*     ET_EVENT_EXIT                    =
*     ER_FORM_TOL                      =
*     ER_FORM_EOL                      =
    .

  CALL METHOD lr_grid->check_changed_data.
  rs_selfield-refresh = 'X'.
  rs_selfield-col_stable = 'X'.
  rs_selfield-row_stable = 'X'.
  CASE r_ucomm.
    WHEN '&IC1'.          "双击时
      CHECK rs_selfield-tabindex > 0.
      READ TABLE ordersh_tab INTO ordersh_stru INDEX rs_selfield-tabindex.
      SUBMIT zu0902_order_trans.
*     SET PARAMETER ID 'ORDERID' FIELD ordersh_tab-orderid.
*     CALL TRANSACTION 'xxx'.
    WHEN 'DISPLAY'.            "ALV显示订单详细
      CHECK rs_selfield-tabindex > 0.
      READ TABLE ordersh_tab INTO ordersh_stru INDEX rs_selfield-tabindex.
      PERFORM get_detail_data.
      PERFORM display_detail.
    WHEN 'PRINTSF'.            "打印SMARTFORM
*     READ TABLE ordersh_tab INDEX rs_selfield-tabindex.
      CHECK rs_selfield-tabindex > 0.
      PERFORM get_sf_data.
      PERFORM call_smartform.
  ENDCASE.
ENDFORM.                    "ALV_USER_COMMAND
7)子程序get_detail_data

用于响应点击ALV工具栏的“显示订单”的操作,获得订单详细数据。

*&---------------------------------------------------------------------*
*&      Form  GET_DETAIL_DATA
*&---------------------------------------------------------------------*
*       获得订单明细数据
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_detail_data .
  SELECT
    oi~orderid
    oi~materialid
    mt~materialname
    oi~oquantity
    oi~ounit
    oi~nprice
    oi~pcurrency
    oi~discount
    INTO TABLE orderdetail_tab
    FROM ztorders_i AS oi
    INNER JOIN ztmaterial AS mt
      ON mt~materialid = oi~materialid
    WHERE oi~orderid = ordersh_stru-orderid.
ENDFORM.
8)子程序display_detail

用于响应点击ALV工具栏的“显示订单”的操作,调用屏幕100显示订单详细。

*&---------------------------------------------------------------------*
*&      Form  DISPLAY_DETAIL
*&---------------------------------------------------------------------*
*       显示订单明细数据
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM display_detail .
  CALL SCREEN 100 STARTING AT 20 10.
ENDFORM.
9)子程序get_sf_data

用于响应点击ALV工具栏的“打印-SF”的操作,获得勾选的订单编号。

*&---------------------------------------------------------------------*
*&      Form  GET_SF_DATA
*&---------------------------------------------------------------------*
*       获得数据准备SmartForms打印输出
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM get_sf_data .
  CLEAR gt_print_out.
  CLEAR gt_print_out[].
  LOOP AT ordersh_tab.
    IF ordersh_tab-sel = 'X'.
      gt_print_out = ordersh_tab.
      APPEND gt_print_out.
    ENDIF.
  ENDLOOP.
ENDFORM.
10)子程序call_smartform

用于响应点击ALV工具栏的“打印-SF”的操作,调用SmartForms输出单据。

*&---------------------------------------------------------------------*
*&      Form  CALL_SMARTFORM
*&---------------------------------------------------------------------*
*       调用SmartForms打印单据
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM call_smartform .
  DATA: lf_fmnam   TYPE rs38l_fnam,
        lv_sfnam   TYPE tdsfname,
        ctrl_param TYPE ssfctrlop,
        out_option TYPE ssfcompop.
  ctrl_param-preview = 'X'.                       " 打印预览
  ctrl_param-no_dialog = 'X'.
*  ctrl_param-device = 'CNSAPWIN'.
  out_option-tddest = 'LP02'.                     " 打印设备
  out_option-tdimmed = 'X'.                       " 直接打印
  out_option-tddelete = 'X'.                      " 打印后删除
  lv_sfnam = 'ZU1002_ORDER_SF'.
  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname = lv_sfnam
*     VARIANT  = ' '
*     DIRECT_CALL              = ' '
    IMPORTING
      fm_name  = lf_fmnam
* EXCEPTIONS
*     NO_FORM  = 1
*     NO_FUNCTION_MODULE       = 2
*     OTHERS   = 3
    .
  IF sy-subrc <> 0.
* Implement suitable error handling here
  ENDIF.
  LOOP AT gt_print_out.
    CALL FUNCTION lf_fmnam
      EXPORTING
*       ARCHIVE_INDEX      =
*       ARCHIVE_INDEX_TAB  =
*       ARCHIVE_PARAMETERS =
        control_parameters = ctrl_param
*       MAIL_APPL_OBJ      =
*       MAIL_RECIPIENT     =
*       MAIL_SENDER        =
        output_options     = out_option
        user_settings      = space
*   IMPORTING
*       DOCUMENT_OUTPUT_INFO       =
*       JOB_OUTPUT_INFO    =
*       JOB_OUTPUT_OPTIONS =
      TABLES
        it_order           = gt_print_out
      EXCEPTIONS
        formatting_error   = 1
        internal_error     = 2
        send_error         = 3
        user_canceled      = 4
        OTHERS             = 5.
    IF sy-subrc <> 0.
* Implement suitable error handling here
    ENDIF.
  ENDLOOP.
ENDFORM.

将如上各部分代码合并,则组成了整个实践的程序,完成后对所有内容进行激活。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容