1、屏幕事件
1.1、AT SELECTION-SCREEN(PAI事件)
该事件是用来对选择屏幕的操作进行交互和校验的,一般是在屏幕有输入或改变执行的事件,PAI执行完毕后,自动执行一次PBO事件,有很多扩展语法。
1.1.1、AT SELECTION-SCREEN ON FIELD
选择屏幕输入所有必填字段后,回车即可触发,点击执行按钮后也会触发。
1.1.2、AT SELECTION-SCREEN ON RADIOBUTTON GROUP 1
响应屏幕上的radiobutton。
1.1.3、AT SELECTION-SCREEN ON BLOCK 1
框架的触发事件。
1.1.4、AT SELECTION-SCREEN ON VALUE-REQUEST FOR FIELD
field指屏幕上定义的字段,该事件可以用来为屏幕字段添加搜索帮助
以上的AT SELECTION-SCREEN ON事件的触发都是根据字段在选择屏幕上的位置来的,如果有多个block,先触发block1内的字段,再触发block1,后触发block2字段,block2......。
1.2、AT SELECTION-SCREEN OUTPUT
该事件是用来实现动态改变选择屏幕的,它会检测选择屏幕的改变,并触发。一般用来根据单选按钮的选择,实现选择屏幕内容的动态隐藏和显示。
动态屏幕看下文 动态选择屏幕
2、SELECTION-SCREEN 格式化屏幕
SELECTION-SCREEN SKIP. 空行
SELECTION-SCREEN ULINE. 水平线
SELECTION-SCREEN COMMENT text FOR FIELD sel. 文本标签
SELECTION-SCREEN PUSHBUTTON button USER-COMMAND fcode. 按钮
SELECTION-SCREEN BEGIN OF LINE. 多元素行(将选择控制在一行)
SELECTION-SCREEN BEGIN OF BLOCK block. 屏幕块(屏幕上划分一个区域)
扩展语法宝包括:
WITH FRAME 创建一个框架
TITLE title 创建一个带标题的框架
NO INTERVALS 创建的框架里限制SELECT只有一个输出项
SELECTION-SCREEN BEGIN OF TABBED BLOCK tblock. Tabstrip
SELECTION-SCREEN FUNCTION KEY n. 激活工具栏中的预设按钮 自定义工作栏按钮
SELECTION-SCREEN BEGIN OF SCREEN dynnr [AS SUBSCREEB] 定义屏幕或子屏幕
3、PARAMETERS 单值
PARAMETERS {para[(len)]}|{para [LENGTH len]}
type_options [{ TYPE type [DECIMALS dec] }| { LIKE dobj }| { LIKE (name) }]
screen_options[{ {[OBLIGATORY|NO-DISPLAY] [VISIBLE LENGTH vlen]}
| {AS CHECKBOX [USER-COMMAND fcode]}
| {RADIOBUTTON GROUP radio [USER-COMMAND fcode]}
| {AS LISTBOX VISIBLE LENGTH vlen [USER-COMMAND fcode][OBLIGATORY]}}
[MODIF ID modid]]
value_options[DEFAULT val][LOWER CASE][MATCHCODE OBJECT hp][MEMORY ID pid][VALUE CHECK]
OBLIGATORY:必须输入(如果某个屏幕输入元素处于隐藏状态,即使是必输的,在提交时也不会提示你必须输入,只有在显示状态下不输入才会提示)。
NO-DISPLAY:将PARAMETERS设置为隐藏,不会在屏幕上显示。
VISIBLE LENGTH:定义显示长度。
AS CHECKBOX:创建CHECKBOX(复选框)。
RADIOBUTTON GROUP radio:创建RADIO单选框。
AS LISTBOX VISIBLE LENGTH vlen:创建一个下拉框,并指定长度
USER-COMMAND fcode:功能码,只能分配给CHECKBOX、RADIOBUTTON和AS LISTBOX VISIBLE LENGTH,当选择以上控件时,程序调用AT SELECTION-SCREEN事件,通过功能码来控制屏幕其他元素的属性。
MODIF ID key:设置修改组代码,方便屏幕元素的批量修改,key中设定的代码将被赋给系统内表SCEEEN-GROUP1字段。
LOWER CASE:如果输入小写,这将在回车或执行时继续保存小写。
MATCHODE OBJECT hp:指定SE11的搜索帮助。
MEMORY ID pid:将PARAMETERS存储在SAP内存,参数名长度不超过三位,通过SAP MEMORY进行同一用户会话不同窗口间的参数传递。
VALUE CHEXK:开启系统自动检验(如果屏幕元素参照的数据元素所对应的Domain(域)设置了Fixed values、Value Table)。
4、SELECT-OPTIONS 多值
SELECT-OPTIONS selcrit FOR {dobj|(name)}
screen_options[OBLIGATORY|NO-DISPLAY][VISIBLE LENGTH vlen][NO-EXTENSION][NO INTERVALS][MODIF ID id]
value_options [DEFAULT val1 [TO val2] [OPTION opt] [SIGN sgn]][LOWER CASE]
[MATCHCODE OBJECT search_help][MEMORY ID pid]
该语句会生成一个名为selcrit选择条件内表(RANGE内表)
OBLIGATORY:限制该SELECT-OPTIOS必输,单只有第一个框中出现勾,第二个没有,即该选项只对LOW字段有效。
NO-EXTENSION:限制该SELECT-OPTIONS只能输入一行数据,输入多行数据的按钮(选择框后后面的一个按钮)被隐藏。
NO INTERVALS:只能输入单值,不能输入范围(只有前面一个框)。
DEFAULT val1:定义单一默认值。
DEFAULT val1 TO val2:定义默认值的范围。
DEFAULT val1 OPTION opt SIGN sgn:定义含判断条件的单一默认值。
DEFAULT val1 TO val2 OPTION opt SIGN sgn:定义默认值的范围及判断条件。
MEMORY ID:将第一个输入框中的数据存放到SAP MEMORY中共享
部分关键字同PARAMETERS。
强调:可使用SELECT-OPTIONS替代PARAMETERS,实际上PARAMETERS 类型的参数完全可以使用SELECT-OPTIONS来替代,外表看上去与PARAMETERS是一样的,但双击后可以出现操作符选择界面,所以唯一不同点就是这个可以选择操作符,而且这样做的好处是:当不输入值时,查询所有的,但PARAMETERS值为空是查询就是为空(或0)的值(如果此时要忽略这个条件,则要将单值转换为Rang或者是分两种情况来写SQL条件)。
5、USER-COMMAND 功能码
如果复选框与单选按钮没有设置Function Code,则它们就会像普通的输入框一样,即使状态发生了改变,也不会触发PAI事件
对话屏幕中的按钮、复选框、单选按钮、下拉框的Function Code都是通过屏幕元素 attributes来设置的;选择屏幕中的FunCode则通过USER-COMMAND选项来设置
SELECTION-SCREEN PUSHBUTTON 1(5) BUT1 USER-COMMAND bt. " 在选择屏幕定义按钮
"PUSHBUTTON 选择屏幕中定义按钮
INITIALIZATION .
CALL FUNCTION 'ICON_CREATE' " 给按钮添加图标和文本
EXPORTING
NAME = '' " 按钮的图片的名字
TEXT = '按钮' "按钮的文本
INFO = '功能'
IMPORTING
RESULT = BUT1
EXCEPTIONS
OTHERS = 0.
AT SELECTION-SCREEN.
CASE SY-UCOMM.
WHEN 'bt'.
MESSAGE 'Button' TYPE 'I'.
WHEN OTHERS.
ENDCASE.
6、动态选择屏幕
选择屏幕、对话屏幕都有对应的SCREEN内表,下面是几个重要属性:
NAME:Name of the screen field。如果参数是select-options类型参数,则参数名以LOW与HIGH后缀来区分。
GROUP1:选择屏幕元素通过MODIF ID选项设置GROUP1(对话屏幕通过属性设置),将屏幕元素分为一组,方便屏幕的元素的批量修改
REQUIRED:控制文本框、下拉列表屏幕元素的必输性,使用此属性后会忽略OBLIGATORY选项。取值如下:
0:不必输,框中前面也没有钩
1:必输,框中前面有钩,系统会自动检验是否已输入,相当于OBLIGATORY选项
2:不必输,但框中前面有钩,系统不会检查是否已输入,此时需要手动检验
INPUT:控制屏幕元素(包括复选框、单选框、文本框)的可输性
ACTIVE:控制屏幕元素的可见性
注:一定要设置 USER-COMMAND ,否则点击之后,不会触发屏幕PAI事件,PAI事件不触发则会导致屏幕的AT SELECTION-SCREEN OUTPUT也就不会被触发(非执行按钮的FunCode触发时都会刷新屏幕,所以再次显示屏幕时再次执行PBO)
PARAMETERS p_rd1 RADIOBUTTON GROUP gp1 USER-COMMAND mxx."用来隐藏 p_lclfil
PARAMETERS p_rd2 RADIOBUTTON GROUP gp1 DEFAULT 'X'."用来显示 p_lclfil
"当通过程序动态修改屏幕元素属性 required 后,会忽略掉这里的 OBLIGATORY 选项
*PARAMETERS p_lclfil(128) AS LISTBOX VISIBLE LENGTH 20 MODIF ID mxy OBLIGATORY .
PARAMETERS p_lclfil(128) MODIF ID mxy OBLIGATORY .
PARAMETERS: c AS CHECKBOX."没什么作用,用来测试 CHECKBOX 的可输入性
"当 C2 被钩选时,屏幕上的其他输入元素均不可输入
PARAMETERS: c2 AS CHECKBOX USER-COMMAND ddd DEFAULT 'X'.
AT SELECTION-SCREEN OUTPUT.
LOOP AT SCREEN .
"当 C2 没有钩选时,其他元素都设置为可输入
IF screen-name <> 'C2' AND c2 IS INITIAL .
screen-input = 1.
MODIFY SCREEN.
ELSEIF screen-name <> 'C2' AND c2 IS NOT INITIAL .
screen-input = 0."C2钩选时,所以屏幕输入元素禁止输入
MODIFY SCREEN.
ENDIF.
"控制下拉列表(文本框也是一样)的必输性:外观上打钩,但不自动校验
IF p_rd2 = 'X' AND screen-group1 = 'MXY'.
"显示
screen-active = '1'.
* screen-input = '1'."显示前设为可输入
screen-required = '2'."外观上打钩,但不自动校验
MODIFY SCREEN.
ELSEIF screen-group1 = 'MXY'. "
"隐藏
screen-active = '0'.
screen-required = '2'.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
AT SELECTION-SCREEN ON p_lclfil.
IF p_rd2 IS NOT INITIAL"手动检验:但当点击单选按钮与复选框 C2 时,不校验
AND sy-ucomm <> 'MXX' AND sy-ucomm <> 'DDD' AND p_lclfil IS INITIAL.
MESSAGE e055(00).
ENDIF.
"代码来源
https://www.cnblogs.com/jiangzhengjun/p/7264657.html#_%E5%8A%A8%E6%80%81%E4%BF%AE%E6%94%B9%E5%B1%8F%E5%B9%95
7、自定义工作栏按钮
SELECTION-SCREEN FUNCTION KEY n 是包含在选择画面(1000)的标准GUI的功能按钮,最多只能有5个,功能码是FC1~FC5.也是系统预留好的。
然后,以上被定义的按钮的图标和文本描述都是可以设定的,在tables:sscrfields的functxt_01 ,functxt_02,functxt_03..............
TABLES sscrfields.
SELECTION-SCREEN: FUNCTION KEY 1.
SELECTION-SCREEN:FUNCTION KEY 2.
DATA:ls_functxt TYPE smp_dyntxt.
PARAMETERS s1 TYPE c.
INITIALIZATION.
ls_functxt-icon_id = icon_other_object.
ls_functxt-quickinfo = 'TEST1'.
ls_functxt-icon_text = 'TEXT1'.
sscrfields-functxt_01 = ls_functxt.
ls_functxt-icon_id = icon_other_object.
ls_functxt-quickinfo = 'TEST2'.
ls_functxt-icon_text = 'TEXT2'.
sscrfields-functxt_02 = ls_functxt.
AT SELECTION-SCREEN.
CASE sy-ucomm.
WHEN 'FC01'. "最多只能有5个,功能码是FC1~FC5.也是系统预留好的
MESSAGE 'TEST1' TYPE 'E'.
WHEN 'FC02'.
MESSAGE 'TEST2' TYPE 'E'.
WHEN OTHERS.
ENDCASE.
8、FIELD <f>
使用FIELD语句后,屏幕字段<f>需要在该语句处理完后才传递到ABAP程序相应的字段中,在后没有带module选项时,仅仅只是控制屏幕字段传输到ABAP程序中的时间点,如需对屏幕字段进行检验,通过以下语句来实现检验:
FIELD<field_name> MODULE<module_name>.
仅只有未出现在FIELD语句中的屏幕字段才会在PAI事件块处理前传输到ABAP程序中去。所以当某个屏幕字段出现在FIELD语句中,并且在该 FIELD语句未执行完之前,不要在PAI dialog modules中使用该屏幕字段(该屏幕字段相关的FIELD语句执行完成之后才可以在后续的PAI dialog modules调用中使用),否则,ABAP程序同名字段中的值使用的是前一次对话屏幕中所设置的值。
9、MODULE
FIELD dynp_field MODULE mod [ {ON INPUT}
| {ON REQUEST}
| {ON *-INPUT}
| {ON {CHAIN-INPUT|CHAIN-REQUEST}}
| {AT CURSOR-SELECTION}.
• ON INPUT:只要该字段不为初始值就会触发module
• ON REQUEST:该字段发生变化后触发module
FIELD <f> MODULE <mod> ON INPUT|REQUEST|*-INPUT. 相当于选择屏幕的 AT SELECTION-SCREEN ON field
CHAIN.
FIELD: <f1>, <f2>,<fi...>.
MODULE <mod1> ON CHAIN-INPUT|CHAIN-REQUEST.
FIELD: <g1>, <g2>,<gi...>.
MODULE <mod2> ON CHAIN-INPUT|CHAIN-REQUEST.
...
ENDCHAIN.
只要<fi>中某个字段满足条件(<mod1>后面的CHAIN-INPUT与CHAIN-REQUEST条件),<mod1>就会被调用,而只要<fi>或<gi>中的某个字段满足条件,则<mod2>就会被调用。如果在module中检测不通过(如MESSAGE… E类消息时),则CHAIN…ENDCHAIN之外的所有其他屏幕字段将会被锁定且置灰,这与选择屏幕的AT SELECTION-SCREEN ON BLOCK校验是一样的
CHAIN.
FIELD: <f1>, <f2>,<fi...>.
FIELD <f> MODULE <mod1> ON INPUT|REQUEST|*-INPUT|CHAIN-INPUT|CHAIN-REQUEST.
MODULE <mod2> ON CHAIN-INPUT|CHAIN-REQUEST.
ENDCHAIN.
<mod1>被调用的条件是所对应字段<f>满足ON后面指定的条件即可执行。<mod2>被调用的条件是只要<fi>或<f>中的某个字段满足条件即可执行。
1、单个字段检查 | FIELD <FLD1> MODULE <MDL1>. |
2、单个字段多个MODULE检查 | FIELD <FLD1> MODULE <MDL1>,MODULE <MDL2>. |
3、检查多个字段,使用CHAIN | CHAIN. FIELD <FLD1>. FIELD <FLD2>,<FLD3>,<FLD4>. MODULE <MDL1>. MODULE <MDL2>. ENDCHAIN. 表示FLD1,FLD2,FLD3,FLD4有MDL1,MDL2检查。 |
4、不是初始值检查 | FIELD <FLD1> MODULE <MDL1> ON INPUT. ON INPUT表示初始值改变时执行。 特殊情况: FIELD <FLD1> MODULE <MDL1> ON *-INPUT. 表示用户输入字段首字输入’*’,并切输入字段属性设置了“*”的属性,MODULE有效。 |
5、有改变的检查 | FIELD <FLD1> MODULE <MDL1> ON REQUEST. |
6、CHAIN中又自断不是初始值检查 (包含CHAIN-REQUEST和CHAIN-INPUT却别就是on input和on request的触发条件) | CHAIN. FIELD <FLD1>. FIELD <FLD2>,<FLD3>,<FLD4>. MODULE <MDL1> ON CHAIN-INPUT. MODULE <MDL2>. ENDCHAIN. 注意:CHAIN-INPUT表示FLD1,FLD2,FLD3,FLD4不是初始值时执行MDL1检查 |
ON INPUT与ON CHAIN-INPUT区别
CHAIN.
FIELD: f1,f2.
FIELD: f3 MODULE mod1 ON INPUT. 只有f3为非初始值时才调用mod1
ENDCHAIN.
CHAIN.
FIELD:f1,f2.
FIELD:f3 MODULE mod1 ON CHAIN-INPUT. f1,f2,f3中任一字段包含非初始值时都调用mod1
ENDCHAIN
如果不在 CHAIN中时,不能像下面这样写:
FIELD a. "FIELD与MODULE只能写在同一语句当中
MODULE check_a ON INPUT.
只有在CHAIN中时,MODULE语句才可以单独出现(不与FIELD在同一语句中),且只能是CHAIN-INPUT:
MODULE mod1 ON CHAIN-INPUT.
10、EXIT-COMMAND
对话屏幕中,对于E类型的Function Code,可以使用如下语句在PAI事件块中来触发:
MODULE <mod> AT EXIT-COMMAND.
不管该语句在screen flow logic的PAI事件块里的什么地方,都会在字段的约束自动检测之前执行,因此,此时其他的屏幕字段的值不会被传递到ABAP程序中去,当该MODULE执行完后,如果未退出该屏幕,则会进行正常PAI(即PAI事件块里没有带EXIT-COMMAND选项的MODULE语句)事件块。
该语句在字段约束自动检测之前会被执行,一般用来正常退屏幕来使用,如果未使用LEAVE语句退出屏幕,则会在这之后还会继续进行字段的自动检测,检测完后还会继续PAI的处理(即执行PAI事件块中不带EXIT-COMMAND选项的MODULE语句)
AT SELECTION-SCREEN ON EXIT-COMMAND
在选择屏幕上,对于E类型的FunCode会触发AT SELECTION-SCREEN ON EXIT-COMMAND事件
11、OK_CODE
如果是回车(命令行中未输入内容时回车)时,由于FunctionCode为空,所以SYST-UCOMM 、SY-UCOMM、OK_CODE都不会被重置;如果非回车,但FunctionCode也是空时,SYST-UCOMM、SY-UCOMM会被重置,但OK_CODE还是不会被重置,所以OK_CODE只有在FunCode非空时才会被重置
ok_code使用前需拷贝
如果一个屏幕中的某个按钮未设置Function Code时也是可以触发PAI事件时,并且由于其Function Code此时为空而不会去设置OK_CODE(但此时SYST-UCOMM 或 SY-UCOMM还是会被重新设置为空),这样的话OK_CODE中的值还为上一次触发PAI时所设置的Function Code。所以一般情况下在使用OK_CODE之前,先将OK_CODE拷贝到SAVE_OK变量中(在后面的程序使用SAVE_OK而不是OK_CODE),并随后将OK_CODE清空,以便为下一次PAI事件所使用做准备
其实还有一种方案可能替换这种使用前拷贝方案:就是还是针对OK_CODE编程,不另外定义save_ok,而是在每个屏幕的 PBO 里将ABAP中的OK_CODE清空。
以上部分内容摘抄于汪老师的博客,非常推荐大家去汪老师那里学习。