抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

最近接了一个需要将XML转换为ABAP内表的开发需求。目前已经将XML的内容读进内存了,但是因为XML嵌套的结构太多也太深,所以常用的通过字段目录创建动态结构的方法无法满足业务需求。所以通过向同事打听与查阅资料,发现了SAP关于RTTC创建动态结构的内容可以满足很深层次的动态结构创建。

现已将其封装成一个工具Function,通过输入想要创建的动态结构内容,然后就可以拿到一个引用类型的对象。

RTTS动态结构创建

一、运行时类型服务(RTTS)

1.介绍

RTTS是使用类型描述类的层次结构实现的,这些类别包含运行时类型创建(RTTC)运行时类型标识(RTTI)的方法。使用这些标准类可以在运行时动态创建ABAP中的结构。

通过在运行时设置由标准类提供的CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE类型的内表内容,然后使用该内表创建新的结构体对象/内表对象。之后在CREATE DATA语句中在TYPE关键词之后使用HANDLE指定新的结构体对象/内表对象后就可以拿到这些新对象的应用变量进行操作了。

上面的内容不明白可以继续往后看,看过实例之后就会有比较清晰的认识了。

2.标准类的层次结构

1.标准类的层次结构

我们主要使用到的类就是上面的内容。通过类的名称与描述信息可以确定自己创建动态结构时需要使用到的具体是哪一个标准类。

类名 作用
CL_ABAP_TYPEDESCR 动态类型类。
CL_ABAP_DATADESCR 变量生成类,可以将由其子类生成的对象传递给该类的对象。然后引用变量直接参照该类的对象创建对象。
CL_ABAP_ELEMDESCR 数据元素生成类,可以根据数据元素生成对象,也可以根据基本数据类型生成变量。
CL_ABAP_ENUMDESCR 枚举类型生成类。
CL_ABAP_REFDESCR 引用类型生成类,可以生成引用类型变量。
CL_ABAP_COMPLEXDESCR 组件生成类,一般不会使用该类生成对象,而是使用它的两个子类来生成结构体与内表对象。
CL_ABAP_STRUCTDESCR 结构体生成类,可以根据上面提到的该类COMPONENT_TABLE类型的变量动态生成结构体对象。
CL_ABAP_TABLEDESCR 内表生成类,需要和上面的结构体生成类对象一起使用,由结构体生成类对象确定内表的结构,然后再根据内表生成类中的其余属性来确定需要生成的内表是什么类型(标准、排序…)的与主键信息等。
CL_ABAP_OBJECTDESCR 对象生成父类,用于生成Object对象的类,主要使用的也是其两个子类来生成对象。
CL_ABAP_CLASSDESCR 类生成对象类,通过传入的自定义类内容来定义和生成对象。
CL_ABAP_INTFDESCR 接口生成队形类,和上面根据类生成对象类似,通过传入自定义的接口内容,创建对象。

二、动态对象生成的核心逻辑

1.根据DDIC结构生成内表

(1)说明

直接参照DDIC结构生成结构体或内表对象。DDIC结构一般指在SE11中定义的结构、数据库表等对象。

(2)实例

参照航班表 SFLIGHT 创建内表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TRY.
"将DDIC的结构名称传入结构体定义对象
DATA(LO_STRUCT_DESC) = CL_ABAP_STRUCTDESCR=>DESCRIBE_BY_NAME( 'SFLIGHT' ).

"根据上面的结构体对象创建内表对象
DATA(LO_TABLE_DESC) = CL_ABAP_TABLEDESCR=>CREATE(
P_LINE_TYPE = CAST #( LO_STRUCT_DESC ) "内表的结构
P_TABLE_KIND = CL_ABAP_TABLEDESCR=>TABLEKIND_STD "内表类型
P_UNIQUE = ABAP_FALSE
).

"使用引用变量创建内表对象
DATA LO_TABLE TYPE REF TO DATA.
CREATE DATA LO_TABLE TYPE HANDLE LO_TABLE_DESC. "请注意此处必须在TYPE关键词后使用HANDLE关键词

"使用指针指向生成的内表
FIELD-SYMBOLS <FT_TABLE> TYPE ANY TABLE.
ASSIGN LO_TABLE->* TO <FT_TABLE>.

CATCH CX_ROOT INTO DATA(LO_ERROR).
DATA(LV_MESSAGE) = LO_ERROR->GET_TEXT( ).
ENDTRY.
2.根据DDIC结构生成的动态内表

生成的内表结构与DDIC对应的航班表SFLIGHT结构一致。

2.动态组件生成内表

(1)说明

接下来的这种方式是在运行时通过传入cl_abap_structdescr=>component_table类型内表中的字段名、字段类型等信息去动态生成内表对象的。字段类型可以是基本数据类型,也可以是数据元素CL_ABAP_COMPLEXDESCR与其子类对象。设置完成该内表值后再使用**cl_abap_structdescr=>create( )**方法根据内表值生成结构体对象。有了结构体对象之后创建内表的方法就和上面一样了。

(2)实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
TRY.
DATA LV_FLDATE TYPE SFLIGHT-FLDATE.

"填充动态组件的属性内表
DATA(LT_COMPONENTS) = VALUE CL_ABAP_STRUCTDESCR=>COMPONENT_TABLE(
"创建一个字段名为CARRID,类型为C类型长度为3位的字段
( NAME = 'CARRID'
TYPE = CL_ABAP_ELEMDESCR=>GET_C( 3 ) )
"创建一个字段名为CONNID,类型为N类型长度为4位的字段
( NAME = 'CONNID'
TYPE = CL_ABAP_ELEMDESCR=>GET_N( 4 ) )
"创建一个字段名为CARRNAME,类型参照数据元素S_CARRNAME的字段
( NAME = 'CARRNAME'
TYPE = CAST #( CL_ABAP_ELEMDESCR=>DESCRIBE_BY_NAME( 'S_CARRNAME' ) ) )
"创建一个字段名为FLDATE,类型参照程序已有变量LV_FLDATE的字段
( NAME = 'FLDATE'
TYPE = CAST #( CL_ABAP_ELEMDESCR=>DESCRIBE_BY_DATA( LV_FLDATE ) ) )
).

"根据动态组件内表生成结构体对象
DATA(LO_STRUCT_DESC) = CL_ABAP_STRUCTDESCR=>CREATE( LT_COMPONENTS ).

"根据上面的结构体对象创建内表对象
DATA(LO_TABLE_DESC) = CL_ABAP_TABLEDESCR=>CREATE(
P_LINE_TYPE = CAST #( LO_STRUCT_DESC ) "内表的结构
P_TABLE_KIND = CL_ABAP_TABLEDESCR=>TABLEKIND_STD "内表类型
P_UNIQUE = ABAP_FALSE
P_KEY = VALUE #(
( NAME = 'CARRID' )
( NAME = 'CONNID' )
)
P_KEY_KIND = CL_ABAP_TABLEDESCR=>KEYDEFKIND_USER
).

"使用引用变量创建内表对象
DATA LO_TABLE TYPE REF TO DATA.
CREATE DATA LO_TABLE TYPE HANDLE LO_TABLE_DESC. "请注意此处必须在TYPE关键词后使用HANDLE关键词

"使用指针指向生成的内表
FIELD-SYMBOLS <FT_TABLE> TYPE ANY TABLE.
ASSIGN LO_TABLE->* TO <FT_TABLE>.

CATCH CX_ROOT INTO DATA(LO_ERROR).
DATA(LV_MESSAGE) = LO_ERROR->GET_TEXT( ).
ENDTRY.
3.动态结构创建内表对象

可以看到根据已有变量创建的字段类型会和变量的类型保持一致。变量LV_FLDATE的类型是日期类型的,所以参照该变量定义的字段也是日期类型的。

三、动态生成组件工具函数

1.程序源码

(1)函数源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
*"----------------------------------------------------------------------
*"*"本地接口:
*" EXPORTING
*" REFERENCE(ER_REF) TYPE REF TO DATA
*" REFERENCE(EV_MESSAGE) TYPE STRING
*" TABLES
*" IT_DEFINITION TYPE ZTT_TYPE_DEFINITION
*" EXCEPTIONS
*" INPUT_TABLE_EMPTY
*" INPUT_TABLE_DATA_EXCEPTION
*" INPUT_TABLE_FIELDNAME_EMPTY
*" STRUCTURAL_HIERARCHY_ANOMALIES
*"----------------------------------------------------------------------
*--------------------------Variables-----------------------------------*
DATA:
LV_TABIX TYPE SY-TABIX VALUE 1, "表索引
LV_KIND TYPE C, "生成对象的类型 S 结构体 T 内表
* LT_COMPONENTS TYPE ABAP_COMPONENT_TAB,
LO_OBJECT TYPE REF TO CL_ABAP_DATADESCR."返回的组件对象
*----------------------------Logic-------------------------------------*

"Input data non-null judgment
IF IT_DEFINITION[] IS INITIAL.
RAISE INPUT_TABLE_EMPTY.
ENDIF.

"设置对象类型
CLEAR: IT_DEFINITION.
PERFORM GET_OBJECT TABLES IT_DEFINITION
* LT_COMPONENTS
USING IT_DEFINITION LV_KIND
CHANGING LV_TABIX LO_OBJECT EV_MESSAGE.

"创建参考对象
CREATE DATA ER_REF TYPE HANDLE LO_OBJECT.
ASSIGN ER_REF->* TO FIELD-SYMBOL(<FO_OBJECT>).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
FORM GET_OBJECT  TABLES PT_DEFINITION TYPE ZTT_TYPE_DEFINITION
* PT_COMPONENTS TYPE ABAP_COMPONENT_TAB
USING VALUE(PS_DEFINITION) TYPE ZTS_TYPE_DEFINITION
VALUE(PV_KIND) TYPE C
CHANGING VALUE(PV_TABIX) TYPE SY-TABIX
VALUE(PO_OBJECT) TYPE REF TO CL_ABAP_DATADESCR
VALUE(EV_MESSAGE) TYPE STRING.
*--------------------------Variables-----------------------------------*
CONSTANTS:
LC_I TYPE C LENGTH 1 VALUE 'I',
LC_F TYPE C LENGTH 1 VALUE 'F',
LC_P TYPE C LENGTH 1 VALUE 'P',
LC_C TYPE C LENGTH 1 VALUE 'C',
LC_N TYPE C LENGTH 1 VALUE 'N',
LC_D TYPE C LENGTH 1 VALUE 'D',
LC_T TYPE C LENGTH 1 VALUE 'T',
LC_X TYPE C LENGTH 1 VALUE 'X'.
DATA:
LT_KEY TYPE ABAP_KEYDESCR_TAB,
LV_TYPE TYPE REF TO CL_ABAP_DATADESCR,
LV_KIND TYPE C, "S 结构体 T 内表
LV_LEVEL TYPE I,
LV_LENGTH TYPE I,
LV_DECIMALS TYPE I,
LT_COMPONENTS TYPE ABAP_COMPONENT_TAB,
LO_TABLE_DESC TYPE REF TO CL_ABAP_TABLEDESCR.
*----------------------------Logic-------------------------------------*
TRY.
"记录当前递归中的层级
LV_LEVEL = PT_DEFINITION[ PV_TABIX ]-LEVEL.

"层级判断,递归中的层级只能比上一层递归的层级高
IF PS_DEFINITION-LEVEL IS NOT INITIAL AND
PS_DEFINITION-LEVEL > LV_LEVEL.
"当前层级不大于上层递归层级,退出本层递归
"递归层级异常,请检查动态表结构内容
EV_MESSAGE = TEXT-E01.
RAISE STRUCTURAL_HIERARCHY_ANOMALIES.
ENDIF.

LOOP AT PT_DEFINITION FROM PV_TABIX WHERE LEVEL = LV_LEVEL.
PV_TABIX = SY-TABIX.

"判断是否是普通字段/结构/表类型
IF PT_DEFINITION-KIND IS INITIAL AND
PT_DEFINITION-ELEMENT IS INITIAL AND
PT_DEFINITION-TYPE IS INITIAL.
"结构体

"设置创建的类型标识
LV_KIND = 'S'.
PV_TABIX = PV_TABIX + 1.
"递归调用,获取结构体对象
PERFORM GET_OBJECT TABLES PT_DEFINITION
* PT_COMPONENTS
USING PT_DEFINITION LV_KIND
CHANGING PV_TABIX PO_OBJECT EV_MESSAGE.

CHECK EV_MESSAGE IS INITIAL.
"将结构对象传入内表
LV_TYPE ?= PO_OBJECT.
LT_COMPONENTS = VALUE #( BASE LT_COMPONENTS
( NAME = PT_DEFINITION-FIELD TYPE = LV_TYPE ) ).
ELSEIF PT_DEFINITION-KIND IS NOT INITIAL AND
PT_DEFINITION-ELEMENT IS INITIAL AND
PT_DEFINITION-TYPE IS INITIAL.
"表类型

"判断是否是第一条数据
IF PV_TABIX = 1 AND PT_DEFINITION-FIELD IS INITIAL AND
PT_DEFINITION-LEVEL = 1.
DATA(LV_EXIT_FLAG) = 'X'.
ENDIF.

"设置创建的类型标识
LV_KIND = 'T'.
PV_TABIX = PV_TABIX + 1.
"递归调用,获取结构体对象
PERFORM GET_OBJECT TABLES PT_DEFINITION
* PT_COMPONENTS
USING PT_DEFINITION LV_KIND
CHANGING PV_TABIX PO_OBJECT EV_MESSAGE.

CHECK EV_MESSAGE IS INITIAL.
"退出判断
IF LV_EXIT_FLAG IS NOT INITIAL.
"是,则代表创建的结构一开始就是一个内表
EXIT.
ELSE.
"将结构对象传入内表
LV_TYPE ?= PO_OBJECT.
LT_COMPONENTS = VALUE #( BASE LT_COMPONENTS
( NAME = PT_DEFINITION-FIELD TYPE = LV_TYPE ) ).
ENDIF.
ELSEIF PT_DEFINITION-KIND IS INITIAL AND
( PT_DEFINITION-ELEMENT IS NOT INITIAL OR
PT_DEFINITION-TYPE IS NOT INITIAL ).
"普通字段类型
IF PT_DEFINITION-ELEMENT IS NOT INITIAL.
"参照DataElement
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>DESCRIBE_BY_NAME(
PT_DEFINITION-ELEMENT ) ).
ELSE.
"基本数据类型
LV_LENGTH = PT_DEFINITION-LENG.
LV_DECIMALS = PT_DEFINITION-DECIMALS.
CASE PT_DEFINITION-TYPE.
WHEN LC_I.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_I( ) ).
WHEN LC_F.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_F( ) ).
WHEN LC_P.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_P(
P_LENGTH = LV_LENGTH
P_DECIMALS = LV_DECIMALS ) ).
WHEN LC_C.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_C(
P_LENGTH = LV_LENGTH ) ).
WHEN LC_N.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_N(
P_LENGTH = LV_LENGTH ) ).
WHEN LC_D.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_D( ) ).
WHEN LC_T.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_T( ) ).
WHEN LC_X.
LV_TYPE = CAST #(
CL_ABAP_ELEMDESCR=>GET_X(
P_LENGTH = LV_LENGTH ) ).
WHEN OTHERS.
ENDCASE.
ENDIF.

IF PT_DEFINITION-KEY IS NOT INITIAL.
LT_KEY = VALUE #( BASE LT_KEY
( NAME = PT_DEFINITION-FIELD ) ).
ENDIF.

LT_COMPONENTS = VALUE #( BASE LT_COMPONENTS
( NAME = PT_DEFINITION-FIELD TYPE = LV_TYPE )
).
ENDIF.

"判断当前层级是否大于下一层级
IF PV_TABIX < LINES( PT_DEFINITION ).
IF LV_LEVEL > PT_DEFINITION[ PV_TABIX + 1 ]-LEVEL.
"当前结构的层级已结束
EXIT.
ENDIF.
ENDIF.

CLEAR: PT_DEFINITION.
ENDLOOP.

"根据判断创建对应的对象
IF LT_COMPONENTS IS NOT INITIAL.
CASE PV_KIND.
WHEN 'S'.
DATA(LO_STRUCT_DESC) =
CL_ABAP_STRUCTDESCR=>CREATE( LT_COMPONENTS ).
WHEN 'T'.
LO_STRUCT_DESC =
CL_ABAP_STRUCTDESCR=>CREATE( LT_COMPONENTS ).
LO_TABLE_DESC = CL_ABAP_TABLEDESCR=>CREATE(
P_LINE_TYPE = LO_STRUCT_DESC
P_TABLE_KIND = PS_DEFINITION-KIND
P_UNIQUE = ABAP_FALSE
P_KEY = LT_KEY
P_KEY_KIND = COND #( WHEN PS_DEFINITION-KEY_KIND IS INITIAL
THEN CL_ABAP_TABLEDESCR=>KEYDEFKIND_DEFAULT
ELSE PS_DEFINITION-KEY_KIND )
).
WHEN OTHERS.
LO_STRUCT_DESC =
CL_ABAP_STRUCTDESCR=>CREATE( LT_COMPONENTS ).
ENDCASE.
ENDIF.

"将对象返回
IF LO_TABLE_DESC IS BOUND.
PO_OBJECT ?= LO_TABLE_DESC.
ELSEIF LO_STRUCT_DESC IS BOUND.
PO_OBJECT ?= LO_STRUCT_DESC.
ENDIF.

MOVE-CORRESPONDING PS_DEFINITION TO PT_DEFINITION.
CATCH CX_ROOT INTO DATA(LO_ERROR).
EV_MESSAGE = LO_ERROR->GET_TEXT( ).
ENDTRY.

FREE: LT_KEY,LT_COMPONENTS.
ENDFORM.

(2)传入参数结构

ZTT_TYPE_DEFINITION为表类型,其参照的结构为ZTS_TYPE_DEFINITION

4.传入参数结构信息

下面是参数的说明与参考值信息。

字段名 描述 参考值 参考值说明/备注
LEVEL 层级 若是简单无嵌套动态结构可不输入
FIELD 字段名称 动态组件的字段名
KEY 关键标识字段 内表中的主键标记字段,主要在排序表中使用
KEY_KIND 关键字段类型 和上面的类型一起使用,关键字段的类型
CL_ABAP_TABLEDESCR=>KEYDEFKIND_DEFAULT 默认类型
CL_ABAP_TABLEDESCR=>KEYDEFKIND_TABLELINE 表主键(一般用于从DDIC创建内表主字段使用)
CL_ABAP_TABLEDESCR=>KEYDEFKIND_TABLELINE 用户自定义键
CL_ABAP_TABLEDESCR=>KEYDEFKIND_EMPTY 用户自定义键
KIND 表类型
CL_ABAP_TABLEDESCR=>TABLEKIND_ANY 泛型表
CL_ABAP_TABLEDESCR=>TABLEKIND_STD 标准表
CL_ABAP_TABLEDESCR=>TABLEKIND_INDEX 索引表
CL_ABAP_TABLEDESCR=>TABLEKIND_HASHED Hash表
CL_ABAP_TABLEDESCR=>TABLEKIND_SORTED 排序表
ELEMENT 数据元素 (语义域) 和下面的TYPE、LENG与DECIMALS类似,都是用来控制字段类型的,但是填写了数据元素后下面的TYPE、LENG与DECIMALS就可以不用填写了,反之填写了TYPE、LENG与DECIMALS就可以不用填写ELEMENT了。
TYPE ABAP 数据类型(C,D,N,…) 基本数据类型,I、F、P、C、N、D、T和X
LENG 长度(字符数) 变量的长度,只有P、C、N与X类型需要填写
DECIMALS 小数位数 小数位长度,只有P类型需要填写
PARENT 父层级 (暂未使用) 暂未使用到,可以不用添加该字段

2.程序说明

该函数主要是适用于上面动态组件生成对象的逻辑。即填充cl_abap_structdescr=>component_table类型的内表然后创建结构体与内表对象。暂时未添加根据DDIC结构创建动态结构的功能,因为直接根据DDIC结构创建动态结构的方法很多。

该函数主要是用来动态创建发杂的/深层级的组件对象的。例如结构体嵌套结构体/内表、内表嵌套结构体/内表,然后他们嵌套的子结构还可以继续嵌套更深层级的组件对象时,可以使用该工具函数创建这些组件对象。

3.使用说明

(1)结构体创建

① 输入参数参考

如果要创建一个结构体,只需要将结构体中字段名称和字段类型填写上即可。

LEVEL FIELD KEY KEY_KIND KIND ELEMENT TYPE LENG DECIMALS
1 FIELD1 CHAR10
1 FIELD2 C 10
1 FIELD3 P 10 2
② 程序执行结果
5.普通结构体创建

(2)内表创建

① 输入参数参考

创建内表时,在输入参数的第一条数据中写上层级与表类型即可,然后在第二行写上表字段的名称层级与类型信息。KIND为S代表标准表,在上面的参考值中对应CL_ABAP_TABLEDESCR=>TABLEKIND_STD

LEVEL FIELD KEY KEY_KIND KIND ELEMENT TYPE LENG DECIMALS
1 S
2 FIELD1 C 10
2 FIELD2 P 10 2
2 FIELD3 SYDATUM
② 程序执行结果
6.普通表创建

(3)复杂结构-结构体嵌套结构体/内表

如果涉及到深层的例如结构体嵌套结构体/内表的情况,则按照下面的方式进行即可。同理如果已经嵌套的组件对象中还有更深层次的组件对象,则可以根据他们在嵌套组件中的位置和层级关系继续嵌套。

① 输入参数参考
LEVEL FIELD KEY KEY_KIND KIND ELEMENT TYPE LENG DECIMALS
1 FIELD1 CHAR10
1 FIELD2 C 10
1 FIELD3 P 10 2
1 STRUCTURE1
2 STRFIELD1 CHAR10
2 STRFIELD2 CHAR10
2 STRFIELD3 CHAR10
2 STRUCTURE2
3 STRFIELD2_1 CHAR10
3 STRFIELD2_2 CHAR10
1 TABLE S
2 TABFIELD1 CHAR10
2 TABFIELD2 CHAR10
2 TABFIELD3 CHAR10
② 程序执行结果
7.复杂结构-结构体嵌套结构体或内表

(4)复杂结构-内表嵌套结构体/内表

在外层的内表中嵌套了结构体STRUCTURE之后,有嵌套了内表TABLE1。在TABLE1内部又再次嵌套了TABLE2.

① 输入参数参考
LEVEL FIELD KEY KEY_KIND KIND ELEMENT TYPE LENG DECIMALS
1 S
2 FIELD1 CHAR10
2 FIELD2 C 10
2 FIELD3 P 10 2
2 STRUCTURE
3 STRFIELD1 CHAR10
3 STRFIELD2 CHAR10
2 FIELD4
2 TABLE1 S
3 TAB1FIELD1 CHAR10
3 TAB1FIELD2 CHAR10
3 TAB1FIELD3 CHAR10
3 TABLE2 S
4 TAB2FIELD1 CHAR10
4 TAB2FIELD2 CHAR10
3 TAB1FIELD4 CHAR10
② 程序执行结果

通过断点调试新增一行初始值可以看的更直观一些。

返回的第一层内表结构图下所示。

8.复杂结构-内表嵌套结构体或内表_第一层内表结构

第一层内表中的STRUCTURE结构如下图所示。

9.复杂结构-内表嵌套结构体或内表_第二层结构体结构

第一层内表中的TABLE1结构如下图所示。

10.复杂结构-内表嵌套结构体或内表_第二层内表结构

第二层内表中的TABLE2结构如下图所示。

11.复杂结构-内表嵌套结构体或内表_第三层内表结构

可以看到创建出来的复杂结构对象满足一开始设计的内容。

四、参考资料

How To Create A Dynamic Internal Table Using RTTS

Runtime Type Services (RTTS)

评论