1. 程式人生 > >ABAP表控制Table Control設計

ABAP表控制Table Control設計

表控制(Table Control)是SAP應用中最重要的物件之一,業務單據的輸入、基礎資料的表格輸入等都是使用Table Control控制元件,本章主要介紹:
(1)在螢幕設計中通過嚮導來製作表控制元件物件,由系統生成程式;
(2)非嚮導設計Table Control控制元件;
(3)通過系統生成資料表維護程式,並在程式中呼叫;
(4)表格設計技巧;
(5)通過表格維護變更內表資料,並將內表資料提交資料庫。

1、使用嚮導製作Table Control

本節先建立一個內表,通過嚮導建立一個表格控制元件使用該內表。

1.1、建立程式

先建立程式,定義內表,螢幕有退出按鈕,主程式程式碼如下

REPORT  YTEST20160615002.

DATA: OK_CODE TYPE SY-UCOMM,
      SAVE_OK LIKE OK_CODE.

*定義內表,注意兩種寫法一樣
*DATA SH1 LIKE YTJAYSCHOOL OCCURS 0 WITH HEADER LINE.
DATA SH1 LIKE TABLE OF YTJAYSCHOOL WITH HEADER LINE.
*增加內表資料
SELECT * INTO CORRESPONDING FIELDS OF TABLE SH1 FROM YTJAYSCHOOL.

*測試輸出資料
LOOP AT SH1.
  WRITE:/ SH1-YCT_ID, SH1-YSH_ID, SH1-YSH_NAME, SH1-YSH_ADDR.
ENDLOOP.

*直接呼叫視窗
CALL SCREEN 100.

*使用者互動
MODULE USER_COMMAND_0100 INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.
*退出按鈕時退出程式
  CASE SAVE_OK.
    WHEN 'CANCEL'.
      LEAVE PROGRAM.
    ENDCASE.
ENDMODULE.

MODULE STATUS_0100 OUTPUT.
  SET PF-STATUS 'STATUS1'.
ENDMODULE.
邏輯流程式
PROCESS BEFORE OUTPUT.
 MODULE STATUS_0100.

PROCESS AFTER INPUT.
 MODULE USER_COMMAND_0100.

1.2、使用嚮導建立Table Control控制元件

啟動螢幕編輯器,選“表控制元件”按鈕,在螢幕上建立該物件後,系統自動導航介面,如圖


輸入Table Control的名稱,繼續


選擇從內表建立,輸入內表名稱SH1(在主程式中已建立該內表)


如果程式沒有啟用,會提示需要啟用,此時再開啟一個SESSION啟用程式,此前我們已經啟用該程式。

選擇表字段,繼續


選擇表格控制元件能輸入(Input control)、有表頭(With column headers)、單選紀錄(Single)


設定屬性無滾動條,繼續


維護生成程式的名稱,使用預設的名稱


單擊“完成”按鈕,完成設計


完成後,設計介面如圖


選擇主程式並執行,系統輸出如圖


嚮導生成的Table Control物件已經能夠正常地瀏覽資料。
分析生成的程式碼
主程式程式碼如下:

REPORT  YTEST20160615002.

DATA: OK_CODE TYPE SY-UCOMM,
      SAVE_OK LIKE OK_CODE.

*定義內表,注意兩種寫法一樣
*DATA SH1 LIKE YTJAYSCHOOL OCCURS 0 WITH HEADER LINE.
DATA SH1 LIKE TABLE OF YTJAYSCHOOL WITH HEADER LINE.
*增加內表資料
SELECT * INTO CORRESPONDING FIELDS OF TABLE SH1 FROM YTJAYSCHOOL.

*測試輸出資料
LOOP AT SH1.
  WRITE:/ SH1-YCT_ID, SH1-YSH_ID, SH1-YSH_NAME, SH1-YSH_ADDR.
ENDLOOP.

*直接呼叫視窗
CALL SCREEN 100.

*使用者互動
MODULE USER_COMMAND_0100 INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.
*退出按鈕時退出程式
  CASE SAVE_OK.
    WHEN 'CANCEL'.
      LEAVE PROGRAM.
    ENDCASE.
ENDMODULE.

MODULE STATUS_0100 OUTPUT.
  SET PF-STATUS 'STATUS1'.
ENDMODULE.

*&SPWIZARD: DECLARATION OF TABLECONTROL 'TBL' ITSELF
CONTROLS: TBL TYPE TABLEVIEW USING SCREEN 0100.

*&SPWIZARD: OUTPUT MODULE FOR TC 'TBL'. DO NOT CHANGE THIS LINE!
*&SPWIZARD: UPDATE LINES FOR EQUIVALENT SCROLLBAR
MODULE TBL_CHANGE_TC_ATTR OUTPUT.
  DESCRIBE TABLE SH1 LINES TBL-lines.
ENDMODULE.

*&SPWIZARD: INPUT MODULE FOR TC 'TBL'. DO NOT CHANGE THIS LINE!
*&SPWIZARD: MODIFY TABLE
MODULE TBL_MODIFY INPUT.
  MODIFY SH1
    INDEX TBL-CURRENT_LINE.
ENDMODULE.
邏輯流程式碼如下:
PROCESS BEFORE OUTPUT.
*&SPWIZARD: PBO FLOW LOGIC FOR TABLECONTROL 'TBL'
  MODULE TBL_CHANGE_TC_ATTR.
*&SPWIZARD: MODULE TBL_CHANGE_COL_ATTR.
  LOOP AT   SH1
       WITH CONTROL TBL
       CURSOR TBL-CURRENT_LINE.
*&SPWIZARD:   MODULE TBL_CHANGE_FIELD_ATTR
  ENDLOOP.

 MODULE STATUS_0100.
*
PROCESS AFTER INPUT.
*&SPWIZARD: PAI FLOW LOGIC FOR TABLECONTROL 'TBL'
  LOOP AT SH1.
    CHAIN.
      FIELD SH1-YCT_ID.
      FIELD SH1-YSH_ID.
      FIELD SH1-YSH_NAME.
      FIELD SH1-YSH_ADDR.
      MODULE TBL_MODIFY ON CHAIN-REQUEST.
    endchain.
  ENDLOOP.
*&SPWIZARD: MODULE TBL_CHANGE_TC_ATTR.
*&SPWIZARD: MODULE TBL_CHANGE_COL_ATTR.

 MODULE USER_COMMAND_0100.

2、手工製作Table Control

先建立一個有退出按鈕的程式,進入螢幕編輯器,選中控制物件,並在螢幕上建立


建立的物件顯示粉紅色,表示屬性未設定正確。輸入名稱屬性後,表頭會轉為灰色。表格的建立與常規程式設計軟體不同,需要選中一個輸入輸出欄位,然後在表身建立

輸入名稱後整個表格都轉為灰色(表示已設定正確)。調整輸入欄位的其他屬性,如圖


手工調整欄位名稱和內表對應的名稱一致後,第一個欄位建立完成,然後為該欄位加上表頭,製作方式和輸入欄位一樣,選中一個文字欄位,建立在該欄位上方的表頭


接著建立等資訊,並新增垂直水平分格符,完成後如圖


邏輯流程式如下

PROCESS BEFORE OUTPUT.
 MODULE STATUS_0100.
*處理LOOP從內表讀到表控制
 LOOP WITH CONTROL TBL1.
   MODULE FILLTBL1.
 ENDLOOP.

PROCESS AFTER INPUT.
*處理LOOP從表控制更新內表
 LOOP WITH CONTROL TBL1.
   MODULE READTBL1.
 ENDLOOP.
 MODULE USER_COMMAND_0100.
主程式程式碼如下
REPORT  YTEST20160615003.
DATA: OK_CODE TYPE SY-UCOMM,
      SAVE_OK TYPE SY-UCOMM.

*定義內表,注意兩種寫法一樣
*DATA SH1 LIKE YTJAYSCHOOL OCCURS 0 WITH HEADER LINE.
DATA SH2 LIKE TABLE OF YTJAYSCHOOL WITH HEADER LINE.
*定義單結構紀錄
DATA SH TYPE YTJAYSCHOOL.
*增加內表資料
SELECT * INTO CORRESPONDING FIELDS OF TABLE SH2 FROM YTJAYSCHOOL.
*直接呼叫視窗
CALL SCREEN 100.
*定義表控制物件
CONTROLS TBL1 TYPE TABLEVIEW USING SCREEN 100.
*輸出資料,看內表有無改變
LOOP AT SH2.
  WRITE:/ SH2-YCT_ID, SH2-YSH_ID, SH2-YSH_NAME, SH2-YSH_ADDR.
ENDLOOP.

MODULE STATUS_0100 OUTPUT.
  SET PF-STATUS 'STATUS1'.
ENDMODULE.

MODULE USER_COMMAND_0100 INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.
  CASE SAVE_OK.
    WHEN 'CANCEL'.
      LEAVE TO SCREEN 0.
  ENDCASE.
ENDMODULE.

*逐行從內表填寫表控制
MODULE FILLTBL1 OUTPUT.
  READ TABLE SH2 INTO SH INDEX TBL1-CURRENT_LINE.
ENDMODULE.

*逐行從內表控制更新內表
MODULE READTBL1 INPUT.
  MODIFY SH2 FROM SH INDEX TBL1-CURRENT_LINE.
ENDMODULE.
輸出結果如圖

調整前兩行資料,如圖

退出編輯螢幕,程式輸出內表資料,螢幕顯示資料已更改


上述表格控制元件是沒有垂直滾動條的,原因是沒有定義表格的記錄數,因而在PBO中還需要新增以下程式碼,新增完程式碼後如下:

REPORT  YTEST20160615003.
DATA: OK_CODE TYPE SY-UCOMM,
      SAVE_OK TYPE SY-UCOMM.

DATA: NUMS TYPE I.

*定義內表,注意兩種寫法一樣
*DATA SH1 LIKE YTJAYSCHOOL OCCURS 0 WITH HEADER LINE.
DATA SH2 LIKE TABLE OF YTJAYSCHOOL WITH HEADER LINE.
*定義單結構紀錄
DATA SH TYPE YTJAYSCHOOL.
*增加內表資料
SELECT * INTO CORRESPONDING FIELDS OF TABLE SH2 FROM YTJAYSCHOOL.
*直接呼叫視窗
CALL SCREEN 100.
*定義表控制物件
CONTROLS TBL1 TYPE TABLEVIEW USING SCREEN 100.
*輸出資料,看內表有無改變
LOOP AT SH2.
  WRITE:/ SH2-YCT_ID, SH2-YSH_ID, SH2-YSH_NAME, SH2-YSH_ADDR.
ENDLOOP.

MODULE STATUS_0100 OUTPUT.
  SET PF-STATUS 'STATUS1'.
  IF NUMS = 0.
    DESCRIBE TABLE SH2 LINES NUMS.
    TBL1-LINES = NUMS.
  ENDIF.
ENDMODULE.

MODULE USER_COMMAND_0100 INPUT.
  SAVE_OK = OK_CODE.
  CLEAR OK_CODE.
  CASE SAVE_OK.
    WHEN 'CANCEL'.
      LEAVE TO SCREEN 0.
  ENDCASE.
ENDMODULE.

*逐行從內表填寫表控制
MODULE FILLTBL1 OUTPUT.
  READ TABLE SH2 INTO SH INDEX TBL1-CURRENT_LINE.
ENDMODULE.

*逐行從內表控制更新內表
MODULE READTBL1 INPUT.
  MODIFY SH2 FROM SH INDEX TBL1-CURRENT_LINE.
ENDMODULE.
執行後結果如圖


3、通過系統生成資料表維護程式

通過系統生成資料表維護程式TCODE:SE55,通過系統資料維護功能使用生成程式(TCODE:SM30),過程如下:
建立一個數據表(SE11),生成維護程式(SE55),資料維護(SM30),設計程式碼呼叫生成程式。

3.1、新建資料表

新建一個數據表YTJAYMANA,詳細步驟請參閱“ABAP資料字典和資料表的讀取”,表結構如圖


3.2、生成維護程式

輸入TCODE:SE55,輸入函式組名稱和螢幕號,選擇許可權組


單擊新建按鈕,選擇“本地物件”,生成維護程式。

3.3、資料維護

輸入TCODE:SM30,輸入表名後單擊維護按鈕


系統進入資料維護介面


單擊右下角的狀態條,螢幕顯示程式名為“SAPLYTJAYMANA”


生成程式的表頭等資訊都可以調整,輸入TCODE:SE51進入螢幕編輯器,輸入程式名“SAPLYTJAYMANA”,找到編號為100的螢幕,進入設計介面後,可以調整螢幕物件


儲存啟用後,使用介面也相應改變


3.4、從程式呼叫生成的維護視窗

通過函式呼叫生成程式,程式如下:
REPORT  YTEST20160616001.
CALL FUNCTION 'VIEW_MAINTENANCE_CALL'
  EXPORTING
    ACTION = 'U'
    VIEW_NAME = 'YTJAYMANA'
  EXCEPTIONS
    FOREIGN_LOCK = 2
    NO_TVDIR_ENTRY = 8.

IF SY-SUBRC <> 0.
*  MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*    WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
執行後,介面如圖


4、表格相關技巧

4.1、取得行號

*取得當前螢幕和行號
GET CURSOR LINE LINEA.
CHECK SY-SUBRC = 0.
*當前行號 = 當前屏首行序號 + 當前屏行號
LINEA = TBLA - LOP_LINE - 1.
*用取得當前行號讀取內表
READ TABLE YTJAYMANA INDEX LINEA.
MESSAGE S005(YMESS) WITH LINEA.

4.2、定義表格的讀寫屬性

WHEN 'READWR'.
*當單擊按鈕時,第一列只讀,其他列讀寫切換
	LOOP AT TBL1-COLS INTO ACOL WHERE INDEX GT 0.
		IF SY-TABIX = 1.
			ACOL-SCREEN-INPUT = '0'.
		ELSE.
			IF ACOL-SCREEN-INPUT = '0'.
				ACOL-SCREEN-INPUT = '1'.
			ELSEIF ACOL-SCREEN-INPUT = '1'.
				ACOL-SCREEN-INPUT = '0'.
			ENDIF.
		ENDIF.
	ENDLOOP.
	MODIFY TBL1-COLS FROM ACOL INDEX SY-TABIX.

5、通過表格維護變更內表資料後提交資料庫

結合內表,對錶格控制元件資料增加、修改、刪除後提交到資料庫,最終介面如圖
步驟:
(1)用嚮導建立表格
(2)建立按鈕“取當前行”,在事件中取表格控制元件當前行,並在狀態條上顯示當前行資料
(3)建立按鈕“刪除行“,在事件中刪除表格上當前選擇的行
(4)增加系統按鈕”儲存“,將內表資料提交資料庫 邏輯流程式:
PROCESS BEFORE OUTPUT.
*&SPWIZARD: PBO FLOW LOGIC FOR TABLECONTROL 'TBL'
  MODULE TBL_CHANGE_TC_ATTR.
*&SPWIZARD: MODULE TBL_CHANGE_COL_ATTR.
  LOOP AT   SH1
       WITH CONTROL TBL
       CURSOR TBL-CURRENT_LINE.
*&SPWIZARD:   MODULE TBL_CHANGE_FIELD_ATTR
  ENDLOOP.

 MODULE STATUS_0100.
*
PROCESS AFTER INPUT.
*&SPWIZARD: PAI FLOW LOGIC FOR TABLECONTROL 'TBL'
  LOOP AT SH1.
    CHAIN.
      FIELD SH1-YCT_ID.
      FIELD SH1-YSH_ID.
      FIELD SH1-YSH_NAME.
      FIELD SH1-YSH_ADDR.
      MODULE TBL_MODIFY ON CHAIN-REQUEST.
    endchain.
  ENDLOOP.
*&SPWIZARD: MODULE TBL_CHANGE_TC_ATTR.
*&SPWIZARD: MODULE TBL_CHANGE_COL_ATTR.

 MODULE USER_COMMAND_0100.
主程式:
REPORT  ytest20160615002.

DATA: ok_code TYPE sy-ucomm,
      save_ok LIKE ok_code.

*定義內表,注意兩種寫法一樣
*DATA SH1 LIKE YTJAYSCHOOL OCCURS 0 WITH HEADER LINE.
DATA: sh1 LIKE TABLE OF ytjayschool WITH HEADER LINE,
      DELA_SCHOOL LIKE TABLE OF YTJAYSCHOOL WITH HEADER LINE.

DATA LINEA TYPE I.

*&SPWIZARD: DECLARATION OF TABLECONTROL 'TBL' ITSELF
CONTROLS: TBL TYPE TABLEVIEW USING SCREEN 0100.
DATA WA1 LIKE YTJAYSCHOOL.

*增加內表資料
SELECT * FROM YTJAYSCHOOL INTO CORRESPONDING FIELDS OF TABLE SH1.

*測試輸出資料
*LOOP AT sh1.
*  WRITE:/ sh1-yct_id, sh1-ysh_id, sh1-ysh_name, sh1-ysh_addr.
*ENDLOOP.

*直接呼叫視窗
CALL SCREEN 100.

*&SPWIZARD: OUTPUT MODULE FOR TC 'TBL'. DO NOT CHANGE THIS LINE!
*&SPWIZARD: UPDATE LINES FOR EQUIVALENT SCROLLBAR
MODULE tbl_change_tc_attr OUTPUT.
  DESCRIBE TABLE sh1 LINES tbl-lines.
ENDMODULE.                    "TBL_CHANGE_TC_ATTR OUTPUT

*&SPWIZARD: INPUT MODULE FOR TC 'TBL'. DO NOT CHANGE THIS LINE!
*&SPWIZARD: MODIFY TABLE
MODULE tbl_modify INPUT.
  MODIFY sh1
  INDEX tbl-current_line.
ENDMODULE.                    "TBL_MODIFY INPUT

*----------------------------------------------------------------------*
*  MODULE STATUS_0100 OUTPUT
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
MODULE status_0100 OUTPUT.
  SET PF-STATUS 'STATUS1'.
ENDMODULE.                    "STATUS_0100 OUTPUT



*使用者互動
MODULE user_command_0100 INPUT.
  save_ok = ok_code.
  CLEAR ok_code.
*退出按鈕時退出程式
  CASE save_ok.
    WHEN 'CANCEL'.
      LEAVE PROGRAM.
    WHEN 'SAVE'.
      MODIFY YTJAYSCHOOL FROM TABLE SH1.
      IF SY-SUBRC NE 0.
        MESSAGE I005(YMESS) WITH '更新資料錯誤!'.
        EXIT.
      ELSE.
        MESSAGE I005(YMESS) WITH '更新資料OK!'.
      ENDIF.
      DELETE YTJAYSCHOOL FROM TABLE DELA_SCHOOL.
      IF SY-SUBRC NE 0.
        MESSAGE I005(YMESS) WITH '更新資料錯誤!'.
        EXIT.
      ELSE.
        MESSAGE I005(YMESS) WITH '更新資料OK!'.
      ENDIF.
    WHEN 'DELA'.
      GET CURSOR LINE LINEA.
      CHECK SY-SUBRC = 0.
      LINEA = TBL-TOP_LINE + LINEA - 1.
      READ TABLE SH1 INDEX LINEA.
      APPEND SH1 TO DELA_SCHOOL.
      DELETE SH1 INDEX : LINEA.
    WHEN 'GETDATA'.
      GET CURSOR LINE LINEA.
      CHECK SY-SUBRC = 0.
      LINEA = TBL-TOP_LINE - 1.
      READ TABLE SH1 INDEX LINEA.
      MESSAGE S006(YMESS) WITH SH1-YSH_NAME SH1-YSH_ADDR.
  ENDCASE.
ENDMODULE.                    "USER_COMMAND_0100 INPUT