一个简单的打印报表程序

时间:2021-09-12 11:41:35

*&---------------------------------------------------------------------*
*& Report  ZPPR0007
*&
*&---------------------------------------------------------------------*
*&zhijian.cai 2013-5-17
*&
*&---------------------------------------------------------------------*

REPORT  zppr0007.
TYPE-POOLS: slis.
TABLES:vekp,vepo,makt.

*&---------------------------------------------------------------------*
*&全局自定义类型定义
*&---------------------------------------------------------------------*
TYPES:BEGIN OF typ_db,
  exidv TYPE vekp-exidv,             "柜号/托号
  matnr TYPE char18,                 "物料编号
  box   TYPE c,
  cmark TYPE c,                      "选择
  venum TYPE vekp-venum,             "HU
  vhilm TYPE vekp-vhilm,             "包装物料
  meins TYPE vekp-meins,             "单位
  velin TYPE vepo-velin,             "处理单位项目内容的类型如果是'3'就是箱子可以通过底层处理单位去取数量
  unvel TYPE vepo-unvel,             "底层处理单位
  vemng TYPE vepo-vemng,             "数量
  maktx TYPE makt-maktx,             "物料描述
  charg TYPE vepo-charg,             "批次
  werks TYPE vepo-werks,             "工厂
  lgort TYPE vepo-lgort,             "发出仓库
  b1000020 TYPE atwrt,               "标称功率
  a_lgort TYPE vepo-lgort,           "接受仓库
  vbeln TYPE char10,                 "凭证号码
  note  TYPE char10,                "备注
END OF typ_db.

*&---------------------------------------------------------------------*
*&全局内表、工作区 定义、
*&---------------------------------------------------------------------*
DATA gt_tab TYPE TABLE OF typ_db.
DATA gs_tab LIKE LINE OF gt_tab.
DATA alv_da TYPE typ_db.
DATA out_tab TYPE TABLE OF typ_db WITH HEADER LINE.
DATA tem_tab TYPE TABLE OF typ_db WITH HEADER LINE.

*----------------------------------------------------------------------*
*       去掉前导零
*----------------------------------------------------------------------*
DEFINE rm_zeros.
  call function 'CONVERSION_EXIT_ALPHA_OUTPUT'
    exporting
      input  &1
    importing
      output &1.
END-OF-DEFINITION.
*----------------------------------------------------------------------*
*       CONSTANTS DEF
*----------------------------------------------------------------------*
CONSTANTS gc_pf_status TYPE slis_formname VALUE 'ALV_PF_STATUS'.                         “用于alv显示调用REUSE_ALV_GRID_DISPLAY函数GUI状态
CONSTANTS gc_user_command TYPE slis_formname VALUE 'ALV_USER_COMMAND'.         ”用于alv显示调用REUSE_ALV_GRID_DISPLAY函数自定义按钮的事件

*----------------------------------------------------------------------*
*       ALV
*----------------------------------------------------------------------*
DATA: gt_sort TYPE slis_t_sortinfo_alv.
DATA: gt_fieldcat TYPE slis_t_fieldcat_alv,
      gs_fieldcat TYPE slis_fieldcat_alv.
DATA: gs_layout   TYPE slis_layout_alv,
      gf_repid    TYPE sy-repid.


*----------------------------------------------------------------------*
*       PARAMTER DEF#SELECT-OPTION etc.#
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK WITH FRAME TITLE text-001.
SELECT-OPTIONS:  s_exidv FOR  vekp-exidv.   "柜号/托号
SELECTION-SCREEN END OF BLOCK a.
*----------------------------------------------------------------------*
INITIALIZATION.
*----------------------------------------------------------------------*
TOP-OF-PAGE.
*----------------------------------------------------------------------*
START-OF-SELECTION.
  PERFORM get_data.
*----------------------------------------------------------------------*
END-OF-SELECTION.
  PERFORM display_data.
*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
FORM get_data .
*----------------------------------------------------------------------*
*  定义物料批次特性的
*----------------------------------------------------------------------*
  DATA: lf_objek TYPE  objnum,
        lf_obtab TYPE  tabelle,
        lf_klart TYPE  klassenart,      "就是T-COD是MM03下面的批次分类下的对象下的类别种类
        lf_class TYPE  klasse_d,        "就是T-COD是MM03下面的批次分类下的分配表里的类别
        tmp_str TYPE string.

  DATA: lt_char TYPE TABLE OF bapi1003_alloc_values_char,
        lt_num TYPE TABLE OF bapi1003_alloc_values_num,
        lt_curr TYPE TABLE OF bapi1003_alloc_values_curr,
        lt_return TYPE TABLE OF bapiret2,
        ls_char TYPE bapi1003_alloc_values_char,
        ls_num TYPE bapi1003_alloc_values_num.

  DATA: tmp_str1 TYPE cha_class_view-sollwert,
        tmp_i    TYPE cha_class_data-sollwert.
*----------------------------------------------------------------------*
* 定义一个子例程  增加物料号前导零
*----------------------------------------------------------------------*
  DEFINE  zm_convert_alpha_input.
    call function 'CONVERSION_EXIT_MATN1_INPUT'
      exporting
        input        &1
      importing
        output       &1
      exceptions
        length_error 1
        others       2.
    if sy-subrc <> 0.
* Implement suitable error handling here
    endif.
  END-OF-DEFINITION.

  SELECT a~venum            "HU
         a~exidv            "柜号/托号
         a~vhilm            "包装物料
         a~meins            "单位
         b~velin
         b~unvel            "底层处理单位
         b~vemng            "数量
         b~matnr            "物料编号
         c1~maktx           "物料描述
         b~charg            "批次
         b~werks            "工厂
         b~lgort            "发出仓库
    INTO CORRESPONDING FIELDS OF TABLE gt_tab
    FROM vekp AS a
    INNER JOIN vepo AS ON a~venum b~venum
    INNER JOIN makt AS c1 ON b~matnr c1~matnr
    WHERE a~exidv IN s_exidv
    AND c1~spras sy-langu.

  LOOP AT gt_tab INTO gs_tab WHERE velin '3'.
    SELECT SINGLE  a~vemng a~matnr a~charg a~werks a~lgort
             INTO (gs_tab-vemng, gs_tab-matnr, gs_tab-charg, gs_tab-werks, gs_tab-lgort)
             FROM vepo AS a
             INNER JOIN makt AS ON a~matnr b~matnr
             WHERE a~venum gs_tab-venum
             AND   a~unvel gs_tab-unvel
             AND   b~spras sy-langu.
    MODIFY gt_tab FROM gs_tab TRANSPORTING  vemng matnr charg werks lgort.
  ENDLOOP.
*----------------------------------------------------------------------*
*  定义存放物料批次特性值的内表
*----------------------------------------------------------------------*
  DATA: BEGIN OF it_data OCCURS 0,
      atnam LIKE cabn-atnam, "特征名称
      atbez LIKE cabnt-atbez, "特征描述
      atwrt LIKE cawn-atwrt, "特性值
END OF it_data.



*----------------------------------------------------------------------*
* 取批次特性先清空这些存放数据的变量和内表
*----------------------------------------------------------------------*
  CLEAR: it_data,lf_objek,lf_obtab,lf_klart,lf_class,ls_num,ls_char,tmp_str1,tmp_i,gs_tab.
  REFRESH: it_data,lt_num,lt_char,lt_curr,lt_return.
  LOOP AT gt_tab INTO gs_tab.
    IF gs_tab-charg IS NOT INITIAL.



      zm_convert_alpha_input: gs_tab-matnr.            "调用刚才定义的增加前导零,把物料编号增加前导零到18位赋给 lf_object

      CALL FUNCTION 'VB_BATCH_2_CLASS_OBJECT'
        EXPORTING
          i_matnr gs_tab-matnr       "物料
          i_charg gs_tab-charg       "批次
          i_werks gs_tab-werks       "工厂
        IMPORTING
          e_objek lf_objek           "对应objectkey
          e_obtab lf_obtab           "对应objecttable
          e_klart lf_klart           "对应classtype
          e_class lf_class.          "对应classnum

      IF lf_objek IS NOT INITIAL.
        CLEAR: lt_char, lt_num, lt_curr, lt_return.
        CALL FUNCTION 'BAPI_OBJCL_GETDETAIL'
          EXPORTING
            objectkey       lf_objek
            objecttable     lf_obtab
            classnum        lf_class
            classtype       lf_klart
          TABLES
            allocvaluesnum  lt_num                "数值型特性值
            allocvalueschar lt_char               "字符型特性值
            allocvaluescurr lt_curr               "货币型特性值
            return          lt_return.            "返回值
      ENDIF.

*----------------------------------------------------------------------*
*循环内表 字符型特性值 放在定义的特性值内表中
*----------------------------------------------------------------------*
      LOOP AT lt_char INTO ls_char.
        it_data-atnam ls_char-charact.          "特性名称
        it_data-atwrt ls_char-value_neutral.    "特性值
        it_data-atbez ls_char-charact_descr.    "特征描述
        APPEND it_data.
        CLEAR: ls_char,it_data.
      ENDLOOP.

*----------------------------------------------------------------------*
*循环内表lt_num把数值型特性放在定义的特性值内表里
*----------------------------------------------------------------------*
      CLEAR: ls_num, it_data.
      LOOP AT lt_num INTO ls_num.
        tmp_i ls_num-value_from.
        CALL FUNCTION 'QSS0_FLTP_TO_CHAR_CONVERSION'
          EXPORTING
            i_number_of_digits 2               "小数点右边的位数是2位
            i_fltp_value       tmp_i           "数值型特性值
          IMPORTING
            e_char_field       tmp_str1.       "转换后的小数点右边的位数是2位 数值型特性值
        it_data-atnam ls_num-charact.          "特性名称
        it_data-atwrt tmp_str1.                "特性值
        CONDENSE it_data-atwrt.                  "去掉前后空格
        it_data-atbez ls_num-charact_descr.    "特征描述
        APPEND it_data.
        CLEAR: ls_num, it_data.
      ENDLOOP.
      SORT it_data BY atnam.                     "排序批次特性表
      DELETE ADJACENT DUPLICATES FROM it_data COMPARING ALL FIELDS. "删除重复的数据。

      CLEAR it_data.
      READ TABLE it_data WITH KEY atnam 'B1000020'.
      gs_tab-b1000020 it_data-atwrt.

      MODIFY gt_tab FROM gs_tab TRANSPORTING  matnr b1000020.
      CLEAR gs_tab.
    ENDIF.
  ENDLOOP.
*----------------------------------------------------------------------*
*计算同一柜子或者箱子在同一物料号下的数量总和
*----------------------------------------------------------------------*

  DATA tem_gs TYPE typ_db.
  DATA sun TYPE vepo-vemng VALUE 0.
  LOOP AT gt_tab INTO gs_tab.
    tem_gs gs_tab .
    sun sun + gs_tab-vemng.
    AT END OF matnr.
         tem_tab tem_gs.
         tem_tab-vemng sun.
         APPEND tem_tab.
         CLEAR sun.
    ENDAT.
    CLEAR: gs_tab, tem_gs, tem_tab.
  ENDLOOP.
ENDFORM.                    " GET_DATA
*&---------------------------------------------------------------------*
*&      Form  DISPLAY_DATA
*&---------------------------------------------------------------------*
FORM display_data .
  PERFORM alv_header.
  PERFORM alv_display.

ENDFORM.                    " DISPLAY_DATA
*&---------------------------------------------------------------------*
*&      Form  ALV_HEADER
*&---------------------------------------------------------------------*
FORM alv_header .
  PERFORM fieldcat_init.
ENDFORM.                    " ALV_HEADER
*&---------------------------------------------------------------------*
*&      Form  FIELDCAT_INIT
*&---------------------------------------------------------------------*
FORM fieldcat_init .
  gs_layout-zebra             'X'. " 显示斑马线
  gs_layout-colwidth_optimize 'X'. " 自动调整列宽
  gs_layout-box_fieldname 'BOX'.
  gs_layout-box_tabname 'GT_OUTPUT'.
  DEFINE add_fieldcat.
    gs_fieldcat-fieldname    &1.  " 指定要显示的字段
    gs_fieldcat-tabname      &2.
    gs_fieldcat-seltext_l    &3.  " 设置表头,就是ALV的列名称
    gs_fieldcat-col_pos      &4.  "位置
    gs_fieldcat-checkbox     &5.  " 设置列为复选框
    gs_fieldcat-no_zero      &6.  " 去掉前导零
    gs_fieldcat-edit         &7.
    append gs_fieldcat to gt_fieldcat.
    clear gs_fieldcat.
  END-OF-DEFINITION.

  gs_fieldcat-fieldname  'CMARK'.
  gs_fieldcat-tabname    'GT_TAB'.
  gs_fieldcat-col_pos    '1'.
  gs_fieldcat-seltext_l  '选择'.
  gs_fieldcat-edit       'X'.
  gs_fieldcat-checkbox   'X'.
  APPEND gs_fieldcat TO gt_fieldcat.

*  add_fieldcat 'CMART' 'GT_TAB' '选择' '1' 'X' '' 'X' .
  add_fieldcat 'EXIDV' 'TEM_TAB[]' '柜号/箱号' '2' '' 'X' '' .
  add_fieldcat 'MATNR' 'TEM_TAB[]' '物料编号' '3' '' 'X' '' .
  add_fieldcat 'CHARG' 'TEM_TAB[]' '批次' '5' '' '' '' .
  add_fieldcat 'MAKTX' 'TEM_TAB[]' '物料描述' '6' '' '' '' .
  add_fieldcat 'VEMNG' 'TEM_TAB[]' '数量' '7' '' '' '' .
  add_fieldcat 'MEINS' 'TEM_TAB[]' '单位' '8' '' '' '' .
  add_fieldcat 'B1000020' 'TEM_TAB[]' '标称功率' '9' '' '' '' .
  add_fieldcat 'WERKS' 'TEM_TAB[]' '工厂' '10' '' '' '' .
  add_fieldcat 'LGORT' 'TEM_TAB[]' '发出仓库' '11' '' '' '' .

ENDFORM.                    " FIELDCAT_INIT
*&---------------------------------------------------------------------*
*&      Form  ALV_DISPLAY
*&---------------------------------------------------------------------*
FORM alv_display .


  gf_repid sy-repid.



  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      i_callback_program       gf_repid
      is_layout                gs_layout
      it_fieldcat              gt_fieldcat
      it_sort                  gt_sort
      i_save                   'A'
      i_callback_pf_status_set gc_pf_status                         ”设置ALV自定义按钮GUI
      i_callback_user_command  gc_user_command              ”设置ALV自定义按钮响应事件
    TABLES
      t_outtab                 tem_tab[]
    EXCEPTIONS
      program_error            1
      OTHERS                   2.
ENDFORM.                    " ALV_DISPLAY

*&---------------------------------------------------------------------*
*&      Form  alv_user_command
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->R_UCOMM      text
*      -->RS_SELFIELD  text
*----------------------------------------------------------------------*
FORM alv_user_command USING r_ucomm LIKE sy-ucomm       ”编写自定义按钮响应事件
      rs_selfield TYPE slis_selfield.
  DATA: lo_guid TYPE REF TO cl_gui_alv_grid.                            “  黄色标记的可以不要
  "alv gridcontrol full screen.
  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      e_grid lo_guid.

  "verification of changes.
  CALL METHOD lo_guid->check_changed_data.

  CASE r_ucomm.

    WHEN 'PRINT'.
      PERFORM print.

    WHEN 'ALL'.
      LOOP AT tem_tab.
        tem_tab-cmark 'X'.
        MODIFY tem_tab TRANSPORTING cmark.
      ENDLOOP.
    WHEN 'SAL'.
      LOOP AT tem_tab.
        tem_tab-cmark ''.
        MODIFY tem_tab TRANSPORTING cmark.
      ENDLOOP.
  ENDCASE.
  rs_selfield-refresh 'X'.

ENDFORM.                    "alv_user_command
*&---------------------------------------------------------------------*
*&      Form  alv_pf_status
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->RT_EXTAB   text
*----------------------------------------------------------------------*
FORM alv_pf_status USING rt_extab TYPE slis_t_extab.
  SET PF-STATUS 'ZPPR0007_GUI001' .
ENDFORM.                    "alv_pf_status
*&---------------------------------------------------------------------*
*&      Form  PRINT
*&---------------------------------------------------------------------*
FORM print .
  DATA: lf_flag TYPE c.
  DATA  lf_var  TYPE  rs38l_fnam.
  DATA: ls_ssf  TYPE  ssfctrlop.

  PERFORM get_alv_selection CHANGING lf_flag .
  IF lf_flag 'X'.
    EXIT.
  ENDIF.

  ls_ssf-langu sy-langu.
  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname           'ZPPFF0004'
*     VARIANT            = ' '
*     DIRECT_CALL        = ' '
    IMPORTING
      fm_name            lf_var
    EXCEPTIONS
      no_form            1
      no_function_module 2
      OTHERS             3.

  CALL FUNCTION lf_var
    EXPORTING
      control_parameters ls_ssf
    EXCEPTIONS
      formatting_error   1
      internal_error     2
      send_error         3
      user_canceled      4
      OTHERS             5.
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.
ENDFORM.                    " PRINT
*&---------------------------------------------------------------------*
*&      Form  GET_ALV_SELECTION
*&---------------------------------------------------------------------*
FORM get_alv_selection  CHANGING p_flag TYPE c.
  out_tab[] tem_tab[].
  DELETE  out_tab[]  WHERE cmark <> 'X'.
  LOOP AT out_tab.
    rm_zeros: out_tab-exidv, out_tab-matnr.
    MODIFY out_tab.
  ENDLOOP.
  IF out_tab[] IS NOT INITIAL.
  ELSE.
    MESSAGE text-m01 TYPE 'I'.
    p_flag 'X'.
  ENDIF.
ENDFORM.                    " GET_ALV_SELECTION

 

 

 

 

 

以下是smartforms获取内表的部分,本程序采用指针的方式获取:

首先在全局定义的类型下面定义和程序内表一样结构的类型,包括表类型如下:

*定义内表的结构类型
TYPES:BEGIN OF typ_db,
  exidv TYPE vekp-exidv,             "柜号/托号
  matnr TYPE char18,                 "物料编号
  box   TYPE c,
  cmark TYPE c,                      "选择
  venum TYPE vekp-venum,             "HU
  vhilm TYPE vekp-vhilm,             "包装物料
  meins TYPE vekp-meins,             "单位
  velin TYPE vepo-velin,             "处理单位项目内容的类型如果是'3'就是箱子可以通过底层处理单位去取数量
  unvel TYPE vepo-unvel,             "底层处理单位
  vemng TYPE vepo-vemng,             "数量
  maktx TYPE makt-maktx,             "物料描述
  charg TYPE vepo-charg,             "批次
  werks TYPE vepo-werks,             "工厂
  lgort TYPE vepo-lgort,             "发出仓库
  b1000020 TYPE atwrt,               "标称功率
  a_lgort TYPE vepo-lgort,           "接受仓库
  vbeln TYPE char10,                 "凭证号码
  note  TYPE char10,                "备注
END OF typ_db.
*定义内表类型
 TYPES out_ty TYPE typ_db OCCURS 0.

接着就是比较重要的部分了,获取程序中的内表数据

全局定义的初始化下面出去:

DATA: field(50).
FIELD-SYMBOLS: <fs> type any.
field '(ZPPR0007)out_tab[]'.    ”程序名和需要打印用的内表,
ASSIGN (fieldTO <fs>.            ”把它分配给字符字段
GT_TAB <fs>.                      ”赋给我们定义的内表里,此内表是全局定义下的全局数据里定义的。

 

 

 

 

备注:在自定义GUI的方法是打开函数REUSE_ALV_GRID_DISPLAY下,进入SE80里面,查看该函数的GUI状态,拷贝状态STANDARD_FULLSCREEN到你需要的程序和新建的GUI状态

然后进入你的程序里,打开你的GUI状态,打开应用工具条选择一个空的单元格,选择编辑、insert、separator line、后在该单元格的下一个单元格中输入单元格名称、后双击该单元格、设置图标和功能键、然后可以在下面的功能键区域里可以看到你分配的功能键,到这里自定义GUI状态设计完毕。研究了好久其实很简单。