ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 本程序是否还可以优化?

本程序是否还可以优化?

原创 Linux操作系统 作者:chouer523 时间:2019-05-11 22:36:05 0 删除 编辑

今天听说有个程序让我同事优化一下。以前我也写过好多的报表,但是程序优化上面接触的不是很多,为了避免这样的事情,今天在网上逛了一下,发现还有挺多的问题的。

以下是我在论坛上看到的一个需要优化的程序,以及一些网友的回答,感觉还不错。


各位台兄,小弟乃一ABAP/4新手,受命写一报表程序,实现采购申请/定单的交货情况查询。。经
百般努力,挤出如下程序。
虽可实现目的,但本人甚不满意。原因有三:
1、该程序冗长,执行效率低!
2、不能查询没有MR的PO..
3、可能还有一些Bugs.修修补补了几个错误(现在已经是版本3.0了。。呵呵),但我怀疑还有不
对的地方。

希望各位大虾多加指教。。对嵌套循环是否有更好的流程?
在此谢过!

REPORT ZMMPUR01 NO STANDARD PAGE HEADING LINE-SIZE 254 LINE-COUNT 65(2).
TABLES: EKPO, "PO Items
EKKO, "PO Header
EBAN, "Purchase Requisition
EKET, "Delivery Schedules
EKBE, "History of PO
LFA1. "Vendor Master

TYPES: MATNUM(9) TYPE N,
CSTRING(24) TYPE C,
TITLESTR(248) TYPE C,
QUANTY(5) TYPE P DECIMALS 2.
DATA CDATE TYPE CSTRING.
DATA: REFCODE TYPE CSTRING, TITLE TYPE TITLESTR.
DATA: BEGIN OF ITTAB OCCURS 100,
LGORT LIKE EBAN-LGORT, "MR Proj. No.
BANFN LIKE EBAN-BANFN, "MR Number
BNFPO LIKE EBAN-BNFPO, "MR Item Number
BADAT LIKE EBAN-BADAT, "MR Requisition Date
AFNAM LIKE EBAN-AFNAM, "Requisiter Name
MATNR TYPE MATNUM, "Material Number
TXZ01 LIKE EBAN-TXZ01, "Material Description
MENGE TYPE QUANTY, "MR Quantity
MEINS LIKE EBAN-MEINS, "MR Unit
LFDAT LIKE EBAN-LFDAT, "MR Delivery Date
EBELN LIKE EBAN-EBELN, "PO Number
EBELP LIKE EBAN-EBELP, "PO Item Number
BEDAT LIKE EKKO-BEDAT, "PO Creation Date
MENGE2 TYPE QUANTY, "PO quantity
MEINS2 LIKE EKPO-MEINS, "PO unit
LIFNR LIKE EKKO-LIFNR, "Vendor Number
LOEKZ LIKE EKPO-LOEKZ, "PO Item Deletion Indicator 'L'
NAME1 LIKE LFA1-NAME1, "Vendor Name
AMOUNT LIKE EKPO-NETPR, "Item Amount in orginal currency
WAERS LIKE EKKO-WAERS, "PO Currency Key
EINDT LIKE EKET-EINDT, "PO Delivery Date
WEMNG LIKE EKET-WEMNG, "Total item GR quantity.
BUDAT LIKE EKBE-BUDAT, "Actual Delivery Date. Posting Date
MENGE3 TYPE QUANTY, "Actual Delivery Quantity (GR Quantity)
ELIKZ LIKE EKPO-ELIKZ, "Delivery Completed Indicator: value 'X'
BWART LIKE EKBE-BWART, "Movement type, '101' for GR
END OF ITTAB.

DATA: Z_BEDAT LIKE EKKO-BEDAT, "PO Creation Date
Z_MENGE2 LIKE EKPO-MENGE, "PO quantity
Z_MEINS2 LIKE EKPO-MEINS, "PO unit
Z_LIFNR LIKE EKKO-LIFNR, "Vendor Number
Z_AMOUNT LIKE EKPO-NETPR, "PO Item Amount in original cucy.
Z_LOEKZ LIKE EKPO-LOEKZ, "PO Item Deletion Indicator
Z_WAERS LIKE EKKO-WAERS, "PO Currency Key
Z_EINDT LIKE EKET-EINDT, "PO Delivery Date
Z_BUDAT LIKE EKBE-BUDAT, "Actual Delivery Date. Posting Date
Z_MENGE3 LIKE EKBE-MENGE, "Actual Delivery Quantity (GR Quantity)
Z_ELIKZ LIKE EKPO-ELIKZ. "Delivery Completed Indicator:value 'X'


SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN: BEGIN OF BLOCK B1 WITH FRAME TITLE TEXT-001.
SELECT-OPTIONS: Y_LIFNR FOR EKKO-LIFNR,
Y_EINDT FOR EKET-EINDT.
PARAMETERS Y_ELIKZ AS CHECKBOX.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 3(30) TEXT2.

INITIALIZATION.
TEXT2 = '排除已全部交货项目!'.
SELECTION-SCREEN: END OF BLOCK B1.

SELECTION-SCREEN SKIP 2.
FORMAT COLOR 6 INTENSIFIED ON.
SELECTION-SCREEN COMMENT 1(83) TEXT-002.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-003.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-004.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-005.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-006.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-007.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-008.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-009.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-010.
SELECTION-SCREEN SKIP 1.
SELECTION-SCREEN COMMENT 1(83) TEXT-011.

CDATE = SY-DATUM.
CONCATENATE SY-SYSID SY-MANDT SY-REPID '.' CDATE INTO REFCODE.
CONCATENATE '*** Printed By' SY-UNAME 'at:' SY-UZEIT 'on' SY-DATUM
'/// Ref. Code:' REFCODE '***'
INTO TITLE SEPARATED BY SPACE.

START-OF-SELECTION.

GET EBAN.

CLEAR:Z_BEDAT,
Z_MENGE2,
Z_MEINS2,
Z_LIFNR,
Z_WAERS,
Z_LOEKZ,
Z_EINDT,
Z_BUDAT,
Z_AMOUNT,
Z_MENGE3,
Z_ELIKZ.
IF EBAN-EBELN NE SPACE AND EBAN-EBELP NE SPACE. "MR 是否已转化为PO
SELECT * FROM EKET WHERE BANFN = EBAN-BANFN AND BNFPO = EBAN-BNFPO.
CLEAR:Z_BEDAT,
Z_MENGE2,
Z_MEINS2,
Z_LIFNR,
Z_WAERS,
Z_LOEKZ,
Z_EINDT,
Z_BUDAT,
Z_AMOUNT,
Z_MENGE3,
Z_ELIKZ.

Z_EINDT = EKET-EINDT.
SELECT * FROM EKPO WHERE EBELN = EKET-EBELN AND EBELP = EKET-EBELP.
Z_MENGE2 = EKPO-MENGE.
Z_MEINS2 = EKPO-MEINS.
Z_ELIKZ = EKPO-ELIKZ.
Z_LOEKZ = EKPO-LOEKZ.
Z_AMOUNT = EKPO-MENGE * EKPO-NETPR / EKPO-PEINH.
ENDSELECT.
SELECT * FROM EKKO WHERE EBELN = EKET-EBELN.
Z_BEDAT = EKKO-BEDAT.
Z_LIFNR = EKKO-LIFNR.
Z_WAERS = EKKO-WAERS.
Z_LIFNR = EKKO-LIFNR.
Z_WAERS = EKKO-WAERS.
ENDSELECT.
SELECT NAME1 INTO ITTAB-NAME1 FROM LFA1 WHERE LIFNR = EKKO-LIFNR.
ENDSELECT.
IF EKET-WEMNG <> '0'.
SELECT * FROM EKBE
WHERE EBELN = EKET-EBELN AND EBELP = EKET-EBELP AND BWART = '101'.
CLEAR: Z_BUDAT, Z_MENGE3.
Z_BUDAT = EKBE-BUDAT.
Z_MENGE3 = EKBE-MENGE.
ITTAB-LGORT = EBAN-LGORT.
ITTAB-BANFN = EBAN-BANFN.
ITTAB-BNFPO = EBAN-BNFPO.
ITTAB-BADAT = EBAN-BADAT.
ITTAB-AFNAM = EBAN-AFNAM.
ITTAB-MATNR = EBAN-MATNR.
ITTAB-TXZ01 = EBAN-TXZ01.
ITTAB-MENGE = EBAN-MENGE.
ITTAB-MEINS = EBAN-MEINS.
ITTAB-LFDAT = EBAN-LFDAT.
ITTAB-EBELN = EKET-EBELN.
ITTAB-EBELP = EKET-EBELP.
ITTAB-BEDAT = Z_BEDAT.
ITTAB-MENGE2 = Z_MENGE2.
ITTAB-MEINS2 = Z_MEINS2.
ITTAB-LIFNR = Z_LIFNR.
ITTAB-AMOUNT = Z_AMOUNT.
ITTAB-LOEKZ = Z_LOEKZ.
ITTAB-WAERS = Z_WAERS.
ITTAB-EINDT = Z_EINDT.
ITTAB-BUDAT = Z_BUDAT.
ITTAB-MENGE3 = Z_MENGE3.
ITTAB-ELIKZ = Z_ELIKZ.
APPEND ITTAB.
ENDSELECT.
ELSE.
ITTAB-LGORT = EBAN-LGORT.
ITTAB-BANFN = EBAN-BANFN.
ITTAB-BNFPO = EBAN-BNFPO.
ITTAB-BADAT = EBAN-BADAT.
ITTAB-AFNAM = EBAN-AFNAM.
ITTAB-MATNR = EBAN-MATNR.
ITTAB-TXZ01 = EBAN-TXZ01.
ITTAB-MENGE = EBAN-MENGE.
ITTAB-MEINS = EBAN-MEINS.
ITTAB-LFDAT = EBAN-LFDAT.
ITTAB-EBELN = EKET-EBELN.
ITTAB-EBELP = EKET-EBELP.
ITTAB-BEDAT = Z_BEDAT.
ITTAB-MENGE2 = Z_MENGE2.
ITTAB-MEINS2 = Z_MEINS2.
ITTAB-LIFNR = Z_LIFNR.
ITTAB-LOEKZ = Z_LOEKZ.
ITTAB-AMOUNT = Z_AMOUNT.
ITTAB-WAERS = Z_WAERS.
ITTAB-EINDT = Z_EINDT.
ITTAB-BUDAT = Z_BUDAT.
ITTAB-MENGE3 = Z_MENGE3.
ITTAB-ELIKZ = Z_ELIKZ.
APPEND ITTAB.
ENDIF.
ENDSELECT.
ELSE.
ITTAB-LGORT = EBAN-LGORT.
ITTAB-BANFN = EBAN-BANFN.
ITTAB-BNFPO = EBAN-BNFPO.
ITTAB-BADAT = EBAN-BADAT.
ITTAB-AFNAM = EBAN-AFNAM.
ITTAB-MATNR = EBAN-MATNR.
ITTAB-TXZ01 = EBAN-TXZ01.
ITTAB-MENGE = EBAN-MENGE.
ITTAB-MEINS = EBAN-MEINS.
ITTAB-LFDAT = EBAN-LFDAT.
ITTAB-EBELN = EKET-EBELN.
ITTAB-EBELP = EKET-EBELP.
ITTAB-BEDAT = Z_BEDAT.
ITTAB-MENGE2 = Z_MENGE2.
ITTAB-MEINS2 = Z_MEINS2.
ITTAB-LIFNR = Z_LIFNR.
ITTAB-LOEKZ = Z_LOEKZ.
ITTAB-AMOUNT = Z_AMOUNT.
ITTAB-WAERS = Z_WAERS.
ITTAB-EINDT = Z_EINDT.
ITTAB-BUDAT = Z_BUDAT.
ITTAB-MENGE3 = Z_MENGE3.
ITTAB-ELIKZ = Z_ELIKZ.
APPEND ITTAB.
ENDIF.

END-OF-SELECTION.

SORT ITTAB BY LGORT BANFN BNFPO EBELN EBELP.
IF Y_ELIKZ = 'X'.
LOOP AT ITTAB WHERE EINDT IN Y_EINDT AND LIFNR IN Y_LIFNR
AND LOEKZ <> 'L' AND ELIKZ <> Y_ELIKZ.
WRITE:/ SY-VLINE NO-GAP, ITTAB-LGORT NO-GAP,
SY-VLINE NO-GAP, ITTAB-BANFN NO-GAP,
SY-VLINE NO-GAP, ITTAB-BNFPO NO-GAP,
SY-VLINE NO-GAP, ITTAB-BADAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-AFNAM NO-GAP,
SY-VLINE NO-GAP, ITTAB-MATNR NO-GAP,
SY-VLINE NO-GAP, ITTAB-TXZ01(36) NO-GAP,
SY-VLINE NO-GAP, ITTAB-MENGE NO-GAP, ITTAB-MEINS NO-GAP,
SY-VLINE NO-GAP, ITTAB-LFDAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-EBELN NO-GAP,
SY-VLINE NO-GAP, ITTAB-EBELP NO-GAP,
SY-VLINE NO-GAP, ITTAB-BEDAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-MENGE2 NO-GAP, ITTAB-MEINS2 NO-GAP,
SY-VLINE NO-GAP, ITTAB-AMOUNT NO-GAP, ITTAB-WAERS NO-GAP,
SY-VLINE NO-GAP, ITTAB-NAME1(33) NO-GAP,
SY-VLINE NO-GAP, ITTAB-EINDT NO-GAP,
SY-VLINE NO-GAP, ITTAB-BUDAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-MENGE3 NO-GAP,
ITTAB-MEINS2 NO-GAP,SY-VLINE NO-GAP.
ULINE.
ENDLOOP.
IF SY-SUBRC <> '0'.
SKIP 4.
WRITE:30 '!!!! NO DATA CAN MEET YOUR REQUIREMENT, PLEASE CHECK YOUR',
'INPUT!!!!'.
ENDIF.
ELSE.
LOOP AT ITTAB WHERE EINDT IN Y_EINDT AND LIFNR IN Y_LIFNR
AND LOEKZ <> 'L'.
WRITE:/ SY-VLINE NO-GAP, ITTAB-LGORT NO-GAP,
SY-VLINE NO-GAP, ITTAB-BANFN NO-GAP,
SY-VLINE NO-GAP, ITTAB-BNFPO NO-GAP,
SY-VLINE NO-GAP, ITTAB-BADAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-AFNAM NO-GAP,
SY-VLINE NO-GAP, ITTAB-MATNR NO-GAP,
SY-VLINE NO-GAP, ITTAB-TXZ01(36) NO-GAP,
SY-VLINE NO-GAP, ITTAB-MENGE NO-GAP, ITTAB-MEINS NO-GAP,
SY-VLINE NO-GAP, ITTAB-LFDAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-EBELN NO-GAP,
SY-VLINE NO-GAP, ITTAB-EBELP NO-GAP,
SY-VLINE NO-GAP, ITTAB-BEDAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-MENGE2 NO-GAP, ITTAB-MEINS2 NO-GAP,
SY-VLINE NO-GAP, ITTAB-AMOUNT NO-GAP, ITTAB-WAERS NO-GAP,
SY-VLINE NO-GAP, ITTAB-NAME1(33) NO-GAP,
SY-VLINE NO-GAP, ITTAB-EINDT NO-GAP,
SY-VLINE NO-GAP, ITTAB-BUDAT NO-GAP,
SY-VLINE NO-GAP, ITTAB-MENGE3 NO-GAP,
ITTAB-MEINS2 NO-GAP,SY-VLINE NO-GAP.
ULINE.
ENDLOOP.
IF SY-SUBRC <> '0'.
SKIP 4.
WRITE:30 '!!!! NO DATA CAN MEET YOUR REQUIREMENT, PLEASE CHECK YOUR',
'INPUT!!!!'.
ENDIF.

ENDIF.
SKIP 1.
IF SY-SUBRC = '0'.
WRITE: '======= THE END ======='.
ENDIF.

TOP-OF-PAGE.
FORMAT RESET.
* Draw a double-line box.
ULINE /1(254).
WRITE: / SY-VLINE.
ULINE 3(250).
WRITE:AT 254 SY-VLINE.
WRITE:/ SY-VLINE,SY-VLINE, AT 252 SY-VLINE,SY-VLINE.

FORMAT COLOR 7 INTENSIFIED ON.
WRITE:AT 4(248) 'MR->PO Delivery Status Report' CENTERED.
FORMAT RESET.
WRITE:/ SY-VLINE, SY-VLINE.
FORMAT COLOR 7 INTENSIFIED ON.
WRITE:(248) TITLE CENTERED.
FORMAT RESET.
WRITE: AT 252 SY-VLINE,SY-VLINE.
FORMAT RESET.
WRITE:/ SY-VLINE,SY-VLINE, AT 252 SY-VLINE, AT 254 SY-VLINE.
ULINE 3(250).
WRITE: SY-VLINE, AT 254 SY-VLINE.
ULINE.

IF SY-SYSID = 'DEV'.
FORMAT RESET.
FORMAT COLOR 6 INTENSIFIED ON.
WRITE:/(254) '!!!CAUTION:THE DATA ON THIS REPORT WAS RETRIEVED FROM THE
TEST/DEV SYSTEM AND THEREFOR CAN NOT BE USED FOR PRODUCTION PURPOSE!!!'
CENTERED.
FORMAT RESET.
ENDIF.
IF Y_ELIKZ = 'X'.
WRITE: / 'The fully delivered items are not included in this report!'.
ENDIF.

SKIP 1.
FORMAT COLOR 2 INTENSIFIED ON.
ULINE.
WRITE:/ SY-VLINE NO-GAP, 'Proj' NO-GAP,
SY-VLINE NO-GAP, 'MR Number' NO-GAP,
SY-VLINE NO-GAP,'M.ITM' NO-GAP,
SY-VLINE NO-GAP, 'MRCrteDate' NO-GAP,
SY-VLINE NO-GAP, ' Requisiter ' NO-GAP,
SY-VLINE NO-GAP,'Matr. No.' NO-GAP,
SY-VLINE NO-GAP,' Material Description ' NO-GAP,
SY-VLINE NO-GAP,' MR Quantity ' NO-GAP,
SY-VLINE NO-GAP,'MR Dlv Dte' NO-GAP,
SY-VLINE NO-GAP,'PO Number' NO-GAP,
SY-VLINE NO-GAP,'POItm' NO-GAP,
SY-VLINE NO-GAP,'POCrteDate' NO-GAP,
SY-VLINE NO-GAP,' PO Quantity ' NO-GAP,
SY-VLINE NO-GAP,'POAmount(OrigCurr.)' NO-GAP,
* SY-VLINE NO-GAP,'Vendor No.' NO-GAP,
SY-VLINE NO-GAP, 'Vendor Name ' NO-GAP,
SY-VLINE NO-GAP,'PODelrDate' NO-GAP,
SY-VLINE NO-GAP,'ActDlvDate' NO-GAP,
SY-VLINE NO-GAP,'Act.Dlvrd.Qty.' NO-GAP,SY-VLINE NO-GAP.
ULINE.
FORMAT RESET.

END-OF-PAGE.
ULINE.
WRITE:/ ' *** Page No:', SY-PAGNO,'***'.
WRITE AT 100 '!!!The deleted PO items are excluded in this report!!!'.

回复1:
你可以试试多用几个内部表, 将每个SELECT....ENDSELECT中的数据一步放入内部表中,然后再循
环内部表, 这样速度会改善很多. 因为在用SELECT...ENDSELECT时,程序每一个循环都要去访问数
据库,就会占用大量的系统资源,甚至会使整个系统的运行速度下降.

SELECT fields INTO CORRESPONDING FIELDS OF TABLE itab1
FROM table 1
WHERE conditions.

如果你在其它SELECT中会用到一个内部表中的值,你可以用下面的语句:

SELECT fields INTO CORRESPONDING FIELDS OF TABLE itab2
FROM table2
FOR ALL ENTRIES IN itab1
WHERE f1 = itab1-f1
AND ...

当然两个表有联系,可以使用INNER JOIN将它们关联起来,这样你可以一下子将两个表中的数据放
入一个内部表中. 不过请注意一点,用JOIN时最好不要多于三个表,会影响程序的性能.
其实你可以多花点时间去看SAP的帮助文件,那里讲的更详细.

回复2:
提几点建议.
1. 关于使用SELECT * : 我不知道你使用SELECT * 的原因,难道表中的所有字段都要使用?如果不
是,请只选择需要的字段,这样做写程序烦一点,但执行效率上也会好一些.
2. 选择条件的使用: 选择条件限制的越早, 选取的记录越少,执行速度也越快.在你的程序中,选
择条件在END SELECTION中使用,这意味着不管输入什么条件,所有的采购单/收货记录被选出来,这
样速度会比较慢.
3. 关于嵌套使用SELECT: 一般情况下不建议使用嵌套的SELECT,替代的方法是把记录取到多个
INTERNAL TABLE 中,然后对INTERNAL TABLE进行循环处理.
4. 既然存在没有MR的PO这种情况, 应该先从EKKO,EKPO表提取数据,等到收货记录提取完毕,最后
在查找相应的MR记录并添加MR没有转变PO的记录.

原贴地址:

http://www.erphome.net/wdb/wdbread.php?forumid=14&filename=f_784

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/332542/viewspace-53578/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-03-28

  • 博文量
    40
  • 访问量
    31423