SAP屏幕开发之Table Control表格控件


前言

      这篇文章给大家介绍一下SAP Dialog程序中 Table Control控件,这个控件在我们SAP中也是很常见的,比如激活时显示的待激活的item就用了Table Control控件做显示,对于屏幕开发没有任何基础的读者请先看笔者另外两篇文章,SAP屏幕开发基础 SAP屏幕开发小案例 这篇文章笔者会省去程序创建等一些操作。


一、案例介绍

        这个案例我们会在屏幕中绘制一个表格控件,讲解自动生成代码的运行逻辑,会解释不可修改与可修改表格的区别,以及表格如何增加删除列,如何控制指定单元格可修改,还有表格中的一些光标位置计算、按钮的控制事件的掌握。


二、绘制Table Control

        绘制Table Control和绘制分页签一样都有两种方式一种是完全自主编写代码一种是根据向导创建自动生成代码。我们一般用的就是根据向导创建,这里也只讲解根据向导如何创建绘制。

            a.绘制

                       1.在Screen Painter中绘制控件
                            绘制之前先创建一个参考的内表在向导步骤中会用得到,记得声明完内表激活。
在这里插入图片描述

                       2.根据向导创建
                            跟着图片一步一步创建即可,有些功能先暂时不用,后面会再讲到的。我们先弄个最简单的看看。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

                       3.调整表头
                            根据向导创建完之后我们需要将表头的文字调整一下。如下图所示逐个点击修改。当我们想调节栏位宽度的时候应该是点击输入框拖动而不是上方的表头,表头这块就是个文本描述它这个宽度是跟着我们下方输入框的宽度变化的。这里的核心是输入框这一列都用的是同样的属性
在这里插入图片描述

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

            b.取数到表格

                       1.在PBO层面进行取数
                            上面步骤的运行效果是没有数据的原因就是我们没有取数到内表所以这里我们在PBO下进行取数。
在这里插入图片描述
                       2.se16n查表 和 运行效果

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

三、生成代码解释

        根据向导创建完之后我们程序会在各模块为我们自动创建一些代码,我们将这些代码搞清楚之后才能灵活运用和修改Table Control这个控件。

            a.TOP数据定义

在这里插入图片描述

                       1.第10行

CONTROLS: TC_CTRL TYPE TABLEVIEW USING SCREEN 0100.

                            这段代码意思就是在哪个屏幕编号中创建Table Control这个控件。有了TC_CTRL这个常量我们才能对表格进行显示等等一系列操作。
                       2.第13行

DATA:     G_TC_CTRL_LINES  LIKE SY-LOOPC.

                            声明变量G_TC_CTRL_LINES指的是我们在进行一个循环的时候所对应的当前行,例如 第2行、第3行、第5行这样的意思。

            b.PBO事件

在这里插入图片描述
                       1.第 5 行对应的MODULE

在这里插入图片描述
                            第5行的这个 MODULE 是去设置了Table Control控件 的一些属性,双击这个MODULE跳转查看,可以发现它是为了描述这个Table Contro有几行,也就是说我内表有5行tc_ctrl-lines这个属性也就为5行,内表为10行tc_ctrl-lines这个属性也就为10行。DESCRIBE这个关键字我们也可以按F1查看它的使用方法,就是可以获取内表行数。

                       2.第 7 行LOOP循环中的MODULE

在这里插入图片描述
                             这个循环做的事情是循环内表GT_SCHOOL到结构GS_SCHOOL 然后WITH CONTROL到我们创建的Table Control控件以上代码的字面意思理解起来就是我用Table Control这个控件来循环展示我这个内表,然后是CURSOR TC_CTRL-CURRENT_LINE 意思就是循环GT_SCHOOL这个内表在当前行做显示,在最后的这个MODULE做的是我表格一共有多少行将这个行数赋值给g_tc_ctrl_lines,注意不是内表的行数而是表格的行数也可以理解为表格显示的大小有多高。按照我上面的运行效果LOOPC这个参数应该是14。因为表格一共有14行。这个MODULE 在这里的作用是在用户与Table Control互动后获取并存储当前显示的行数,以便程序的其他部分可以使用这些信息进行进一步的处理或逻辑决策。

            c.PAI事件

                       PAI这块执行的代码就是当用户进行了输入回车或者点击了某些按钮触发了Fctcode之后执行的代码
在这里插入图片描述
                       1.第 19 行的LOOP循环
                             这块的循环中的核心就是有一个CHAIN,这个在之前的文章也提过了是批量检测输入框值变化的关键字,但是仔细观察可以发现CHAIN后面是没有MODULE的,没有MODULE就意味着没有意义,在我们当前这个程序中其实也可以删掉的,这是因为我们创建的Table Control控件是只输出的,不能修改的。

                       2.第 29 行对应的MODULE

在这里插入图片描述

                             我们双击进来查看这个MODULE可以发现它对OK_CODE与系统变量有个赋值的过程,主要还是看这个USER_OK_TC子程序,双击跳转到F01的包含程序查看,可以发现它是对Table Control控件中按钮功能的一些处理。

四、增加删除列

        

            a.增加

                       增加我们有两种方法,一种就是删除当前创建的Table Control重新参考内表根据向导创建,还有一种就是在当前基础上调整参考内表的字段。然后再去Screen Painter中绘制一列,我们在这里使用后者,现在来给我们当前这个Table Control控件增加一列叫“序号”的字段。
                       1.给内表增加字段
                             之前我们是直接参照数据库表声明的内表,现在我们使用TYPES关键字创建一个符合我们要求的类型来声明内表。或者使用DATA BEGIN OF配合INCLUDE来直接创建出符合要求的内表,总之就是要给这个内表加上一个序号的字段。
在这里插入图片描述
                       2.给序号这个字段赋值
                             我们直接在取数完成之后使用LOOP循环对SEQ序号这个字段进行赋值。
在这里插入图片描述
                       3.在Screen Painter中绘制增加的列
                             绘制插入列的时候要在控件里面点击不能超出控件不然就绘制失败了,如果没绘制上我们继续点击Get from Program重新获取一遍参考对象即可。
在这里插入图片描述
在这里插入图片描述
                             调整新增列的属性与表头,我们新增的列属性需要和我们其他列属性保持一致,也调整为不可输入,Name就和字段名保持一致。
在这里插入图片描述
                       4.运行效果

在这里插入图片描述
                       5.检测字段变化
                             这里我们也在PAI下的CHAIN中加入我们添加的字段,虽然在当前的这个程序中这个CHAIN是没有用的,但是如果这个Table Control调整为可修那么没有这个字段可能会出问题的,这样也是一个比较好的编码习惯。
在这里插入图片描述

            b.删除

                       删除的话这里不过多介绍,只需要在Screen Painter中点击输入框注意不是点击表头然后再点击Delete即可删除,然后注意事项就是我们绘制有几列,PAI下面LOOP循环的CHAIN就有几个字段,不然激活会报错。这是因为我们CHAIN去检测的字段根本不存在于表格中了。

五、可修改的Table Control

        我们要将Table Control调整为可修改的状态可以在我们刚才做的基础上进行调整,先去Screen Painter 中将每列的属性改为可输入状态,然后再运行查看效果,也可以重新根据向导直接创建一个可修改的Table Control。

            a.调整之前的Table Control

                       1.调整每列属性
                             这里其实只是为大家做一个演示,最终并不会将我们刚才的Table Control调整为可修改状态。
在这里插入图片描述

                       2.调整取数逻辑
                             这里要将取数逻辑进行调整当我们内表为空的时候再进行取数,这样就可以防止我们内表数据重新填充了,就不会影响我们对数据的测试了。
在这里插入图片描述
                       3.运行效果
                             可以看到我们已经可以对表格数据进行修改输入了,但是当我们修改调整数据之后回车,发现数据又会恢复,这就是因为我们 PAI 中LOOP CHAIN 并没有执行的 MODULE 去更改内表的值,我们也可以自己编写这块的数据修改逻辑MODULE然后加在CHAIN里面,但是这里我就不做演示了。我们接下来会根据向导创建可修改的Table Control,然后再进行代码对比查看不同点。
在这里插入图片描述
在这里插入图片描述

            b.创建可修改的Table Control

                       我们现在创建一个可以修改的Table Control 并在左侧添加上选择框,然后将Table Control的所有的按钮都设置出来。我们可以在当前程序重新创建一个屏幕然后把T-code调用的屏幕也设置成新创建的屏幕再重新创建一些包含程序出来,这样就跟之前的案例不混淆了,或者直接新创建一个新的Dialog程序也可以。

                       1.创建 屏幕、包含程序、修改T-code
                             这里省略详细创建步骤。

在这里插入图片描述

                       2.声明数据内表
                             因为这次我们需要显示左侧的选择框所以还需要一个字段。我们再到之前内表的基础上添加一个CHECK字段。
在这里插入图片描述

                       3.根据向导创建Table Control
                             这里只指出和上面案例不一样的地方。其余步骤省略。
在这里插入图片描述
                       4.调整表头与取数
                             和上面的案例一样,我们需要将表头文字调整还有表格宽度并且在PBO进行取数。记住取数的时候不要取错内表了。
在这里插入图片描述
在这里插入图片描述

                             修改表头文本的地方也可以在Element list中修改。
在这里插入图片描述

                       5.运行效果
                             现在我们可以修改表格中的数据再回车可以发现数据已经可以保留住了。
在这里插入图片描述

            c.可输入不可输入Table Control代码对比

                       可输入表格在代码属性上和不可输入的表格是有区别的,然后最主要的就是程序是如何将数据保留到内表当中去展现在页面当中的。

                       1.相同部分

                             TOP、PBO自动生成的代码是一样的。
                            
                            
                            
                       2.不同部分
在这里插入图片描述
                             PAI中的这个LOOP循环是多了两行可执行的MODULE,首先看第28行:也就是说当我们CHAIN中的某一个字段发生变化时程序都会去执行TC_CTRL01_MODIFY这个MODULE。这个MODULE执行的内容也就是根据我们屏幕最新的数据修改了我内表的当前行,如下图所示。所以这就是为什么可以保留住数据的原因了。
在这里插入图片描述

                             下来我们在看第二个MODULE第31行:这个MODULE是当CHECK值发生变化的时候才会去执行的,我们双击进去查看可以发现它就是为了更新内表当中的CHECK字段的,如下图所示,这里17行有一个判断的逻辑,TC_CTRL01-line_sel_mode 是Table Control控件的一个属性代表的是选择模式也就是们在向导创建过程中选择了Single的话这个值就会为 1 如果选择了Multiple的话就为 2,当设置选择的是Single模式的话也就是只能选择一行程序会进入判断循环已选中的行并设置CHECK字段为空等于清空了之前的选择状态。最后会根据当前行修改内表CHECK的值,这样就确保实现了单行选择。当设置选择的是Multiple的话就直接根据当前循环的行修改内表即可不会进入判断的逻辑。
在这里插入图片描述

            d.Table Control的按钮异常

                       好久之前的版本好像有这样一个BUG大家作为了解即可,先点击插入按钮插入一行,然后再敲击回车我们会发现也会再插入一行,或者点击滚动条的上下按钮也会插入一行,那么这样就是有问题的,按钮功能混乱了,这是因为回车还有滚动条这些操作也会触发PAI事件,但是这些操作并不会给SY-UCOMM这个系统变量重新赋值,回车滚动条这些事件并没有一个显性的Fctcode,所以当我们回车的时候SY-UCOMM还是依然保持着我们INSERT这个Fctcode所以程序依然会插入一行。

                       1.解决方案
                             再定义一个OK_SAVE变量,我们需要巧妙的将这个变量置于SY-UCOMM和OK_CODE之外,就如下图所示,如果我们点击了BACK按钮后程序会给OK_SAVE这个变量赋值正确的Fctcode,然后会清空SY-UCOMM和OK_CODE,这相当于我们这次的操作将系统变量保存到了OK_SAVE中让程序这次可以正常执行,然后当我们再点击回车的时候,因为之前已经对SY_UCOMM进行了清空所以OK_SAVE这次被SY_UCOMM赋值的时候也就被赋值为空了。这样就解决了这个BUG。这样修改之后同样的Table Control控件的按钮功能也就不会混乱了。因为程序退出的时候对SY-UCOMM做了清理。
在这里插入图片描述

            e.Table Control存储数据异常

                       现在我们取消掉PBO的取数到内表的MODULE,然后运行程序直接输入数据再回车,此时会发现我们输入的数据是无法保留到表格当中的,这是因为再执行修改内表的语句时因为索引问题修改失败了。下面我们会详细说明原因并给出解决方法。

                       1.取消PBO取数
                             取消掉PBO取数到内表后我们会发现运行程序整个表格为空,整个表格也都是可以修改状态,并没有灰色不能输入的行。并且在我们输入数据并回车之后发现数据是保留不住的。
在这里插入图片描述

                       2.详细原因
                             输入数据后,我们可以 /H 打断点,然后再回车触发PAI事件看一下,为什么会修改失败。
在这里插入图片描述

                             按F5一直到28行进入修改内表的MODULE
在这里插入图片描述

                             然后我们插入SY-SUBRC系统变量根据程序运行随时观察,这里可以看到表格中的数据是刷新到了我们的结构当中的,但是我们的内表目前还是空的,TC_CTRL01-CURRENT_LINE为1,也就是这段代码会根据结构修改第一行的数据,可是我们内表当前根本就没有第一行所以可以看到会修改失败SY-SUBRC也是4了,这样就是我们回车后数据为什么不能保留在表格中的原因。
在这里插入图片描述

                       3.解决方法 运行效果
                             其实我们可以先点击插入按钮插入一行,然后在进行数据的修改增加,但是用户一般可不会去这么做,用户运行了这个程序之后一上来看是一个空表格就会直接输入数据了,所以这是不符合用户习惯的,我们的解决方法就是在合适的位置给内表默认插入一行即可。
在这里插入图片描述

六、在Dialog程序中用代码插入选择界面

        要实现这样的功能我们需要使用到子界面控件,在我们想要插入的屏幕编号中绘制一个子屏幕,然后再将代码生成的选择屏幕放置在绘制的子界面中。下面这个案例我们将使用代码生成一个选择屏幕用户输入值之后可以在Table Control中显示符合条件的数据。

            a.屏幕绘制

                       首先在0200屏幕中绘制一个子屏幕并且命名。
                       1.绘制子界面
                             命名尽量规范。
在这里插入图片描述

                       2.代码绘制选择屏幕
                             以下是用代码绘制了一个0201的屏幕,我将这些代码放在了TOP数据定义里面。接下来我们要做的就是将这个0201屏幕放入到我们上面绘制的子界面subscreen_0201当中去。
在这里插入图片描述                             用代码创建的这个屏幕可能你点刷新按钮后还是显示不出来但是你重新登陆一下系统应该就可以显示了,不过没即时显示的话也不会影响我们下面的操作的。

在这里插入图片描述

            b.代码逻辑编写

                       这块的逻辑代码编写和分页签控件有点像有兴趣的朋友可以看我另外一篇文章 屏幕开发之分页签 这篇文章详细解释了为什么要在PAI部分调用子界面。
                       1.PBO调用子界面
                             这块的代码其实也很好理解,意思就是将程序 ZTEST_SCREEN_GLYN004 当中屏幕编号为 0201 的屏幕调用放置在了我们子界面控件 subscreen_0201 当中。
在这里插入图片描述

                       2.PAI调用子界面
                             同样PAI也要写上这段代码,原因这里不多做解释有兴趣朋友可以看上面提到的另外一片文章。
在这里插入图片描述
                       3.取数逻辑编写
                             取数逻辑加入了Where条件,并且注释掉了内表为空的判断逻辑,不然会影响我们程序的运行效果。
在这里插入图片描述

                       4.运行效果
                             当我们在选择界面中输入值之后可以发现Table Control能显示我们所符合条件的数据。
在这里插入图片描述

七、Table Control 属性的设置

        在我们Table Control控件中有许多属性的,像可修改与只输出、左边选择框的选择模式、等等。下面我们做几个修改input属性的案例。

            a.变更列的可修改状态

                       以下我们实现一个功能,绘制一个按钮然后点击此按钮可以实现我们培训信息列的可修改或者不可修改状态。
                       1.绘制按钮
                             我们在Table Control底部绘制了一个按钮叫"培训信息列可修改/不可修改",并且给了一个Fctcode为 mod_info
在这里插入图片描述

                       2.查看Table Control属性信息
                             我们可以 /H 打断点然后再触发PAI事件,将我们程序参考 TABLEVIEW 的变量输入到Debug界面就可以查看这个变量也就是我们Table Control控件的一些属性信息了。
在这里插入图片描述
在这里插入图片描述
                             TC_CTRL01 变量它是一个纵深的数据可以看到有标注deep,上面我标注了个别属性字段的意思,这个TC_CTRL01包含有一个内表叫COLS,在这个案例中我们主要控制这个内表来实现。我们可以双击这个内表进去再查看。这个内表中有些许字段其中 INDEX 代表为第几列,还有一个特别中要的字段是 SCREEN,如果我们需要操作控件第一列的属性那么就去调整INDEX为1这行的SCREEN结构,这里我们调整的是最后一行所以我们设置INDEX为7的SCREEN结构的值就可以控制培训信息列的一些属性了。
在这里插入图片描述

                             SCREEN结构
在这里插入图片描述

                       3.逻辑代码编写
                             程序先判断用户点击的按钮Fctcode是否为 mod_info 然后调用子程序修改指定列的属性,子程序这块不过多解释大家看注释即可。
在这里插入图片描述

                       4.运行效果
                             当我们点击”培训信息列可修改/不可修改“按钮时我们可以发现第7列会在可修改与不可修改状态之间来回切换。
在这里插入图片描述

            b.变更单元格的可修改状态

                       下来我们实现控制某个单元格的可修改状态和控制行的修改状态。这里我们就不做按钮了直接在PBO下面完成,当我们回车的时候触发PAI来查看效果。单元格和行的可修改属性的调整就和我们上面所说的有点不一样了,首先我们需要确定更改的行,这我们用CHECK也就是那个选择框按钮来确定某行,然后再用表格控件的列字段名就可以精确到某个单元格了。那么都能精确到某个单元格了肯定也就可以实现整行的属性状态修改了。

                       1.将所有列设为不可输入状态
                             我们在先将所有列调整为不可输入状态,这样再根据用户选择的那行再将选择行的指定单元格设置为可输入状态。
在这里插入图片描述

                       2.逻辑代码编写
                             这里我们直接在PBO循环展示数据中写一个MODULE,这个MODULE作用就是循环到CHECK为 X 的行就对 SCREEN 内表进行修改,来达到修改界面控件属性状态的效果。代码这里不多解释直接看注释即可。
在这里插入图片描述

                             要注意取数的部分不能重复取数,不然会覆盖掉我们已经在PAI部分对CHECK字段的赋值。CORRESPONDING FIELDS会将内表中不存在于透明表的字段覆盖掉。这样就会导致我们判断CHEKC字段异常无法达到想要的效果,这里我们就做简单的处理就不要重复取数即可,但是实际开发中要考虑到其他问题。
在这里插入图片描述

                       3.运行效果
                             当我们选中第5行后回车会发现第5行的性别单元格变为可修改状态,然后再选中其他行回车也会出现相同的效果并且原来可修改的状态栏也会恢复。这里程序有点小BUG,在选择屏幕第二次输入为空的时候数据就会取不到了,不过这都是小问题,这里不多解释了。
在这里插入图片描述

            c.变更行的可修改状态

                       上面我们都能精确控制某个单元格了那么控制行也就不难了,我们直接在上面的基础上进行调整,这里可以在修改SCREEN内表的时候对每个输入框的name进行判断,也可以去给这些输入框进行分组再判断。

                       1.判断每个输入框的name
                             这种方法就是简单粗暴,灵活多变。
在这里插入图片描述

                       2.输入框分组判断
                             分组代码会更简洁,但是如果需要调整的话就得去绘制界面重新调整分组了。
在这里插入图片描述
在这里插入图片描述

                       3.两种方式运行效果是相同的
                            
在这里插入图片描述

八、Table Control 光标位置计算

        在我们Table Control控件中有好多关于光标位置以及当前所循环的行位置这些属性,像TOP_LINE这个属性代表的是我Table Control这个控件最顶部显示的是内表中的第几行,current_line就是我内表当前循环的行在PBO的LOOP循环显示数据中有用到。以下我们通过案例来理解加深这些行位置变量的变化。

            a.根据光标位置设定单元格属性

                       以下我们实现一个功能,当用户光标点击了某个单元格之后并回车就将此单元格设置为可修改状态。

                       1.获取光标位置以及字段名
                             获取光标位置和光标所在控件name名可以用GET CURSOR FIELD <fieldname> LINE <linenum> 其中 <filedname> 是控件name名称 <linenum>是光标在Table Control第几行。我们将获取光标位置所在信息的代码写在PAI下。
在这里插入图片描述

                       2.获取效果查看
                            我们将光标定位到第四行的NAME字段上并打断点回车触发PAI事件进行查看,这样看起来我们可以直接去根据获取到的GV_LINE和GV_FIELD去修改对应单元格的属性了,但其实这里有个很严重的问题当我们滑动滚动条之后 GV_FIELD 依然是正确的但是 GV_LINE 就不是我们光标所在位置的行了,上面我们也提过了 GV_LINE 是在Table Control控件中的第几行并不是我内表真实的第几行。
在这里插入图片描述

                            可以看到当我们滑动滚动条之后光标继续定位序号为4的行也就是内表的第4行,但是打断点查看 GV_LINE 已经不是我内表所在的第几行了而是Table Control控件中所在的第几行了。所以这里我们不能直接去用 GV_LINE 对相应单元格的属性进行修改。
在这里插入图片描述

                       3.计算光标真实位置
                            现在 TOP_LINE 是表格最顶部的内表所在行,也就是 TOP_LINE 显示的永远是内表正确的第几行。我们要根据 TOP_LINE 这个行来用相对位置计算出光标所在内表的第几行。公式为 TOP_LINE + GV_LINE - 1 下图我给出了计算例子。
在这里插入图片描述

                       4.逻辑代码编写
                            我们上面已经在PAI下获取到了 GV_LINE 的值还有输入框的 name ,现在到PBO下面判断如果循环的当前内表行与我光标所在的真实内表行一样的话就进行单元格属性的修改。循环的内表当前行的值:在PBO里面已经有了就是tc_ctrl01-current_line它是Table Control的一个属性,光标所在内表真实行:是我们根据上面公式计算出来的,有了这两个值我们就可以判断是否要修改当前循环行单元格的属性了。代码我们依然写在之前根据CHECK字段更改行属性的MODULE中,代码逻辑具体看注释。
在这里插入图片描述

                       5.运行效果
                            可以看到我们光标不管在哪个单元格并且按下回车就可以变为可输入状态了。
在这里插入图片描述

九、总结

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

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xiao贱贱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值