l 屏幕序号(Screen number)。四个数字组成的序列号,用于在程序中确定屏幕,该序号在同一个ABAP程序内部是唯一的。
l 屏幕类型(Screen type)。ABAP中的屏幕类型包括普通屏幕、模式对话框、选择屏幕和子屏幕等。普通屏幕一般占据整个用户窗口,而模态对话框只占据用户窗口的一部分;选择屏幕是根据程序中定义的select-option和parameters自动生成的,一般不用于对话程序设计中;子屏幕则可以显示在不同屏幕的某个区域之中。
l 后续屏幕(Next screen)。定义当前屏幕的后续屏幕序号,即系统的对话处理器结束当前屏幕的处理之后,应前往的下一个屏幕。通过后续屏幕,可以把事务中的一系统屏幕连接起来,形成一个屏幕序列,如果某个屏幕的后续屏幕值为0或没有设置,则表明该屏幕是一个屏幕序列的结束。该属性可以在程序中动态控制。
l 光标位置(Cursor position)。屏幕初始状态的光标位置,一般默认状态下,光标位于屏幕中的第一个输出字段。在程序设计中,可以动态地替换属性中定义的初始光标位置。
l 屏幕组(Screen group)。可以将一系列的屏幕组合在一个4字符的屏幕组中,屏幕组ID运行期间存储于系统字段sy-dyngr中,用于程序对多个屏幕整体操作。
l 行列范围(Lines/columns)。用于设定屏幕所占据的空间,如果屏幕较大,系统将自动生成滚动条。
l 上下文菜单(Context memu),用于设定属于整个屏幕的上下文菜单(右键菜单)。
每一个屏幕都有一个OK_CODE字段,但不显示在屏幕上。用户触发PAI事件的操作所对应的Function Code就会存储到这个字段中,然后再传递到ABAP程序中相同名称的全局变量中,必须为每个屏幕分配这个名叫OK_CODE的屏幕元素,否则虽然可以触发事件,但Function Code不能在屏幕与ABAP程序之间进行传递了
在屏幕中也可以像ABAP程序那样读写系统预置的系统变量,但是,在屏幕中系统变量是通过结构SYST来管里的,而不是SY,所以,你必须使用SYST-<name>来定位它们
1. 如果复选框与单选按钮没有设置Function Code,则它们就会像普通的输入框一样,即使状态发生了改变,也不会触发PAI事件。但是对于按钮,即使没有设置Function Code,也会触发PAI事件,此时的Function Code 为空。
2. 如果复选框与单选按钮设置Function Code,则复选框与单选按钮不只是简单的输入元素,而且还会触发PAI事件。
3. 以下屏幕元素可以触发PAI事件
? 点击屏幕上的某个按钮
? 点击了某个已分配了Function Code的单选按钮或复选框
? 点击了某个菜单或标准工具条、应用工具条件上的按钮
? 快捷键
? 从下拉框中选择条目
4. 不同的屏幕元素的Function Code的设置方式如下:
? 屏幕中的按钮、复选框、单选按钮、下拉框的Function Code都是通过屏幕元素 attributes来设置的(注:如果是选择屏幕,则通过USER-COMMAND选项来设置)
? 而菜单、standard toolbar、application toolbar中的Function Code是通过GUI status来设置的
? 快捷键所对应的Function Code也是通过GUI status来设置的
屏幕流逻辑包括四种事件块:
PROCESS BEFORE OUTPUT.
...
PROCESS AFTER INPUT.
...
PROCESS ON HELP-REQUEST.
...
PROCESS ON VALUE-REQUEST.
...
前两个一定要有,当都出现时请按上面顺序写
当你创建一个新屏幕时,头两个事件块会自动的创建。运行时触发时间点如下:
? PROCESS BEFORE OUTPUT (PBO)
在前一屏幕的PAI事件后或当前屏幕显示之前自动触发,你可以在这个块中对数据进行初始化赋值。在PBO结束时,屏幕将会显示出来。
? PROCESS AFTER INPUT (PAI)
当用户操作(如F8,点击按钮,回车、或点击带Function Code的单选/复选按钮,可选择带Function Code下拉框中的某选项时)了屏幕上某个功能元素时就会触发,你可以在这个块中如对输入值的检查。PAI事件结束后,系统将会调用一下屏幕或者返回到屏幕调用处(ABAP程序)继续执行
? PROCESS ON HELP-REQUEST (POH) and PROCESS ON VALUE-REQUEST (POV)
当用户按F1与F4时触发,处理完之后返回到当前屏幕
在对话屏幕中为输入字段命名时,名字一定要大小,否则在屏幕逻辑流中用到该字段时则会出错:
原因就是在屏幕设计界面中,命名时写成了小写了:
所以屏幕字段命名时一定要大写(好像小写时,如果不在屏幕逻辑流中使用时也是可行的,但一旦用在屏幕逻辑流中进,就会出问题),正确的做法是在输入名称之后,回车一下,则名称会自动转换为大小:
即Element list中的命名为大小即可:
如果屏幕上的元素字段参考的是数据词典的字段(屏幕元素的名称为表名-字段名的形式)时,必须在ABAP程序里使用TABLES语句来定义这个表接口,这样就可以通过这个表接口在屏幕与ABAP程序之间自动的进行数据传递:
另外,也可以是只引用一个或几个数据词典中某个表中一个或几个字段,不一定要引用整张表。再次,这些参照词典中的字段需要将以下钩上:
当给某个屏幕字段命名时,如果这个字段的名称为“表名(或结构)-字段名”形式时,回车时系统会提示:
当点击Yes后,该字段的Parameter ID会自动的设置为 MARA-MATNR字段所对应Data Element所设置的Parameter ID,另外,From dict.也会自动被钩上,但时,SET Parameter与GET Parameter 没有自动钩上,如果需要通过SAP Memory传递值,则需要将这两个手动钩上:
Data Element中的Parameter ID对选择屏幕是没有任何作用的,如下面的语句不能用来在SAP Memory中传递值:
PARAMETERS: m TYPE mara-matnr.
除非使用MEMORY ID 选项才起作用:
PARAMETERS: m TYPE mara-matnr MEMORY ID mat.”注,这里的MEMORY ID不一定要设置成与MATNR所对应的Data Element设置的Parameter ID一样,这里可以随便设置,如XXX
所以选择屏幕中的参数选项 MEMORY ID的作用就等同于对话屏幕中的SET/GET Parameter,它们是作用是相同的(都是针对SAP Memory),只不过一个用于选择屏幕中,一个用于对话屏幕。
ABAP程序如下:
TABLES: spfli.
DATA: wa_spfli TYPE spfli. "只要与屏幕字段名前缀结构同名即可自动绑定
CALL SCREEN 200.
MODULE get_data INPUT.
SELECT SINGLE countryfr cityfrom airpfrom INTO CORRESPONDING FIELDS OF spfli
FROM spfli WHERE carrid = spfli-carrid AND connid = spfli-connid.
ENDMODULE.
运行程序,输入条件后回车,结果屏幕如下:
注:由于Airline配置了Check Table,如果输入的Airline不合法,则不会执行PAI事件,所以在执行PAI事件前,数据词典中所设置的数据有效性会先进行检查。
当用户在对话屏幕上触发一个命令时,会将命令所对应的Function Code复制到对话屏幕上一个特殊的隐藏字段OK_CODE中,如果在ABAP中具有一个与对话屏幕这个隐藏字段同名的OK_CODE时,则在屏幕字段向内存字段进行同名拷贝时,屏幕上的这个隐藏字段OK_CODE的值也将会被自动拷贝到程序中的这个字段中,然后就可以在PAI事件块里调用ABAP中的Module中使用此隐藏字段
如果触发PAI时的Function Code为空,则不会放入到对话屏幕中定义的OK_CODE 字段中(SYST- UCOMM与SY-UCOMM也不会发生改变:还是保留上次PAI的Function Code),
注意,此图还有点问题,如果是针对回车键(命令行中未输入内容时回车)是对的,但如果按的是屏幕中的未分配Function Code的按钮时,虽然不会重置OK_CODE,但还是会重置SYST- UCOMM 与 SY-UCOMM。
在程序中你应该使用OK_CODE来代替SY-UCOMM,这有两种原因:第一,ABAP程序可以完全控制在它里面定义的变量,第二,你不应该修改ABAP系统变量的值。然而,你必须在ABAP程序中清空OK_CODE,因为以下几个原因:如果一个屏幕中的某个按钮未设置Function Code时也是可以触发PAI事件时,并且由于其Function Code此时为空而不会去设置OK_CODE(但此时SYST- UCOMM 或 SY-UCOMM会被重新设置为空),这样的话OK_CODE中的值还为上一次触发PAI时所设置的Function Code。所以一般情况下在使用OK_CODE之前,先将OK_CODE拷贝到SAVE_OK变量中,并随后将OK_CODE清空,以便为下一次PAI事件所使用做准备(比如下一屏幕直接在屏幕上按回车时,Function Code为空,因为在回车时命令框里没有输入任何命令,则此时OK_CODE字段不会被设置,所以还回沿用上次所设置的OK_CODE,所以就会出现问题),并在MODULE 中针对SAVE_OK来进行编程:
DATA: ok_code LIKE sy-ucomm,
save_ok LIKE ok_code.
在第一个PAI module中,需要将ok_code放在save_ok中,并清空ok_code,其他PAI module中就直接使用save_ok即可
MODULE user_command_0100 INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
LEAVE PROGRAM.
WHEN OTHERS.
ENDCASE.
ENDMODULE.
其实还有一种方案可能替换这种使用前拷贝方案:就是还是针对OK_CODE编程,不另外定义save_ok,而是在每个屏幕的 PBO 里将ABAP中的OK_CODE清空。
另外如果在Command Line未输入内容时就按回车(其实光标在屏幕上输入框里按回库也是这样,只要命令行没有输入内容时),此时的Function Code也是空,此时除OK_CODE还是不会被重置, 并且SYST- UCOMM 与 SY-UCOMM也不会被重新设置为空。
每个屏幕的OK字段都可以用不同的名字,但是,最好的做法是每个屏幕中的OK字段都叫OK_CODE,这样的话ABAP程序中只需要定义一个名称为OK_CODE的变量即可以接受所屏幕中的OK字段值(即Function Code)
GUI主要有:
1、 标题栏:当前屏幕的标题,GUI Title
2、 菜单条:包含了可扩展的菜单,其中每个子菜单项都指向一个应用程序的功能,其中“System”、“Help”两个菜单项不能被应用程序更改和扩展,因此这类菜单荋以及其中的子菜单项将出现在每一个应用的屏幕中。
每个屏幕都会有系统标准工具条(Standard Toolbar),包含的按钮代表了所有屏幕中都会用到的系统功能,如保存、回退、取消等。可以为菜单项和工具条项分配功能键(FunctionKeys),这样当用户在屏幕按下相应的功能键时,相当于执行了已经分配了这个功能的菜单项。
应用工具条(ApplicationToolbar)是与特定应用相关的工具条,集成了当前屏幕常用的功能。
将菜单条、标准工具条、功能键的设置以及应用工具条统称为“GUI Status”,使用SETPF-STATUS xxx来设置的。使用SET TITLEBAR xxx设置标题。
若为ABAP屏幕分配一个GUI Status、GUI Title,则该屏幕的所有后续屏幕缺省都有了该Status、Title,如果想在后续的子屏幕中更换成另外一个不同的Title,则需要重新设置
ABAP中维护GUI Status的工具叫Menu Painter。
除开“System”与“Help”菜单,最多还可以创建6个菜单项
GUI status为用户提供了屏幕范围内的功能,每一种功能都有一个Function Code,并且当用户选择这个功能时,就会触发PAI事件,在每PAI事件里,这些Function Code将会放到系统变量SYST-UCOMM(SY-UCOMM)中,并且分配给OK_CODE隐藏字段。在Screen中使用OK_CODE之前,必须在Screen Painter中给它分配一个名字。
(注:这里讲的是对话屏幕上的Status,如果是List Status,则不会有什么PAI事件,也不会将Function Code存储到什么OK_CODE,而是直接触发ABAP报表程序中的 AT USER-COMMAND 事件,可以在此事件中通过ABAP系统全局变量SY-UCOMM来接收传递过来的Function Code)
ABAP程序中的所有Function Code,除了按钮(还有复选框、单选按钮)的Function Code是在Screen Painter中分配的,其他都是在Menu Painter中进行定义与管理的:
GUI Status可以是让用户很方便的操作屏幕,它代替了命令行中的输入。当然我们可以不点击Menu bars、Standard toolbars、Application toolbars或者屏幕中的按钮,直接在Command Line中输入这些菜单、工具条与按钮所对应的Function Code,回车后也可以触发PAI事件。
此种类型的Status用在如下类型的普通屏幕中:
通过Menu Bar可以创建新的菜单,在创建时不需要分配键盘快捷键,但可以在Function Keys设置部分中的Freely Assigned Function Keys(此类型的Function Key——快捷键,可由用户自己自由分配)中为菜单设置一个键盘快捷键,这样不需要通过鼠标点击菜单而是通过所设置的快捷键来代替鼠标;
通过Application Toolbar创建应用工具条件上的按钮的过程中,会弹出一个设置快捷键的对话框要求设置快捷键,所以创建自定义应用工具条时一定要分配一个键盘快捷键;
Function Keys中的Standard Toolbar不需要设置快捷键(正是因为这些为标准工具条,已经为这些固有的图标绑定了快捷键,并且这些快捷键被系统所保留使用),因为这些是预设的标准工具条(因为标准工具条上有哪些功能图标是不能再由我们自己定义了,只能使用上面预设的那几个,如果要使用,只需要输入相应的Function code就代表开启此按钮了),并且已经固定分配了相应的快捷键,系统预设的快捷键如下:
Functionkey |
Icon |
Purpose |
Ctrl+Sor F11 |
Save |
|
F3 |
Back |
|
Shift+F3 |
Exit |
|
Esc or F12 |
Cancel |
|
Ctrl+P |
|
|
Ctrl+F |
Find |
|
Ctrl+G |
Find next |
|
Ctrl+PgUp |
Firstpage |
|
PgUp |
Previous page |
|
PgDn |
Nextpage |
|
Ctrl+PgDn |
Lastpage |
具体的内置快捷键可以通过以下方式来查看:
另外,也可以设置一个与菜单或工具条按钮无关的纯粹的快捷键,如上面的Function Code为 SHORTCUT 的快捷键。
不管是菜单、工具条按钮、还是快捷键最终都会触发PAI事件,并且会将所对应的Function Code会存储到SY-UCOMM系统变量中。
上面的Recommended Function Key Setting(此类型的Function Key——快键捷,已经被系统推荐使用,所以最好不要另作其它用途,如F2为查看详情,相当于鼠标双击)部分的为推荐部分,当不输入FunctionCode时,相应的功能不会被激活,只要输入了Function code则会激活相应功能,Function Code可以任意,相应功能不需要我们写代码去实现了,因为系统已具备这样的功能。
Standard Toolbar栏中预设的图标按钮在默认情况是不会被激活的,只有当输入相应Function Code才会被激活,但此时在Standard Toolbar中只能点击它,具体的功能还是需要在ABAP程序中写代码来实现相应功能,这与Recommended Function Key Setting部分是不一样的。
一般情况下,需至少激活Standard Toolbar中的Back (F3), Exit (shift+F3), and Cancel (F12)中的一个功能,并实现相应代码,以便用户能够离开屏幕(如果将的Funcode设为BACK、设置为EXIT、设置为BREAK时(具体什么值与屏幕的类型有关系:选择屏幕、List列表输出屏幕、对话屏幕都是不一样,如要使用系统提供的默认实现,则一定要按要求值给出,具体值请参考后面),会自动的leave program.对话屏幕好像就不行???,选择屏幕好像已自动实现)
下面这些Function Keys不会触发PAI事件,它们被保留下来用作其他的功能:
? F1 calls the field help调用字段的帮助
? F4 calls the input help调用输入帮助
? F10 places the cursor in the menu bar将光标定位到菜单条上
回车:standard toolbar中的回车键 默认就是被激活的,即使根本没有给屏幕设置过GUI status。只要用户在命令行中按回车键后(不管是否输入了内容),都会触发相应屏幕的PAI事件,并且输入的内容会被当作Function Code传递给SY-UCOMM或OK_CODE(在Screen中)字段(如果未输入,则不会输入到SY-UCOMM或OK_CODE中,但会触发PAI事件)
F2(鼠标双击):在预设中,F2已经与鼠标的双击关联起来了,F2已具有了鼠标双击的功能。当用户按了F2或在屏幕上双击了鼠标都会触发PAI事件,所以F2是一个很特别的键,一般不要拿来作其他功能使用。
Shift + F10(鼠标右键):该组合键已经被分配给了鼠标右击功能,不能再用于其他用途。注意:有时鼠标右键弹不出右键菜单,这是因为选中了快捷剪切和粘贴功能了,去掉即可,否则只能使用Shift + F10快捷键或者使用Shift+鼠标右击才能弹出右键菜单:
选择屏幕与List列表输入屏幕上的标准工具按钮FunctionCode需要如下输入才能使用系统提供的默认的功能(不需要我们再实现):
选择屏幕:
List列表:
(注意:Dialog Box类型的Status没有Menu Bar与Standard Toolbar两项)
Reserved Function Keys部分为保留快捷键,如果要相应对应功能,只需要输入Function Code,但要注意的是Function code一定要为上面图中输入的,否则功能将不会被触发(这些功能也已经由系统实现了,我们不需要实现)。另外,如果将Reserved Function Keys部分所配置的Function Code又在Application Toolbar部分进行了分配,这些功能图标将会在对话框屏幕下方出现,如:
(但不知为什么上面红色字体的 ENTER 没有显示??后来找到原因了:是因为Function Code被去激活了:
该类型的Status用作右键菜单
可以将右键菜单链接到某些屏幕元素,包括输入输出字段、文本字段、表格控件以及屏幕区域等。
具体使用请参考Context Menus for Screen中的示例代码
可以将系统标准GUI Status作为模板导入到当前程序中,在Menu Painter中选择系统菜单“ExtrasàAdjusttemplate”。
将系统标准的GUI STATUS导入到当前的GUI STATUS中作为编辑的模板:
当需要为ALV报表或普通程序绘制Status时,我们先可以拷贝标准的Status,则在此基础上修改即可:
上面的ALV工具条是先拷贝自标准条,再在标准条上加一按钮,通过SE41,拷贝程序SAPLSLVC_FULLSCREEN的状态STANDARD_FULLSCREEN过来:
如果不是ALV,是Write输入时,拷贝:
要想在对话屏幕与ABAP程序中进行数据传递,则还得要在ABAP定义中作如下定义才可:
TABLES: sdyn_conn.
或者是:
DATA: sdyn_conn TYPE sdyn_conn.(注:此种方式可能会有问题,数据不能传输??)
在ABAP对话屏幕编程中,对话屏幕与程序之间的数据自动传输发生在:屏幕字段名与程序中定义的同名的全局变量之间,此变量一般可以是普通的类型的单变量,但更多是定义成结构体变量。下面以结构体变量为传输体来了解数据传输过程。
使用TABLE语句来定义一个内存结构体变量,该结构中的字段与对话屏幕上的各输入字段是一一对应的,即名称与类型都相同。TABLE后面的数据类型可以是词典中的结构类型或透明表类型,具定义出来的结构体变量名与后面指定的词典结构类型及透明表类型一致,例如:
TABLES sdyn_conn.:利用结构体类型sdyn_conn定义了一个结构体变量sdyn_conn
TABLES sflight.:利用透明表类型sflight定义了一个结构体变量sflight
因为结构体变量中的各字段与对话屏幕上的各输入字段具有对应关系,因此,该结构体变量被用作屏幕与程序之间的数据传输通道:
上图中,使用了词典中的结构体类型sdyn_conn定义了一个内存变量sdyn_conn,而对话屏幕100上的各个字段的定义也是来自于结构体类型sdyn_conn,因此,内存变量sdyn_conn将作为屏幕100与调用它的程序之间的数据传输通道:即在屏幕100的PBO事件完成后,内存变量sdyn_conn中的各字段值将自动传输给对应的屏幕字段;当用户在屏幕上点击确认结束输入后,在触发PAI事件之前,各屏幕的字段的值将自动传输给内存变量sdyn_conn相应各同名字段中,因此,可以在PAI事件块中对结构体变量sdyn_conn进行处理。
其中“分隔符”的插入方法为:在需要插入分隔符的方框内选择菜单“Edit—>Insert——>Separator line”即可插入分隔符
在PBO事件块里,你可以使用MODULE语句来调用在ABAP program里如下定义的dialog module:
MODULE <mod> OUTPUT.
...
ENDMODULE.
在PAI, POH, 与 POV事件块里,你可以使用MODULE语句来调用在ABAP program里如下定义的dialog module:
MODULE <mod> [INPUT].
...
ENDMODULE.
从技术角度来说,在同一个ABAP Program里,两个不同类型的module(OUTPUT、INPUT)可以使用相同的名称,但这不推荐使用。不同的屏幕可以调用ABAP程序里同一个dialog module,所以可以将多个屏幕共同的代码写在一个dialog module里(如将OK_CODE拷贝到SAVE_CODE里,将将OK_CODE清空这一过程),然后在所有的屏幕的PAI事件开头调用这个dialog module。
MODULE位于ABAP主程序中,相当于该主程序中声明的的不带参数的子程序,因此在ABAP主程序中声明的所有全局变量在MODULE块的程序中都可以进行调用,而且MODULE块内部定义的变量在其他MODULE来说也是全局的,但MODULE外面程序代码中不可引用,而且声明变量的MODULE要在引用变量所在MODULE的前面:
MODULE status_0100 OUTPUT.
DATA texttable TYPE tt_text.
...
ENDMODULE.
MODULE user_command_0100 INPUT.
CALL METHOD editor->get_text_as_stream
IMPORTING
text = texttable. 这里的texttable实质上引用是的上面module中声明的变量
ENDMODULE.
SY-DYNNR系统变量里存储了当前屏幕的屏幕号。
在flow logic里,有各种不同的调用dialog modules的方法,flow logic的语法允许你在调用dialog modules时附加一些条件,并且通过控制数据在screen与ABAP program之间的传输入:
ABAP中的Module经常是用来对屏幕字段输入的值进行检验的,具体请参考这里
可以使用如下的flow logic语句来调用module:
MODULE <mod>.
(如果前面未指定FIELD选项,则表示此Module对所有字段都有效,而不是针对某个屏幕字段校验的,相当于选择屏幕的AT SELECTION-SCREEN事件)
如果你使用这种简单的流逻辑语句来调用module,则数据在屏幕与ABAP程序之间是这样传输的:
? 在PAI事件中,所有屏幕字段会在第一个PAI module调用之前(前提是自动输入检查需要通过),就已传递到ABAP程序中相同名的字段中(数据从“对话屏幕”传递到“ABAP程序”中进行处理)。
? 在最后一个PBO module调用之后与屏幕显示之前,所有ABAP程序中的同名(与屏幕字段)字段将会传回到屏幕相应字段中(数据从“ABAP程序”传递到“对话屏幕”中进行显示)。
如果使用前一节的介绍的简单调用Module的方式来调用dialog module时,所有的屏幕字段在PAI事件块处理开始之前都会传递到ABAP程序。
screen flow logic 中的FIELD语句可以用来控制在什么时候将屏幕字段传递到ABAP程序中相应的字段中。
FIELD <f>.
使用FIELD语句后,屏幕字段<f>需要在该语句处理完后才传递到ABAP程序相应的字段中,在后没有带module选项时,仅仅只是控制屏幕字段传输到ABAP程序中的时间点,如需对屏幕字段进行检验,需要在屏幕字段值传递到ABAP程序之前,通过以下语句来实现检验:
FIELD <field_name> MODULE <module_name>:可以用来对屏幕字段field_name进行检验使用,检验的代码写在module_name中。这相当于选择屏幕的 AT SELECTION-SCREEN ON < field_name>的作用,即Module只对<field_name>字段起作用,因此Module是专门用来校验此屏幕字段的
仅只有未出现在FIELD语句中的屏幕字段才会在PAI事件块处理前传输到ABAP程序中去。所以当某个屏幕字段出现在FIELD语句中,并且在该 FIELD语句未执行完之前,不要在PAI dialog modules中使用该屏幕字段(该屏幕字段相关的FIELD语句执行完成之后才可以在后续的PAI dialog modules调用中使用),否则,ABAP程序同名字段中的值使用的是前一次对话屏幕中所设置的值。
FIELD可以被使用在PAI、POH、POV事件中,但在PBO中不起作用。
PROCESS BEFORE OUTPUT.
MODULE init_screen_100.
PROCESS AFTER INPUT.
MODULE user_command_0100.
MODULE module_1.
"box2屏幕字段在该语句执行完后,且在module_2调用之前,才会传递ABAP程序中,所以
"在该语句执行完之前ABAP程序中相应字段是不会有值
FIELD box2.
MODULE module_2.
"box1、box3屏幕字段在该语句执行完后,且在module_3调用之前,才会传递ABAP程序中,所以
"在该语句执行完之前ABAP程序中相应字段是不会有值
FIELD: box1, box3.
MODULE module_3.
DATA: ok_code LIKE sy-ucomm,
save_ok LIKE ok_code,
box1, box2, box3, box4,
mod1_result1, mod1_result2, mod1_result3, mod1_result4,
mod2_result1, mod2_result2, mod2_result3, mod2_result4,
mod3_result1, mod3_result2, mod3_result3, mod3_result4.
CALL SCREEN 200.
MODULE init_screen_100 OUTPUT.
SET PF-STATUS 'SDSS'.
CLEAR: box1, box2, box3, box4.
ENDMODULE.
MODULE user_command_0100 INPUT.
save_ok = ok_code.
CLEAR ok_code.
IF save_ok = 'CANCEL'.
LEAVE PROGRAM.
ENDIF.
ENDMODULE.
MODULE module_1 INPUT.
mod1_result1 = box1.
mod1_result2 = box2.
mod1_result3 = box3.
mod1_result4 = box4.
ENDMODULE.
MODULE module_2 INPUT.
mod2_result1 = box1.
mod2_result2 = box2.
mod2_result3 = box3.
mod2_result4 = box4.
ENDMODULE.
MODULE module_3 INPUT.
mod3_result1 = box1.
mod3_result2 = box2.
mod3_result3 = box3.
mod3_result4 = box4.
ENDMODULE.
? 由于BOX4未在FIELD语句出现过,所以在PAI事件之前就已经传递到ABAP程序中,所以在module_1、module_2、module_3三个PAI dialog modules里BOX4字段都是有值的。
? BOX2屏幕字段要在FIELD BOX2.语句之后才能传递取ABAP相应的BOX2字段中去,所以在module_1中是BOX2字段是没有值的,但在module_2、module_3中会有值。
? 而BOX1、BOX3需要在FIELD: box1, box3.语句后才能传递取ABAP相应的BOX1、BOX3字段中去,所以在module_1、module_2中不会有值,只有在module_3中才有值。
如果某个屏幕字段有一些约束检查(如参照的是某个数据表中的字段),则需要先通过这些字段的检测,才会触发PAI事件。如果某个屏幕字段为必须,但没有输入时,点击工具条中的退出按钮或屏幕中的按钮时是不会起作用的,这就意味着在输入检测通不过的情况下,PAI事件块里的正常MODULE语句是不会被执行的,如屏幕中的文本框为必输入,点击工具条中的Cancel按钮或者是屏幕中的Cancel按钮时无法退出程序:
为了避免这个问题:在输入不合法的情况下也可以退出程序,可以使用以下几步:
1. 设置成E类型的Function Codes
可以将屏幕中的按钮与GUIstatus上的按钮的Function Code的类型设置为E类型。
将屏幕中的按钮的Function Code设置为E类型:
同样,在GUI status的Standard Toolbar栏中,我们一般需要将Back (F3), Exit (shift+F3), and Cancel (F12)所对应的Function Code类型设置为E类型(因为这三个按钮一般是用来退出程序来使用的):
2. 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语句)
注意:PAI事件块里只有第一个附加EXIT-COMMAND选项的MODULE语句者会被执行(只要有一类型为E的Function Code按钮被点击就会执行),其他附加EXIT-COMMAND选项的MODULE语句不会被执行,如:
PROCESS AFTER INPUT.
MODULE execute1.
"只要是E类的Function Code都会执行
MODULE cancel AT EXIT-COMMAND.
"永远都不会执行
MODULE back AT EXIT-COMMAND.
MODULE execute2.
上面的 MODULE execute1.与MODULE execute2.两个语句会在字段约束自动检测通过之后才会被执行,而MODULE cancel AT EXIT-COMMAND语句则会在字段约束自动检测之前就会被执行,由于MODULE back AT EXIT-COMMAND语句是第二个事EXIT-COMMAND选项的MODULE语句,所以永远都不会被执行了。
这里的FIELD与前面的数据传输控制(FIELD)的使用是一样的:只有当FIELD <f>执行完成后,后面ABAP中<mod>中才能读到字段<f>的值,在这之前的module中是没有数据的。
FIELD dynp_field MODULE mod [ {ON INPUT}
| {ON REQUEST}
| {ON *-INPUT}
| {ON {CHAIN-INPUT|CHAIN-REQUEST}}
| {AT CURSOR-SELECTION}.
1、单个字段检查(即调用module) |
FIELD <FLD1> MODULE <MDL1>. |
2、单个字段被多个MODULE检查 |
FIELD <FLD1> MODULE <MDL1>,MODULE <MDL2>. |
3、检查多个字段,使用CHAIN |
CHAIN. |
4、不是初始值(即不为空时、非初始值)才检查,该事件适合于对屏幕新增数据的检查 |
FIELD <FLD1> MODULE <MDL1> ON INPUT. |
5、屏幕字段输入框中的值发生变化时检查(如在原本为空值的字段中输入数据,或修改某字段的值),该事件适合于屏幕中字段的值变更时的检查 |
FIELD <FLD1> MODULE <MDL1> ON REQUEST. |
6、CHAIN中不是初始值检查 |
CHAIN. |
FIELD <f> MODULE <mod> ON INPUT|REQUEST|*-INPUT.
在编辑屏幕的PAI的时候,对字段的检查一般用field xxx module xxx或者用chain。有两种操作可供选择,一种是on input,另一种是on request。
? ON INPUT:只要该字段不为初始值就会触发module。不同类型字段的初始值是不一样的:如果是字符类型其初始值为Space;数字类型的为zero(不同类型的具体初始值请参考《ABAP BC Programming.docx》)。即使用户在输入框输入了值,但这个值为初始值时也不会触发
? ON REQUEST:该字段发生变化后触发module
例如,有两个字段,a、b,两个module,check_a check_b:
field a module check_a on input.
field b module chec_b on request.
无论a发生任何变化,只要a不为空,则每一次回车都会触发check_a;
反之,只有b发生变化后才会触发check_b,如果两次回车中间b没有发生变化,则不会触发check_b。
注:此方式与CHAIN不同,不能如下写法:
FIELD a. " FIELD与MODULE只能写在同一语句中
MODULE check_a ON INPUT.
FIELD a,b. "非Chain中时,FIELD后面不能跟多个字段
MODULE check_a ON INPUT.
FIELD a.
MODULE check_a ON CHAIN-INPUT. "但可以使用CHAIN-?是否有意思没有测试
? ON *-INPUT
如果屏幕字段<f>的输入内容第一个字符为“*”,并且该屏幕字段<f>设置了“* Entry”属性,且没有ON INPUT时,则会调用<mod>module ,并且首字符星号不会被传递到ABAP程序中去。
不能嵌套。可以将多个屏幕字段组织在一块进行验证。此语句的作用就是相当于选择屏幕的AT SELECTION-SCREEN ON BLOCK block事件,用来对一个逻辑块的屏幕字段进行校验,这里的逻辑块是按Module前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>中的某个字段满足条件即可执行。
CHAIN.
FIELD:f1,f2.
FIELD: f3 MODULE mod1 ON INPUT.
ENDCHAIN.
只有f3包含非初始值时才调用mod1
CHAIN.
FIELD:f1,f2.
FIELD:f3 MODULE mod1 ON CHAIN-INPUT.
ENDCHAIN
f1,f2,f3中任一字段包含非初始值時都調用mod1.
注意on input 与on chain-input的不同
在AT CURSOR-SELECTION语句调用之前,先也要通过字段有效性检测这一过程,这与AT EXIT-COMMAND是不一样的(它会绕过字段输入有效检测过程),屏幕字段的值会按照FIELD语句的出现的顺序传递到ABAP程序中,但此时Function Code不会传递到ABAP程序中去,所以此时SY-UCOMM与OK_CODE不受影响,存放的值还是上一次的值。
MODULE <mod> AT CURSOR-SELECTION.
当鼠标双击(或F2)输入/输出( I/O)类型的屏幕字段时(比如下图中屏幕字段类型为 I/O 的屏幕字段)才会调用<mod>:
注意:要使鼠标双击屏幕输入元素时AT CURSOR-SELECTION生效,还必须在GUI Status里设置:将F2(一般使用F2,不要使用别的快捷键,因为F2本来就是系统预设的鼠标功能)所对应的Function Code为CS,并且Function Type为S,此时才能激活鼠标双击功能:
还可以与FIELD一起使用:
FIELD <f> MODULE <mod> AT CURSOR-SELECTION.
或者,针对多个屏幕字段时:
CHAIN.
FIELD: <f1>, <f2>,...
MODULE <mod> AT CURSOR-SELECTION.
ENDCHAIN.
上面这两种方式下,只有当鼠标双击(或F2)I/O 类型字段<f>或<fi>屏幕字段时,<mod>才会被调用(注意:<f>或<fi>只能是I/O 类型的屏幕字段)。
AT CURSOR-SELECTION语句调用优先顺序:
? 如果有某个屏幕字段可能有以下三种语句:MODULE <mod> AT CURSOR-SELECTION(包括在CHAIN…ENDCHAIN里的语句)、FIELD <f> MODULE <mod> AT CURSOR-SELECTION有关,则带FIELD的语句会先执行(不管FIELD语句这三者前还是后),其他的语句不再被执行。
? 对于同一个屏幕字段<f>,如果有多条FIELD <f> MODULE <mod> AT CURSOR-SELECTION语句,则只有第一条会被执行
? 如果有多条MODULE <mod> AT CURSOR-SELECTION 的语句,则只有最后一条语句会被执行
示例:
DATA: ok_code LIKE sy-ucomm,
input1(20),
input2(20),
input3(20),
fld(20).
CALL SCREEN 200.
MODULE init_screen_0100 OUTPUT.
SET PF-STATUS 'STATUS_100'.
ENDMODULE.
MODULE cancel INPUT.
LEAVE PROGRAM.
ENDMODULE.
MODULE cursor INPUT.
GET CURSOR FIELD fld.
MESSAGE i001(00) WITH 'cursor: ' fld.
ENDMODULE.
MODULE module_1 INPUT.
MESSAGE i001(00) WITH 'module_1'.
ENDMODULE.
MODULE module_2 INPUT.
MESSAGE i001(00) WITH 'module_2 '.
ENDMODULE.
MODULE module_* INPUT.
MESSAGE i001(00) WITH 'module_*'.
ENDMODULE.
MODULE c1 INPUT.
GET CURSOR FIELD fld.
MESSAGE i001(00) WITH 'c1: ' fld.
ENDMODULE.
MODULE c2 INPUT.
GET CURSOR FIELD fld.
MESSAGE i001(00) WITH 'c2: ' fld.
ENDMODULE.
在GUI status STATUS_100中,图标被激活,且Function Code为CANCEL,类型为E。快捷键F2也被激活,Function Code为 CS类型为S。
? 只要1或2输入框不为空时,MODULE_1将被调用
? 只要3个框任何一个输入内容发生了改变,则MODULE_2就会被用调用
? 只要输入框3输入的内容以*开头,则会调用MODULE_*(注意:屏幕字段INPUT3需要设置“* Entry”属性才能触发)
? 当在INPUT1上按F2或双击时,c1会被调用(因为带FIELD的要比不带FIELD的语句调用优先级要高);如果将第20行注掉,则此时cursor会被调用(因为有多条不带FIELD的语句时,最后一条才会被执行,所以要想在INPUT1上双击时调用c2,则需要将19、20都注掉)
? 当在INPUT2或INPUT3上按F2或双击时,cursor会被调用,而c2不会被调用,因为有多条不带FIELD的语句时,最后一条才会被执行
SET PF-STATUS <stat> [OF PROGRAM <prog>] [EXCLUDING <f>|<itab>].
给屏幕设置STATUS(屏幕菜单、工具条)
DATA fcode TYPE TABLE OF sy-ucomm.
...
MODULE status_0100 OUTPUT.
"去激活Function code为CHANGE、SAVE的功能
APPEND 'CHANGE' TO fcode.
APPEND 'SAVE' TO fcode.
SET PF-STATUS 'STATUS_0100' EXCLUDING fcode.
ENDMODULE.
SET TITLEBAR title [OF PROGRAM prog][WITH text1 ... text9].
除非另外有一个SET TITLEBAR重新设置了Title,否则当前屏幕及后继屏幕的Tile一样。占位符placeholders &1 ... &9可以被相应的text1 ... text9所替换,如果要显示一个&,则要在Title中使用&&来代替
DATA: title TYPE string,
prog TYPE string,
p1 TYPE c LENGTH 10,
p2 TYPE c LENGTH 10.
...
MODULE status_0100 OUTPUT.
...
title = 'TITLE_0100'.
prog = '...'.
p1 = '...'.
p2 = '...'.
SET TITLEBAR title OF PROGRAM prog WITH p1 p2.
...
ENDMODULE.
GET CURSOR FIELD<f>[OFFSET<off>][LINE<lin>][VALUE<val>] [LENGTH<len>] [AREA area]..
当用户在屏幕上进行操作后,我们需要知道光标操作所在哪个屏幕元素上,这个典型应用是F2(或鼠标双击)。该语句就是找出光标所在屏幕元素,它会将光标所在屏幕是元素的名称写入<f>变量中,如果光标在屏幕字段里,则SY-SUBRC为0,否则为4。
? OFFSET将光标所在屏幕元素内容中的位置写到变量off中
? LINE如果光标落在了table control表格控件中的某行,则将光标所在的行号写到lin变量中。如果光标不在table control表格控件中,则lin的值为0.
? VALUE将屏幕字段的内容(指显示模式下的内容,也就是说还包括格式字符)写到val变量中
? LENGTH将屏幕字段的显示长度写入到len变量中
? AREA
LIST屏幕的光标读取与定位请参考GET CURSOR FIELD、GET CURSOR LINE
DATA: ok_code LIKE sy-ucomm,
save_ok LIKE ok_code.
DATA: input_output(20) TYPE c,
fld(20) TYPE c,
off TYPE i,
val(20) TYPE c,
len TYPE i.
CALL SCREEN 200.
MODULE user_command_0100 INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE save_ok.
WHEN 'CANCEL'.
LEAVE PROGRAM.
WHEN 'SELE'.
GET CURSOR FIELD fld OFFSET off VALUE val LENGTH len.
ENDCASE.
ENDMODULE.
MODULE init_screen_0100 OUTPUT.
SET PF-STATUS 'SDSS'.
ENDMODULE.
光标定位一是可以通过屏幕属性静态的设置
二是在PBO中动态的指定光标位置:
SET CURSOR FIELD <f> [OFFSET <off>].
屏幕的自动检测在所有屏幕字段内容传递到ABAP程序中之前,也在screen flow logic处理之前发生。如果想绕过自动检测之前就要调用module,则需要在调用时使用 AT EXIT-COMMAND选项
如果自动检测出现了错误,消息将显示在屏幕的状态条上显示,相应字段继续等待正确的输入,只有当所有输入都通过了自动检测后才会触发PAI正常处理(AT EXIT-COMMAND选项的调用除外)。自动检查以如下顺序来运行:
1. 必输字段检测
2. 数据格式检测
3. ABAP Dictionary检测
? 如果参照的字段为foreign key,则会进行Check Table检测
? fixed values检测
发现在一个自动联动现象:当SDYN_CONN-CARRID、SDYN_CONN-CONNID同时出现时,自动就具有联动功能,如果输入了SDYN_CONN-CARRID的值,则SDYN_CONN-CONNID的值会受它影响,如果不输入就选择SDYN_CONN-CONNID的值,则SDYN_CONN–CARRID框中的值会自动填上。
已过时
当检测不通过时,可以在相应的module中发送warning (type W) 或者 error (type E)类型的消息,PAI处理就会暂停,直到输入通过检测后才会继续向后执行。
FIELD <f> MODULE <mod>.
当<mod>中发送出警告或错误类型的信息时,相应字段<f>将会要求重新输入,一旦输入检测通过后,将继续后面的PAI语句的处理,以前的module不会再次调用。
CHAIN.
FIELD: <f1>, <f2>,...
MODULE <mod1>.
FIELD: <g1>, <g2>,...
MODULE <mod2>.
...
ENDCHAIN.
当<mod1>或者<mod2>中发送出警告或错误类型的信息时,所以出现在CHAIN…ENDCHAIN块FIELD语句中的屏幕字段将会要求重新输入,其他屏幕字段被锁定且置灰不能输入。一旦输入检测通过后,将继续进后面的PAI语句的处理,以前的module不会再次调用
PROCESS BEFORE OUTPUT.
MODULE init_screen_0100.
PROCESS AFTER INPUT.
MODULE cancel AT EXIT-COMMAND.
FIELD input1 MODULE module_1.
FIELD input2 MODULE module_2.
FIELD input3 MODULE module_3.
CHAIN.
FIELD input4.
MODULE chain_module_1.
FIELD input5.
FIELD input6 MODULE chain_module_2.
ENDCHAIN.
MODULE execution.
DATA: ok_code LIKE sy-ucomm,
input1 TYPE i,
input2 TYPE i,
input3 TYPE i,
input4 TYPE i,
input5 TYPE i,
input6 TYPE i,
sum TYPE i.
CALL SCREEN 200.
MODULE init_screen_0100 OUTPUT.
SET PF-STATUS 'SDSS'.
ENDMODULE.
MODULE init_screen_100 OUTPUT.
CLEAR: input1, input2, input3, input4, input5, input6.
SET PF-STATUS 'SDSS'.
ENDMODULE.
MODULE cancel INPUT.
LEAVE PROGRAM.
ENDMODULE.
MODULE module_1 INPUT.
IF input1 < 50.
MESSAGE 'module_1: input1 < 50' TYPE 'E'.
ENDIF.
ENDMODULE.
MODULE module_2 INPUT.
IF input2 < 100.
MESSAGE 'module_2: input3 < 100' TYPE 'E'.
ENDIF.
ENDMODULE.
MODULE module_3 INPUT.
IF input3 < 150.
MESSAGE 'module_3: input1 < 150' TYPE 'E'.
ENDIF.
ENDMODULE.
MODULE chain_module_1 INPUT.
IF input4 < 10.
MESSAGE 'chain_module_1: input4 < 10' TYPE 'E'.
ENDIF.
ENDMODULE.
MODULE chain_module_3 INPUT.
IF input4 > 20.
MESSAGE 'chain_module_3 : input4 > 20' TYPE 'E'.
ENDIF.
ENDMODULE.
MODULE chain_module_2 INPUT.
CLEAR sum.
sum = sum + : input4, input5, input6.
IF sum <= 100.
MESSAGE 'chain_module_2: (input4 + input5 + input6) <= 100' TYPE 'E'.
ENDIF.
ENDMODULE.
MODULE execution INPUT.
MESSAGE 'execution:' TYPE 'I'.
ENDMODULE.
F4 Help也叫“Input Help”,而Search help又是Input Help的一种
F4IF_FIELD_VALUE_REQUEST:通过函数绑定搜索帮助
也可以在Domain中指定一个值表(Value Table)作为字段取值范围的限制,但是与指定固定值的方式不同的是,为一个Domain简单地指定一个取值表不会导致用户的输入被自动校验,也不会自动出现F4 Help。只有通过表外键按钮将该Value Table指定为主表之后,一个值表才能真正成为Check Table。所以要想成为真正有效的Check Table,必须要做两个操作:
一是要为字段对应的Domain设置Value Table(即主表,其实这一步不是必须的,在通过按钮指定主表时,可以不用指定为字段所参照的元素所对应Domain所设置的Value Table,而是指定其他的主表也是可以的—— 但最好不要这样做,Value Check时会出其他问题),
检查表(主表:SCOUNTER)的主键字段与外键表(从表:SBOOK)中的外键字段一一对应进行校验。
外键的检验也只能用于屏幕用户的输入检查,如果用ABAP程序直接向表中插入记录,则此处定义的外键检查不起作用
PARAMETERS p_carid TYPE sbook-carrid VALUE CHECK.
PARAMETERS p_cuter TYPE sbook-counter VALUE CHECK.
F4命中清单中的所有数据都来自于主表:
注:命中清单中的ID列即CARRID背景色不是蓝色,所以选择一条时,不会自动填充屏幕字段P_CARID,原因是对应的Search Help中的CARRID参数对应的EXP没有打上钩:
如果将这个钩打上,则会相应列背景色会为蓝色,且会自动填充,达到联动效果。
一般当某个外键所参照主表的主键上如果设置了搜索帮助(如上面COUNTER外键所引用的主表主键字段SCOUNTER-COUNTNUM已分配搜索“SCOUNTER_CARRIER_AIRPORT”:),则这个主表主键上的搜帮助会带到从表中相应外键上来,请看上面的SBOOK-COUNTER外键字段的搜索帮助也为“SCOUNTER_CARRIER_AIRPORT”,该搜索帮助决定了整个F4 Help处理及显示过程(如联动查询及自动填充效果)。另外,虽然主表主键上的搜索帮助会带到相应外键上来,但带过来后还可以修改,比如上面示例中带过来的搜索帮助中,CARRID参数所对应的EXP没有钩上,所以示例中的屏幕字段P_CARID不能使用命中清单中的ID列来自动填中,所以我们可以新建一个搜索帮助,并将CARRID搜索参数所对应的EXP钩上,则可达到自动上屏幕的效果;
另外,有些外键所参照的主表主键没有指定搜索帮助,此时参考的从表(或主表)屏幕字段的F4 Help就只有一个简单的字段了,如上面SBOOK-LOCCURKEY字段:
PARAMETERS p_cur TYPE sbook-LOCCURKEY VALUE CHECK.
创建搜索帮助时,搜索帮助的数据源可以来于:表/视图(通过“选择方法”指定)、ABAP程序(通过“搜索帮助出口”指定)。下面以视图为源来创建搜索帮助。
SE11中,SAP提供了一种“帮助视图”,专门为维护搜索帮助设立的,该类视图提供表的关联信息,不会在数据库服务器上占用实际的物理空间。
创建交货订单信息相关视图:
l LIKP:交货单的表头
l VBUK:交货单状态
l KNA1:客户主数据
需要在帮助视图中显示的字段有:LIKP-VBELN交货单号;LIKP-KUNNR货物送达方的编码;KNA1-NAME1送达方的名称;VBUK-WBSTK交货单状态,“C”表示已交货
基本索引帮助:最基本也是“集合搜索帮助”组成部分的帮助,如果按F4后显示条件限制对话框,则只会有一个限制条件页面;
集合搜索帮助(collective search help):是由多个基本索引帮助组成的,中可以包含多个search help,这个也就是我们看到的选择界面有多个tab的那种情况。如果按F4后显示条件限制对话框,则会有多个条件限制页面TAB标签,即可以选择不同的“基本索引帮助”来筛选数据
l 简短描述:设置的简短描述不是限制对话框中的标题。限制对话框中的标题如何设置???
l 选择方法(selecttion method):可以是选数据表,或者是视图。当所选择的表有text table时,会自动填充下面的“文本表”标签,并且search help会根据用户登录语言自动选择相应的text。
l 限制对话框行为:按F4后是否弹出条件过滤对话框,有以下三种选择:
2 立即显示值:在按F4后立即显示命中清单,不会弹出限制对话框,通常如果命中清单记录很少时则建议使用该选项。
2 具有值限制的对话:立即显示限制值的对话框。如果正常情况下可能条目的清单非常大,则选择该选项。
2 根据值集合的对话:如果命中清单包含的条目小于100个,那么立即显示该命中清单。如果其包含的条目多余100个,那么显示限制值用的对话框。
l 快捷键:此键只在该基本搜索帮助包括到某个集合搜索帮助里时,才可使用(有意义)??作用是在集合搜索帮助的限制对话框中,出现了多个限制TAB标签页面,所以可以使用此处设置的键快速切换到相应的TAB标签页面????
HOT KEY是用来做多个search help合并时用到的,决定出现的顺序。
l 搜索帮助出口(search help exit):可以用作此搜索帮助的增强函数,对搜索出来的数据进一步进行处理。如下面出口中,在命中清单显示之前,对数据进行过滤处理:
(代码中STRING+3(4)取的是搜索帮助的第一个参数,但如果是在 CALLCONTROL-STEP = RETURN时间点时,STRING+0(4)才是第一个搜索帮助参数,因RECORD_TAB在不同时间点可能是变化着的,具体请参照后面IMP、EXP参数详细说明)
l 搜索帮助参数:来自于数据库表或视图中的字段
定义search help的parameter时,你需要定义它是IMPORT还是EXPORT。同fm一样IMPORT和EXPORT PARAMETER构成了search help的interface。
2 IMP:输入参数。表示屏幕上相应字段是否作为搜索帮助的过滤条件(即报表选择屏幕上的字段的值是否从报表选择屏幕上传递到搜索帮助中去)
如果是F4字段时,屏幕字段中的值包含“*”时,才会将F4字段传递到Search Help中。除开F4屏幕字段外,而其他只要是Link到了相应的Search Help参数的屏幕字段,则不管IMP是否钩选上,只要相应屏幕字段中有值,则会传入到搜索中作为过滤条件。所以IMP是否钩选上,只会影响该参数所Link到的F4屏幕字段值是否传入到搜索帮助,而其他非F4屏幕字段,只要与搜索帮助相应参数Link过,不管IMP参数是否钩先,则屏幕字段值都会传入到搜索帮助中。
另外,如果要对已传入的屏幕字段值进行再次修改,则可以将搜索帮助的“对话框性为—对话类型”设为“C 具有值限制的对话”,传入的屏幕字段值会在弹出限制对话框中相应字段中显示,此时就可以对这些值做进一步修改;如果没有弹出限制对话框,则屏幕上传入的值不会再次被修改的可能,会直接传入到搜索帮助作为过滤条件
注:上图中只有屏幕字段是参照表或结构字段而非通过编程来绑定Help时,在搜索帮助查询时,除了可以将F4屏幕字段传入到搜索帮助中(前提是值中有“*”,且IMP被钩选过了)作为搜索帮助的过滤条件,其他非F4屏幕字段(与搜索参数有Link关系的屏幕字段)的值也会传入到搜索帮助中作为搜索条件;在返回时,会将相应的命中清单中的列(这些列与屏幕字段是有映射关系)自动填充到相应的屏幕字段中。另外,如果是通过程序方式 MATCHCODE绑定(或其通过Data Element绑定)时,则在查询时不会将其他非F4屏幕字段传入到搜索帮助时,也不会在返回时填充其他非F4屏幕字段,在返回时,会默认返回 EXP中第一个钩选列到F4屏幕字段中。
注:IMP与EXP一定要至少一个被钩选,在将此搜索帮助分配给表字段时,IMP或EXP被钩选的列才会出现在分配界面,否则在绑定过程的分配界面是不会出现这些参数的
TABLES:zsflight.
SELECT-OPTIONS:so_carr FOR zsflight-carrid," MATCHCODE OBJECT ZH_SCARR,"航线代码
so_conn FOR zsflight-connid," MATCHCODE OBJECT ZH_SPFLI."航班代码
so_from for zsflight-CITYFROM.
2 EXP:输出参数,表示搜索帮助的此列会从搜索帮助中传递到报表选择屏幕上(表示F4选中一条记录后显示到屏幕上文本框中的值——背景字段为浅蓝色的列的数据会被输出,输出的数据可能是多列。注:只有当EXP钩上且相应字段出现在了屏幕上,才会自动填充到相应屏幕字段,如果没有钩上——没钩上的字段背景色为白色,即使出现在了屏幕上,选择命中清单时也不会自动填充),且F4字段一定要将EXP钩上(否则选择后F4字段不能上屏)。可以通过return_tab(具体可以参考自定义对话屏幕字段F4中相应代码解释)参数接收用户所选择的数据。
是否显示为浅蓝色,是由SHLP-FIELDPROP内表参数中SHLPOUTPUT字段的值来决定的;但如果是通过“Attaching to Data Elements”或直接通过编程方式使用Search Help时,即使EXP有多列被钩选,也只有最前面被钩选的列的背景色为浅蓝色,如果此时也要使被钩选的所有EXP列背景色为浅蓝色,则可以通过修改内表中SHLPOUTPUT字段的值来达此目的,因为调试发现在CALLCONTROL-STEP= DISP 时间点之前时,如果此时SHLPOUTPUT的值为X,则显示出来的命中清单相应列背景色就是浅蓝色的:
(注:此内表实质上就是用来存储“搜索帮助参数”属性列表的。刚进入F4IF_SHLP_EXIT_EXAMPLE时,搜索帮助参数EXP列中只要是被钩选的列,它所对应此内表的 SHLPOUTPUT列都会是 X ——上图就是首次进入出口函数时SHLP-FIELDPROP内表的内存状态,但运行到CALLCONTROL-STEP= DISP 时间点时,只有EXP列中第一个被钩选的列所对应的SHLPOUTPUT字段的值为X,其他都会清空,所以需要在CALLCONTROL-STEP= DISP 时间点修改此内表值,下面为CALLCONTROL-STEP= DISP 时间点时内表 SHLPOUTPUT的内存状态:)。
另外,不管时搜索帮助参数的EXP列钩选了多少个,返回时,命中清单中所选记录的所有列都会返回,这可以通过观察F4IF_SHLP_EXIT_EXAMPLE的RECORD_TAB内表参数获知,因为RECORD_TAB在不同的时间点存储了不同的数据——如果刚好是在CALLCONTROL-STEP= DISP时间点之后,存储的是搜索帮助所有命中的记录(如从数据库中搜索出来的所有数据);如果是在CALLCONTROL-STEP= RETURN时间点时,存储的则是用户选中的记录。下面就来在这两个时间点来看看RECORD_TAB内表数据:
2 CALLCONTROL-STEP= DISP时:
2 当从命中清单中选中第一条记录进入到F4IF_SHLP_EXIT_EXAMPLE函数后,此时是CALLCONTROL-STEP= RETURN时间点:
上面两个时间点来看,RECORD_TAB内表中STRING字段存储的就是命中清单与用户选中记录的数据,并且是将这些数据的多列拼接起来之后存储在此字段中的(注:不管搜索帮助参数中的LPOS是否设置为0或留空时,所有搜索帮助的参数还是都会被拼接起来存储在此字段中,与LPOS设置无关),这些拼接在一起的数据是通过F4IF_SHLP_EXIT_EXAMPLE的SHLP-FIELDDESCR内表参数中的OFFSET(按字节来计算的)及INTLEN(内部长度,按字节来计算的)来划分的,并且在不同的CALLCONTROL-STEP时间点时,OFFSET的取值是变化的,且时间与上面两种是相对应的:
2 CALLCONTROL-STEP= DISP时:
2 当从命中清单中选中第一条记录进入到F4IF_SHLP_EXIT_EXAMPLE函数后,此时是CALLCONTROL-STEP= RETURN时间点:
l LPOS(列表):命中清单中各列的显示顺序,如果为0或留空的列则不会显示。位置编号不能在列中出现多次,但是允许有间隔。另外,在基本搜索帮助中,至少在命中清单中出现一个参数
l SPOS:搜索帮助的过滤条件,对搜索结果进行过滤。如果在命中清单显示之前,弹出限制对话框,则还可以进一步修改那些从选择屏幕上带过来的条件值。此数字就是限制搜索帮助选择条件屏幕字段摆放顺序,如果为0或留空的列则不会出在限制条件页中
l SDis:如果勾选了,则在弹出的限制对话框中对应的字段用户不可输入,是只读的。下面是前面创建的Search Help,其中搜索参数WBSTK的SDis钩上了,所以弹出的限制对话框中所对应的屏幕字段不能进行修改:
l Modified:如果这个勾打上的话,数据元素(Data Element)列,变成可修改状态,也就是说可以为这个字段指定其它数据元素
l 缺省值:此处设置的默认值是被相应的SPos列所使用的。可以有三种值设置方式:a ‘literal’(in quotes), a parameter ID(ZRD), or a system field (SY-UNAME).
u 出口函数参数
下面以ZH_SPFLI搜索帮助来理解F4IF_SHLP_EXIT_EXAMPLE出口函数各参数:
TABLES: zsflight.
SELECT-OPTIONS:s_carrid FOR zsflight-carrid, "航线代码
s_connid FOR zsflight-connid, "航班代码
s_ctyfrm FOR zsflight-cityfrom. "起飞城市
以上面搜索帮助为例,运行报表程序,并在出口函数中设置断点,来理解一下F4IF_SHLP_EXIT_EXAMPLE出口函数各参数:
l SHLP参数
2 SHLPNAME 搜索帮助名
2 SHLPTYPE 搜索帮助的类型,取值如下:
SH Search help 搜索帮助
CH Check table 表检查
CT Check table with text table 有文本表的检查表
FV Fixed values for domains 域的固定值
DV Fixed values from flow logic 流逻辑的固定值
CA Calendar help 日历帮助
CL Time help 时间帮助
SR Search help for data element (temporary) 数据元素的搜索帮助(临时)
MC Matchcode 匹配代码
MI Matchcode ID 匹配代码标识
IN Internal Table 内表
2 INTDESCR搜索帮助的内部信息,一般程序使用不到
2 INTERFACE 包含了Help中的所有参数,当前使用哪个参数为F4屏幕字段,屏幕字段与Help参数映射信息(映射关系是通过SHLPFIELD与VALFIELD两列来映射),以及传入的F4屏幕字段的值(其他非F4屏幕字段的值不会在这里存储,而是在SHLP-SELOPT存储的)
2 FIELDDESCR注要描述了Help各参数在命中清单RECORD_TAB-STRING中的偏移量与长度,便于各字段值的读取:
2 FIELDPROP实质上存储的就是Help参数属性,与Search Help SE11维护界面里的相同
2 SELOPT存储了选择屏幕与限制对话框屏幕上所有与此Help Link过的字段值,即这些会作为搜索帮助的过滤条件
l CALLCONTROL参数
Callcontrol-step: 该字段的值是由系统设置,并且你可以在程序中进行修改它。出口函数会在处理的每一步(时间点)都会调用一次This field is set by the system and can be changed by your code. The function module will be called once for each step of the process, with some conditional exceptions noted below.
1. SELONE
Call before selecting an elementary search help. The possible elementary search helps are already in SHLP_TAB. This timepoint can be used in a search help exit of a collective search help to restrict the selection possibilities for the elementary search helps.
在选择基本元素搜索帮助之前调用。所有基本搜索帮助都已经放在了SHLP_TAB中了。该时间点是用来在集合搜索帮助中限制某些基本搜索帮助是否可选(应该就是在该时间点用来控制某个基本搜索帮助在弹出限制对话框中是否显示出来)
Entries that are deleted from SHLP_TAB in this step are not offered in the elementary search help selection. If there is only one entry remaining in SHLP_TAB, the dialog box for selecting elementary search helps is skipped. You may not change the next timepoint.
The timepoint is not accessed again if another elementary search help is to be selected during the dialog.
2. PRESEL1
After selecting an elementary search help. Table INTERFACE has not yet been copied to table SELOPT at this timepoint in the definition of the search help (type SHLP_DESCR_T). This means that you can still influence the attachment of the search help to the screen here. (Table INTERFACE contains the information about how the search help parameters are related to the screen fields).
在选择一个基本搜索帮助后调用。在该时间点上,SHLP/SHLP_TAB中的表INTERFACE不再复制到表SELOPT,这就意味着你仍然可以在这里影响搜索帮助到屏幕的映射关系(表INTERFACE包含了关于搜索帮助参数到屏幕字段的映射信息)
3. PRESEL
Before sending the dialog box for restricting values. This timepoint is suitable for predefining the value restriction or for completely suppressing or copying the dialog.
在限制对话框中的条件值发送之前调用。该时间点适合于对预定义值进行控制
4. SELECT
Before selecting the values. If you do not want the default selection, you should copy this timepoint with a search help exit. DISP should be set as the next timepoint.
选值之前调用(如果有弹出限制对话框,则会在弹出限制对话框中点击确认按钮后调用)。如果你不想使用默认选择,那就应该使搜索帮助退出该时间点,将DISP设置成下一个时间点
5. DISP
Before displaying the hit list. This timepoint is suitable for restricting the values to be displayed, e.g. depending on authorizations.
在命中清单显示之前调用。该时间用于控制搜索帮助的输出结果。例如,在输出搜索结果时对用户检查权限,删除未授权的数据
5. RETURN (usually as return value for the next timepoint一般作为下一个时间点的返回值)
set by your code if one hit was found during selection
The RETURN timepoint should be returned as the next step if a single hit was selected in a search help exit.
如果在一个搜索帮助退出中选择了一个单独命中,那么就将RETURN时间点作为下一步返回
It can make sense to change the F4 flow at this timepoint if control of the process sequence of the Transaction should depend on the selected value (typical example: setting SET/GET parameters). However, you should note that the process will then depend on whether a value was entered manually or with an input help.
如果对事务处理序列的控制取决于已选中的值(典型例子:设置SET/GET参量),那么在该时间点上改变F4的流程就是有意义的。然而,应该注意到,该处理将取决于一个值是手工输入的还是用输入帮助输入的。
7. RETTOP
follows RETURN if called from a collective search help
You only go to this timepoint if the input help is controlled by a collective search help. It directly follows the timepoint RETURN. The search help exit of the collective search help, however, is called at timepoint RETTOP.
只有当输入帮助由集合搜索帮助控制时,才转到该时间点。它直接跟着时间点RETURN。然而,集合搜索帮助的搜索帮助退出是在时间点RETTOP上调用的。
8. EXIT (only for return as next timepoint仅为了下一个时间点的返回)
set by your code. Terminates the search help process
The EXIT timepoint should be returned as the next step if the user had the opportunity to terminate the dialog within the search help exit.
如果用户有机会在一个搜索帮助退出中终止对话,那么EXIT时间点应作为下一步返回
9. CREATE
The CREATE timepoint is only accessed if the user selects the function "Create new values". This function is only available if field CUSTTAB of the control string CALLCONTROL was given a value not equal to SPACE earlier on.
仅当用户选择函数“创建新值”时,才访问CREATE时间点。且当赋予控制参数CALLCONTROL所对应的结构体中的字段CUSTTAB为非空值时,该时间点才是有效的。
The name of the (customizing) table to be maintained is normally entered there. The next step returned after CREATE should be SELECT so that the newly entered value can be selected and then displayed.
正常的情况下,在那里输入将要维护的表(定制)的名字。CREATE之后,返回的下一步应该是SELECT,这样才能选择新输入的值,并且随后显示。
10. APP1, APP2, APP3
If further pushbuttons are introduced in the hit list with function module F4UT_LIST_EXIT, these timepoints are introduced. They are accessed when the user presses the corresponding pushbutton.
如果带有函数模块F4UT_LIST_EXIT的命中列表包含了更深一层的按钮,那么也会介入这些时间点。当用户单击相应的按钮时,就能访问这些时间点。
注:如果F4帮助是一个集合搜索帮助,那么就在时间点SELONE和RETTOP上调用集合搜索帮助的出口。(RETTOP仅当用户选择一个值)。在所有的其也时间点上,调用选择的元素搜索帮助的出口。
如果F4帮助是一个基本搜索帮助,不执行RETTOP时间点。在时间点SELONE(当时)调用元素搜索帮助的出口,其他准备工作都在时间点PRESEL1上执行
Table中的接口定义:
l SHLP_TAB
Table of elementary search helps
存储所有的基本搜索帮助,行结构与Changing接口中的SHL结构类似
l RECORD_TAB
用来存储命中清单上将要显示的所有记录数据。另外,在选择命中清单上某条件数据返回时,该内表也会存储被选中记录
u 出口函数实例1
下面创建一个与F4IF_SHLP_EXIT_EXAMPLE函数一样的出口函数ZFVBELN_FIND_EXIT:
FUNCTION zfvbeln_find_exit.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" TABLES
*" SHLP_TAB TYPE SHLP_DESCT
*" RECORD_TAB STRUCTURE SEAHLPRES
*" CHANGING
*" VALUE(SHLP) TYPE SHLP_DESCR
*" VALUE(CALLCONTROL) LIKE DDSHF4CTRL STRUCTURE DDSHF4CTRL
*"----------------------------------------------------------------------
"此内表用于存储命中清单数据.注:字段的名称一定要与搜索参数名一样,但顺序可以不同,
DATA: BEGIN OF lt_tab OCCURS 0,
wbstk TYPE wbstk,
lfdat TYPE lfdat_v,
vbeln TYPE vbeln_vl,
END OF lt_tab.
"用于存储从选择屏幕上传进的屏幕字段的选择条件值
DATA: r_vbeln TYPE RANGE OF vbeln_vl WITH HEADER LINE,
r_lfdat TYPE RANGE OF lfdat_v WITH HEADER LINE,
r_wbstk TYPE RANGE OF wbstk WITH HEADER LINE,
wa_selopt LIKE LINE OF shlp-selopt."
"callcontrol-step该字段的值是由系统设置,并且你可以在程序中进行修改它。出口函数会在处理的每一步(时间点)都会调用一次
IF callcontrol-step = 'SELECT'."如果有弹出限制对话框,则会在弹出限制对话框中点击确认按钮后step值才为SELECT
"shlp-selopt存储的是经过映射转换后选择屏幕上字段的值,而不是直接为
"选择屏幕字段名,而是转映射为Help参数名后再存储到 selopt 内表中,
"屏幕字段到Help参数映射是通过 shlp-interface 来映射的
LOOP AT shlp-selopt INTO wa_selopt.
CASE wa_selopt-shlpfield.
WHEN 'VBELN'."由于屏幕字段已映射为了Help相应参数,所以这里不是S_VBELN
MOVE-CORRESPONDING wa_selopt TO r_vbeln.
APPEND r_vbeln.
WHEN 'LFDAT'.
MOVE-CORRESPONDING wa_selopt TO r_lfdat.
APPEND r_lfdat.
WHEN 'WBSTK'.
MOVE-CORRESPONDING wa_selopt TO r_wbstk.
APPEND r_wbstk.
ENDCASE.
ENDLOOP.
"根据屏幕上传进的条件查询数据
SELECT likp~vbeln likp~lfdat vbuk~wbstk INTO CORRESPONDING FIELDS OF TABLE lt_tab
FROM likp INNER JOIN vbuk ON likp~vbeln = vbuk~vbeln
WHERE likp~vbeln IN r_vbeln AND
likp~lfdat IN r_lfdat AND
vbuk~wbstk IN r_wbstk.
"该函数的作用是将内表 lt_tab 中的数据转换成record_tab,即将某内表中的数据显示在命中清单中
CALL FUNCTION 'F4UT_RESULTS_MAP'
TABLES
shlp_tab = shlp_tab
record_tab = record_tab
source_tab = lt_tab
CHANGING
shlp = shlp
callcontrol = callcontrol.