SAP屏幕开发之Tabstrip分页签控件


前言

      这篇文章给大家介绍一下SAP Dialog程序中 Tabstrip控件 的使用,也就是我们最常见的分页签,对于屏幕开发没有任何基础的读者请先看笔者另外两篇文章,SAP屏幕开发基础 SAP屏幕开发小案例 这篇文章笔者会省去程序创建等一些操作,会直接切入正题解释分页签的逻辑原理。


一、案例介绍

        这个案例我们会在屏幕中绘制一个子屏幕,屏幕中有三个分页签,分别为 新建 修改 显示,点击分页签子屏幕会出现不同的内容,会解释到当你点击分页签的时候程序中数据变量到底是如何赋值调用相应内容执行的以及主屏幕与子屏幕之间PBO PAI的执行顺序,掌握了以上之后我们可以对分页签进行调整,如删除其中的一个分页签或增加一个。


二、绘制屏幕

        绘制一个分页签的方式一共有两种 一个是通过向导创建程序自动生成代码,另外一种是完全自己绘制自己编写代码,两种方式最终的效果都是一样的,但是我们一般用向导创建的方式就可以了,这里我也只介绍向导创建的方式。

            a.根据向导创建分页签

                       我们首先进入Screen Painter 屏幕绘制界面然后选择 Tabstrip (with Wizard)进行向导创建分页签。

                       根据顺序编号一步一步创建即可,图片有点乱不要介意。

在这里插入图片描述

                       Dialog程序运行需要创建T-code此处省略

                                                                                运行效果

运行效果

                       下图中绿框中的区域就是子界面,我们可以双击它查看它的类型就是Subscreen Area,我们可以看到根据向导创建已经自动帮我们创建了3个屏幕编号分别为0101、0102、0103的屏幕,当我们点击创建按钮的时候程序就会把0101屏幕中的内容显示到绿色框中,当点击修改按钮的时候程序就会把屏幕0102中的内容显示到绿色框中。

在这里插入图片描述在这里插入图片描述

                       我们可以点击自动创建的屏幕可以发现这些屏幕的 Screen Type是 Sbuscreen,也只有这种类型的屏幕才可以被我们放到 Tabstrip控件Subscreen Area里面 也就是上图绿色框选出来的区域。

在这里插入图片描述

三、自动生成代码解释

            接下来从数据定义和用户点击了分页签按钮到屏幕显示这么一个过程给大家逐步介绍自动生成的这些代码,当我们点击分页签按钮界面变化显示出来其实是走了两步,先是执行PAI里面的代码,再是界面显示前执行PBO里面的代码。

            a.TOP数据定义代码解释

                       下图中使用 CONSTANTS 定义了一个结构,CONSTANTS 和 DATA 定义数据有什么区别可以查看笔者另外一篇文章 ABAP关键字详解 ,我们建了几个分页签这个结构就有几个字段,这个结构的名称也是 C开头加上我们 Tabstrip控件的名字。这些字段的值也是我们向导中所见到的 Fctcode 并且这些字段的类型是SY-UCOMM说明它们都是按钮功能的值。
在这里插入图片描述
                       下图 CONTROLS关键字是用来创建屏幕控件的,参照变量类型 Tabstrip 声明一个 TS_CTRL的变量,参照Tabstrip声明出来的控件也就是我们的分页签控件。在这个声明之后,可以使用 TS_CTRL 这个控件变量来操作和控制 Tabstrip 控件,比如向其添加选项卡、管理显示的内容等。
在这里插入图片描述

                       下图中声明了一个名为 G_TS_CTRL 的结构,其中有三个字段 SUBSCREEN 字段参考 SY-DYNNR 这意味着它是界面编号的意思,PROG 字段是程序名默认值是当前程序名,PRESSED_TAB 字段是按钮功能代码类型的, 默认值是 C_TS_CTRL-TAB1 是我们上面结构的第一个字段的Fctcode也就是默认点了哪个分页签。如果我们把1改为2那么我们重新进入程序可以看到默认显示的是”修改“这个分页签。

在这里插入图片描述

                       OK_CODE 这个变量其实可以理解为 为了暂存SY-UCOMM变量的,它的主要作用是下图中的代码逻辑。但其下图的逻辑不用OK_CODE直接用SY-UCOMM也可以实现相同效果,至于为什么要定义这个OK_CODE原因如下,通过将 SY-UCOMM 赋值给 OK_CODE,是为了提高代码的可读性和可维护性。开发者认为在程序的其他部分会多次使用 SY-UCOMM,为了避免在多处使用系统变量造成混淆或不便于理解,将其赋值给一个具有描述性名称的变量,以提高代码的清晰度和可维护性。虽然在这个特定的代码段中,直接使用 SY-UCOMM 也能实现相同的功能,但对于复杂的程序,将系统变量赋值给一个具有描述性名称的变量可能更有助于提高代码的可读性和维护性。

在这里插入图片描述

            b.PAI代码解释

                       当用户点击分页签按钮的时候PAI这部分的代码其实就是为了给G_TS_CTRL-PRESSED_TAB赋对应的值,这个字段的默认值是TS_CTRL_FC1也就是”创建“按钮的 Fctcode。这个字段也是能正确调用相应子界面屏幕的关键,解释PBO自动生成代码的时候会提到这个字段。
在这里插入图片描述

            c.POB代码解释

                       TS_CTRL-ACTIVETAB这个字段其实是我们Tabstrip控件的一个属性吧,就代表的是前台已激活的那个分页签也就是正在使用的那个分页签,G_TS_CTRL-PRESSED_TAB这个字段是有默认值的我们上面也提过了默认值是第一个分页签。下面这行代码是为了确保用户在切换分页签时,分页签显示的内容与上方几个分页签按钮相关联。也就是我分页签显示的0101屏幕内容的话”创建“的这个按钮就会高亮突出,我分页签显示的0102屏幕内容的话“修改”的这个按钮就会高亮突出。我们可以注释这行代码改为红框中写死的那行,这样再执行程序就可以发现无论我们点击那个分页签虽然内容是正确显示的但是按钮始终是”修改“高亮突出。
在这里插入图片描述

                       当画面要显示前调用的PBO这部分代码其实就是为了给G_TS_CTRL-SUBSCREEN赋值相应的屏幕编号,G_TS_CTRL结构这个变量是屏幕逻辑流中能正确调用子界面的原因,也就是说我分页签中显示哪个屏幕编号中的内容完全是根据G_TS_CTRL这个结构中的数据来关联的。
在这里插入图片描述

            d.屏幕逻辑流代码解释

                       CALL SUBSCREEN 语句用于在屏幕上调用子屏幕。子屏幕是一种可以嵌入到主屏幕中的小屏幕区域。这行代码其实还有一个很重要的含义,如果写在PAI下面就是执行子界面下的PAI事件写的PBO下面就是执行子界面下的PBO事件,如果执行子界面PAI那么也就意味着我子界面中的输入框等控件会和我程序中的变量进行双向赋值,文章第三部分会用一个案例做详细解释的。

                       5 、6行代码意思就是将这个G_TS_CTRL-PROG程序中的这个G_TS_CTRL-SUBSCREEN界面编号中的内容显示在 TS_CTRL_SCA区域中 ,其中TS_CTRL_SCA 双击查看类型可以发现是子屏幕。这些字段G_TS_CTRL-PROG、G_TS_CTRL-SUBSCREEN已经在执行PAI和PBO的MODULE中赋值了程序名是默认赋值了屏幕编号是逻辑赋值了。
在这里插入图片描述
                       我们可以发现在PAI中也有CALL SUBSCREEN调用相同子屏幕的语句,我最初也不理解为什么要在PAI部分写CALL SUBSCREEN TS_CTRL_SCA 语句,不是当PAI执行完就会执行PBO吗,PBO中明明已经有了CALL SUBSCREEN TS_CTRL_SCA 语句呀。所以这样看起来PAI下面的这个语句有点多余,当我们注释掉这行代码之后执行程序并多次点击分页签发现并没有什么异常,这是因为在某些情况下,如果子屏幕的内容不受用户交互行为的影响或者在特定的业务流程中并不需要即时更新,那么删除这个调用可能不会立即引发问题。PAI是在用户与程序交互之后,用于处理用户输入数据后的逻辑。在这个阶段,再次调用 CALL SUBSCREEN TS_CTRL_SCA 的目的可能是为了确保在用户进行了某些操作后,子屏幕的内容能够及时更新或反映出用户的操作。在文章第三部分会介绍到的

四、子界面/主界面运行逻辑流

        子界面和主界面的执行逻辑顺序是一个很重要的部分,如果我们涉及到主界面的数据与子界面的数据有流转的情况就必须要搞清楚子界面和主界面执行的逻辑顺序,这样才可以保证我们将数据正确有效的传递展示。下面用一副图和文字来描述它两之间的逻辑流,再加上一个小案例进行解释。

            a.图文解释

                       如下图所示,我们PBO和PAI下面的代码都是至上而下的顺序执行的也有个别是直接跳到指定MODULE执行比如PAI下面检测是否点击了E类型按钮的MODULE。当我们存在子界面的时候我们整个画面展示前PBO和PAI其实都是有3步,PBO第一步是执行主界面下面的PBO的MODULE直到遇见CALL SUBSCREEN调用子界面的语句然后是第二步,然后就会执行子界面下的PBO,子界面的PBO执行完毕之后就会执行剩余的主界面的MODULE也就是CALL SUBSCREEN下面的语句直到执行完所有的MODULE画面就会显示,这就是第三步。然后当用户点击了回车或者按钮之类的交互事件之后就会执行主界面下的PAI这是PAI的第一步,直到遇见CALL SUBSCREEN语句的时候就会调用子界面下的PAI,这是第二步,然后再执行剩余的PAI MODULE,这是第三步,然后又会回到PBO的三步直到画面显示。

在这里插入图片描述

                       从代码看的话可能更显而易见

在这里插入图片描述

            b.案例解释

                       这个案例中我们做两个输入框但是这两个输入框指向的是同一个变量,在合适的MODULE下面赋初始值,然后在特定的MODULE中又修改变量,看看每种情况下界面当中的两个输入框值的情况。
                       1.声明变量绘制输入框
                            绘制过程不过多赘述,我们直接参考声明的变量进行绘制,子界面中的输入框我们绘制在”创建“这个屏幕中也就是0101屏幕,我们可不能在主屏幕0100下去绘制子界面中的内容,子界面的内容是点击对应的屏幕编号后再点击Layout去绘制,当然我们子界面下面还可以继续嵌套分页签的。主界面下也可以绘制多个分页签。
在这里插入图片描述
                       1.情况一
                            当前的代码我们不做任何的改动,我们在子界面的输入框中输入内容回车后会发现这个值也会反应到主界面的输入框中,反过来在主界面输入框输入内容回车之后这个值也会反应到子界面的输入框中。这样程序是没有什么问题和异常的。
                                                                                运行效果
在这里插入图片描述

                       情况二.
                            当我们注释掉PAI下面的CALL SUBSCREEN,也就是上面我们所提到的PAI第二步,就是执行子界面下的PAI,这样我们可以发现当我们在子界面中的输入框输入内容之后再回车主界面和子界面的输入框都为空了,反过来在主界面输入框输入内容再回车这个值可以反应到子界面当中去。这里就很有意思了。这就是涉及到我们上面所提到的子界面主界面执行逻辑流顺序的问题。我们要好好捋一捋这其中的顺序逻辑流,当我们在子界面的输入框输入内容后并回车,程序并不会执行子界面的PAI因为我们注释掉了CALL SUBSCREEN,这也就说明我们输入的值并没有在程序中去双向赋值,也可以说这个值并没有被我们程序所抓到,所以input01变量还是初始值为空,这就是为什么要在PAI下面写这个语句 CALL SUBSCREEN 的原因,没有抓到等于我们这个变量实际还是为空,等到画面展示后就会发现主界面的输入框也为空,但是反过来在主界面输入后能反应在子界面的原因就是因为我们执行了主界面的PAI,当在主界面输入框输入内容回车之后就会先执行主界面的PAI,也就意味着我们程序去给变量中与输入框名称相同的变量名称赋值了,这也就是我们Dialog程序所说的双向赋值,也可以说就是抓到了我们输入的这个值,既然这个变量已经有值了那么画面展示之后主界面和子界面的输入框中当然是显示我们输入的内容。
在这里插入图片描述
                                                                                运行效果

在这里插入图片描述

                       3情况三.
                            当我们在PBO的第三步给input01赋值,也就是在调用完子界面的PBO后再给input01赋值,我们就会发现程序首先执行后子界面中的输入框是空,主界面的输入框是我们在程序中赋值的那个值,现在当我们在子界面的输入框输入值回车之后会发现子界面和主界面的输入框会出现两个不同的值,这也就很有意思了,明明是同一个变量却在界面中显示的是不一样的内容,其实这也很好理解,只要理解捋清楚我们子界面和主界面直接的逻辑流执行顺序之后也就感觉不到奇怪了。这个情况三我简略解释一下就行,当我们在子界输入框输入值回车后,这个值会在程序中赋值给我们input01然后执行完剩余的PAI MODULE之后再执行主界面PBO遇到 CALL SUBSCREEN 后执行子界面的PBO此时我们input01是我们刚才输入的值对吧,所以画面应该显示我们输入的值,然后程序会执行PBO剩余的MODULE此时就剩余了一个input01_set_value 这个MODULE我们又去给input01赋值了所以主界面就会显示我们在程序中赋值的那个值。这也就是为什么我们主界面和子界面会显示不同的内容的原因了,因为在执行主界面子界面PBO显示画面的时候我们input01本来就是不同的值。
在这里插入图片描述

                                                                                运行效果
在这里插入图片描述

                            反过来当我们在主界面输入值回车之后会有两种情况

                             情况三--- 1 当子界面输入框为空时
                             在主界面输入框输入值回车之后也会发现这个值可以反应到子界面中去,这个原因可能是因为当子界面输入框值为空的时候并程序并不会去执行子界面的PAI因为子界面中的值并没有和程序中变量的值相互赋值的操作吧,所以input01会一直保持我们在主界面中输入的值,直到画面显示我们会发现子界面和主界面输入框的值是相同的。这个也只是我自己的猜测。主要还是以情况三— 2 为主吧。

                             情况三--- 2 当子界面输入框为有值时
                            在主界面输入框输入值回车之后也会发现这个值并不能反应到我们子界面当中去,这是因为当给主界面输入框输入值后我们先执行主界面的PAI此时input01应该会赋值为我们输入的这个值,但是下来又会执行子界面的PAI此时我们程序就会抓取子界面输入框中的内容这时input01又变为了子界面输入框当前的值,直到我们调用子界面PBO的时候这个值依然还是子界面的当前值,最后我们又在PBO中对input01赋值了 ”POBSETVAL“这个值, 这样就是主界面输入的值并不能反应到子界面中去,也就是子界面会保持它原本的值。

                       
p
                                                        运行效果
在这里插入图片描述
        总之主界面和子界面PAI和PBO的执行顺序就是先主后子,上述代码中其实我们在子界面的PAI、PBO中并没有写执行的MODULE,大家可以尝试在这些子屏幕的逻辑流中加入一些MODULE然后断点查看会更明显。
在这里插入图片描述

五、增加删除分页签

        增加和删除分页签其实很简单,只要我们理解了上面的代码就没有什么难度,删除其实就是直接删除掉其中一个分页签按钮即可代码可删可不删,只要不会触发到删除的那个Fctcode就行,增加的话也就是增加一个分页签按钮给它设置一个Fctcode再创建一个子屏幕,当触发增加了的这个Fctcode后去把相应的子屏幕放到我们这个分页签区域即可。

            a.增加

                       1.绘制分页签按钮以及属性设置
                            我们再增加一个查询的分页签,直接在主屏幕的Layout中绘制即可。它就是个按钮而已,我们绘制好按钮后双击按钮进行一些属性设置,我们可以双击原先自动创建的按钮进行参考设置即可。Name和Fctcode和之前的按钮命名规则保持一直,当然也可以随便命名,但是规则保持一直的话更易于维护。也符合编码习惯。
在这里插入图片描述

                       2.创建子屏幕
                            创建一个0104的子屏幕作为我们点击查询分页签按钮后调用的子屏幕。
在这里插入图片描述

                       3.功能代码编写
                            功能代码编写我们按照顺序添加即可,因为有之前自动生成的代码再加上我们已经理解了原先的逻辑代码,增加一个分页签的功能逻辑代码编写起来也会很容易,我们按照定义数据,PAI事件,PBO事件逐个编写代码即可,这样也就不会漏掉逻辑代码了。
                                                                                1.数据声明
在这里插入图片描述

                                                                                2.PAI事件
在这里插入图片描述
                                                                                3.PBO事件
在这里插入图片描述
                                                                                运行效果
在这里插入图片描述

            b.删除

                       删除我感觉没有必要做演示和解释了,怎么样创建的就怎么删除,根据自己需求调整即可,删除分页签按钮只需再绘制界面点击按钮之后点击键盘Delete即可,功能代码和创建的子屏幕想删就删吧无所谓。

六、根据不同分页签设置按钮状态

        通常我们程序在查询情况下保存按钮是灰色不可用的,创建和修改界面保存按钮才是可以使用的,所以这里给大家解释一下怎么样实现点击不同分页签设置不同的按钮状态。按照最简单的逻辑我们应该是在不同的子界面下的PBO下执行设置按钮状态的MODULE点击创建的时候设置的按钮状态应该在设置按钮界面把保存要设置,点击显示分页签的时候设置的按钮状态应该在设置按钮界面把保存不要设置。也就是说我们这个程序是由多套按钮状态的。但其实这样是错误的。因为程序不允许我们在子界面中设置按钮状态,因为子界面中其实是不包含这些基础按钮的,它是存在于我们主界面下的。这也是我们主界面和子界面的一个最大区别,这些菜单标准工具栏Status的设置都是在主界面中使用设置并且相应的按钮功能也应该写在主界面下。但是如果你在子界面种绘制了按钮这个按钮的功能的判断是要写在子界面下的PAI中的。

            a.设置按钮

                       这里不详细描述创建过程具体可以看另外一篇文章
在这里插入图片描述

            b.逻辑代码实现

                       这里我们主要是通过设置按钮的语句 SET PF-STATUS 的后缀关键字 EXCLUDING来实现EXCLUDING的意思就是不包含的意思。这里我们会声明一个内表这个内表只有一个字段,只要我们将不想用的按钮名称添加进这个内表当中然后再配合EXCLUDING关键字即可设置不同的按钮状态。

  SET PF-STATUS '0100' EXCLUDING gt_status.

                       1.声明所需内表
在这里插入图片描述
                       2.逻辑代码编写
                            这个内表赋值的位置没有固定的地方,我们只需要在合适的时候调整内表的值就行了,我下面演示两种写法
                                                                                第一种

在这里插入图片描述

                                                                                第二种
在这里插入图片描述
                                                                                运行效果
在这里插入图片描述

七、根据不同分页签设置TITLEBAR标题

        通常我们点击了不同的分页签可能标题也会改变,比如点击了创建我们程序的标题就变为创建XXX,点击了显示标题就变为显示XXX。

            a.设置标题

                       标题我们已经刚才和按钮一起设置过了也叫“0100”。

            b.逻辑代码实现

                       这里我们主要是通过设置标题的语句 SET TITLEBAR 的后缀关键字 WITH来实现,其实WITH这个关键字在我们SAP消息中也是常用的,这里的用法也跟消息WITH的用法基本一样。

  SET TITLEBAR '0100' WITH GV_TITLE1 GV_TITLE2.

                       1.声明所需变量

在这里插入图片描述
                       2.调整TITLEBAR格式
在这里插入图片描述
                       3.逻辑代码
在这里插入图片描述
                                                                                运行效果
在这里插入图片描述

八、加深理解

        为了加深理解我们做一个奇怪的需求,我们在创建这个分页签的子界面中绘制一个检查按钮,当我们点击检查按钮后分页签自动切换到显示。这个需求我们会涉及到程序执行子界面下的PAI顺序逻辑流,也会对分页签如何调用相应的子屏幕有更深的理解。

            a.绘制按钮

                       不过多赘述,记得是在0101“创建“的子屏幕绘制,记得设置Fctcode就行。
在这里插入图片描述

            b.需求实现思路

                       按照自动生成的代码逻辑来看,我们只需要在下图中红框做做手脚就行了,只需点击检查按钮的时候也这样赋值即可调用0103”显示“子界面了,那么下图为什么能走到15行G_TS_CTRL-PRESSED_TAB = C_TS_CTRL-TAB3.这是因为点击了显示的分页签按钮后sy-ucomm的值是TS_CTRL_FC3。所以我们实现的思路很简单点击了检查按钮后在子界面下的PAI中给sy-ucomm赋值 TS_CTRL_FC3 即可。但其实这样是不能实现这个功能的,在逻辑上是走得通的,这是因为sy-ucomm是一个系统变量,我们给它赋值之后它又会在程序运行的过程中变为系统变量。所以需要用以下方案来实现。
在这里插入图片描述

                       1.代码实现
                            先直接看代码,稍后详细解释。其实也很好理解。
在这里插入图片描述
在这里插入图片描述
                       2.详细解释
                            这里我用主界面的顺序逻辑流解释。重点就是这里的13、14行,程序执行完13行里面的内容后就等于给gv_judgecheck变量赋值了也就是执行完了我们子界面下的PAI,14行因为我们给这个变量赋值了,所以14行在给g_ts_ctrl-pressed_tab赋了显示按钮的Fctcode,导致在执行PBO画面显示前调用了0103"显示"的这个子界面。这里我们很明显的看到了子界面下PAI的一个执行过程。
在这里插入图片描述

九、总结

        以上就是今天要讲的内容,本文仅仅简单介绍了分页签控件,感觉笔者讲的好对自己有帮助的还麻烦点个免费的赞赞制作不易谢谢谢谢!!!如果有说错或者不好的地方还望大家提出来见谅。感觉笔者写的好的别忘了关注点赞加评论哦,也欢迎大家一起来讨论。谢谢!

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiao贱贱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值