ABAP-动态编程
转载:http://www.cnblogs.com/jiangzhengjun/p/4293407.html
How to get a Type Object获取类型对象
Working with Type Objects通过类型对象创建数据或对象
Principles(实践) of Dynamic Type Creation
动态创建内表Dynamic Creation of Table Types
动态创建引用类型Dynamic Creation of Reference Types
动态创建结构类型Dynamic Creation of Structured Types
Analyzing Structures with Includes
动态的基本语法
动态内容必须是大写
多种不同的动态编程
动态字段
arbitrary:任意的
动态类型
指定结构、内表组件字段的动态
Open SQL语句中的动态
动态访问程序
创建与运行临时Subroutines
上面讲的是对一个存在的物理程序文件进行动态操作的过程。如果想要不生成的物理文件,则可以为某个程序临时动态的创建Subroutines:
GENERATE SUBROUTINE POOL <itab> NAME <prog> [<options>].
该语句将会在当前running program的main memory area中创建临时subroutine pool,其源代码为<itab>中的内容。<prog>是类型为C类型8位长度的变量,用来接受该语句返回动态生成的subroutine pool的名字。你可以使用这个名字<prog>来调用通过<itab>内表动态生成的外部subroutines。
动态生成的subroutine pool只会在生成它的程序里运行期间存在,并且也只能从生成它的程序里调用它。你可以为一个程序最多创建36个subroutine pools。
如果在生成期间发行了错误,则SY-SUBRC将设置为8
语句中的[<options>]可选项如下:
? MESSAGE <mess>
如果发生语法错误,则会存储这些错误消息
? INCLUDE <incl>
如果发生语法错误,则该字段会存储了问题发生的include program的名字
? LINE <line>
如果发生语法错误,则该字段存储了发生错误的行
? WORD <word>
如果发生语法错误,该字段存储了wrong word (发生错误的单词)
? OFFSET <offs>
如果发生语法错误,该字估存储了wrong word所在行的偏移量位置
? TRACE-FILE <trac>
如果发生语法错误,将会切换到trace mode ,并且该字段存储了traceoutput
与INSERT REPORT相比,GENERATE SUBROUTINE POOL语句具有更好的性能,另外,生成的临时程序不会覆盖现有的程序
REPORT zmaster2.
,
prog),
msg),
lin),
wrd),
off).
APPEND 'PROGRAM SUBPOOL.' TO code.
APPEND 'FORM DYN1.' TO code.
APPEND 'WRITE / ''Hello, I am the temporary subroutine DYN1!''.' TO code.
APPEND 'ENDFORM.' TO code.
APPEND 'FORM DYN2.' TO code.
"此处的WRITE故意写成了WRIT,运行时会出编译错误
APPEND 'WRIT / ''Hello, I am the temporary subroutine DYN2!''.' TO code.
APPEND 'ENDFORM.' TO code.
"临时生成外部程序的Form
GENERATE SUBROUTINE POOL code NAME prog
MESSAGE msg
LINE lin
WORD wrd
OFFSET off.
.
WRITE: / 'Error during generation in line: ', lin,
/ 'Msg:' , msg,
/ 'Word:', wrd, 'at offset', off.
ELSE.
WRITE: / 'The name of the subroutine pool is', prog.
"动态调用临时生成的Form
PERFORM dyn1 IN PROGRAM (prog).
PERFORM dyn2 IN PROGRAM (prog).
ENDIF.
如果将第6行的WRITE修改成WRIT时,运行时会显示编译出错的结果:
否则调用临时生成的外部程序Form成功结果:
RTTS(Run Time Type Services)
Run Time Type Services (RTTS)是以以下三项为基础的:
1、 Type identification and description at run time (formerly RTTI)
2、 Dynamic type creation (RTTC)
3、 Implemented as system classes
数据变量反射
TYPES my_type TYPE i.
DATA: my_data TYPE my_type,
descr_ref TYPE ref to cl_abap_typedescr.
descr_ref = cl_abap_typedescr=>describe_by_data( my_data ).
WRITE: / 'Typename:', descr_ref->absolute_name.
WRITE: / 'Kind :', descr_ref->type_kind.
WRITE: / 'Length :', descr_ref->length.
WRITE: / 'Decimals:', descr_ref->decimals.
Typename:\PROGRAM=ZJZJ_TEST3\TYPE=MY_TYPE
Kind : I
Length : 4
Decimals: 0
对象引用反射
DATA: oref1 TYPE REF TO object,
oref2 TYPE REF TO object.
DATA: descr_ref1 TYPE REF TO cl_abap_typedescr,
descr_ref2 TYPE REF TO cl_abap_typedescr,
mess TYPE string.
TRY.
CREATE OBJECT: oref1 TYPE ('C1'),
oref2 TYPE ('C2').
CATCH cx_sy_create_object_error.
MESSAGE 'Create object error!' TYPE 'I' DISPLAY LIKE 'E'.
LEAVE PROGRAM.
CATCH cx_root.
MESSAGE 'Other error!' TYPE 'I' DISPLAY LIKE 'E'.
LEAVE PROGRAM.
ENDTRY.
"根据对象引用来进行反射
descr_ref1 = cl_abap_typedescr=>describe_by_object_ref( oref1 ).
descr_ref2 = cl_abap_typedescr=>describe_by_object_ref( oref2 ).
TRY.
IF descr_ref1 <> descr_ref2.
RAISE EXCEPTION TYPE conv_exc.
ELSE.
oref1 = oref2.
ENDIF.
CATCH conv_exc.
mess = `Assignment from type ` &&
descr_ref2->absolute_name &&
` to ` &&
descr_ref1->absolute_name &&
` not allowed!`.
MESSAGE mess TYPE 'I' DISPLAY LIKE 'E'.
ENDTRY.
RTTS系统类结构图
CL_ABAP_TYPEDESCR
|
|--CL_ABAP_DATADESCR
| |
| |--CL_ABAP_ELEMDESCR
| |--CL_ABAP_REFDESCR
| |--CL_ABAP_COMPLEXDESCR
| |
| |--CL_ABAP_STRUCTDESCR
| |--CL_ABAP_TABLEDESCR
|
|--CL_ABAP_OBJECTDESCR
|
|--CL_ABAP_CLASSDESCR
|--CL_ABAP_INTFDESCR
ABAP中类型的原理
immutable:不可变
每种类型都会有一个运行时类型对象
每种类型对象都会对应到相应的类型
类型对象是一个RTTS类的一个实例
类型对象是不可变的
类型对象描述了所有类型的属性
类型对象可以用来代替类型名
How to get a Type Object获取类型对象
l Get type object by type name通过类型名获取
DATA: structtype TYPE REF TO cl_abap_structdescr.
structtype ?= cl_abap_typedescr=>describe_by_name( 'spfli' ).
l Get type object from a data object通过数据对象获取
DATA: datatype TYPE REF TO cl_abap_datadescr,
) TYPE c.
datatype ?= cl_abap_typedescr=>describe_by_data( field ).
l Get elementary types直接获取基本类型对象
DATA: elemtype TYPE REF TO cl_abap_elemdescr.
elemtype = cl_abap_elemdescr=>get_i( ).
elemtype = cl_abap_elemdescr=>get_ ).
Working with Type Objects通过类型对象创建数据或对象
l Create a data object of a specific type using a type object
DATA: dref TYPE REF TO data,
c20type TYPE REF TO cl_abap_elemdescr.
c20type = cl_abap_elemdescr=>get_c( ).
CREATE DATA dref TYPE HANDLE c20type.
l Casting of a field symbol using a type object
DATA: x20Type TYPE REF TO cl_abap_elemdescr.
FIELD-SYMBOLS: <fs> TYPE any.
x20Type = cl_abap_elemdescr=>get_x( ).
ASSIGN dref->* TO <fs> CASTING TYPE HANDLE x20Type.
Principles(实践) of Dynamic Type Creation
Dynamically created types are
?? transient (exist only for the lifetime of the internal mode)
?? program local (live only in roll area)
?? anonymous (no name, only accessible by type object)
l Implicit(隐式) type creation
only for table and reference types
CREATE DATA dref TYPE TABLE OF type.
CREATE DATA dref TYPE REF TO type.
l Explicit(显示) Type creation
factory method CREATE( ) in RTTS classes
structType = CL_ABAP_STRUCTDESCR=>create( compTab ).
动态创建内表Dynamic Creation of Table Types
这些默认的值是该类中定义的常量,可以直接使用
动态创建引用类型Dynamic Creation of Reference Types
动态创建结构类型Dynamic Creation of Structured Types
类型component_table是一种类型cl_abap_structdescr=>component_table的内表,其内表行结构如下:
begin of abap_componentdescr,
name type string,
type type ref to cl_abap_datadescr,
as_include type abap_bool,
suffix type string,
end of abap_componentdescr,
Analyzing Structures with Includes
动态创建基本类型、结构体、内表
****************** hardcoded "old style" local type*******************
* This is a normal hardcoded local type
TYPES : BEGIN OF typ_hardcoded,
l_count TYPE i.
INCLUDE STRUCTURE sflight.
TYPES: END OF typ_hardcoded.
* create a table based on hardcoded type
DATA : lt_hardcoded TYPE TABLE OF typ_hardcoded.
****************** dynamic "new wave" local type *******************
*TYPES: typ_count TYPE i.
FIELD-SYMBOLS :<fs_str> ,"指向结构
<fs_itab> TYPE ANY TABLE,"指向内表
<fs_i> .
DATA: dref_str TYPE REF TO data,
dref_tab TYPE REF TO data,
dref_i TYPE REF TO data,
itab_type TYPE REF TO cl_abap_tabledescr,
struct_type TYPE REF TO cl_abap_structdescr,
elem_type TYPE REF TO cl_abap_elemdescr,
table_type TYPE REF TO cl_abap_tabledescr,
comp_tab TYPE cl_abap_structdescr=>component_table WITH HEADER LINE.
"========动态创建基本类型数据对象
elem_type ?= cl_abap_elemdescr=>describe_by_name( 'I' )."根据类型名称来创建类型对象
"或者是
*elem_type ?= cl_abap_elemdescr=>get_i( ).
CREATE DATA dref_i TYPE HANDLE elem_type ."动态的创建基本类型数据对象
"========动态创建结构体数据对象
* We read information about each fields of SFLIGHT (see ABAP FAQ #2)
struct_type ?= cl_abap_typedescr=>describe_by_name( 'SFLIGHT' )."结构类型
* we read all fleids of SFLIGHT and create a component table
comp_tab[] = struct_type->get_components( )."组成结构体的各个字段组件
* We add manually the counter 向结构中动态的新增一个成员
comp_tab-name = 'L_COUNT'."为结构新增一个成员
comp_tab-type = elem_type."新增成员的类型对象
.
* we create the structure 动态创建结构类型对象
struct_type = cl_abap_structdescr=>create( comp_tab[] ).
CREATE DATA dref_str TYPE HANDLE struct_type."使用结构类型对象来创建结构对象
ASSIGN dref_str->* TO <fs_str>."将字段符号指向新创建出来的结构对象
"========动态创建内表类型对象
* ... and the internal table 基于结构类型对象创建内表类型对象
itab_type = cl_abap_tabledescr=>create( struct_type ).
* The new thing here is the "type handle" which create a pointer to a handle
CREATE DATA dref_tab TYPE HANDLE itab_type."使用内表类型对象来创建内表类型
* we finally assign a field symbol to the pointer because we cannot directly access a pointer.
ASSIGN dref_tab->* TO <fs_itab>."将字段符号指向新创建出来的内表对象
* At the end of this small program, internal table lt_hardcoded and <fs_itab> are the same
"========给现有的内表动态的加一列
table_type ?= cl_abap_tabledescr=>describe_by_data( itab ).
struct_type ?= table_type->get_table_line_type( ).
comp_tab[] = struct_type->get_components( ).
comp_tab-name = 'FIDESC'.
comp_tab-type = cl_abap_elemdescr=>get_c( 120 ).
.
struct_type = cl_abap_structdescr=>create( comp_tab[] ).
itab_type = cl_abap_tabledescr=>create( struct_type ).
CREATE DATA dref_tab TYPE HANDLE itab_type.
另外,在ALV中可以根据FieldCat来动态创建内表:
rt_fieldcatalog type lvc_t_fcat
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = rt_fieldcatalog[]
importing
ep_table = g_table.
动态访问指定的数据库表
*================================================================
) TYPE c DEFAULT 'SFLIGHT'.
DATA dy_struc TYPE REF TO data.
FIELD-SYMBOLS <fs_struc> TYPE ANY.
FIELD-SYMBOLS <feld> TYPE ANY.
*================================================================
START-OF-SELECTION.
"基于数据词典类型动态创建结构
CREATE DATA dy_struc TYPE (tabnam).
ASSIGN dy_struc->* TO <fs_struc>.
SELECT * FROM (tabnam) INTO <fs_struc>.
NEW-LINE.
DO.
"动态访问内表内容
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_struc> TO <feld>.
.
EXIT.
ENDIF.
) <feld>.
ENDDO.
ENDSELECT.
TOP-OF-PAGE.
DATA struct_type TYPE REF TO cl_abap_structdescr.
DATA component TYPE cl_abap_structdescr=>component_table WITH HEADER LINE.
"获取结构对象的结构类型对象
struct_type ?= cl_abap_typedescr=>describe_by_data( <fs_struc> ).
NEW-LINE.
component[] = struct_type->get_components( ).
"遍历结构类型对象,输出结构的每个成员名称
LOOP ATcomponent.
) component-name.
ENDLOOP.
ULINE.
ABAP-动态编程的更多相关文章
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- Java动态编程初探——Javassist
最近需要通过配置生成代码,减少重复编码和维护成本.用到了一些动态的特性,和大家分享下心得. 我们常用到的动态特性主要是反射,在运行时查找对象属性.方法,修改作用域,通过方法名称调用方法等.在线的应用不 ...
- 十七、C# 反射、特性和动态编程
反射.特性和动态编程 1.访问元数据 2.成员调用 3.泛型上的反射 4.自定义特性 5.特性构造器 6.具名参数 7.预定义特性 8.动态编程 特性(attribute)是在一个程序集中插入 ...
- Java动态编程---动态代理
java中动态编程用到的技术有:反射(动态代理),javassist和ASM,这几种动态编程方法相比较,在性能上Javassist高于反射,但低于ASM,因为Javassist增加了一层抽象.在实现成 ...
- [.NET] 《Effective C#》快速笔记 - C# 中的动态编程
<Effective C#>快速笔记 - C# 中的动态编程 静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静 ...
- C# 4动态编程新特性与DLR剖析
=================================================== 注:很久没有发文了,贴一篇新文吧.从Word直接贴过来的,没仔细排版,诸位海涵.有关DLR和C# ...
- 动态编程(Dynamic Programming)
本文素材来自视频,请自备梯子观看:What Is Dynamic Programming and How To Use It Dynamic Programming:动态编程分为如下几步: 将复杂问题 ...
- 使用javassist进行动态编程
今天在研究dubbo时,发现一个新的知识点,可以使用javassist包进行动态编程,hibernate也使用该包进行编程.晚上百度了很多资料,将它的特性以代码的形式展现出来. package com ...
- 【java编程-Javassist】秒懂Java动态编程(Javassist研究)
作者:ShuSheng007 来源:CSDN 原文:https://blog.csdn.net/ShuSheng0007/article/details/81269295 版权声明:本文为博主原创文章 ...
- C# 4.0中的动态类型和动态编程
# 4.0的主题就是动态编程(Dynamic Programming).虽然C#仍然是一种静态语言,但是对象的意义开始变得越来越“动态”.它们的结构和行为无法通过静态类型来捕获,或者至少编译器在编译程 ...
随机推荐
- cmd下查看当前登陆用户
cmd下查看当前登陆用户 终端下,自然可以用quser这个命令了.但是在其它如专业版2k下如何查看在线用户呢? C:\Documents and Settings\Administrator>n ...
- 容器、应用服务器和web服务器的区别
什么是容器 servlet没main()方法.它们受控于另一个java应用,这个java应用称为容器(Container)Tomcat是这样的容器,Web服务器应用(Apache)得到一个指向serv ...
- 和为 s 的两个数字(和为 s 的连续正数序列)
题目 输入一个递增排序的数组和一个数字 s,在数组中查找两个数,得它们的和正好是 s.如果有多对数字的和等于 s,输出任意一对即可 思路 我们先在数组中选择两个数字,如果它们的和等于输入的 s,我们就 ...
- 在服务端处理同步发送小消息的性能上Kafka>RocketMQ>RabbitMQ
在发送小消息的场景中,三个消息中间件的表现区分明显: Kafka的吞吐量高达17.3w/s,远超其他两个产品.这主要取决于它的队列模式保证了写磁盘的过程是线性IO.此时broker磁盘IO已达瓶颈. ...
- gitlab-ce-omnibus社区版的备份、还原及升级
gitlab-ce-omnibus社区版的备份和还原,可以使用gitlab自带工具,gitlab-rake来完成,详见下面例子 将旧gitlab服务器备份,并还原至新gitlab服务器 ,这两台git ...
- 设置zedgraph鼠标拖拽和局部放大属性(转帖)
说一下几个属性的意义和具体应用: (1)鼠标拖拽显示区域 PanModifierKeys ->> Gets or sets a value that determines which mo ...
- 用7z.exe 压缩整个文件夹里的内容
以下是批处理中的内容: 7z.exe a -tzip zmv9netSrc.zip "D:\IE收藏夹备份\*"pause7z.exe a -tzip zmv9netSrc.zip ...
- appium+python自动化42-微信公众号
前言 本篇介绍如何在微信公众号上自动化测试,以操作我的个人公众号:yoyoketang为例,没关注的,先微信关注了,再跟着操作 环境准备: python 3.6 appium 1.7以上版本 微信6. ...
- xcode编译失败
iPhone自动化需要使用WDA.经过一段时间,再次编译,会出现WDA编译失败的问题,提示 The operation couldn't be completed. Unable to log in ...
- IO基础知识
传统的IO是阻塞的,BIO----基于流的模式,数据与Stream直接通信 NIO非阻塞的基于快的模式.数据与channel不直接交换数据,而是通过buffer进行数据交换. 基于文件的IO 基于网络 ...