zoukankan      html  css  js  c++  java
  • ABAP 的TABLE CONTROL实践积累

    TABLE CONTROL 是一个结构,

    假设我们定义的TC名称为  ZTEST_TC (具体结构参照:SCXTAB_CONTROL)

    那么我们定义ZTEST_TC-CURENT_LINE ,ZTEST_TC-LINES 等等都有意义,我们可以将其理解为一个DEEP STRUCTURE.

            General TC attributes: |                      Column attributes

     1.FIXED_COLS LINES TOP_LINE CURRENT_LINE.... | COLS   INDEX SELECTED VISLENGTH INVISIBLE..

                                                    |

     2.                                           SCREEN   

                                                    

     3. NAME GROUP1 ... GROUP4 REQUIRED INPUT OUTPUT INTENSIFIED..INVISIBLE LENGTH ACTIVE DISPLAY_3D VALUE_HELP REQUEST...

     1是一个整体的TABLE CONTROL结构

     2是 ZTEST_TC-COLS的结构内容 也就是我们经常用的LOOP AT SCREEN. ... ENDLOOP.

     3.是SCREEN结构的属性。

    那么这些有什么用呢?

    一、现在需求如下(我在实际项目中接触到的实例):

    通过选择屏幕,将数据库表A的内容显示出来,A有一个审批字段,如果这个审批字段是对勾(CHAR4 (ICON_D) 类型字段 存储内容: @01@ 就自然被系统装换成对勾显示了 ),那么这些数据在TABLE CONTROL中试灰色的,新添加的没有被审批的数据,就可以修改。

    拿导航生成代码为例:PBO

    我自定义TC输出内表名称为 T_ZTEST 工作区 WA_ZTEST

      PROCESS BEFORE OUTPUT.
    *&SPWIZARD: PBO FLOW LOGIC FOR TABLECONTROL 'ZTEST_TC'

      MODULE ZTEST_TC_CHANGE_TC_ATTR.
    *&SPWIZARD: MODULE ZTESTTC_CHANGE_COL_ATTR.
      LOOP AT   T_ZTEST
           INTO WA_ZTEST
           WITH CONTROL ZTEST_TC
           CURSOR ZTEST_TC-CURRENT_LINE .
        MODULE ZTEST_TC_GET_LINES.
    *&SPWIZARD:   MODULE ZTESTTC_CHANGE_FIELD_ATTR
      ENDLOOP.
      MODULE STATUS_8000.

     

     最开始接触ABAP的时候,看到有这样的一个LOOP语句我发蒙了。除了在PBO里面,在其他地方使用不了的。

    在这里,我们将 我们在屏幕的上显示的数据 每一行LOOP 进工作区中WA_TEST.

    WITH CONTROL ZTEST_TC 说明了这个LOOP的过程是要和TC绑定LOOP的 CURSOR ZTEST_TC-CURRENT_LINE 。通过我上面罗列的结构为基础,我们进去 MODULE ZTEST_TC_GET_LINES中,添加一段代码:

    LOOP AT SCREEN.

    IF SCREEN-NAME CS 'WA_ZTEST' AND WA_ZTEST-STATUS EQ '@01@'.

    IF SY-SUBRC EQ 0.

    SCREEN-INPUT EQ 0.

    MODIFY SCREEN.

    ENDIF.

    ENDIF

     CURSOR 是光标在控件中的位置,这时候光标所处的位置为,LOOP的当前行的数据。

     整个逻辑如下: 首先 我们LOOP 内表一条数据,然后和TC绑定.随后LOOP AT SCREEN. 这个时候,TC只会操作CURRENT_LINE这行的属性。如果这行的标识位为 mailto:‘@01@’那么就会不能输入(整行变灰色),如果没有标示位,则正常。由于CURSOR的作用,TC的每行属性是逐行操作的。

    二、如何得到TC中更新的数据.(TC-> TABLE CONTROL)

    在PAI的 模板代码中加了些代码。

       LOOP AT T_ZTEST.
        CHAIN.
          FIELD WA_ZTEST-VKORG.
          FIELD WA_ZTEST-VKBUR.
          FIELD WA_ZTEST-KUNNR MODULE KUNNR_TEXT ON INPUT.
          FIELD WA_ZTEST-MATNR MODULE MATNR_TEXT ON INPUT.
          FIELD WA_ZTEST-ZYEAR.
          .......
          MODULE ZHGXS_XSJH_TC_MODIFY ON CHAIN-REQUEST.
        ENDCHAIN.

          FIELD WA_ZHGXS_XSJH-SEL
          MODULE ZHGXS_XSJH_TC_MARK ON REQUEST.

       ENDLOOP.

         

     

    FIELD .... MOUDLE ...ON INPUT 就是那个字段不为空,会触发这个ON INPUT ...MODULE

    当有了INPUT操作后,会触发 MODULE.... ON REQUEST(响应MODULE).  

    还有:MODULE ZHGXS_XSJH_TC_MODIFY ON CHAIN-REQUEST.

    这个MOUDLE的作用,在触发PAI后,要是被CHAIN。。ENDCHAIN的数据只要有改变,TC会触发这个MODULE,然后更新最新当前行的最新值。
    源代码如下    MODIFY T_ZTEST
                 FROM WA_ZTEST  INDEX ZTEST_TC-CURRENT_LINE.

    所以我们利用这个地方,巧妙的定义一个用来存储更新数据的内表,然后

    MODIFY 更新内表统计
                 FROM WA_ZTEST  INDEX ZTEST_TC-CURRENT_LINE.

    这样所有改变后值得数据都会在这个内表出现,

    DECRIBE 内表就知道更新多少行了。

    对于TC的内表,永远是操作后的数据,非常准确。

    因为他的每一个PAI都要出发LOOP 并且MODIFY改变值 原来的内表.

    那么就要有一个疑问了,删除行时候,会怎样呢?

    假设我使用的是导航本身生成的 - (删除行)操作,那么在PAI的时候,虽然在我们看来这行数据没有了,然是,PAI的LOOP检查会触发 一个MARK 标识位的操作,然后将内表的SEL打上X。当程序流走到PAI的INSR控件触发的事件时候,将SEL = 'X'的数据从内表删除。

    所以PAI 的 CHAIN只会对存在的 操作前的数据进行LOOP,不会减少内表数据。主要的精华都在于

    MODULE .... ON REQUEST的控制了。

    三。对一些TABLE CONTROL的经典动态代码进行分析。

        FIELD-SYMBOLS <TC>                 TYPE CXTAB_CONTROL.
       FIELD-SYMBOLS <TABLE>              TYPE STANDARD TABLE.
       FIELD-SYMBOLS <LINES>              TYPE I.
    *&SPWIZARD: END OF LOCAL DATA------------------------------------------*

       ASSIGN (P_TC_NAME) TO <TC>.

    *&SPWIZARD: get the table, which belongs to the tc                     *
       CONCATENATE P_TABLE_NAME '[]' INTO L_TABLE_NAME. "table body
       ASSIGN (L_TABLE_NAME) TO <TABLE>.                "not headerline

    *&SPWIZARD: get looplines of TableControl                              *
       CONCATENATE 'G_' P_TC_NAME '_LINES' INTO L_LINES_NAME.
       ASSIGN (L_LINES_NAME) TO <LINES>.

    *&SPWIZARD: get current line                                           *
       GET CURSOR LINE L_SELLINE.
       IF SY-SUBRC <> 0                  append line to table
         L_SELLINE <TC>-LINES 1.
    *&SPWIZARD: set top line                                               *
         IF L_SELLINE <LINES>.
           <TC>-TOP_LINE L_SELLINE <LINES> 1 .
         ELSE.
           <TC>-TOP_LINE 1.
         ENDIF.
       ELSE                              insert line into table
         L_SELLINE <TC>-TOP_LINE L_SELLINE 1.
         L_LASTLINE <TC>-TOP_LINE <LINES> 1.
       ENDIF.
    *&SPWIZARD: set new cursor line                                        *
       L_LINE L_SELLINE <TC>-TOP_LINE 1.

    *&SPWIZARD: insert initial line                                        *
       INSERT INITIAL LINE INTO <TABLE> INDEX L_SELLINE.
     
     

    一些ABAP的动态操作,可复用性代码都是这么写的。

    FIELD-SYMBOLS <TC>                 TYPE CXTAB_CONTROL.
     

        ASSIGN (P_TC_NAME) TO <TC>.

    充分说明了 我自定义的TC 是一个结构。我将我自定义的TC名称,这时候声明一个引用,也就是TC的别名。

    然后我就可以使用<TC>进行操作了。

    插入操作和当前自己的光标位置相关,然后

    INSERT INITIAL LINE INTO <TABLE> INDEX L_SELLINE. 

    SET CURSOR FIELD L_SELLINE.

    觉得还是有点复杂吧,但是能看明白,却说不明白。

  • 相关阅读:
    Scss支持多主题切换的方案实现
    一探前端开发中的JS调试技巧
    【基础】CSS居中的15种方式
    代码打开输入法的手写功能
    谷歌使用navigator.mediaDevices.getUserMedia 调用摄像头拍照功能,不兼容IE
    VUE中使用canvas做签名功能,兼容IE
    vue项目放在IE上页面空白的问题
    element-ui中使用el-radio单选切换表格
    vue中使用canvas绘制签名
    简单使用vuex状态管理
  • 原文地址:https://www.cnblogs.com/elegantok/p/1545714.html
Copyright © 2011-2022 走看看