事件流(6个):
INITIALIZATION(初始化)
AT SELECTION-SCREEN(屏幕跳出前)
START-OF-SELECTION(取数据)
END-OF-SELECTION(展示数据)
TOP-OF-PAGE(普通报表输出页头)
END-OF-PAGE(普通报表输出页尾)
1. 引用类型z_ref数据对象myref在程序中的声明方式:
DATA myref TYPE z_ref.
CREATE DATA myref TYPE z_ref.
2. 参照数据字典中的表类型生成内表对象或结构体:
DATA mytable TYPE z_table,”数据字典表类型,声明内表.
myline TYPE LINE OF z_table.”表类型的行结构,声明结构体.
3. 取系统日期:SY-DATUM,
4. 取系统时间:SY-UZEIT.0
5. 系统字段定位:SY-FDPOS.字符比较结果为真时,此字段将给出偏移量信息.
6. 系统字段SY-FDPOS给出字符的位置信息.(P109)
7. 系统字段SY-INDEX记录循环语句中的循环次数
8. 操作内表行结束后系统字段SY-TABIX返回该行索引.对于所有行操作,如果操作成功,系统变量SY-SUBRC返回0,否则返回非0值.
9. 系统用户名:SY-UNAME.
10. SY-HOST?屏幕序号:sy-dynnr.
11. OK代码:SY-UCOMM或SYST-UCOMM
12. 屏幕组ID:SY-DYNGR.
13. 常量声明:CONSTANT const(len) TYPE type|LIKE dobj [DECIMALS dec] [VALUE val].
14. 确定数据对象属性:DESCRIBE FIELD f [LENGTH l] [TYPE t [CONPONENTS n]] [OUTPUT-LENGTH o] [DECIMALS d] [EDIT MASK m] [HELP-ID h].
15. 数据赋值:MOVE source TO destination.或destination = source.
16. 设定初始值:CLEAR F.
17. 检查字段是否为初始值:f IS INITIAL….
18. 检查字段是否被分配:fs IS ASSIGNED…..
19. 检查过程中的参数是否被实参填充:p IS [SUPPLIED|REQUESTED]….
20. 检查数据对象的值是否属于某范围之间:f1 BETWEEN f2 AND f3…..
21. 检查数据对象f的内容是否遵从某个选择表的逻辑条件:f in seltab….
22. WRITE: /10 g,”在10个空格后输出变量g
/(8) time using edit mask ‘__:__:__’.”输出的变量time保持8位的长度.
23. 将光标移动到下一行:SKIP.
24. 强制结束循环:EXIT,STOP或REJECT.
25. 循环的中止:CONTINUE无条件中止当前循环并开始下一轮循环,CHECK条件为真时循环,为假时结束本次循环并开始下一轮循环,EXIT无条件中止并退出整个循环.
26. 将字符串左移:SHIFT string.
27. 连接字符串:CONCATENATE s1 s2 …..sn INTO s_dest [SEPARATED BY sep].如果结果出现被截断的情况,将SY-SUBRC返回4,否则返回0.符号&用于在字字符串换行时的连接.
28. 根据分隔符sep拆分字符串:SPLIT s_source AT sep INTO s1 s2 ……sn.使用内表操作可以避免被截断的情况:SPLIT s_source AT sep INTO TABLE itab.此语句根据子串数目生成n行的内表.
29. 循环输出内表的每一行数据:LOOP AT itab INTO text.ENDLOOP.
30. 替换字段内容:REPLACE str1 WITH str2 INTO s_dest [LENGTH len]. 字段SY-SUBRC的返回值为0时表示己成功替换.
31. 确定字段长度:[COMPUTE] n = STRLEN( str ).
32. 删除字符串中的多余空格:CONDENSE
33. 字符转换,如将ABC转换为abc:TRANSLATE
34. 创建一个可以排序的格式:CONVERT TEXT.
35. 用一个字符串覆盖另一个字符串:OVERLAY
36. WRITE TO赋值时将忽略数据对象的类型,而将其视为字符类型数据.
37. 字符串比较中的换码字符:#,用于转换比较时使用的通配符:*或+.及进行区分大小写,空格的比较,如#A表示比较大写的A.
38. 定位操作子串:strName[+0][(1)].
39. 字段符号,数据引用:动态数据对象.
40. 子过程定义:FORM subroutine_name USING parameters1 parameters2…. ….ENDFORM.
41. 子程序调用:PERFORM subroutine_name USING actual_parameters1 p2…. (其中USING可换成CHANGING)
42. ULINE.输出下划线.
43. 错误查看:ST22
44. 程序打包release:SE01:找到对应的程序,点开后点上面小汽车,再选中上面的后再点小汽车.点check.程序修改后需要重新打包.
45. 制作T-CODE:SE93,TCODE应按顺序编号:ZMF+流水号,我的程序名
46. 创建table:t-code:se11,attributes:Delivery class:C.开发类别:ZFI,当自定义Field type时,名称需为Z+…..格式.->设置技术属性(Technical Setting):Logical storage parameters中Data class:APPL1,Size category:4à创建function group:SE80,创建好后将创建的TABLE挂接到function grouph上去:用se11查出table,点utilites->table maintenance generator:Authorization groups:&NC&,Function group中填刚才创建的功能组名称->one step->overview screen中必须填未使用的number,此处screen number与table是一一对应的关系,也可让点系统上面的按钮:find screen number来自动搜索适合的scr. Number.->create,成功后,找到对应的function group中的screen number双击即可看到生成的代码.需要修改域名可在function group中的element list或layout中.-->se93创建t-code,start object选transaction with parameters(parameter transaction)->default values for->transantion:SM30->Default Values->name of screen field:viewname\update,value:table name\X.
47. field-sign:,field—option:,field-low:表示选择条件中起始值
48. 在where子句中如果只有一个表的话,可以不用指定表名.
49. 获取用户IP地址及用户名:
call function 'TH_USER_INFO' " Get user IP,hostname
importing
hostaddr = iporg”转化前的IP地址
terminal = host”计算机名
exceptions
others = 1.
"Conv.IP addr to format 'xxx.xxx.xxx.xxx'
call function 'ZGJ_IPADR2STRING' "Conv.IP addr
exporting
ipadr = iporg”转化前的IP地址
importing
string = ipdec.”转化后的最终需要的IP地址
50.删除内表中数据完全相同的行,只保留一行: delete adjacent duplicates from itab1 COMPARING
51. spro:后台设定
52. 输出选择框write:/ itab1-flag as checkbox
第四章 ABAP基础
4.1.5 程序运行
1.程序内部调用,如下表:
功能 |
报表调用语句 |
事务调用语句 |
无返回调用 |
SUBMIT |
LEAVE TO TRANSACTION |
调用并返回 |
SUBMIT AND RETURN |
CALL TRANSACTION |
例:
REPORT z_calling_program.
START-OF-PROGRAM.
WRITE ‘This program calls another program.’.”此内容在输出界面看不到
SUBMIT z_simple_program.”上面的输出被此程序覆盖.
如果改用SUBMIT AND RETURN来调用则可以输出以上内容.
2.结束程序:LEAVE PROGRAM.可在任意点强制结束当前运行的程序.
4.1.6 内存管理
SAP程序同一个用户和系统可进行最多6个SAPGUI主会话.
4.2.1 数据定义
TYPES:BEGIN OF t_staff,
S_no(3) type n,
Name(20),
END OF t_staff.
DATA staff TYPE t_staff.
上例中定义了一个结构类型t_staff,并根据其声明了一个结构体对象staff.
数据类型中的扁平结构与纵深结构:
扁平类型:运行时长度固定的类型.
纵深类型:运行时长度可峦的类型.
4.2.2 ABAP内置基本数据类型:
数据 类型 |
默认大小 |
有效大小 |
初始值 |
说明 |
示例 |
C |
1 |
1-65535 |
SPACE |
文本字符(串) |
‘name’ |
N |
1 |
1-65535 |
’00…0’ |
数字文本 |
‘0123’ |
T |
6 |
6 |
‘000000’ |
时间(HHMMSS) |
‘123010’ |
D |
8 |
8 |
‘00000000’ |
日期(YYYYMMDD) |
‘20080101’ |
I |
4 |
4 |
0 |
整型(整数) |
99 |
F |
8 |
8 |
0 |
浮点数 |
5E+04 |
P |
8 |
1-16 |
0 |
压缩数 |
12.91 |
X |
1 |
1-65535X |
‘0’ |
十六进制数 |
‘3A’ |
String |
1 |
无限定 |
SPACE |
字符串(长度可峦) |
‘A String’ |
XString |
1 |
无限定 |
SPACE |
十六进制字符串 |
‘A3FF’ |
注意:
1.其中C,N,T,D,I,F,P,X为定长类型,即在运行期间长度不能改变.
2.类型T,D,I,F的数据存储长度是固定的,不能指定参照其生成的数据对象占用的内存字节数.
3.基于类型C,N,P,X生成的数据对象需要在声明时指定其长度.否则取默认值.
4.如果在声明一个数据对象时未指明其数据类型,则该数据默认为C类型.
5.类型I的数值范围:-231到231-1的整数.如果运算时出现非整型结果则进行四舍五入取值.而不是截断小数.
6.类型P用于声明小数字固定的压缩数,其占据内存字节数和数值范围取决于定义时指定的整个数据的大小和小数点后位数,如果不指定小数字,则将其视为I类型数据.有效大小可以是从1~16字节的任意值,小数点后最多允许14个数字.
7,类型F为浮点数,浮点意思是数字在内存中以字节形式表示,数值范围:1*10-307到1*10308,因系统将F类型转换为二进制数,所以可能出现舍入误差,若用户要求较高精度且数值较大时,应使用P类型数据.
8.长度可峦的内置类型String, XString是通过引用实际动态的数据对象的固定内存地址来操作.
4.2.3 程序内部数据定义
参照自定义类型或内置类型生成数据的语法格式:
TYPES|DATA …TYPE l_type…
参照程序中已经声明的数据对象生成新数据语法:
TYPES|DATA …LIKE dobj…
3.结构类型和结构体
参照结构类型生成的数据对象称为结构体.
TYPES|DATA:BEGIN OF structure.
k1 [TYPE type |LIKE dobj]…,
k2 [TYPE type |LIKE dobj]…,
…
kn [TYPE type |LIKE dobj]…,
END OF structure.
参照生成:
参照结构生成:TYPES|DATA structure TYPE str_type |LIKE str_dobj...
参照数据库表生成:TYPES|DATA structure TYPE dbtab.
4.表类型和内表
表类型的对象称为内表.
4.2.4 数据字典中的类型
l 数据元素(Data elements),相当于ABAP中的基本类型和引用类型.
l 结构(Structures),由数据元素字段构成,对应ABAP中的结构类型.
l 表类型(Table types),对应ABAP中的表类型.
数据字典中的数据类型与ABAP中的中数据类型对应关系:
数据字典类型 |
ABAP类型 |
运行长度 |
说明 |
ACCP |
N(6) |
6 |
会计结算周期 |
CHAR |
C(n) |
1~255 |
字符 |
CLNT |
C(3) |
3 |
集团,数据区域代码 |
CUKY |
C(5) |
5 |
货币代码 |
CURR(n,m) |
P((n+1)/2)DECIMAL m |
1~17 |
货币金额 |
DATS |
D(8) |
8 |
日期 |
DEC n,m |
P((n+1)/2)DECIMAL m |
n(1~31)m(1~17) |
数值计算 |
FLTP |
F(8) |
18 |
浮点数 |
INT1 |
X(1)(类型b) |
3 |
单字节整型数 |
INT2 |
X(2)(类型s) |
5 |
双字节整型数 |
INT4 |
X(4)(类型i) |
10 |
四字节整型数 |
LANG |
C(1) |
内部1位外部2位 |
语言代码 |
LCHR |
C(n) |
256~最大值 |
长字符 |
LRAW |
X(n) |
256~最大值 |
长位字符 |
NUMC n |
N(n) |
1~255 |
数值文字 |
PREC |
X(2) |
16 |
精确度 |
QUAN n,m |
P((n+1)/2)DECIMAL m |
1~17 |
数量 |
RAW n |
X(n) |
1~255 |
位字符串 |
TIMS |
T(6) |
6 |
时间 |
VARC n |
C(n) |
255~最大值 |
长字符(仅V3.0前可用) |
STRING |
STRING |
1~最大值 |
字符串 |
RAWSTRING |
XSTRING |
1~最大值 |
位字符串 |
UNIT |
C(n) |
2~3 |
单位 |
4.2.5 程序中的数据对象
1.文字对象
当字符文字长度超过编辑器的一行时,可以使用”&”进行连接,避免因换行而产生的多余空格,如:long = ‘This is ‘&
‘a long sentence’.
如果需要输出“’”,则需要在前面多加一个“’”转回愿意.
2.有名称的数据对象
常量声明:
CONSTANT: const(len) TYPE|LIKE dobj [DECIMALS dec] VALUE val.
结构体常量声明(每个组件必须指定初始值):
CONSTANT:BEGIN OF structure,
str1 TYPE|LIKE dobj [DECIMALS dec] VALUE val,
str2 TYPE|LIKE dobj [DECIMALS dec] VALUE val,
...,
strn TYPE|LIKE dobj [DECIMALS dec] VALUE val,
END OF structure.
3.系统数据对象(见附表)
4.查明数据对象属性
DESCRIBE FIELD f LENGTH len.此语句将字段f的长度写入变量len.
l LENGTH:确定数据对象长度.
l TYPE: 确定数据对象类型.
l OUTPUT-LENGTH:确定实际输出长度.
l DECIMALS:确定P类型小数位长.
l EDIT MASK:确定在数据字典中定义转换例程.
l HELP-ID:确定在数据字典中定义的F1帮助信息.
4.3 基本数据操作
4.3.1数据赋值
l MOVE source TO incept.等介于:incept = source.
l CLEAR dobj.将数据对象dobj还原为初始值.
l 结构体间赋值:struct2 = struct1.(组件结构相同).
l MOVE-CORRESPONDING struct1 TO struct2.(部分组件结构相同).
4.3.2类型转换(见附表).
4.3.3数值运算
1.算术运算
运算 |
数学表达式语句 |
关键词语句 |
加法 |
n = x + y. |
ADD y TO x. |
减法 |
n = x – y. |
SUBTRACT y FROM x. |
乘法 |
n = x * y. |
MULTIPLY x BY y. |
除法 |
n = x / y. |
DIVIDE x BY y. |
整除 |
n = x DIV y. |
无 |
取余 |
n = x MOD y. |
无 |
幂(乘方) |
n = x ** y. |
无 |
两个结构体的同名字段之间可以整体进行算术运算:
ADD-CORRESPONDING struct1 TO struct2.
SUBTRACT-CORRESPONDING struct1 FROM struct2.
MULTIPLY-CORRESPONDING struct2 BY struct1.
DIVIDE-CORRESPONDING struct2 BY struct1.
以上将对两个结构体中的同名字段进行相应运算(非数值类型数据会引起错误).
2.数学函数
任意类型参数的函数列表:
函数名 |
说明 |
ABS( dobj ) |
返回参数绝对值 |
SIGN( dobj ) |
返回参数符号:正数返回1,0返回0,负数返回-1. |
TRUNC( dobj ) |
返回参数的整数部分 |
FRAC( dobj ) |
返回参数的小数部分 |
CEIL( dobj ) |
返回不小于输入参数的最小整数值 |
FLOOR( dobj ) |
返回不大于输入参数的最大整数值 |
注意:函数名与左括号间不能有空格,括号与参数间必须有空格.
F类型参数的函数列表(其它类型参数将首先被转换为F类型).
函数名 |
说明 |
COS,SIN,TAN |
三角函数 |
ACOS,ASIN,ATAN |
反三角函数 |
COSH,SINH,TANH |
双曲函数 |
EXP |
底数为e(2.7182818285)的幂函数 |
LOG |
底数为e的自然对数 |
LOG10 |
底数为10的对数 |
SQRT |
平方根 |
4.3.4数据输出
输出格式化选项:
选项 |
应用类型 |
说明 |
LEFT-JUSTIFIED |
所有类型 |
左对齐 |
CENTERED |
所有类型 |
居中 |
RIGHT-JUSTIFIED |
所有类型 |
右对齐 |
UNDER g |
所有类型 |
输出直接开始于字段g |
NO-GAP |
所有类型 |
忽略输出时字段后的一位空格 |
USING EDIT MASK m |
所有类型 |
指定数据字典中定义的格式模板m |
USING NO EDIT MASK |
所有类型 |
撤消对格式模板的激活 |
NO-ZERO |
所有类型 |
用空格替代所有有前导零 |
NO-SIGN |
数值类型 |
不输出前导符号 |
DECIMALS d |
数值类型 |
输出d定义小数点后的数字位数,如需截断,则四舍五入 |
EXPONENT e |
数值类型 |
对F类型字段在e>定义幂指数 |
ROUND r |
数值类型 |
用10的负r次方乘P类型字段,然后取整 |
CURRENCY c |
数值类型 |
按系统表格TCURX中定义的格式将货币c格式化 |
DD/MM/YY|MM/DD/YY |
时间日期 |
格式调整,”/”为用户主记录中定义的分隔符 |
DD/MM/YYYY,...(同上) |
时间日期 |
格式调整,”/”为用户主记录中定义的分隔符 |
DDMMYY...(同上) |
时间日期 |
格式调整,无分隔符 |
注:用户主记录System->User profile->Own data(SU01).
4.3.5逻辑表达式
通用逻辑表达式列表:
运算符 |
意义 |
EQ或= |
等于 |
NE或<>或>< |
不等于 |
LT或< |
小于 |
LE或<= |
小于等于 |
GT或> |
大于 |
GE或>= |
大于等于 |
3.IS操作符
l ...f IS INITIAL...:检查字段f是否为初始值.
l ...fs IS ASSIGNED...:检查字段符号是否被分配.
l ...p IS [SUPPLIED|REQUESTED]...:检查过程中的参数是否被实参填充.
4.BETWEEN操作符
l ...f1 BETWEEN f2 AND f3...:检查数据对象的值是否属于特定范围之间.
5.IN操作符(P110)
l ...f IN seltab...:检查一个数据对象的内容是否遵从某个选择表的逻辑条件.
6.组合逻辑表达式
l AND:与.
l OR:或.
l NOT:非.
注:括号与操作数间至少要有一个空格,如:IF ( c > n ) AND ( c < f ).
4.4结构控制
程序代码分三种结构:
l 顺序结构:语句逐行执行.
l 分支结构:根据不同的条件执行不同语句块.
l 循环结构:反复执行某个语句.
4.4.1分支控制
1.IF/ENDIF结构:
IF
ELSEIF
......
ELSE.
ENDIF.
注:可嵌套.
2.CASE/ENDCASE结构:
CASE f.
WHEN f11 [OR f12 OR ...].
......
[WHEN OTHERS.]
ENDCASE.
其中,f为变量,fij可以是变量或者固定值.
4.4.2循环控制
1.无条件循环
DO [n TIMES].
ENDDO.
说明:n为循环次数,可以是文字或变量,如果没有限定n值,则必须用EXIT,STOP或REJECT等语句强制结束循环.DO循环可嵌套,SY-INDEX为当前循环次数.
2.条件循环
WHILE
ENDWHILE.
注:可嵌套,其它同上.
3.循环中止
l CONTINUE:无条件中止当前本轮循环,开始下一轮循环.
l CHECK:条件中止当前本轮循环(条件为假时), 开始下一轮循环.
l EXIT:无条件完全中止当前循环,继续循环结束语句(ENDDO,ENDWHILE等)后面的代码,如果在嵌套循环中,系统仅退出当前循环.
4.5处理字符数据
4.5.1字符数据
1.连接字符串
CONCATENATE s1 s2 ... sn INTO s_dest [SEPARATED BY sep].
注:所有字符串操作将忽略s1....sn中的尾部空格(如需保留空格,可使用指定偏移量).
如果出现截断情况,将SY-SUBRC设为4,否则返回0.
2.拆分字符串
SPLIT s_source AT sep INTO s1 s2 ... sn.
如果所有子串足够长且不必截断任何部分,则将SY-SUBRC设为0,否则返回4,
如果源字符串能够拆分的子串多过指定的数目,则源子串最后的剩余部分包括其后的分隔符都将写入最后一个子串,要避免这种情况,需要使用内表进行操作:
SPLIT s_source AT sep INTO TABLE itab.在该形式中,根据子串数目生成n行的内表.例如:
DATA:text type string,
itab TYPE TABLE OF string.
text = ‘ABAP is a programming language’.
SPLIT text AT space INTO TABLE itab.
LOOP AT itab INTO text.
WRITE / text.
ENDLOOP.
3.查找子串模式
SEARCH c FOR str.在字段c中查找字符串str.如果找到,则将SY-SUBRC返回0,SY-FDPOS返回字段c中该字符串的位置(从左算起的字节偏移量),否则SY-SUBRC返回4,查找模式有以下几种:
l str 搜索str并忽略尾部空格.
l .str. 搜索str,但不忽略尾部空格.
l *str 搜索以str结尾的单词.
l str* 搜索以str开始的单词.
REPORT z_string_search.
DATA string(30) TYPE c VALUE 'This is a testing sentence.'.
WRITE: / 'searched','sy-subrc','sy-fdpos'.
SEARCH string FOR 'X'.
WRITE: / 'X', sy-subrc UNDER 'sy-subrc',sy-fdpos UNDER 'sy-fdpos'.
SEARCH string FOR 'itt '.
WRITE: / 'itt ', sy-subrc UNDER 'sy-subrc',sy-fdpos UNDER 'sy-fdpos'.
SEARCH string FOR '.e .'.
WRITE: / '.e .', sy-subrc UNDER 'sy-subrc',sy-fdpos UNDER 'sy-fdpos'.
SEARCH string FOR '*e '.
WRITE: / '*e ', sy-subrc UNDER 'sy-subrc',sy-fdpos UNDER 'sy-fdpos'.
SEARCH string FOR 's* '.
WRITE: / 's* ', sy-subrc UNDER 'sy-subrc',sy-fdpos UNDER 'sy-fdpos'.
输出结果如下:
searched sy-subrc sy-fdpos
X 4 0
itt 4 0
.e . 4 0
*e 0 18
s* 0 18
4.替换字段内容.
REPLACE str1 WITH str2 INTO s_dest [LENGTH len].搜索s_dest中前len个字符中的子串str1,用str2来替换它,如果成功,SY-SUBRC返回0,否则还回非0值.
REPORT z_replace.
DATA name TYPE string.
name = 'Michael-Cheong'.
WHILE sy-subrc = 0.
REPLACE '-' WITH ' ' INTO name.
ENDWHILE.
WRITE / name.
输出结果: Michael Cheong
5.确定字段长度
n = STRLEN( str ).函数将str作为字符数据类型处理,不考虑其实际类型,也不进行转换.计算其首字符到最后一个非空字符的长度,不包括结尾空格.
6.其它操作语句
l SHIT:将字符串整体或子串进行位移.
l CONDENSE:删除字符串中的多余空格.
l TRANSLATE:字符转换,如将ABC转换为abc.
l CONVERT TEXT:创建一个可以排序的格式.
l OVERLAY:用一个字符串覆盖另一个字符串.
4.5.2字符数据比较(用于判断两个字符串之间的包含关系):
运算符 |
含义 |
s1 CO s2 |
如果s1仅包含s2中的字符,逻辑表达式为真 |
s1 CN s2 |
如果s1还包含s2之外的字符,逻辑表达式为真 |
s1 CA s2 |
如果s1包含任何一个s2中的字符,逻辑表达式为真 |
s1 NA s2 |
如果s1不包含s2的任何字符,逻辑表达式为真 |
s1 CS s2 |
如果s1包含字符串s2,逻辑表达式为真 |
s1 NS s2 |
如果s1不包含字符串s2,逻辑表达式为真 |
s1 CP s2 |
如果s1包含模式s2,逻辑表达式为真 |
s1 NP s2 |
如果s1不包含模式s2,逻辑表达式为真 |
注:CO,CN,CA,NA比较时区分大小写,且尾部空格也在比较范围之内,CS,NS,CP,NP比较时忽略尾部空格且不区分大小写,比较结束后,如果结果为真,SY-FDPOS将给出s2在s1中的偏移量信息.模式表示可以使用通配符,”*”用于替代任何字符串,”+”用于替代单个字符.
换码字符使用:
l 指定大小写(如#A,#b).
l 通配符”*”(输入#*),将其转回原义.
l 通配符”+”(输入#+),将其转回原义.
l 换码符本身”#”(输入##),将其转回原义.
l 字符串结尾空格(输入#__),指定比较结尾空格.
4.5.3定位操作子串
str[+position][(len)].从字符串str中的position位开始取出长度为len的子串.
可动态指定偏移量及长度的情况(即position及len可为变量):
l 用MOVE语句或赋值运算符给字段赋值时.
l 用WRITE TO语句向字段写入值时.
l 用ASSIGN将字段分配给字段符号时.
l 用PERFORM将数据传送给子程序时.
off = 6.
len = 2.
date+off(len) = ‘01’.
4.6使用内表
types定义的并不是结构体对象,只是结构类型,不能作为工作区,当定义的内表没有表头行(工作区)时,必须为其定义一个结构体作为工作区,否则无法使用此内表.如果没有给内表定义工作区,则在定义内表时必须声明表头行(with header line).
DATA:BEGIN OF line, "work area(structure)结构类型且结构体对象
num TYPE i,
sqr TYPE i,
END OF line,
"无表头行内表,内表定义都使用data关键词.
itab TYPE(LIKE) STANDARD TABLE OF line WITH KEY table_line.
DATA DIRTAB LIKE CDIR OCCURS 10 WITH HEADER LINE.定义标准内表
DO 5 TIMES.
line-num = sy-index.
line-sqr = sy-index ** 2.
APPEND line TO itab.
ENDDO.
LOOP AT itab INTO line.
WRITE:/ line-num,line-sqr.
ENDLOOP.
CLEAR itab.
注:
1.TYPES与DATA区别:TYPES是用来定义某种类(型)的,需(用DATA语句)实例化以后才可以使用,而DATA是用来定义数据对象(实例变量)的,对于用DATA直接定义的结构体对象(不参照其它结构类型),其同时也是一个结构类型.
2.TYPE与LIKE区别:TYPE后面跟随的只能是某种类(型),而LIKE后面可以跟随类型或实例对象,参照结构体对象生成内表时只能用LIKE,不能用TYPE,因为结构体对象不是类型,只是一种实例对象,参照结构类型生成内表时可以用LIKE也可以用TYPE.其中通过LIKE定义的内表直接拥有参照结构类型的元素结构,而通过TYPE定义的内表只能间接拥有被参照结构类型的元素结构,结构类型不能作为内表的工作区,只有结构体对象才可以.
内表定义语法:
1.标准表:可指定或不指定关键词,可重复.逻辑索引,操作数据时数据内存位置不峦,系统只重排数据行的索引值.
DATA itab TYPE|LIKE [STANDARD] TABLE OF structure [WITH KEY comp1 ... compn(DEFAULT KEY) WITH HEADER LINE INITIAL SIZE n].
2.排序表:可指定唯一或不唯一的关键词,也可不指定,逻辑索引,按关键词升序存储.
DATA itab TYPE|LIKE SORTED TABLE OF structure [WITH NON-UNIQUE(UNIQUE) KEY comp1 ... compn(DEFAULT KEY) WITH HEADER LINE INITIAL SIZE n].
3.哈希表:必须指定唯一关键词.无索引
DATA itab TYPE|LIKE HASHED TABLE OF structure WITH UNIQUE KEY comp1 ... compn(DEFAULT KEY) [WITH HEADER LINE INITIAL SIZE n].
注:如果n值为0或不指定的话,程序会为内表对象分配8KB大小内存,所以,如果内表比较小,不要把该值设为0,以避免内存浪费.
旧版标准表定义语法:
DATA itab TYPE|LIKE [STANDARD] TABLE OF structure OCCURS n.或者
DATA:BEGIN OF itab OCCURS n,
...,
fi...,
END OF itab.
4.6.2操作内表行
|
标准表 |
排序表 |
哈希表 |
索引访问 |
允许 |
允许 |
不允许 |
关键词访问 |
允许 |
允许 |
允许 |
相同值关键词行 |
可重复 |
可重复或不可重复 |
不可重复 |
推荐访问方式 |
主要通过索引 |
主要通过关键词 |
只能通过关键词 |
注:CLEAR itab[].表示操作的是内表对象.而CLEAR itab.当itab有表头行时表示操作表头行,如无表头行时表示操作内表对象.
当一个操作语句结束后,SY-TABIX返回该行的索引值,对于所有行操作,如果访问成功,SY-SUBRC返回0,否则返回非0值.
4.插入行—INSERT
l INSERT structure INTO itab INDEX idx.无表头行索引表,itab的行数应大于或等于idx-1.否则失败
l INSERT itab INDEX idx.有表头行索引表.
l 对于哈希表,系统按关键词将新行插入特定位置.
l INSERT structure INTO|INITIAL LINE INTO TABLE itab.此语句对于标准表来说与append效果相同,对于排序表来说,插入的行不可以打乱按照关键词排序的顺序,否则插入不成功,对于哈希表来说,插入过程中系统按照关键词对行进行定位.INITIAL关键词是用于向内表中插入结构中各类型的初始值的.
l INSERT LINES OF itab1 [FROM n1] [TO n2] INTO [TABLE] itab2 [INDEX idx].将内表中部分或全部数据行整体插入到另一内表中,指定行数时itab1,itab2必须为索引表,指定TABLE关键词时,itab2可以是任意内表.此方式比其它方式快20倍左右.
5.附加行—APPEND(只能操作索引表)
APPEND [structure TO|INITIAL LINE TO] itab.
APPEND LINES OF itab1 [FORM n1] [TO n2] TO itab2.
6.聚集附加—COLLECT
COLLECT line INTO itab.对于需要附加的数据,如果在内表中存在关键词内容与其相同的数据行,则此语句将需要附加的数据累加到内表中的这一行上,而不会另外再添加一行,操作成功后,SY-TABIX返回被处理过的行的索引.
注:关键词以外的所有字段必须是数字类型
7.读取行—READ(可用于任何类型内表)
l READ TABLE itab [INTO wa|ASSIGNING
l READ TABLE itab FROM structure [INTO wa|ASSIGNING
l READ TABLE itab WITH TABLE KEY field1 = v1 ... field2 = v2 [INTO wa|ASSIGNING
l READ TABLE itab WITH KEY field1 = v1 ... field2 = v2 [INTO wa|ASSIGNING
8.修改行—MODIFY
l MODIFY itab [FROM wa] [INDEX idx] [TRANSPORTING f1 f2 ...].如果内表包含的行数少于idx,则不更改任何行.
l MODIFY TABLE itab FROM wa [TRANSPORTING f1 f2 ...].根据工作区wa中关键词修改内表行, TRANSPORTING表示修改指定字段值.
l MODIFY itab FROM wa TRANSPORTING f1 f2 ... WHERE condition.修改符合WHERE子句中条件的内表中的指定字段值.
9.删除行—DELETE
l DELETE itab INDEX idx.根据索引删除内表行.
l DELETE TABLE itab FROM wa.根据工作区关键词删除行.
l DELETE TABLE itab WITH TABLE KEY field1 = v1 ... field2 = v2.根据指定关键词值删除行.
l DELETE itab [FROM n1] [TO n2] [WHERE
10.循环处理--LOOP
LOOP AT itab [INTO wa] [FROM n1] [TO n2] [WHERE condition].
ENDLOOP.
4.6.3操作整个内表
1.排序
SORT itab [ASCENDING|DESCENDING] [AS TEXT] [STABLE]
[BY f1 [ASCENDING|DESCENDING] [AS TEXT]
......
f1 [ASCENDING|DESCENDING] [AS TEXT]]
说明:
l ASCENDING|DESCENDING:升序或降序.默认升序.
l AS TEXT:根据当前语言按字母顺序排序字符字段,否则按字符平台相关内部编码进行排序.
l STABLE:保持排序前后不需要改变的数据行的相对顺序.
2.控制级操作(用于总计,缩进,格式控制等)
AT FIRST|LAST|NEW f|END OF f.
ENDAT.
说明:
l FIRST:当循环为内表的第一行时,执行语句块中语句.在工作区中,系统用*填充所有关键词内容.
l LAST: 当循环为内表的最后一行时,执行语句块中语句. 在工作区中,系统用*填充所有关键词内容.
l NEW f:字段f前面(即左边)的全部字段内容之一不同于上一行时, 执行语句块中语句.在工作区中,系统用*填充f后面所有关键词内容.
l END OF f:如果下一行行组中的任何字段内容不同于上一行, 执行语句块中语句.在工作区中,系统用*填充f后面所有关键词内容.
注:在控制级操作期间,在工作区中,对于非标准关键词段,将全部进行初始化,在执行完控制操作后(即ENDAT语句后)工作区中的数据将全部还原到进入控制级操作语句前(即进入AT前)状态.
3.初始化内表
l CLEAR itab.:带表头行时只清空表头行,不带表头行时清空整个内表.
l CLEAR itab[].:只清空整个内表对象数据.不清空表头行.
l REFRESH itab或REFRESH itab[].:只清空整个内表对象数据.不清空表头行.
l FREE itab.或FREE itab[].:只清空整个内表对象数据.不清空表头行,同时释放内存.
l ......itab IS INITIAL....:检查内表是否为空.
4.整体复制内表
l MOVE itab1 TO itab2.:如果两表都存在表头行,则此语句只复制了表头行.
l MOVE itab1[] TO itab2[].:指定表体复制.
l MOVE itab1[] TO itab2.:表itab2无表头行时才成立.
l itab2 = itab1.同上1
l itab2[] = itab1[].同上2
l itab2 = itab1[].同上3
5.比较内表大小
... itab1
4.6.4Extract Datasets
l FIELD-GROUP fg.行结构分配.
l INSERT f1 f2 ... INTO fg.生成字段组fg的具体字段结构.
l EXTRACT fg.将字段组填充给EXTRACT.
l SORT.排序.
l LOOP.
4.7动态数据对象
4.7.1字段符号
l FIELD-SYMBOLS
l ASSIGN f TO
l ASSIGN f[+i] [(j)] TO
l ASSIGN (f) TO
4.7.2数据引用
TYPES t_dref TYPE REF TO DATA.
DATA dref TYPE REF TO DATA.
4.8模块化技术
4.8.2子程序
1.定义:
FORM subr [[USING [VALUE(p1)]... ] [TYPE t|LIKE f]...] [TYPE ANY]
[CHANGING [VALUE(p1)] ... ] [TYPE t|LIKE f]...] [TYPE ANY].
ENDFORM.
注:
l VALUE参数表未示值传递,此方式在子程序调用后实参的值不会被改变.
l 无VALUE参数时表示引用传递,会改变实参的值.
l USING与CHANGING无任何区别.
l 位于两个子程序间的代码不属于任何事件块.
l 参数传递时不存在类型转换,要求必须兼容.
2.调用:
PERFORM subr [USING p1 ... pn] [CHANGING pi ... pj].
4.8.3功能模块(p153)
4.8.5源代码复用
1.包含程序
包含程序是单纯的代码复用,不是可执行程序,不能单独运行,必须被其它程序调用,包含程序不能调用自身.
INCLUDE incl.包含程序调用,此语句必须独占一行.
2.宏:(语句块中最多只能包含9个占位符&1...&9).
例:
DATA:result TYPE i,
int1 TYPE i VALUE 1,
int2 TYPE i VALUE 2.
DEFINE operation.
result = &1 &2 &3.
output &1 &2 &3 result.
END-OF-DEFINITION.
DEFINE output.
write: / 'The result of &1 &2 &3 is',&4.
END-OF-DEFINITION.
operation 1 + 2.
operation int2 - int1.
4.9.1静态错误检查
1.语法检查:用Check键.
2.扩展语法检查(SLIN):在ABAP初台界面输出程序名后,选择Program->Check->Extended Syntax Check.àStandard.
4.9.2运行时错误控制
1.可捕捉的错误
CATCH SYSTEM-EXCEPTIONS exc1 = rc1 ... excn = rcn.
...
ENDCATCH.
其中exci表示一个单一可捕捉错误或者一个ERROR类,rci则代表一个数字.如果其中错误之一在CATCH和ENDCATCH语句之间出现,程序就不会中止,而是直接跳至ENDCATCH后,把系统指定的错误代码rci赋给字段SY-SUBRC.此语句可嵌套.例如:
DATA:result1 TYPE p DECIMALS 3,
number TYPE i VALUE 11.
CATCH SYSTEM-EXCEPTIONS arithmetic_errors = 5.
DO.
number = number - 1.
result1 = 1 / number.
WRITE: / number,result1.
ENDDO.
ENDCATCH.
IF sy-subrc = 5.
WRITE / 'division by zero!'.
ENDIF.
2.不可捕捉的错误(通过ST22查看,在SAP系统中保存14天,可通过Keep功能保存更长时间).
第六章 数据库操作
6.2.1表字段
在数据字典中,每创建一个数据库表后,都将同时生成一个同名的结构化数据类型.
6.2.2外部关键词
外部关键词内容必须在其对应的约束表(check table)中存在,否则无法插入.
6.2.3技术设定
1.数据类型(data class):
l APPL0(Master data),较少需要被修改的系统数据表,如员工个人信息.
l APPL1(Transaction data),需要经常被修改的数据表,如产品库存量表.
l APPL2(Organization and customizing),系统定制数据表,在系统安装后很少需要修改,如国家代码等.
2.数量级别:
0 0 to 6,600
1 6,600 to 26,000
2 26,000 to 100,000
3 100,000 to 420,000
4 420,000 to 34,000,000
3.缓冲(Buffering)机制
如果在缓冲设定中选择了Buffering switched on项,则需要设定其缓冲类型(有Full,Single-record和Generic三种).
缓冲机制的意义在于首次查询时将数据表中的数据放入应用服务器缓冲区,以提高后续查询效率,要注意最好不要对经常需要的数据库表设置该机制,对于经常读取但很少更新或者通常只有在60秒后才可能被其他应用服务器程序修改的数据库表,开启缓冲机制可以上百倍地提高效率.
4.Log data changes用于设定表中的数据修改时是否在系统日志中记录.
6.2.4索引
一个数据库表可以包含一个主索引(Primary Index)和多个附属索引(Secondary Indexes).主索引只包含表关键词和指向整个数据条目的指针,由系统自动生成并在添加数据库条目时进行维护.索引中的数据已经排序.
6.3.1SELECT语句
SELECT
[WHERE
[HAVING
l HAVING子句用于限定ORDER BY子句中数据条目组的选择条件
1.选择单行数据:
l SELECT SINGLE * FROM tab INTO wa_tab WHERE
l SELECT SINGLE field1 ... fieldn FROM tab INTO (wa_field1,...,wa_fieldn) WHERE
l SELECT SINGLE *|field1 ... fieldn FROM tab INTO CORRESPONDING FIELDS OF wa_tab WHERE
6.3.3选择多行数据
1.循环选择(DISTINCT去掉结果重复的行):
SELECT [DISTINCT] ... .
ENDSELET.
系统字段SY-DBCNT给读取的行计数.
2.选择至内表:
SELECT ... INTO|APPENDING [CORRESPONDING FIELDS OF] TABLE itab.
其中INTO选项将复盖itab中的数据,如果不想复盖只想追加则用APPENDING.
3.指定选择包大小(一次选择到内表的行数):
SELECT * FROM tab INTO|APPENDING TABLE wa_tab PACKAGE SIZE n.
ENDSELET.
6.3.4指定查询条件
1.比较运算符:=,<,>,<>,<=,>=.
2.范围限定运算符:WHERE ... f [NOT] BETWEEN g1 AND g2 ....
3.字符比较运算符:WHERE ... f [NOT] LIKE g [ESCAPE h]...其中g中通配符”_”用于替代单个字符,”%”用于替代任意字符串. ESCAPE选项举例如下:
SELECT ... WHERE city LIKE ‘edit#_%’ ESCAPE ‘#’.选择所有以”edit_”开始的城市.
4.检查列表值:WHERE ... f [NOT] IN (g1,...gn)...
5.检查空值: WHERE ... f IS [NOT] NULL...注:这里的NULL值不等同于初始值INITIAL
6.检查选择表.
l WHERE ... f [NOT] IN seltab...其中seltab为选择表,如选择屏幕中用户填充数据.
l SELECT ... WHERE ( code = ‘01’ OR code = ‘02’ ) AND NOT (country = ‘usa’ ).:AND,OR,NOT可以按照任意顺序组合.
l SELECT ... WHERE
6.3.5多表结合查询
1.SELECT语句嵌套
DATA:wa_carrid TYPE spfli-carrid,
wa_connid TYPE spfli-connid,
wa_carrname TYPE scarr-carrname.
SELECT carrid connid
FROM spfli
INTO (wa_carrid,wa_connid)
WHERE cityfrom = 'BOSTON'.
SELECT carrname
FROM scarr
INTO wa_carrname
WHERE carrid = wa_carrid.
WRITE:/ wa_carrname.
ENDSELECT.
ENDSELECT.
2.FOR ALL ENTRIES选项(比上面的嵌套要快)
DATA: BEGIN OF wa_carrid,
carrid TYPE spfli-carrid,
END OF wa_carrid.
DATA:wa_carrid_tab LIKE TABLE OF wa_carrid.
DATA:BEGIN OF wa_carrname,
carrid TYPE scarr-carrid,
carrname TYPE scarr-carrname,
END OF wa_carrname.
SELECT carrid
FROM spfli
INTO TABLE wa_carrid_tab
WHERE cityfrom = 'BOSTON'.
SELECT carrid carrname
FROM scarr
INTO wa_carrname
FOR ALL ENTRIES IN wa_carrid_tab”相当于循环输出内表在WHERE子句中出现的
WHERE carrid = wa_carrid_tab-carrid.”字段的值
WRITE:/ wa_carrname-carrid, wa_carrname-carrname.
ENDSELECT.
注:此子句中不能使用LIKE,BETWEEN,IN,ORDER BY.
3.使用视图:可先用SE11创建视图然后查询,效率更高.
4.结合查询
SELECT ... FROM table [INNER] JOIN jointab1 [AS alias1] ON
[INNER] JOIN jointab2 [AS alias2] ON
WHERE
SELECT ... FROM table LEFT [OUTER] JOIN jointab1 [AS alias1] ON
5.子查询(没有INTO子句,不能结合ON同时出现,可嵌套)
l SELECT ... FROM scar INTO
WHERE EXIST ( SELECT * FROM spfli
WHERE carrid = scarr-carrid
AND cityfrom = ‘BOSTON’ ).
l ...WHERE city IN ( SELECT cityfrom FROM spfli WHERE ...只返回单个字段.
l ...WHERE city = ( SELECT cityfrom FROM spfli WHERE ...单行返回结果.
l ... WHERE city > ALL|ANY|SOME ( SELECT cityfrom FROM spfli WHERE ...多行返回值.
6.3.6组合查询结果
1.总计功能
SELECT MAX|MIN|SUM|AVG|COUNT( [DISTINCT] f1 ) [AS a1]...其中DISTINCT选项将在统计之前先排除相同的选择结果.
2.分组总计
SELECT f1 [AS a1] ... MAX|MIN|SUM|AVG|COUNT( [DISTINCT] fm ) [AS am] ...
INTO (s1,...,sm...)|CORRESPONDING FIELDS OF itab...
GROUP BY f1...
注:分组总计必须指定查询字段或使用INTO CORRESPONDING FIELDS OF附加项,使用后者时需要通过AS后面的别名将总计结果存放在与别名同名的字段中.
3.指定分组条件
SELECT f1 [AS a1] ... MAX|MIN|SUM|AVG|COUNT( [DISTINCT] fm ) [AS am] ...
INTO (s1,...,sm...)|CORRESPONDING FIELDS OF itab...
GROUP BY f1...
HAVING
4.排序(SQL Trace工具查看数据库索引)
l ...ORDER BY PRIMARY KEY.系统将按主关键词升序排序.
l ...ORDER BY f1 [ASCENDING|DESCENDING] ...指定字段,默认升序.
6.3.7其它格式说明
l TABLSE dbtab.声明与数据库表同名同结构的工作区,是一种结构体对象,不是内表.
l dbname = ‘EKBE’.SELECT f1... FROM (dbname) INTO (s1,...)...动态指定数据库表,注意数据库表名必须大写.
l SELECT|UPDATE ... FROM dbtab CLIENT SPECIFIED WHERE mandt BETWEEN ‘100’ AND ‘103’.用CLIENT SPECIFIED选项取消系统自动处理当前集团数据表功能,同时就可以在WHERE子句中指定需要读取的集团.
l SELECT ... FROM dbtab BYPASSING BUFFER...取消TABLE技术设定中设定的缓冲机制,另,DISTINCT附加项与结合选择,总计选择,IS NULL条件,子查询,以及GROUP BY和ORDER BY同时使用时,也将自动忽略缓冲设定.
l SELECT ... FROM dbtab UP TO n ROWS...只选取满足条件的n行数据,如果n为0,则选取所有满足条件的数据,如果同时使用ORDER BY子句,则系统首先先出所有满足条件的数据并排序,然后将头n行作为选择结果.
l GET RUN TIME FIELD f.系统返回从程序开始后的毫秒数,其中f为I类型数据.
6.3.8使用光标(多个光标可指向同一个选择)
DATA: cur TYPE cursor.
OPEN CURSOR cur FOR SELECT carrid FROM spfli WHERE cityfrom = 'BOSTON'.打开光标.
DO.
FETCH NEXT CURSOR cur INTO (wa_carrid_tab-carrid).相当于循环读取OPEN CURSOR语句生成的结果集中的下一行数据.
APPEND wa_carrid_tab.
或者FETCH NEXT CURSOR cur INTO TABLE wa_carrid_tab.整体读取放放内表.
IF sy-subrc <> 0.如果FETCH语句没有读取任何行, sy-subrc返回4,否则返回0.
CLOSE CURSOR cur.关闭光标.
EXIT.
ENDIF.
ENDDO.
在SELECT语句中,数据从数据库中以大小为32KB的数据包传递至应用服务器,并通过INTO子句传至ABAP程序.
6.4更新数据
数据库操作结束后通过SY-SUBRC返回标识代码,如果操作成功,返回0,另SY-DBCUT还将返回实际操作的数据行数.
6.4.1 INSERT语句(数据库表必须是可维护状态)
l INSERT INTO dbtab|view VALUES wa.插入单行,视图数据必须来自同一个表.
l INSERT INTO dbtab|view FROM wa. 插入单行,视图数据必须来自同一个表.
l INSERT dbtab FROM TABLE itab.当有一条数据插入失败,系统不更新任何数据.
l INSERT dbtab FROM TABLE itab ACCEPTING DUPLICATE KEYS.如果出现关键词字相同条目,SY-SUBRC返回4,并跳过该条目,并更新其它条目.
6.4.2 UPDATE语句
l UPDATE dbtab SET f1 = g1 ... fn = gn WHERE
l UPDATE dbtab FROM wa.根据工作区中的关键词更新对应的条目.
l UPDATE dbtab FROM TABLE itab.根据内表关键词批量更新数据.
6.4.3 MODIFY语句
l MODIFY dbtab FROM wa.添加或更新单行.
l MODIFY dbtab FROM TABLE itab.添加或更新多行.
6.4.5 DELETE语句
l DELETE FROM dbtab WHERE
l DELETE dbtab FROM wa.
l DELETE dbtab [CLIENT SPECIFIED] FROM TABLE itab.如果有一行不能删除,系统继续处理下一行,成功删除内表中所有行时,SY-SUBRC返回0.如果内表为空,会删除所有数据,且SY-SUBRC和SY-DBCNT都返回0.
6.5数据一致性
6.5.1 SAP LUW与DB LUW
1.LUW概念:在SAP系统中,两个数据一致状态中的时间间隔为LUW(Logical Unit of Work),每一个LUW都需要以一个提交(COMMIT)或者返回(ROLLBACK)作为结束标志.如果以提交操作结束则进行所有更新操作,而返回操作则取消所有数据库表的更改.
2.数据库LUW:这是底层数据库自身提供的保持数据一致性的机制,与SAP系统无关,对于ABAP程序来说,主要的问题在于如何确定数据库的LUW的触发时机,一个工作过程总是在下述情况下结束一个数据库LUW并隐式地进行数据库提交:
l 当一个对话步骤(Dialog step)结束,即显示一个新屏幕给用户时.
l 在另一个工作过程继续程序的执行,这一般出现在RFC(远程功能模块)的调用或返回过程中.
相应地,下列情况将使数据库隐式地进行返回操作:
l 当前ABAP程序出现运行错误.
l 一个ABAP程序因类型A或X的消息而导致中止.
3.SAP LUW:一个SAP LUW可以包含多个对话步骤,即多个数据库LUW,但一个OPEN SQL语句不能被分隔为几个对话步骤,即通过SAP LUW可以将多个数据库LUW进行捆绑,并保存整体初始状态,不进行真正的数据库修改,当SAP LUW中的最后一个数据库LUW结束时,再进行整体修改,或者整体取消操作.
SAP LUW提供两种具体数据库LUW捆绑机制:
l 在定义FUNCTION时将其定义为Update module,同时在调用时用如下方式:CALL FUNCTION ...IN UPDATE TASK.则该模块不是马上被执行,而是被放置于应用服务器中的一个特殊的更新工作过程(Update work process)中,因此可以将多个分布在不同对话过程中的类似模块捆扎在一起,当SAP LUW结束时,确保所有模块被同时成功执行或整体放弃,因此可通过该方式封装分布在不同对话过程中的所有数据库更新操作.一个SAP LUW显式提交方式:COMMIT WORT [AND WAIT].该语句结束SAP LUW并触发更新工作过程,该过程在同一个数据库LUW中进行更新操作,因而数据库LUW此时可以替代SAP开始进行一致性控制.这些进行更新工作的FUNCTION可以被设为同步(加AND WAIT)或异步模式.即是否要等到更新任务完成后才继续执行后续语句.
l PERFORM ... ON COMMIT [LEVEL n].效果与上面相同,此方法更高效,但此时子程序不能传递参数. LEVEL表示优先级,n取整数.n越小越先执行.
l ROLLBACK WORK.控制SAP LUW整体返回,在实现SAP LUW更新功能的FUNCTION或子程序内部不能使用此语句及COMMIT语句.
TABLES SPFLI.
DATA FLAG.
SPFLI-CARRID = 'LH'. SPFLI-CONNID = '1245'.
SPFLI-CITYFROM = ............
INSERT SPFLI.
IF SY-SUBRC <> 0.
FLAG = 'X'.
ENDIF.
SPFLI-CARRID = 'AA'. SPFLI-CONNID = '4574'.
SPFLI-CITYFROM = ............
INSERT SPFLI.
IF SY-SUBRC <> 0.
FLAG = 'X'.
ENDIF.
................
IF FLAG = 'X'.
ROLLBACK WORK.
ELSE.
COMMIT WORK.
ENDIF.
6.5.2 SAP数据锁定
用SE11创建一个锁定对象(lock object).激活它时会自动同时生成两个FUNCTION:ENQUEUE_
l 共享锁定(shared):该模式允许 多个用户访问指定表行,但只能读访问.任何时候都不允许写访问。
l 排他锁定(exclusive,not cumulative):该模式允许单个用户对指定表行进行读和写访问。其它用户不能访问该行。
l 扩展排他锁定(exclusive,cumulative): 该模式避免具有读写访问权限的单个用户获得对相同表行集的进一步锁定。当使用递归例程更新时,该模式很有用。
激活锁定对象导致系统生成用于锁定和解锁对象的特殊功能模块。这些功能模块称为:
调用 ENQUEUE/DEQUEUE 功能模块
ENQUEUE_
运行时,在试图读或写之前可以锁定该数据库对象。要锁定对象,请在第一屏幕的PAI事件中调用功能模块ENQUEUE_
ENQUEUE/DEQUEUE参数
ENQUEUE/DEQUEUE功能模块有下列参数集:
?arg和x_arg(ENQUEUE和DEQUEUE)
这两个EXPORTING参数,存在于锁定参数的每个字段arg中。将arg设置为所需的关键字字段值。如果该字段不需要特殊值,则忽略arg参数,或者将其设置为字段的初始值。如果要将字段的初始值作为实际选择值,请将x_arg设置为‘X’。
?_SCOPE(ENQUEUE)
如果事务不调用更新任务功能,则只在对话任务中更新。应该使用相应的DEQUEUE功能直接释放锁定。
如果调用任意的V1更新任务功能,请设置参数_SCOPE以告知系统应该如何释放SAP锁定。可能的值为:
1该值用于创建更新任务中不需要的锁定。在整个对话任务处理中保持使用_SCOPE=1设置的锁定,但该锁定并不能用于任意的更新任务请求。要保证不将锁定保持超过必要的时间,在事务结束时应该直接释放它(通过相应的DEQUEUE功能)。
在ROLLBACKWORK时释放:系统不释放使用_SCOPE=1设置的锁定。在编制反转程序时,请使用DEQUEUE功能。
2该值用于创建下列锁定:
-在更新任务触发之前在对话任务中使用
-一旦已经触发了更新任务,则只在更新任务中使用。
这意味着在COMMITWORK已经触发更新任务之后,如果该任务继续运行,则锁定不再可用于对话任务事务。系统在V1更新任务处理结束之后(或者在下一ROLLBACKWORK)释放锁定。
如果不指定_SCOPE,该值就是缺省值。不需要将DEQUEUE用于使用_SCOPE值创建的锁定。但是,如果_SCOPE=2,并且不调用更新任务功能,则不触发更新任务而且系统不释放锁定。
在ROLLBACKWORK释放:如果在提交前发生反转,则系统释放使用_SCOPE=2设置的锁定。在提交之后,锁定保持到更新任务处理结束。
3使用该值创建以下锁定:
-在触发更新任务之前在对话任务中使用
-在触发更新任务之后,由对话任务和更新任务使用。
也就是说,对话任务程序继续使用该锁定,甚至该更新任务功能正在运行时也是如此。在这种情况下,锁定由对话事务和更新任务功能所“共有”。
在V1更新任务处理之后的某个时刻系统释放锁定。但是,应该直接释放锁定(通过相应的DEQUEUE函数)以确保尽可能早地释放。
在ROLLBACKWORK释放:一旦已经触发更新任务,则使用_SCOPE=3设置的锁定有两个独立的所有者。要删除锁定,必须在对话任务和更新任务两方同时删除此锁定。如果在提交前发生反转,则在更新任务方释放锁定,但是对话任务方仍然保留它。如果在提交后发生反转,则系统在双方都不释放该锁定。在这种情况下,必须使用DEQUEUE功能在对话方直接释放该锁定。更新任务方将自动释放锁定。
如果用户在事务完成前已经退出了该事务(例如通过“/n”)或者程序异常终止,则系统释放所有锁定。V2功能也不能继承对话任务所创建的锁定。
?_WAIT(只ENQUEUE)
此EXPORTING参数告知:如果即将锁定的对象已经由其它用户锁定,ENQUEUE是否应该等待。如果要等待则将_WAIT设置为'X'。在这种情况下,系统试图以指定时间长度的重复间隔锁定该对象。如果这些尝试失败,则ENQUEUE导致FOREIGN_LOCK例外。
如果程序不想等待,则将_WAIT设置为其它任何值。在这种情况下,ENQUEUE导致FOREIGN_LOCK例外,并且将系统字段SY-MSGV1设置为已经拥有该锁定的用户名。
ENQUEUE例外
在调用ENQUEUE功能模块之后,应该检查在程序中该对象是否已经锁定。在功能模块中定义了下列例外:
?FOREIGN_LOCK
其它用户已经锁定了对象。系统字段SY-MSGV1包含该用户名。
?SYSTEM_FAILURE
一般系统错误。
6.5.3用户权限检查
(1)事务运行权限
(2)程序运行权限
(3)程序内部权限检查
首先用T-CODE:SU21创建授权对象.
AUTHORITY-CHECK OBJECT ‘object’
ID ‘field_name1’ FIELD f1
ID ‘field_name2’ FIELD f2|ID ‘field_name’ DUMMY
6.6其它数据操作形式
6.6.1文件接口
l 创建逻辑文件名及路径名(解决平台相关性问题):FILE.
l 猎取当前平台可识别的文件名:FILE_GET_NAME
(1) 处理应用服务器文件
1.打开文件:OPEN DATASET dsn
l FOR INPUT:读取方式,如果文件不存在则忽略此命令.如果文件己打开,操作指针将复位到文件的起始位置.
l FOR OUTPUT:写入方式,如果文件不存在则创建文件,如果文件存在但处于关闭状态则删除其内容,如果文件存在且己打开,指针复位.
l FOR APPEND:附加方式,如果文件不存在则创建文件,如果文件存在则打开文件同时将指针定位到文件末尾,SY-SUBRC总是返回0.
l FOR TEXT MODE:文本模式,读取或写入数据时,数据逐行传输,系统假定文件具有行结构,如果要将字符串写入文件或己知现有文件是基于行结构的格式,则应用使用此模式.
l FOR BIANARY MODE:二进制模式,读取或写入数据时系统逐字节地传输数据,传输期间系统不解释文件内容,在将某文件内容写入到另一文件时,系统将传输源文件的所有字节,在从文件读取到字段时,传输的字节数取决于目标字段的大小.
l FOR POSITION pos:打开文件并将读写数据操作指针定位于位置pos,该位置从文件起始处按字节计算.
l MESSAGE msg:系统将在变量msg中放置相关操作系统消息.要进行错误处理,应与通过该选项和系统字段SY-SUBRC返回值一起接收完整的错误消息.
l FILITER filt:该选项与操作系统相关,对于UNIX或者NT系统,可以通过将系统指令置于filt中执行.如在读取之前将文件用windows指令解压缩.
2.关闭文件:CLOSE DATASET dsn.只有在写入文件前要删除当前文件内容时,才有必要关闭文件.
3.删除文件:DELETE DATASET dsn.删除成功SY-SUBRC返回0,否则返回4.
4.TRANSFER f TO dsn [LENGTH len].将数据对象f的值写入文件dsn.字段f可以是基本数据类型,或者不包含作为内表组件的结构体,文件写入模式由OPEN DATASET语句在打开时指定的,如果没有打开,系统将尝试用二进制方式打开,或使用上一个OPEN DATASET语句的模式,LENGTH指定传输数据的长度,如果f的长度大于len则截断,否则填充空格,如果文件以文本模式打开,则每个TRASFER语句中,系统向文件中传输除结尾空格之外的所有字节,并在其后作结束标记.
5.从文件中读取数据:READ DATASET dsn INTO f [LENGTH len].在读取前应用OPEN DATASET语句指定传输模式,读取成功SY-SUBRC返回0,读到文件末尾返回4,不能打开时返回8,如文件以二进制模式打开,可用LENGTH指定传输长度,如文件以文本模式打开,则每个READ DATASET语句中,系统将读取下一个行结束标记之前的所有数据.
REPORT z_file_test .
PARAMETERS file(30) TYPE c DEFAULT '\tmp\myfile'.
DATA:wa_sflight TYPE sflight,
sflight_tab_1 LIKE TABLE OF wa_sflight,
sflight_tab_2 LIKE TABLE OF wa_sflight.
OPEN DATASET file FOR OUTPUT IN BINARY MODE.
SELECT * FROM sflight INTO wa_sflight.
TRANSFER wa_sflight TO file.
APPEND wa_sflight TO sflight_tab_1.
ENDSELECT.
CLOSE DATASET file.
OPEN DATASET file FOR INPUT IN BINARY MODE.
DO.
READ DATASET file INTO wa_sflight.
IF sy-subrc <> 0.
EXIT.
ENDIF.
APPEND wa_sflight TO sflight_tab_2.
ENDDO.
CLOSE DATASET file.
IF sflight_tab_1 = sflight_tab_2.
MESSAGE i888(sabapdocu) WITH 'OK'.
ENDIF.
该程序在应用服务器的\tmp目录中创建了一个文件myfile存储程序内表中的数据,SAP应用服务器文件及目录可以通过事务AL11(SAP Directories)进行浏览.
(2) 处理展示服务器文件(客户端本机)
1. 下载文件到本机FUNCTION:DOWNLOAD或WS_DOWNLOAD,其中DOWNLOAD在下载时会显示用户对话框.
2. 上传文件到程序FUNCTION:UPLOAD或WS_UPLOAD,其中UPLOAD在文件上传时会显示用户对话框.
3. 获取展示服务器上文件和操作系统信息FUNCTION:WS_QUERY.
6.6.2数据簇操作
(1)ABAP/4内存中的数据簇
1.在 ABAP/4 内存中存储数据对象
EXPORT
此语句将列表中指定的数据对象存储为ABAP/4内存中的数据簇。如果忽略选项FROM
注:ID
2. 从内存中读取数据对象
IMPORT
此语句从ABAP/4内存的数据簇中读取列表中指定的数据对象。如果忽略选项TO
不必读取存储在特定ID
此语句不进行这种检查:即内存中的对象结构与要写入的结构是否匹配。因为数据是按位进行传送的,所以不匹配的结构可能会引起不一致。
3.删除内存中的数据簇
FREE MEMORY [ID
(2)数据库中的数据簇
1.簇数据库的结构:
建立簇数据库的规则如下所述。必须创建第一点到第四点中列出的关键字段。上述数据类型都是ABAP/4词典类型。
1.如果该表是针对客户的,第一个字段必须这样定义:名称为MANDT,类型为CHAR,长度为3字节,用于存储客户ID。存储数据簇时,系统既可自动使用当前客户填写字段MANDT,还可使用EXPORT语句中显式指定的客户进行填写。2.下一字段(对于与客户无关的表,这是第一个字段)必须这样定义:名称为RELID,类型为CHAR,长度为2字节。该字段包含区域ID。簇数据库被分成不同的区域。存储数据簇时,系统用EXPORT语句中指定的区域ID填写字段RELID。3.下一字段类型为CHAR,长度可变。它包含簇的名称
4.下一字段必须名称为SRTF2,类型为INT4,长度为4。单个数据簇可以扩展到数据库表的好几行中。在理论上,每个簇可能有2**31行。字段SRTF2包含存储的数据簇内行的顺序号码,可以是0和2**31-1之间的任何值。存储数据簇时,系统自动填写此字段(参见第7点)。
5.SRTF2的后面可以是任何数目的数据字段,这些字段名称和类型可任意交换。存储数据簇时,系统并不自动填写这些字段。必须在程序中的EXPORT语句之前将值显式分配到这些字段。通常包含诸如程序名、用户ID等控制信息。
6.行上的倒数第二个字段名称必须为CLUSTR,类型为INT2,并且长度必须为2。它包含后面的字段CLUSTD中的数据长度。存储数据簇时,系统自动填写此字段。
7.行上的最后一个字段必须名称为CLUSTD,类型为VARC。其长度可以任意,但通常为1000个字节左右。存储数据簇时,系统按压缩格式用实际数据填写此字段。如果CLUSTD的长度不足以存储簇数据,则数据就被分布到多行上。这些行在字段SRTF2中进行编号(参见上面的第4点)。
既可以按照上述规则创建自己的簇数据库(此时参见文档ABAP/4词典),也可以使用系统定义的簇数据库INDX
(2)在簇数据库中存储数据对象
EXPORT
TO DATABASE
此语句将列表中指定的数据对象存储为簇数据库
l
l
l 在处理特定客户的簇数据库时可以使用选项CLIENT
l EXPORT语句也将表工作区
在具有相同名称
(3)创建数据簇目录表
IMPORT DIRECTORY INTO
FROM DATABASE
[CLIENT
此语句在存储于数据库
IMPORT语句也自动从数据库表中读取表工作区
(4)从簇数据库中读取数据对象
IMPORT
FROM DATABASE
[CLIENT
此语句从数据库
不必读取存储在特殊名称
运行时,系统检查此语句以查看数据库中对象的结构是否与要写入的结构相符。如果不符合,将出现运行时间错误。类型C字段是此规则的例外,也可显示在结构数据字段结尾。可以加长、缩短、附加或忽略。
(5)从簇数据库中删除数据簇
DELETE FROM DATABASE
此语句删除数据库表
列表中双击行的交互事件:atline-selection.
53. 对话程序运行时触发事件:load-of-program.
54. leavetolist-processing:离开屏幕处理同时进入报表列表处理(如选择屏幕).
55. 系统内表SCREEN保存了屏幕元素的各种属性.
例如:将一个屏幕字段由可以将接受输入状态改为显示状态:
LOOPATSCREEN.Bestregards,
Ifscreen-name=‘mod’.
screen-input=‘0’.
Modifyscreen.
Endif.
Endloop.
56. 流逻辑事件:
PROCESSBEFOREOUTPUT(PBO):用户与屏幕交互前事件.
PROCESSAFTERINPUT(PIO):用户与屏幕交互后事件.
PROCESSONHELP-REQUEST(POH):查询帮助信息(或F1键)事件.
PROCESSONVALUE-REQUEST(POV):查询帮助按钮(或F4键)事件.
57. 流逻辑语句:
PROCESS
MODULE:
FIELDf:PAI中屏幕字段f的值在此语句后才传给abap程序.
ON:
VALUES:
CHAIN
ENDCHAIN:
CALL:
LOOP:
58. 屏幕调用语句:
1.SETSCREENnext_screen_number:为当前屏幕指定后续屏幕.不会自动返回当前屏幕.
2.CALLSCREENscreen_number及CALLTRANCTIONtcode:挂起当前屏幕序列,进入新屏幕(序列)或事务.在新的屏幕序列中,通过语句LEAVESCREENTOSCREEN0调用的屏幕就能够返回到挂起的屏幕序列上.(返回到原程序)
3.LEAVESCREEN:如果需要未完成当前屏幕控制流就要转入后续屏幕,使用此语句.
4.LEAVETOSCREENscreen_number及LEAVETOTRANCTIONtcode:未完成当前屏幕就要转入后续屏幕.不返回原有程序.
59. CALLSCREENdynnrSTARTINGATx1y1ENDINGATx2y2:将调用的屏幕作为弹出对话框,(x1,y1)及(x2,y2)分别为左上角和右下角的横纵坐标.
60. 中止当前屏幕并返回到调用点:
LEAVETOSCREEN0.
或
SETSCREEN0.
LEAVESCREEN.
61. 中止当前屏幕并进入新屏幕:
LEAVETOSCREENdynnr
或
SETSCREENdynnr
LEAVESCREEN.
62. 将GUI状态连接到屏幕:SETPF-STATUSstat.
63. 设置屏幕标题:SETTITLEBARstat.
64. 类型为E的PAI模块:类型为E的GUI状态元素被触发时将直接调用流逻辑中PAI中的语句:MODULEmodATEXIT-COMMAND.(无条件调用).
65. 模块条件调用:
1.FIELDfMODULEmodONINPUT:当字段f的值不是初始值时才调用mod.
2.FIELDfMODULEmodONREQUEST:只有用户在字段f中输入值时(包含空值和原值)才调用mod.
3.组合字段条件调用:
CHAIN.
FIELD:f1,f2,…
MODULEmod1ONCHAIN-INPUT|CHAIN-QEQUEST.
FIELD:g1,g2,…
MODULEmod2ONCHAIN-INPUT|CHAIN-QEQUEST.
…
ENDCHAIN.
当fi之一满足条件时,mod1被调用,当fi或gi满足条件时,mod2被调用.
CHAIN.
FIELD:f1,f2.
FIELD:f3MODULEmod1ONINPUT.
ENDCHAIN.
只有f3包含非初始值时才调用mod1.
CHAIN.
FIELD:f1,f2.
FIELD:f3MODULEmod1ONCHAIN-INPUT.
ENDCHAIN.
f1,f2,f3中任一字段包含非初始值时都调用mod1.
注:条件调用也将使值被延迟传输.
66. 输入检查:
PROCESSAFTERINPUT.
FIELDspfli-airpfrom.
MODULEcheck_fr_airport.
MODULEcheck_fr_airportINPUT.
SELECTSINGLE*FROMsairportWHEREid=spfli-airpfrom.
Ifsy-subrcNE0.
MESSAGEe003WITHspfli-airpfrom.
ENDIF.
ENDMODULE.
字段spfli-airpfrom将进行有效性检查.
PROCESSAFTERINPUT.
CHAIN.
FIELD:spfli-carrid,spfli-connid.
MODULEcheck_flight.
ENDCHAIN.
MODULEcheck_flightINPUT.
SELECTSINGLE*FROMspfli
WHEREcarrid=spfli-carrid
AND connid=spfli-connid.
Ifsy-subrcNE0.
MESSAGEe005WITHspfli-carridspfli-connid.
ENDIF.
…
ENDMODULE.
spfli-carrid,spfli-connid二者之一出现错误时系统都触发错误信息,需重新输入
67. F1和F4帮助:
F1帮助:
1.数据字典帮助:
PCOCESSONHELP-REQUEST.
FIELDfWITHdocnum.
PCOCESSONHELP-REQUEST.
FIELDfMODULEmod.
功能模块HELP_OBJECT_SHOW可以显示任意SAPScrip文本,
68. 过程定义输入帮助:
PROCESSONVALUE-REQUEST.
FIELDfWITHmod.
DYNP_VALUE_READ:读取屏幕字段当前值.
DYNP_VALUE_UPDATE:选择了帮助列表中的字段后,对该字段进行更新.
F4IF_INT_TABLE_VALUE_REQUEST:定义输入帮助FUNCTION,将内表的形式的值列表显示给用户并返回用户选择的值.
69. 上下文菜单:
在屏幕元素属性对话框中填充ON_CTMENU字段,同时创建同名子程序
FORMon_ctmenu_
CALLMETHODl_menu->add_function
EXPORTINGfcode=‘DISY’
Text=‘displaydetails’.
CALLMETHODl_menu->add_function
EXPORTINGfcode=‘CLAR’
Text=‘Clearall’.
ENDFORM.
当在屏幕相应字段上单击右键并选择相应的菜单时,程序调用PAI事件,同时将此子程序中设定的功能代码传递给OK_CODE字段.而不是屏幕中设定的功能代码,所以一定要注意此处的功能代码要与屏幕中的功能代码设置为一致.
70. 下拉列表框:
在屏幕的流逻辑中定义字段的下拉列表(POV事件):
PROCESSONVALUE-REQUEST.
FIELDsexMODULEmod.
然后定义mod:
MODULEmodINPUT.
SELECTcarridcarrnameFROMscarr
INTOCORRESPONDINGFIELDSOFTABLEitab_carrid.
CALLFUNCTION'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
retfield='CARRID'
value_org='S'
TABLES
value_tab=itab_carrid
EXCEPTIONS
parameter_error=1
no_values_found=2
OTHERS=3.
ENDMODULE.
71. 表格控件:是SAP的标准控件,是一种平台无关的软件元素,定义方式如下:
CONTROLSctrlTYPEctrltype.
SY-STEPL:表格控件中当前操作的屏幕行号.
SY-LOOPC:当前表格控件在屏幕中总行数.
72. 屏幕中的传统列表:
调用基本列表输出所有WRITE语句中的内容,方法是在某个对话模块中使用下列语句:LEAVETOLIST-PROCESSING[ANDRETURNTOSCREEN
要离开列表自理过程,可以按BACK,EXIT或CANCEL或者使用下列语句:
LEAVELIST-PROCESSING.