ABAP内表(Internal Table)的定义及使用(一)

0

Posted by admin | Posted in 其它 | Posted on 26-07-2010

一、Internal Table的定义

1. 概念

Internal Table中文成为内表,是ABAP中一种比较特殊的数据对象,它用于存储数据集,一行一行存储某一固定格式的数据。数据集中中每一个行的每一个数据对象都可以访问。内表中的一行称作 Table Line或Table Entry。内表的行数可以自动扩展,其最大行数的限制依赖于系统的参数设定。内表结构可以包含一个单独的数据元素,一个结构也可以是一个内表,甚至更复杂。

abap-3-1

内表的定义由以下方面完全定义:
Line type: 行的数据结构中每一列的属性,一般用structure type指定line type,实际上任意数据类型都可以。
Key definition: key列及其顺序的定义被用于鉴别内表中不同的行,内表中的key列可以定义为unique 或non-unique,这一点取决于我们访问内表的方式。如果是unique的,内表中所有行不能出现相同Key值的字段。
Access type: key access方式是指我们访问内表时通过key列的内容查询数据;index access方式是指我们通过行的顺序编号访问相应的行(并不是所有类型的内表都可以这样访问)
Table kind: Standard tables, Sorted tables, Hashed tables,这三种类型的内表在key列的设置、Access type有所不同,各有特点,使用的时候需要根据逻辑特性选择相应的类型。

abap-3-2

Standard tables: 在这种内表中,系统会自动为每一行数据编号,我们可以通过index 和 key两种方式访问某一行。
Sorted tables: 在这种内表中,数据总是按照key字段排序后保存的,我们也可以通过index 和 key两种方式访问某一行。
Hashed tables: 在这种内表中,数据记录的管理方法是为了运行时优化,定义这种表的时候key列必须是unique的,访问的时候也只能通过key access访问。

从三种类型内表(Internal table)的特性中我们可以推断,当我们的程序对一个内表进行的访问大多数情况下是逐行处理,使用standard table就足够了;如果需要对一个内表的数据进行固定顺序排序,并且多数情况下通过key 访问,选用sorted table比较好;第三种情况,如果内表仅用于根据key列查询,我们应该选用Hashed table,可以极大的提高性能,尤其是在数据量较大或查询频繁的程序中。

ABAP 内表(Internal Table)的定义及使用(三)

0

Posted by admin | Posted in 其它 | Posted on 26-07-2008

二、Internal Table的使用

1 Adding Lines by Key Access 以key access的方式添加数据

abap-3-5

如上图所示的几种命令三种内表均适用,但是对于不同类型的内表,技术层面上的操作略有不同:
Standard table: 在内表的最后一行增加一行数据,与APPEND命令相同
Sorted table: 如果是unique key, 新增的记录将被插入在按照key列升序排列相应的位置,如果是non-unique key,如果已经存在相同Key值的行,输将将被插入第一个相同key值的列前面。
Hashed table: 新增的记录被插入内表最后一行(看上去,实际在哪一行对访问内表都无意义),相应的HASH INDEX中也增加一行。

如果内表是unique key定义的话,内表中如果已经存在同样key值的数据,则操作失败,SY-SUBRC返回值为4;当以上语句成功执行之后,即数据被插入内表,SY-TABIX值为插入后数据所在的位置。

COLLECT命令只能用于非key列全是数字类型(I,P,F)的内表。该语句的作用是将工作区的数据累加入内表相同key值的行,或没有的情况下新增一行。需要注意的是,对于non-unique key定义的内表,如果内表中存在多个key值相同的行,则COLLECT命令将只在第一个key值相同的列累加。示例代码如下:

TYPES: BEGIN OF TY_ITAB,
EBELN TYPE EKKO-EBELN,
EBELP TYPE EKPO-EBELP,
MATNR TYPE EKPO-MATNR,
MENGE TYPE EKPO-MENGE,
END OF TY_ITAB.
TYPES: TT_ITAB TYPE TABLE OF TY_ITAB.
DATA: WA_ITAB TYPE TY_ITAB.
DATA: T_ITAB_STANDARD TYPE TT_ITAB. "Default: Standard table
DATA: T_ITAB_SORTED TYPE SORTED TABLE OF TY_ITAB WITH NON-UNIQUE KEY EBELN EBELP MATNR. "Sorted table, NON-UNIQUE KEY
DATA: T_ITAB_HASHED TYPE HASHED TABLE OF TY_ITAB WITH UNIQUE KEY EBELN EBELP MATNR. "Hashed table, UNIQUE KEY

*fill data into working area line
DEFINE DEF_WA_ITAB.
WA_ITAB-EBELN = &1.
WA_ITAB-EBELP = &2.
WA_ITAB-MATNR = &3.
WA_ITAB-MENGE = &4.
END-OF-DEFINITION.
DEF_WA_ITAB ’4500010001′ ’00010′ ’000000000010000000′ ’100′.
INSERT WA_ITAB INTO TABLE T_ITAB_STANDARD.
INSERT WA_ITAB INTO TABLE T_ITAB_SORTED.
INSERT WA_ITAB INTO TABLE T_ITAB_HASHED.

DEF_WA_ITAB ’4500010010′ ’00010′ ’000000000010000002′ ’200′.
INSERT WA_ITAB INTO TABLE T_ITAB_STANDARD.
INSERT WA_ITAB INTO TABLE T_ITAB_SORTED.
INSERT WA_ITAB INTO TABLE T_ITAB_HASHED.

DEF_WA_ITAB ’4500010002′ ’00010′ ’000000000010000003′ ’100′.
INSERT WA_ITAB INTO TABLE T_ITAB_STANDARD. " Just append
INSERT WA_ITAB INTO TABLE T_ITAB_SORTED. " Sorted automatically: sorted table, asending order
INSERT WA_ITAB INTO TABLE T_ITAB_HASHED. " Apears to be append, but an entry of a hash index is made

DEF_WA_ITAB ’4500010002′ ’00010′ ’000000000010000003′ ’100′. "same record as last one
INSERT WA_ITAB INTO TABLE T_ITAB_STANDARD.
INSERT WA_ITAB INTO TABLE T_ITAB_SORTED. " inserted before the first entry of the same key
INSERT WA_ITAB INTO TABLE T_ITAB_HASHED. " Failed inserting: unique key sy-subrc = 4

DEF_WA_ITAB ’4500010002′ ’00010′ ’000000000010000003′ ’100′. "NUMBERIC FIELDS ARE COLLECTED ACCORDING KEY FIELDS
COLLECT WA_ITAB INTO T_ITAB_STANDARD. " ONLY TO THE FIRST LINE OF KEY-VALUE-OCCURED
COLLECT WA_ITAB INTO T_ITAB_SORTED. " THE SAME AS ABOVE
COLLECT WA_ITAB INTO T_ITAB_HASHED. " UNIQUE-KEY

DATA: T_ITAB_NAK TYPE SORTED TABLE OF TY_ITAB WITH NON-UNIQUE KEY EBELN EBELP. "NOT ALL CHAR-LIKE FIELDS ARE KEY FIELDS
DEF_WA_ITAB ’4500010003′ ’00010′ ’000000000010000002′ ’200′.
INSERT WA_ITAB INTO TABLE T_ITAB_NAK.
DEF_WA_ITAB ’4500010003′ ’00010′ ’000000000010000002′ ’100′.
*COLLECT WA_ITAB INTO T_ITAB_NAK. " IF UNCOMMENTED, SYNATX CHECK

2 Adding Lines by Index Access 以index access的方式添加数据

abap-3-6 

以上语句均是以index access的方式向内表添加数据,需要注意的是,如果INDEX指定的数值超过内表已有数据行数的范围,则语句执行失败,SY-SUBRC为4,数据也不会插入到内表中。在LOOP…ENDLOOP中间使用INSERT命令,数据将插入到由LOOP命令打开的游标处。INSERT LINES OF 命令用于批量插入数据。需要注意的是,如果使用Index access向 sorted table插入数据,我们必须确保index所指定的位置是按照key列排序相应的位置,否则将会出现runtime error;由于hashed table根本不支持 index access,写下的代码连语法检查也无法通过。因此建议仅对standard table使用index access方式插入数据。

上图中:Ranked list APPEND wa INTO rank_itab SORTED BY f.这个命令我在试验中发现WA中的数据根本不会添加到内表中,有人知道这是怎么用的话请留言,多谢。其它部分示例代码如下:

DEF_WA_ITAB ’4500010006′ ’00010′ ’000000000010000002′ ’100′.
INSERT WA_ITAB INTO T_ITAB_STANDARD INDEX 2.
*INSERT WA_ITAB INTO T_ITAB_SORTED index 2. " UNCOMMENT, runtime error
*INSERT WA_ITAB INTO T_ITAB_HASHED index 2. " UNCOMMENT, SEE SYNATX CHECK
LOOP AT T_ITAB_STANDARD INTO WA_ITAB.
INSERT INITIAL LINE INTO T_ITAB_STANDARD. " LOOP…ENDLOOP OPEN A CURSOR
ENDLOOP.
* INSERT INITIAL LINE INTO T_ITAB_STANDARD. " WITHOUT A LOOP, RUNTIME ERROR
INSERT INITIAL LINE INTO T_ITAB_STANDARD INDEX 2. " INDEX ACCESS, AN INIT LINE IS INSERTED INTO LINE 2
INSERT INITIAL LINE INTO T_ITAB_SORTED INDEX 1. " IF POSITION IS NOT CORRECT ACCORDING TO SORT CONDITION,
" RUNTIME ERROR, SO RECOMMAND USING ONLY ON STANDARD TABLE
*INSERT INITIAL LINE INTO T_ITAB_HASHED. " UNCOMMENT, SEE SYNATX CHECK
INSERT LINES OF T_ITAB_SORTED FROM 1 TO 4
INTO T_ITAB_STANDARD INDEX 1. "currently 11 records in the internal table, 1~12 IS OK, BEYOND 12, LIKE 13, 14… INSERTING FAILED

3 Changing Content by Key Access 以Key access的方式修改内容

abap-3-7

如上图所示的语句中,如果使用FROM wa addition,要求wa中的key field必须有值。如果在内表中根据key值没有找到相符的行,删除、修改都没有执行成功,则SY-SUBRC 为4。TRANSPORTING 关键字用于限定更新选定的字段。WHERE addition中可以填写几乎各种条件表达式,但是要求表达式中关系运算符左边的表达式必须是内表中的字段,可以通过(变量名)的方式动态构造WHERE。

DELETE ADJACENT DUPLICATES… 命令用于删除内表中相邻行重复的数据。重复的定义是相对的,如果不适用COMPARING addition,重复是根据KEY FIELD定义的,如果使用ALL FIELDS则是全部字段,如果使用COMPARING,则根据指定的条件比较。通常使用这个命令时,我们首先对内表排序。

4 Changing Content by Index Access 以Index Access的方式修改内表数据

abap-3-8

以上命令可以用于Standard table和Sorted table,不能用于Hashed table.

关于SY-SUBRC, TRANSPORTING, LOOP游标在这里就不再说明了,需要注意的是,LOOP…ENDLOOP中间用DELETE效率较低,对于多行的删除,建议使用DELETE itab FROM N1 TO N2或DELETE WHERE.

ABAP 内表(Internal Table)的定义及使用(二)

0

Posted by admin | Posted in 其它 | Posted on 26-07-2008

2. 内表定义的ABAP Code

通过ABAP Code定义内表有三种方式,
With an implicitly defined (bound) type
With an explicitly defined local type
With an explicitly defined global type

内表定义的文法如下图所示:

abap-3-3

文法中的STANDARD/ SORTED/HASHED TALBE指定了该内表示什么类型,内表定义时所引用的行类型(data_type, data_object, global_itab_type, local_itab_type, itab_data_object等)可以是本地或全局定义的类型或表,也可以是一个Data object。 WITH key_def用于指定内表的key列定义,UNIQUE或NON-UNIQUE指定了该内表的key列性质。需要注意的是,如果不适用WITH key_def addition定义key列,可以通过DEFAULT KEY指定默认字段为key列,对于Standard tables,默认的key列是由所有CHAR-LIKE字段组成的(C,N,D,T,X,STIRNG,XSTRING)。

table kind和key definition有多种组合,简要列出来如下: standrad table(only non-unique), sorted table(unique or non-unique), hashed table(only unique)。

standard table最常用,可以用以下简化方式定义:
DATA: itab_name TYPE TABLE OF line_type. ABAP运行时将此行代码编译为以下代码:
DATA: itab_name TYPE [STANDARD] TABLE OF line_type [WITH NON-UNIQUE DEFAULT KEY].

一个完整的定义如下:

abap-3-4

如上图所示代码为通过参考一个本地定义的LINE TYPE的STANDARD TABLE.如果将TYPE STANDARD TABLE替换为TYPE SORTED TABLE 或TYPE HASHED TABLE将定义两个结构完全一样的另外两种类型的内表。需要注意的是,对于SORTED TABLE,数据存储的顺序不同。定义内表的时候并一定需要通过INITIAL SIZE指定初始内存大小,在程序执行过程中,如果内表的大小不足,系统会自动扩展内表所占内存空间,而且没有最大限制。

Generic table kind是指没有使用TABLE TYPE明确定义是哪种内表,通常用于子程序参数定义。

用SET PARAMETER ID为选择屏幕设定参数

0

Posted by admin | Posted in 其它 | Posted on 26-07-2008

在定义选择屏幕的时候,可以为选择屏幕的选择条件字段指定MEMORY ID,这样的话,在其他SESSION执行过的SET PARAMETER ID动作存入的数据,会在选择屏幕显示的时候自动填入数据。在标准程序中,很多地方都使用到这样的方法。不光是选择屏幕,自己开发的SCREEN也有类似的机制。为SELECTION-SCREEN设定MEMORY ID的方法如下:

PARAMETERS: P_VBELN LIKE VBAK-VBELN MEMORY ID AUN.

程序初始化的时候,相应MEMORY ID 的数据会被自动填入该选择屏幕字段中,如上例,刚刚查看过的销售订单号会被自动填入P_VBELN字段中。

SAP ERP开发ABAP代码走查地方法

0

Posted by admin | Posted in 其它 | Posted on 26-07-2008

      每次讨论质量问题,都不可避免的谈到ERP实施、二次开发的特殊性,需求、过程,与完整的软件系统开发,从表面上看可以说完全不同。SAP ABAP开发不向JAVA, C#等有众多的开发人员基础,因此很少有人专门开发其工具,代码的编码水平、管理水平都非常落后。Eclipse有众多插件,VS2005也一样,插件可以有很多功能,提高开发效率,可是ABAP没有。

      怎么办?ABAP开发是一个需求复杂、技术简单的过程。因此针对需求变更、代码质量的手段也应当有所不同。在此,针对ABAP代码提出代码走查的一些想法,有待实践。下午在对一个已有报表的代码进行重构的过程中总结如下:

      1 检查程序头注释是否更新完整:应包括需求名称、程序标题、修改记录等信息

      2 代码结构体注释:如REPORT PROGRAM EVENT的注释、子程序的注释要明确

      3 数据定义注释:DATA, SELECT-OPTIONS, PARAMETERS等定义要明确

      4 子程序参数是否正确:子程序中的数据应通过参数传递

      5 对于修改的代码注释是否完备:应简洁的注明时间、人、原因

      6 检查传输请求 短描述是否符合项目规范

      7 检查传输请求 文档是否完备

      8 检查传输请求 是否包含且仅包含该程序及相关的对象

      目前仅考虑到这一步,对代码进行走查非常重要,但是以上8条仅对代码、传输请求进行了简单步骤规定,这些步骤还没有涉及到代码对业务的实现逻辑,主要解决的问题是将来维护程序时,不知道先前的改动、逻辑是什么用处。希望能和文档工具配合使用,减少开发人员编写文档的工作量。

      虽说我们不能像VS 2005, Eclipse插件那样开发工具,但是ABAP中也有一些特性可以让我们更轻松的处理其他问题,仍然可以编写一些程序提高工作效率,如写程序辅助代码走查,将某些内容集中显示。

      还是那句话,纵使二次开发的过程再“特殊”,我也不会放弃对于高质量的追求!