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:a€?@01@a€?那么就會不能輸入(整行變灰色),如果沒有標示位,則正常。由于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.
覺得還是有點復雜吧,但是能看明白,卻說不明白。
總結
以上是生活随笔為你收集整理的ABAP 的TABLE CONTROL实践积累的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Screen返回选择界面的问题
- 下一篇: SAP 4.6C升级ECC6.0 WS_