一切开发都来自于需求,需求并不决定开发。当接到需求的时候,一定要进行可行性分析,是否可以进行开发,否则将会严重影响工作效率
1.SAP报表
- List:原始技术,直接输出数据
- ALV:简单到复杂,也可以面向对象
- MS Office Excel:调用excel输出数据
SAP提供多种方式开发报表,这里只介绍常用的ALV报表,其他的大家有兴趣也可以去网上找资料研究一下
2.需求
1)假设有一个客户提出需求开发一个销售订单报表,报表应该包含的字段有:销售订单(so)、行项目、工厂、物料号、库存地点、需求数量、订单数量、创建日期、交货日期等等
2)接到需求进行可行性分析,如果SAP存在可满足需求的报表则不用进行开发或则进行修改;如果不存在则考虑报表开发是否可行,如果能做就准备开发,否则再和客户进行讨论。
3)假设可行性分析OK!
3、如何下手开发
1)从需求入手,分析需求
该报表主要是关于SO,这就是我们需要重点关注的地方
2)熟悉表
报表中的数据是怎么来的?当然并不是凭空产生的,需求中的销售订单、物料号等数据都将取自于数据库。所以得分析需要哪些表。当然你有可能不熟悉SAP中的表,你可以向有经验的同事请教。通过积累,让这些也成为你的东西
T-CODE:se16n可以查询透明表

以下是需要用到的一些表和一些重点关注字段,当然在实际中可能会涉及到更多的表和字段
1.【VBAK:销售凭证】 字段:vbeln(销售凭证)、erdat(创建日期)、ername(创建者)、auart(销售类型)、bstnk(采购订单)、bsark(采购订单类型)、bstdk(采购日期) 2.【VBAP:销售凭证行项目】 字段:vbeln(销售凭证)、posnr(项目)、matnr(物料)、werks(工厂)、lgort(库存地点)、erdat(销售订单创建日期)、PRCTR(利润中心)、aufnr(订单) 3.【VBPA:销售凭证合作伙伴】 字段: vbeln(销售凭证)、posnr(项目)、kunnr(客户)、lifnr(供应商) 3.【MAKT:物料描述】 字段:matnr(物料号)、spras(语言)、maktx(描述) 4.【LIPS:SD凭证交货项目数据】 字段:vbeln(交货)、posnr(项目)、werks(工厂)、lgort(地点)、lfimg(交货数量) 5.【VBKD:销售凭证业务数据】 字段: vbeln(销售凭证)、posnr(项目)、bstkd(PO)、inco1(国际贸易条件)、 6.【VBEP:销售凭证计划行数据】 字段: vbeln(销售凭证)、posnr(项目)、ETENR(计划行)、edatu(交货日期)、ezit(到达时间)、wmeng(订单数量)、lmeng(需求数量)、bmeng(确认的数量)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
4、报表开发
1)se38创建程序,创建完会有一行代码
2)自定义输出表结构
REPORT zbsdr_025. TABLES:vbak,mara,t001w,vbap,vbep. *--------------类型池定义 TYPE-POOLS: slis. DATA:t_fieldcat TYPE slis_t_fieldcat_alv, w_fieldcat TYPE LINE OF slis_t_fieldcat_alv, t_layout TYPE slis_layout_alv. *------------------定义输出表结构 TYPES:BEGIN OF ty_result, vbeln TYPE vbak-vbeln, "so auart TYPE vbak-auart, "销售类 型 posnr TYPE vbap-posnr, "项目 bstkd TYPE vbkd-bstkd, "po aufnr TYPE vbap-aufnr, werks TYPE vbap-werks, "工厂 lgort TYPE vbap-lgort, "库存地点 matnr TYPE vbap-matnr, "物料 maktx TYPE makt-maktx, kunnr TYPE vbpa-kunnr, "客户 lifnr TYPE vbpa-lifnr, "供应商 * lfimg TYPE lips-lfimg, "交货数量 edatu TYPE vbep-edatu, "计划交货日期 erdat TYPE vbap-erdat, "创建日期 lmeng TYPE vbep-lmeng, "需求数量 wmeng TYPE vbep-wmeng, "订单数量 END OF ty_result. *-----------------------------定义输出表和工作区域 DATA:t_result TYPE TABLE OF ty_result. DATA:w_result TYPE ty_result.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
(1)类型池:slis 。类型池顾名思义就是个池子,池子里面有很多的类型。开发ALV报表得用到slis里面的类型,所以要引用slis这个类型池
(2)DATA:主要用于声明变量,【TYPE】表示改变量参考的类型。在报表里一般都定义两个东西:内表和工作区。
(3)内表和工作区。内表可以理解为临时表,对内表操作不影响数据库中的表。如果频繁地从数据库中取数会导致效率降低,所以可以用内表临时存放数据;工作区只能存放一条数据,对数据进行处理,一般用于循环中。
DATA:t_fieldcat TYPE slis_t_fieldcat_alv, w_fieldcat TYPE LINE OF slis_t_fieldcat_alv, t_layout TYPE slis_layout_alv.
- 1
- 2
- 3
(4) se11查看类型池,如果不知道变量参考的类型可以在这里查找,比如ALV报表字段(我们取名t_fieldcat)


(5)TYPES自定义结构,可以的字段可以来自于不同的表,一般先定义输出表结构(把报表需要展示的字段都放在一个结构里),当然为了后面的操作也要定义内表和工作区,参考的类型就是该结构
DATA:t_result TYPE TABLE OF ty_result. DATA:w_result TYPE ty_result.
- 1
- 2
2)声明所需表
TYPES:BEGIN OF ty_vbakp, vbeln TYPE vbak-vbeln, "so auart TYPE vbak-auart, "销售类型 posnr TYPE vbap-posnr, "项目 werks TYPE vbap-werks, "工厂 lgort TYPE vbap-lgort, "库存地点 matnr TYPE vbap-matnr, "物料 erdat TYPE vbap-erdat, "创建日期 bstkd TYPE vbkd-bstkd, "po END OF ty_vbakp. DATA:t_vbakp TYPE TABLE OF ty_vbakp, w_vbakp TYPE ty_vbakp. *---------------------------------------------- "引入makt主要是为了获取物料描述信息 DATA:t_makt TYPE STANDARD TABLE OF makt, w_makt TYPE makt. DATA:rt_extab TYPE slis_t_extab. *---------------------------------------------- "引入vbpa主要是为了获取客户和供应商 DATA:t_vbpa TYPE STANDARD TABLE OF vbpa, w_vbpa TYPE vbpa. *------------------------------------------- "为获取计划交货时间,需求数量,订单数量 data:t_vbep type STANDARD TABLE OF vbep, w_vbep type vbep.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
需要什么,就声明什么。比如需要获取物料描述信息就定义一个内表参考类型为物料描述表(makt),如果需要的多个表有联系,也可以定义结构,把所需字段放在结构里。如上面的结构ty_vbakp.(表vbak,vbap,vbkd都有销售凭证字段)
3)选择屏幕
*-------------------------------定义选择屏幕 SELECTION-SCREEN:BEGIN OF BLOCK a1 WITH FRAME TITLE text-001. SELECT-OPTIONS:s_vbeln FOR vbak-vbeln, s_matnr FOR mara-matnr, s_werks FOR t001w-werks, s_erdat FOR vbap-erdat, "创建日期 s_edatu FOR vbep-edatu. "交货日期 SELECTION-SCREEN:END OF BLOCK a1.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
(1)选择屏幕就是SAP的前台,一般是一些查询条件

(2)select-options 可以进行多值查询(有范围的),如上图会有两个输入框。比如用户想查询1000到1010工厂的销售订单。点击输入框后面的搜索按钮,会从数据库里查询,关键字【FOR】后面就是的数据源。要注意的是,select-options里的数据源表都要在TABLES里声明下不然会出错。
TABLES:vbak,mara,t001w,vbap,vbep. SELECT-OPTIONS:s_vbeln FOR vbak-vbeln.
- 1
- 2
(3)parameters 用于单值查询
PARAMETERS p_matnr like mara-matnr.
- 1

(4)设置选择屏幕的文本值


4)获取数据
START-OF-SELECTION. *-----------------------获取数据 PERFORM frm_get_data. *-------------------------处理数据 PERFORM frm_handle_data. *&---------------------------------------------------------------------* *& Form FRM_GET_DATA *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* IF t_result IS NOT INITIAL. PERFORM frm_alv_show. ELSE. MESSAGE '没有符合的数据,请重新查询' TYPE 'S' DISPLAY LIKE 'E'. ENDIF. END-OF-SELECTION.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
(1)START-OF-SELECTION.程序的开始,PERFORM frm_get_data可以创建子程序,点击子程序名系统自动创建,选第二个,子程序会包含在当前程序里面,如下

FORM frm_get_data . SELECT * INTO CORRESPONDING FIELDS OF TABLE t_vbakp FROM vbak JOIN vbap ON vbak~vbeln = vbap~vbeln JOIN vbkd ON vbap~vbeln = vbkd~vbeln AND vbap~posnr = vbkd~posnr WHERE vbak~vbeln IN s_vbeln AND vbap~werks IN s_werks AND vbap~matnr IN s_matnr AND vbap~erdat IN s_erdat. IF t_vbakp[] IS NOT INITIAL. *物料描述 SELECT * INTO TABLE t_makt FROM makt FOR ALL ENTRIES IN t_vbakp WHERE matnr = t_vbakp-matnr. * 客户供应商 SELECT * INTO CORRESPONDING FIELDS OF TABLE t_vbpa FROM vbpa FOR ALL ENTRIES IN t_vbakp WHERE vbpa~vbeln = t_vbakp-vbeln. * AND vbpa~posnr = t_vbakp-posnr. *计划交货时间 SELECT * INTO CORRESPONDING FIELDS OF TABLE t_vbep from vbep FOR ALL ENTRIES IN t_vbakp where vbeln = t_vbakp-vbeln and posnr = t_vbakp-posnr and edatu in s_edatu. ENDIF. ENDFORM. " FRM_GET_DATA *&---------------------------------------------------------------------*
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
(2)INTO CORRESPONDING FIELDS OF TABLE XXX:一般会把查询到的数据存放到内表对应的字段里
(3) JOIN…ON…:可以把两张表进行关联,ON后面的就是条件,但是不建议关联太多张表,会导致效率下降
(4)IS NOT INITIAL 判断不为空
(5) FOR ALL ENTRIES IN:相当于一个子查询。假设上面代码通过第一个select语句后,t_vbakp有值了。我们还想获取物料描述,当然可以直接从物料描述表(makt)里取,但是好多不是我们需要的,所以要加个条件,条件就是内表t_vbakp里的物料(matnr)即获取这些物料的物料描述。最后再把数据存放在内表t_makt里,所以t_makt就有了我们需要的物料描述
*物料描述 SELECT * INTO TABLE t_makt FROM makt FOR ALL ENTRIES IN t_vbakp WHERE matnr = t_vbakp-matnr.
- 1
- 2
- 3
- 4
- 5
- 6
5)处理数据
(1)和之前一样创建一个子程序
FORM frm_handle_data . CLEAR w_vbakp. LOOP AT t_vbakp INTO w_vbakp. w_result-auart = w_vbakp-auart. w_result-vbeln = w_vbakp-vbeln. w_result-werks = w_vbakp-werks. w_result-lgort = w_vbakp-lgort. w_result-posnr = w_vbakp-posnr. w_result-matnr = w_vbakp-matnr. w_result-erdat = w_vbakp-erdat. w_result-bstkd = w_vbakp-bstkd. READ TABLE t_makt INTO w_makt WITH KEY matnr = w_vbakp-matnr. IF sy-subrc = 0. w_result-maktx = w_makt-maktx. ENDIF. READ TABLE t_vbep INTO w_vbep WITH KEY vbeln = w_vbakp-vbeln posnr = w_vbakp-posnr. IF sy-subrc = 0. w_result-lmeng = w_vbep-lmeng. w_result-wmeng = w_vbep-wmeng. w_result-edatu = w_vbep-edatu. ENDIF. READ TABLE t_vbpa INTO w_vbpa WITH KEY vbeln = w_vbakp-vbeln. * posnr = w_vbakp-posnr. IF sy-subrc = 0. w_result-kunnr = w_vbpa-kunnr. w_result-lifnr = w_vbpa-lifnr. ENDIF. APPEND w_result TO t_result. ENDLOOP. CLEAR w_result. ENDFORM. " FRM_HANDLE_DATA
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
(2)一般建议使用工作区前先清空工作区
(3)LOOP AT … INTO…. :主要用于循环内表,把内表数据一条一条取出来into到工作区里(马上要工作了^_^)
w_result-auart = w_vbakp-auart. w_result-vbeln = w_vbakp-vbeln. w_result-werks = w_vbakp-werks. w_result-lgort = w_vbakp-lgort. w_result-posnr = w_vbakp-posnr. w_result-matnr = w_vbakp-matnr. w_result-erdat = w_vbakp-erdat. w_result-bstkd = w_vbakp-bstkd.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
(4)上面循环的内表有很多需要的数据直接赋值给工作区w_result就可以
(5)对于循环内表t_vbakp没有的,比如物料描述信息等就要从其他地方取。前面我们已经获取了物料描述信息放在了内表t_makt里, 在这一步要做的是去取出物料对应的物料描述,就用到了READ TABLE …INTO…
(6)READ TABLE …INTO…WITH KEY…:主要用于读取内表数据into到工作区间,条件就是with key后面的。假设内表t_vbakp里有个物料112,当循环到这条记录时,就以这个物料号为条件去t_makt中查,有的话就把数据取出来放在工作区w_makt里。
READ TABLE t_makt INTO w_makt WITH KEY matnr = w_vbakp-matnr. IF sy-subrc = 0. w_result-maktx = w_makt-maktx. ENDIF.
- 1
- 2
- 3
- 4
- 5
- 6
(7)sy-subrc = 0表示语句运行成功。如果成功就给工作区w_result的物料描述赋值,但是read table只取一条数据,什么意思呢?比如说物料112有两个物料描述,但是w_makt工作区的物料描述就取第一条,因为工作区只能放一条数据。
(8)APPEND… to…:一般把工作区的数据添加到内表里。每一次循环都是给工作区w_result里的字段赋值,赋值完再把工作区添加到内表t_result里。即每次循环都往内表存数据。
6)展示ALV
创建子程序frm_alv_show,子程序里再创建以下几个程序。子程序可以让报表可读性增强,双击程序名可以快速定位到对应的位置
FORM frm_alv_show. PERFORM frm_init_layout. PERFORM frm_set_fieldset. PERFORM frm_output_alv. PERFORM f_status USING rt_extab . ENDFORM. "frm_alv_show *&---------------------------------------------------------------------*
- 1
- 2
- 3
- 4
- 5
- 6
- 7
(1)PERFORM frm_init_layout.
初始化ALV布局,可以自动根据数据长度调整列宽
FORM frm_init_layout . t_layout-colwidth_optimize = 'X'. t_layout-zebra = 'X'. *t_layout-box_fieldname = 'BOX'. ENDFORM.
- 1
- 2
- 3
- 4
- 5
(2)PERFORM frm_set_fieldset:
该子程序主要用于设置ALV字段
FORM frm_set_fieldset . PERFORM frm_init_fieldcat USING 'VBELN' '销售凭证'. PERFORM frm_init_fieldcat USING 'AUART' '销售类型'. PERFORM frm_init_fieldcat USING 'WERKS' '工厂'. PERFORM frm_init_fieldcat USING 'LGORT' '库存地点'. PERFORM frm_init_fieldcat USING 'POSNR' '项目'. PERFORM frm_init_fieldcat USING 'MATNR' '物料'. PERFORM frm_init_fieldcat USING 'MAKTX' '物料描述'. PERFORM frm_init_fieldcat USING 'ERDAT' '创建日期'. PERFORM frm_init_fieldcat USING 'EDATU' '计划交货日期'. PERFORM frm_init_fieldcat USING 'KUNNR' '客户'. PERFORM frm_init_fieldcat USING 'LIFNR' '供应商'. PERFORM frm_init_fieldcat USING 'BSTKD' 'PO'. PERFORM frm_init_fieldcat USING 'LMENG' '订单数量'. PERFORM frm_init_fieldcat USING 'WMENG' '需求数量'. ENDFORM. " FRM_SET_FIELDSET *&---------------------------------------------------------------------*
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
这里的字段就是ALV报表即将显示的字段,注意这里的字段名都必须大写否则报错
可以看到该程序里面又有一个子程序frm_init_fieldcat,SAP通过USING传递参数,对应子程序的参数。
PERFORM frm_init_fieldcat USING 'VBELN' '销售凭证'.
- 1
FORM frm_init_fieldcat USING fieldcatname LIKE w_fieldcat-fieldname seltext LIKE w_fieldcat-seltext_l. CLEAR w_fieldcat. w_fieldcat-fieldname = fieldcatname . w_fieldcat-seltext_m = seltext. w_fieldcat-seltext_l = seltext. w_fieldcat-seltext_s = seltext. APPEND w_fieldcat TO t_fieldcat. ENDFORM.
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
frm_init_fieldcat 通过using 接收参数,这里有两个参数:字段和字段描述。
(3)PERFORM frm_output_alv.
这里需要调用函数[‘REUSE_ALV_GRID_DISPLAY’]输出ALV

FORM frm_output_alv . CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY' EXPORTING * I_INTERFACE_CHECK = ' ' * I_BYPASSING_BUFFER = ' ' * I_BUFFER_ACTIVE = ' ' i_callback_program = sy-repid i_callback_pf_status_set = 'F_STATUS ' * I_CALLBACK_USER_COMMAND = ' ' * I_CALLBACK_TOP_OF_PAGE = ' ' * I_CALLBACK_HTML_TOP_OF_PAGE = ' ' * I_CALLBACK_HTML_END_OF_LIST = ' ' * I_STRUCTURE_NAME = * I_BACKGROUND_ID = ' ' * I_GRID_TITLE = * I_GRID_SETTINGS = is_layout = t_layout it_fieldcat = t_fieldcat * IT_EXCLUDING = * IT_SPECIAL_GROUPS = * IT_SORT = * IT_FILTER = * IS_SEL_HIDE = * I_DEFAULT = 'X' * I_SAVE = ' ' * IS_VARIANT = * IT_EVENTS = * IT_EVENT_EXIT = * IS_PRINT = * IS_REPREP_ID = * I_SCREEN_START_COLUMN = 0 * I_SCREEN_START_LINE = 0 * I_SCREEN_END_COLUMN = 0 * I_SCREEN_END_LINE = 0 * I_HTML_HEIGHT_TOP = 0 * I_HTML_HEIGHT_END = 0 * IT_ALV_GRAPHICS = * IT_HYPERLINK = * IT_ADD_FIELDCAT = * IT_EXCEPT_QINFO = * IR_SALV_FULLSCREEN_ADAPTER = * IMPORTING * E_EXIT_CAUSED_BY_CALLER = * ES_EXIT_CAUSED_BY_USER = TABLES t_outtab = t_result * 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_OUTPUT_ALV
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
上面的t_outtab就是要输出的ALV表即t_result表。
(4)创建状态
没有状态ALV报表状态栏上的按钮都不能用

看看状态里有什么,直接双击状态名

FORM f_status USING rt_extab TYPE slis_t_extab. SET PF-STATUS 'STANDARD_FULLSCREEN' EXCLUDING rt_extab. ENDFORM. "FRM_PLATFORM_O
- 1
- 2
- 3
5.效果

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/178092.html原文链接:https://javaforall.net
