** 常用的预定义数据类型
**
** 类型缩写 类型 默认长度 最大长度 初始值 描述
** C 字符 1 space 字符串,‘Program’
** D 日期 8 8 '00000000'
** F 浮点 8 8 0 浮点数
** I 整 4 10 0 带正负符号的整数
** N 数值 1 31 '00000000' 数值所组成的字符串
** P 压缩 8 16 0 将两个十进制压缩到一个字节 可以表示整形或浮点型
** T 时间型 6 6 ‘00000000’ 时间
**
** 1.默认定义的数据类型是 CHAR
** 2.取值的时候C型默认从左取 N型从右取,超过定义长度则截断
** 3.C类型,可以赋值数值,也可以赋值字符,还可以混合,不过取值时如果是数值类型靠右取值
** 4.日期和时间类型的变量可进行加减乘除运算
** 5.P类型。小数点要使用DECIMAL声明
**
** 变量定义包含name length type等语法如下:
** 语法:DATA {] TYPE [value ] [decimal ]
** DATA {] LIKE [value ] [decimal ]
** TYPE和LIKE的区别:TYPE 参考某一数据类型
** LIKE 用在已有值的数据类型 如系统变量
** 其中:[] 里的内容表示可选项 <>表示名称
** :变量名称,最长30个字符,不可含有 + . , ; ()等字符
** 长度 要用圆括号括起来 如LINE(20) TYPE C.
** :数据类型
** :初始值
** :小数位
**
** 常量定义使用 CONSTANTS<常量名>[<长度>] TYPE <数据类型> VALUE<默认值>
** 常量值一旦被定义,即被长期保存在内存你,其值无法改变
** sy-subrc sy-uname sy-datum sy-uzeit sy-tcoce sy-index st-tabix sy-mandt sy-vline sy-uline
**
** 结构体的定义:
** 1.DATA:BEGIN OF
** 2.程序中用DATA定义的局部变量
**
** DATA:BEGIN OF
** ,
** ,
** END OF .
**
** DATA LIKE USERINF.
**
** 结构体赋值
** WRITE (结构体名字) 输出结构体所有字段 使用-输出指定字段
** 相同结构体之间使用Move...To...进行赋值
** 有差异的结构体可以使用 MOVE-CORRESSPONDING匹配即赋值相同的字段
** 结构体继承 INCLUEDE STRUCTURE
DATA lv_c TYPE c.
DATA lv_d TYPE d.
DATA lv_f TYPE f.
DATA lv_i TYPE i.
DATA lv_n TYPE n.
DATA lv_p TYPE p.
DATA lv_t TYPE t.
WRITE: / 'lv_c:', lv_c.
WRITE: / 'lv_d:', lv_d.
WRITE: / 'lv_f:', lv_f.
WRITE: / 'lv_i:', lv_i.
WRITE: / 'lv_n:', lv_n.
WRITE: / 'lv_p:', lv_p.
WRITE: / 'lv_t:', lv_t.
WRITE sy-uline.
** 给变量赋值
** A.定义变量的时候赋予初始值
** 语法:DATA {] TYPE [value ] [decimal ]
** eg1: 定义C类型变量名为lv_c2的变量并给变量赋值'我是赋值了的lv_c2'
DATA lv_c2 TYPE c VALUE '我是赋值了的lv_c2'.
WRITE: / 'LV_C2:' ,lv_c2. "注意 此时变量定义的长度10 取值的时超过定义长度则截断
** 定义C类型长度为10
** 方式1 在变量名后用括号(10)
DATA lv_c3(10) TYPE c VALUE '我是赋值了的lv_c3'. "长度不够 也只截取变量的前10位
WRITE: / 'LV_C3:' ,lv_c3.
** 方式2 加LENGTH 关键字
DATA lv_c4 TYPE c LENGTH 10 VALUE '我是赋值了的lv_c4'."长度不够 也只截取变量的前10位
WRITE: / 'LV_C3:' ,lv_c4.
** 定义C类型长度位20
** 方式1 在变量名后用括号(10)
DATA lv_c5(20) TYPE c VALUE '我是赋值了的lv_c5'. "长度足够 完整输出
WRITE: / 'LV_C5:' ,lv_c5.
** 方式2 加LENGTH 关键字
DATA lv_c6 TYPE c LENGTH 20 VALUE '我是赋值了的lv_c6'."长度足够 完整输出
WRITE: / 'LV_C6:' ,lv_c6.
** B.定义变量后再赋值 语法:变量名 = 跟变量类型相同类型的值
DATA lv_c7 TYPE c LENGTH 20.
DATA lv_c8(20) TYPE c.
DATA lv_i2 TYPE i.
DATA lv_n2 TYPE n LENGTH 5.
lv_c7 = '我是赋值了的lv_c7'.
lv_c8 = '我是赋值了的lv_c8'.
lv_i2 = 10086422.
lv_n2 = 10010.
WRITE: / 'LV_C7:',lv_c7.
WRITE: / 'LV_C8:',lv_c8.
WRITE: / 'LV_I2:',lv_i2. "ABAP的用户默认的参数科学计数法 数值每隔三位用,分开
WRITE: / 'LV_N2:',lv_n2. "N类型虽然表示数值 但是编译时候类型转换 用''把数值包含起来了 所以输出的时候是字符 而不是科学计数法
DATA lv_d2 TYPE d VALUE '20230510'.
WRITE: / 'LV_D2:',lv_d2.
DATA lv_f2 TYPE f VALUE '4542.3232'.
WRITE: / 'LV_F2:',lv_f2.
DATA lv_p2 TYPE p VALUE '34234.99'.
WRITE: / 'LV_P2:',lv_p2. "没指定小数位 会进行四舍五入 输出34235
DATA lv_p3 TYPE p DECIMALS 2 VALUE '23234.99'.
WRITE: / 'LV_P3:',lv_p3. "会保留两位小数
DATA lv_p4 TYPE p DECIMALS 2 VALUE '23234.999'.
WRITE: / 'LV_P4:',lv_p4. "因为小数点后面有三位 只保留两位 所以编译器把第3个小数位运算四舍五入 变成了23235.000
DATA lv_t2 TYPE t VALUE '202020'. "表示20:20:20 晚上8点20分20秒
WRITE: / 'LV_T2:',lv_t2.
DATA lv_d3 TYPE d.
lv_d3 = sy-datum. "SY-DATUM是系统变量 用来存储系统的实时日期
WRITE: / 'LV_D3:',lv_d3.
DATA lv_t3 TYPE t .
lv_t3 = sy-uzeit. "SY-UZEIT是系统变量 用来存储系统的实时时间
WRITE: / 'LV_T3:',lv_t3.
WRITE: sy-uline. "SY-ULINE是系统变量 运行程序时 出现一条横线
** 自定义数据类型.
** 语法:TYPES <类型名字> TYPE 数据类型
** 注意: LENGTH 关键字只有在 TYPE (C、N、X、P)类型时有效
** 所以在自定义类型时需结合实际情况定义数据类型的长度
TYPES ty_my_c1 TYPE c LENGTH 30.
TYPES ty_my_c2(30) TYPE c.
DATA lv_ty01 TYPE ty_my_c1 VALUE '我是参考了ty_my_c1类型的变量'.
WRITE: / 'lv_ty01:',lv_ty01.
DATA lv_ty02 TYPE ty_my_c2 VALUE '我是参考了ty_my_c2类型的变量'.
WRITE: / 'lv_ty02:',lv_ty02.
** ABAP可以自定义类似C语言的结构体类型
** 用法和C语言的结构体类似
** 语法TYPES:BEGIN OF 结构名,
** 结构包含字段1,
** 结构包含字段2,
** END OF 结构名.
** 注意:自定义结构体类型时不能赋值 结构体定义字段长度使用字段名(长度)
** WRITE (参考了结构的变量名) 输出结构体所有字段 需要结构体字段全是文本型才能使用
** WRITE (参考了结构的变量名)- 输出结构体指定字段
** EG:
** 定义一个学生类型
TYPES:BEGIN OF ty_student,
age(3) TYPE i,
name(10) TYPE c,
sex(2) TYPE c,
END OF ty_student.
** 参考结构类型声明一个学生变量
DATA lv_student01 TYPE ty_student.
** 给学生结构体变量赋值
lv_student01-age = 18.
lv_student01-name = '张三'.
lv_student01-sex = '男'.
WRITE:/ 'lv_student01的年龄:',lv_student01-age.
WRITE:/ 'lv_student01的姓名:',lv_student01-name.
WRITE:/ 'lv_student01的性别:',lv_student01-sex.
WRITE:/.
**下面这种方式可以直接定义结构体变量 不需要参考结构体类型
DATA:BEGIN OF lv_student02,
age(3) TYPE i,
name(10) TYPE c,
sex(2) TYPE c,
END OF lv_student02.
** 给学生结构体变量赋值
lv_student02-age = 18.
lv_student02-name = '李四'.
lv_student02-sex = '女'.
WRITE:/ 'lv_student02的年龄:',lv_student02-age.
WRITE:/ 'lv_student02的姓名:',lv_student02-name.
WRITE:/ 'lv_student02的性别:',lv_student02-sex.
WRITE:/.
** 结构体变量赋值的其他方式:
** 参考了相同类型的结构体变量间赋值:变量a = 变量b 或者 move 变量a to 变量b
** 参考ty_student结构体类型声明变量lv_student03 和 lv_student04
DATA lv_student03 TYPE ty_student.
DATA lv_student04 TYPE ty_student.
lv_student03 = lv_student01.
MOVE lv_student01 TO lv_student04.
WRITE:/ 'lv_student03的年龄:',lv_student03-age.
WRITE:/ 'lv_student03的姓名:',lv_student03-name.
WRITE:/ 'lv_student03的性别:',lv_student03-sex.
WRITE:/.
WRITE:/ 'lv_student04的年龄:',lv_student04-age.
WRITE:/ 'lv_student04的姓名:',lv_student04-name.
WRITE:/ 'lv_student04的性别:',lv_student04-sex.
WRITE:/.
DATA lv_student05 TYPE ty_student.
DATA lv_student06 TYPE ty_student.
** 只要是结构体的结构相同(即两个结构体所有的字段名和字段名类型相同)也是可以直接赋值的
MOVE lv_student02 TO lv_student05.
lv_student06 = lv_student02.
WRITE:/ 'lv_student05的年龄:',lv_student05-age.
WRITE:/ 'lv_student05的姓名:',lv_student05-name.
WRITE:/ 'lv_student05的性别:',lv_student05-sex.
WRITE:/.
WRITE:/ 'lv_student06的年龄:',lv_student06-age.
WRITE:/ 'lv_student06的姓名:',lv_student06-name.
WRITE:/ 'lv_student06的性别:',lv_student06-sex.
WRITE:/.
WRITE sy-uline.
** 不同自定义结构体类型的赋值
** 定义两个不同的结构体类型 但是它们的结构相同(即所有结构体-字段名和字段名类型相同)
** 定义班级的结构体类型
TYPES:BEGIN OF ty_class,
ccode(11) TYPE c,
name(12) TYPE c,
dept(13) TYPE c,
END OF ty_class.
** 定义学生的结构体类型
TYPES:BEGIN OF ty_student02,
scode(10) TYPE c,
ccode(11) TYPE c,
name(12) TYPE c,
dept(13) TYPE c,
END OF ty_student02.
** 根据班级结构体类型声明班级结构体变量
DATA ls_class TYPE ty_class.
** 根据部门结构体
DATA ls_student TYPE ty_student02.
** 结构体变量 ls_student 赋值
ls_class-ccode = '1001'.
ls_class-name = '王五'.
ls_class-dept = '教学部'.
** 结构体变量 ls_student赋值 语法: MOVE-CORRESPONDING 变量a TO 变量b.
ls_student-scode = '01'.
** 将ls_class和ls_student比较 如果两个结构体变量字段名和字段数据类型相同
** 则将ls_clss字段的值赋给ls_student相对应的值
MOVE-CORRESPONDING ls_class TO ls_student.
WRITE: / 'LS_STUDENT:',ls_student.
WRITE: / .
WRITE: / 'LS_CLASS:',ls_class.
WRITE: / .
** 可以看到ty_student02结构体类型包含了ty_class结构体类型中的所有字段
** ABAP为了方便程序开发者 减少ABAPER开发的代码量 增加了INCLUDE 关键字
** 提高了代码复用率 防止代码冗余
** EG: 定义一个结构体类型ty_student03 使用INCLUE 关键字
TYPES: BEGIN OF ty_student03,
scode(10) TYPE c.
INCLUDE TYPE ty_class.
TYPES END OF ty_student03.
** 也可以这样定义
TYPES: BEGIN OF ty_student04.
INCLUDE TYPE ty_class.
TYPES scode(10) TYPE c.
TYPES END OF ty_student04.
** ty_studen03和ty_student04这两个结构体类型和ty_student02结构体类型相似
** 接下来给变量复制看看效果
** 参考ty_student03结构体类型声明一个ls_student03的结构体变量
DATA ls_student03 TYPE ty_student03.
** 给ls_student03的结构体变量赋值
MOVE ls_student TO ls_student03.
WRITE: / 'ls_student03:',ls_student03.
** 参考ty_student04结构体类型声明一个ls_student04的结构体变量
DATA ls_student04 TYPE ty_student04.
** 给ls_student03的结构体变量赋值
MOVE ls_student TO ls_student04.
WRITE: / 'ls_student04:',ls_student04.
** 使用 WRITE TO 赋值
** 不想写个DATA关键字圣声明变量这样声明变量
DATA: gv_char01(20) TYPE c,
gv_char02(20) TYPE c,
gv_p1(10) TYPE p DECIMALS 2 VALUE '2215.12'.
** 日期类型的赋值
** 使用WRITE TO 语法赋值
WRITE sy-datum TO gv_char01.
** 使用MOVE TO语法赋值
MOVE sy-datum TO gv_char02.
WRITE:/ '输出gv_char01 gv_char02看看有什么区别'.
WRITE:/ 'gv_char01:',gv_char01.
WRITE:/ 'gv_char02:',gv_char02.
** P类型的赋值
** 使用WRITE TO 语法赋值
WRITE gv_p1 TO gv_char01.
** 使用MOVE TO语法赋值
MOVE gv_p1 TO gv_char02.
WRITE:/ '输出gv_char01 gv_char02看看有什么区别'.
WRITE:/ 'gv_char01:',gv_char01.
WRITE:/ 'gv_char02:',gv_char02.
SKIP.
** 使用偏移量赋值 只有效于与字符型
** 语法: MOVE <源字段名>[+偏移量][(<取位数>)] TO <目标字段名>{+偏移量][(<取位数>)]
** WRITE <源字段名>[+偏移量][(<取位数>)] TO <目标字段名>{+偏移量][(<取位数>)]
** <目标字段名>{+偏移量][(<取位数>)] = <源字段名>[+偏移量][(<取位数>)]
** []为可选 <>为必选 ()属于语法
** 声明两个变量 lv_date1 lv_date2
** LIKE 和 TPYE 的区别 TYPE没有限制条件 LIKE必须要在SAP内存已经存在的变量或者类型
** 不过它们声明变量的数据类型是相同的
DATA:lv_data01 LIKE sy-datum,
lv_data02 LIKE sy-datum,
lv_data03 LIKE sy-datum,
lv_data04 LIKE sy-datum,
lv_data05(10) TYPE c,
lv_data06(10) TYPE c.
lv_data01 = sy-datum.
WRITE:/ 'LV_DATA01:',lv_data01.
WRITE:/ '日期的天数修改为30'.
** 偏移量赋值 LV-DATA01从第六位之后的二位改成30
lv_data01+6(2) = '30'.
WRITE:/ 'LV_DATA01:',lv_data01.
lv_data02 = sy-datum.
WRITE:/ 'LV_DATA02:',lv_data02.
WRITE:/ '日期的天数修改为31'.
** 偏移量赋值 LV-DATA01从第六位之后的数改成30
lv_data02+6 = '31'.
WRITE:/ 'LV_DATA02:',lv_data02.
lv_data03 = '20220520'.
lv_data04 = '20220430'.
** 偏移量赋值 当前系统实时日期的年份赋值给lv_data05
WRITE sy-datum+(4) TO lv_data05.
** 偏移量赋值 LV_DATA03的月份赋值给LV_DATA05
WRITE lv_data03+4(2) TO lv_data05+4(2).
** 偏移量赋值 LV_DATA04的天数赋值给LV_DATA05
WRITE lv_data04+6(2) TO lv_data05+6(2).
** 输出字符'20230530' 而不是日期格式'2023-05-30'.
WRITE:/ 'LV_DATA05:',lv_data05.
**
WRITE lv_data02 TO lv_data06.
WRITE:/ 'LV_DATA06:',lv_data06.
DATA:lv_char01(9) TYPE c VALUE '123456789',
lv_char02(9) TYPE c,
lv_char03(9) TYPE c.
WRITE:/ 'LV_CHAR01:',lv_char01,
/ 'LV_CHAR02:',lv_char02,
/ 'LV_CHAR03:',lv_char03.
lv_char02 = '12'.
** 偏移量赋值 LV_CHAR01第二位以后的值 赋给 LV_CHAR02第二位以后的值
MOVE lv_char01+2 TO lv_char02+2.
** 偏移量赋值 LV_CHAR01前六位赋值给 LV_CHAR03
MOVE lv_char01+(6) TO lv_char03.
WRITE:/ 'LV_CHAR01:',lv_char01,
/ 'LV_CHAR02:',lv_char02,
/ 'LV_CHAR03:',lv_char03.