sap DY1
- 激活的重要性,每个程序,报表都要激活
- 背景白色,字为黑色解决方法: 编辑-》修改操作-》关闭助理。
- 绕过注册获取abaper开发者权限的破解操作:破解链接
数据定义
- 定义一个简单数据类型:
TYPES type.
TYPES type(len).
- 定义一个结构化的数据类型
TYPES: BEGIN OF structype
END OF structype.
- 定义一个内表形式的数据类型
TYPES itabtype {TYPE linetype|LIKE lineobj} OCCURS n.
OCCURS 表示一个初始的行数,一般n取0行就好。
举例:
Example 1:
DATA: COUNTER TYPE P DECIMALS 3.
NAME (10) TYPE C VALUE ‘Delta’.
S_DATE TYPE D VALUE ‘19991203’.
Example 2:
DATA: BEGIN OF PERSON,
NAME(10) TYPE C,
AGE TYPE I,
WEIGHT TYPE P DECIMALS 2,
END OF PERSON.
用到结构下的某一个字段:PERSON-NAME
4. 此外还有CONSTANTS , STATICS定义数据。CONSTANS用来声明常数的,STATICS则是用来声明临时变量。
举例:
Example:
CONSTANTS: CNAME(10) VALUE ‘周慶日’,
BIRTH_DAY TYPE D VALUE ‘19650201’.
- TABLES 用来定义表工作区的。
Example:
TABLES: SPFL.
SELECT * FROM SPFL.
WRITE: SPFL-MANDT, SPFL-CARRID,SPFL-CONNECTION.
ENDSELECT.
上面的select循环是会覆盖前面的数据的。读取的数据会进入到TABLES定义的SPEL
系统保留变数说明
- sy-subrc : 0 表示成功。
- sy-uname: 表示当前登录的用户名
- sy-datum: 表示当前系统日期 ‘yyyymmdd’,可在事物码SU01设置我们想显示的日期格式。可以使用字符串截取一下单独取出我们想要的数据。系统有专门的函数取出月份的最后一天是什么,注意还有日期计算函数。
- sy-uzeit: 时间
- sy-tcode: 当前事物码
- sy-index: loop 循环的次数
- sy-tabix: 内表的第几行(笔)
- sy-vline: 画竖线
- sy-uline: 画横线
- sy-pageno:页数
- sy-rows: 屏幕的行数
syst 表中可以看见系统中全部的保留关键字。
tables: EKKO.
types: begin of linetype,
ebeln like EKKO-ebeln,
end of linttype.
data stru2 type EKPO. "即使EKPO没有在数据里面定义,也不会报错,因为是内置的数据库表,type是定义的一个类型,而LIKE则必须对应一个实例。(新版本好像不存在这些问题)
data stru type linetype. "stru是一个结构
内表
定义同结构体非常相像,不过是多了后面OCCURS N.这样的是已经自带了一个表头即:表的工作区。
DATA: BEGIN OF STUDENT OCCURS 20,
STD_ID TYPE N,
NAME(10) TYPE C,
AGE TYPE I,
BIRTH TYPE D,
SCORE TYPE P DECIMALS 2,
END OF STUDENT.
1.定义格式有:
格式一. DATA: BEGIN OF <internal table> OCCURS <n>,
<field 1> TYPE <type1>,
[<field 2> TYPE <type 2>,
<field 3> TYPE <type 3>,
… ]
END OF <internal table>.
格式二. TYPES: BEGIN OF <work area>,
<field 1> TYPE <type1>,
[<field 2> TYPE <type 2>,
<field 3> TYPE <type 3>,
… ]
END OF <work area>.
TYPES <internal table> TYPE <work area> OCCURS <n>.
格式三. DATA: BEGIN OF <work area>.
INCLUDE STRUCTURE <table name>.
DATA: END OF <work area>.
DATA: <internal table> LIKE <work area> OCCURS <n>.
格式二即先定义一个结构,可以看作为工作区域(表头),然后在申请出内表空间来。格式三定义的格式需要注意:多个DATA .(结构可以定义多个字段,但是只有一行,而内表可以有多行。)内表在程序运行时候有效,可以看作JAVA中的集合的作用。
- APPEND LINE向内表插入数据.LINE结构跟内表的必须一样。
例一. (使用work area)
DATA: BEGIN OF LINE,
COL1 TYPE I,
COL2 TYPE I,
END OF LINE.
DATA ITAB LIKE LINE OCCURS 10.
DO 2 TIMES.
LINE-COL1 = SY-INDEX.
LINE-COL2 = SY-INDEX ** 2.
APPEND LINE TO ITAB.
ENDDO.
LOOP AT ITAB INTO LINE.
WRITE: / LINE-COL1, LINE-COL2.
ENDLOOP.
执行结果二:
1 1
2 4
示例二的ITAB不是表示一个内表,而是一个工作区(表头),APPEND后不需要to
举例二:. (不使用work area)
DATA: BEGIN OF ITAB OCCURS 10,
COL1 TYPE I,
COL2 TYPE I,
END OF ITAB.
DO 2 TIMES.
ITAB-COL1 = SY-INDEX.
ITAB-COL2 = SY-INDEX ** 2.
APPEND ITAB.
ENDDO.
LOOP AT ITAB.
WRITE: / ITAB-COL1, ITAB-COL2.
ENDLOOP.
结果同上
将内表中元素增加到另一个内表:
格式: APPEND LINES OF <itab1> [FROM <n1> ] [TO <n2>] TO <itab2>. "从第几行到第几行。
- COLLECT LINE。汇总行,COLLECT指令在非数值栏位相同的情況下,將数值栏位汇总.即相等字段累加。
格式: COLLECT [<work area> INTO ] <itab>
DATA: BEGIN OF ITAB OCCURS 3,
COL1(3) TYPE C,
COL2 TYPE I,
END OF ITAB.
ITAB-COL1 = ‘ABC’. ITAB-COL2 = 10.
COLLECT ITAB.
ITAB-COL1 = ‘XYZ’. ITAB-COL2 = 20.
COLLECT ITAB.
ITAB-COL1 = ‘ABC’. ITAB-COL2 = 80.
COLLECT ITAB.
此時, internal table中放的是2筆數据, 分別為:
ITAB-COL1 ITAB-COL2
‘ABC’ 90
INSERT LINE. 指定位置插入数据:
格式: INSERT [ INTO] [INITIAL LINE INTO ] [INDEX ]
或者 INSERT LINES OF [FROM TO ] INTO INDEX读取内表:
格式一: LOOP AT。 逐行读取,如果没有表头则必须into到一个wa(work area)中读取。 where 是条件。
LOOP AT <itab> [INTO <wa>][FROM <n1> TO <n2>][WHERE <conditions>]
<statement>
ENDLOOP.
格式二:READE 读取一行数据:
READ TABLE <itab> [INTO <wa>] [INDEX <idx> / WITH KEY <conditions>]
举例:
DATA: BEGIN OF ITAB OCCURS 10,
COL1 TYPE I,
COL2 TYPE I,
END OF ITAB.
DO 10 TIMES.
ITAB-COL1 = SY-INDEX.
ITAB-COL2 = SY-INDEX * 2.
APPEND ITAB.
ENDDO.
READ TABLE ITAB INDEX 3. "从1开始
(或者: READ TABLE ITAB WITH KEY COL1 = 3.)
WRITE: / ‘ITAB-COL1 = ‘, ITAB-COL1, ‘ITAB-COL2 = ‘, ITAB-COL2.
執行結果同樣是:
ITAB-COL1 = 3
ITAB-COL2 = 6.
- 修改内表中的值,TRANSPORTING表示只修改某几个字段。如果没有匹配的行可以修改,则会增加一行。
格式: MODIFY [FROM ][INDEX ][TRANSPORTING …][WHERE ]
READ TABLE ITAB INDEX 3.
LINE-COL1 = 29.
MODIFY ITAB FROM LINE TRANSPORTING COL1.
將第三筆記錄的COL1欄位的值修改為29.
T_SALARY – salary = 50.
MODIFY T_SALARY TRANSPORTING salary WHERE birthday = ‘1999/12/06’.
DELETE,删除内表中的栏位。在非LOOP中使用必须加index或者是where条件。delete不会删除表头。
格式: DELETE INDEX .
或: DELETE [FROM TO ] [WHERE ]内表排序。SORT
SORT <itab> [<order way>][BY <f1><f2>…]
有降序,升序。DESCENDING ,ASCENDING(默认)加总。SUM
總和計算存放与work area中,但只能在LOOP 中使用.
例: LOOP AT ITAB INTO LINE.
SUM.
ENDLOOP.
WRITE: / LINE-COL1, LINE-COL2.
- 初始化内表
refresh itab : 清空内表表体中值
clear itab: 清空表头中值
free itab: 释放内表的内存空间。
选择屏幕 SELECTION-SCREEN
- PARAMETERS语句, 单个值参数
type…定义类型
obligatory…必填
as checkbox…多选框
radiobutton group radi…单选框
default… 默认
Example:
PARAMETERS: NAME(8),
AGE TYPE I,
BIRTH TYPE D.
2.SELECT-OPTIONS语句,表示一个范围选择。可以选择多个单指,范围。或者是排除单值,范围。通常在获取的值的条件里面用 IN 这个来,即判断有没有落在所选值之中。
語法:
SELECTION-OPTIONS <check-option> FOR <table-field>
Example:
TABLES SPFLI.
SELECTION-OPTIONS AIRLINE FOR SPFLI-CONNID.
- 产生空白列
SELECTION-SCREEN SKIP [<n>]
Example:
SELECTION-SCREEN SKIP 2.
產生兩列空白列
- 产生底线
SELECTION-SCREEN ULINE / <pos>(length)
Example:
SELECTION-SCREEN ULINE /10(30).
自第10格開始產生長度30的底線
- 输出在一个模块中
語法:
SELECTION-SCREEN BEGIN OF BLOCK
[WITH FRAME [TITLE ].
SELECTION-SCREEN BEGIN OF BLOCK RADIO WITH FRAME .
PARAMETER R1 RADIOBUTTON GROUP GR1.
PARAMETER R2 RADIOBUTTON GROUP GR1.
PARAMETER R3 RADIOBUTTON GROUP GR1.
SELECTION-SCREEN END OF BLOCK RADIO.
Processing Data(数据处理)
- 给变量赋值
MOVE <F1> TO <f2>.
語法:
MOVE <F1> TO <F2>
將F1的值存至變數 F2 中, 也可寫成 F2 = F1
Example:
M_NAME = ‘CHER’.
- Offset 偏移量
語法:
MOVE <F1>[+<O1>] TO <F2>[+<O2>]
Example:
DATA: F1(10) VALUE ‘ABCDEFGHIJ’.
F2(5).
F2 = F1+3(5). “自第4個位置開始取出5個字元
F2 的內容會變成 DEFGH
- MOVE-CORRESPONDING ,将相同的字段进行赋值操作。
MOVE –CORRESPONDING <Strings1> TO <String2>.
Example:
DATA: BEGIN OF ADDRESS,
FIRSTNAME(10) VALUE ‘LULU’,
LASTNAME(10) VALUE ‘CHOU’,
TEL(12) VALUE ‘4660570’,
END OF ADDRESS.
DATA:BEGIN OF NAME,
FIRSTNAME(10),
LASTNAME(10),
E_MAIL(30),
END OF NAME.
MOVE-CORRESPONDING ADDRESS TO NAME.
NAME-FIRSTNAME 变成 ‘LULU’, NAME-LASTNAME 变成 ‘CHOU’,
而 NAME-E_MAIL 则不变
- write to ,to后面是必须加一个字符串型的变量,用用户主数据中定义的格式中输出。
DATA: NAME(20) VALUE ‘SOURCE’,
SOURCE(10) VALUE ‘LILY’,
TARGET(10).
WRITE (NAME) TO TARGET.
WRITE / TARGET.
打印出 LILY
- 日期与时间的运算
Example:
DATA: Mdata TYPE D.
Mdate = SY-DATUM. “ 如传回 19971015
Mdate+6(2) = ‘01’ “ Mdate 变成 19971001
Mdate = Mdate - 1 “ Mdate 变成 19970931
时间格式为 ‘hhmmss’, 如 ‘212030’ 表 ’21:20:30’
Example:
DATA: HOURS TYPE I,
MINUTES TYPE I,
T2 TYPE T VALUE ‘200000’,
T1 TYPE T VALUE ‘183000’.
HOURS = (T2 - T1) / 3600. “计算有几个小时
MINUTES = (T2 – T1) / 60. “计算几分钟
- abapdocu事物码中含有大量的abap开发程序,可进行demo查看。
过程处理-事件块
源代码中时间快顺序无关
graph LR
A[INITZATION]-->B[at-election-screen]
B-->C[start-of-selection]
C-->D[end-of-selection]
D-->E[GET]
E-->F[TOP-OF-PAGE]
F-->G[END-OF-PAGE]
A: 通常在此事件块中设定输入屏幕字段的初始值。
B: 通常在此事件块中进行用户输入数据的合法性检查,发现错误则以消息的形式给出警示,直到用户输入正确的数值
AT SELECTION-SCREEN .
IF P_DATE = SPACE .
MESSAGE E001 .
ENDIF.
效果: 如果字段P_DATE为空,则程序会用消息001“日期字段不能为空!”来提示用户必须输入一个日期。而且输入屏幕会等待用户输入,直到该字段数值合法
C: 此事件中针对业务需求进行系统数据的查询
start-of-selection .
perform get_data_for_oil .
效果:
在输入屏幕用户按下执行按钮后,子程序get_data_for_oil被执行, 在其中获得业务相关的数据存放到内表或者其它变量,这些数据在END-OF-SELECTION事件块中被输出
D: 通常在此事件中进行结果清单的输出
end-of-selection .
write : 23(1) sy-vline,
24(20) tab-gas_plan right-justified ,
效果:
数据以清单的形式输出
E:从逻辑数据库中得到数据(较少用)
F:在此事件块中设计输出清单的页头
TOP-OF-PAGE
write : /1(240) '汽柴油日出厂情况表' centered .
write : /20(8) '日期:' ,
29(10) s_date ,
180(6) '单位:' ,
190(10) '吨' .
G:在此事件中设定输出清单的页脚
END-OF-PAGE .
Write : ‘制作人’ , p_name .
默认事件:没有紧跟着事件关键字或FORM-ENDFORM块的语句自动成为默认事件START-OF-SELECTION的一部分。
如果在 REPORT 或 PROGRAM 语句与第一个事件关键字或 FORM 语句之间写语句,则将把这些语句包括在 START-OF-SELECTION 过程块中。
如果没有把 START-OF-SELECTION 关键字包括在报表中, 则这些语句构成整个 START-OF-SELECTION 过程块。
如果将 START-OF-SELECTION 关键字包括 在报表中, 则将把这些 语句插入到 此块的开始部分。
其中AT SELECTION-SCREEN和START-OF-SELECTION分别属于选择屏幕的结尾和输出屏幕的开始,选择屏幕和输出屏幕在两者之间区分开来。意识到这一点很重要,在取数的时候会用到着一点。例如,一般的报表程序首先要判断根据输入条件能否取到数,如果取不到就退出,并反馈相应的信息。按理说这一步取数是在选择屏幕中进行的,而如果是在START-OF-SELECTION中执行,那么在取数之前就进入了输出屏幕,导致在取不到数的情况下想重新输入时需要返回选择屏幕。这虽然是一个小问题,但反应了一定的逻辑和先后关系,需要注意。当然具体情况要根据客户的要求和设计书而定。
子程序
子程序在事件块中被调用
REPORT ...
DATA: REVENUE ...,
a1 type c.
...
perform <name> using a1 a2 a3 changing a4.
...
form <name> using value(f1) type p
value(f2) type i
f3 like revenue changing value(f4) type p.
<statement>
endform.
- 接口定义:
using(值调用)和changing(地址调用)的区别。Using只是把值传过去,而不传回来,changin则是还要穿穿回来。