ABAP技術總結

 

 

 

 

 

 

 

 

 

 

 

 

 

SAPhtml

——ABAP/4 技術總結 V3.0java

 

 

2014-10-14node

 

--江正軍git

 

 

 

 

 

1.      基礎... 1算法

1.1.           基本數據類型... 1sql

1.1.1.        P類型(壓縮型)數據... 1數據庫

1.2.           TYPELIKE. 2express

1.3.           DESCRIBE. 3編程

1.4.           字符串表達式... 3api

1.5.           Data elementDomain. 4

1.6.           詞典預約義類型與ABAP類型映射... 5

1.7.           字符串處理... 7

1.7.1.        countmatch結合... 7

1.7.2.        FIND …SUBMATCHES. 8

1.7.3.        FIND …RESULTS  itab. 8

1.7.4.        正則式類... 9

1.7.4.1.             matchesmatch. 9

1.7.4.2.             contains. 10

1.7.4.3.             find_all10

1.7.4.4.             find_next. 11

1.7.4.5.             get_lengthget_offsetget_submatch. 11

1.7.4.6.             replace_all12

1.8.           CLEARREFRESHFREE. 12

1.9.           ABAP程序中的局部與全局變量... 12

1.10.         FormFunction. 13

1.10.1.     FORM.. 13

1.10.2.     FUNCTION.. 15

1.10.2.1.           Function Group結構... 15

1.10.2.2.           Function參數傳值、傳址... 18

1.11.         字段符號FIELD-SYMBOLS. 20

1.11.1.     ASSIGN隱式強轉... 21

1.11.2.     ASSIGN顯示強轉... 21

1.11.3.     ASSIGN 動態分配... 21

1.11.4.     UNASSIGNCLEAR. 21

1.12.         數據引用、對象引用... 21

1.12.1.     數據引用Data References. 21

1.12.2.     對象引用Object references. 22

1.12.3.     GET REFERENCE OF獲取變量/對象/常量地址... 22

1.13.         動態語句... 22

1.13.1.     內表動態訪問... 22

1.13.2.     動態類型... 23

1.13.3.     動態SQL. 23

1.13.4.     動態調用類的方法... 23

1.13.5.     ASSIGN 動態分配... 23

1.13.5.1.           動態訪問類的屬性成員... 24

1.14.         反射... 24

1.14.1.     TYPE HANDLE. 24

1.14.2.     動態建立數據Data或對象Object. 25

1.14.3.     動態建立基本類型變量、結構、內表... 25

1.14.4.     類對象反射... 26

2.      面向對象... 27

2.1.           類與接口定義... 27

2.1.1.        components. 27

2.2.           類定義、實現... 27

2.3.           接口定義、實現... 27

2.4.           類、接口繼承... 28

2.5.           向下強轉型 ?=. 28

2.6.           方法... 28

2.6.1.        parameters. 29

2.6.2.        PREFERRED PARAMETER首選參數... 29

2.6.3.        普通調用... 29

2.6.4.        簡單調用... 30

2.6.5.        函數方法... 30

2.7.           mesuper. 30

2.8.           事件... 30

2.8.1.        事件定義... 30

2.8.2.        事件觸發... 31

2.8.3.        事件處理器Event Handler. 31

2.8.4.        註冊事件處理器... 32

2.8.5.        示例... 32

3.      內表... 33

3.1.           LOOP AT循環內表... 33

3.1.1.        SUM.. 34

3.1.2.        AT...ENDAT. 34

3.1.3.        自已實現AT...ENDAT. 37

3.2.           LOOP AT中修改當前內錶行... 39

3.2.1.        循環中修改索引表... 39

3.2.2.        循環中修改HASH... 40

3.3.           第二索引... 40

3.3.1.        使用第二索引... 41

3.3.2.        示例... 41

3.4.           適合全部類型的內表操做... 42

3.5.           適合索引內表操做... 43

4.      OPEN SQL. 43

4.1.           SELECT INSERTUPDATEDELETEMODIFY. 43

4.2.           條件操做符... 44

4.3.           RANG條件內表... 44

4.4.           FOR ALL ENTRIES. 45

4.5.           INNER JOINLEFT OUTER JOIN使用限制... 46

4.6.           動態SQL. 46

4.7.           子查詢... 47

4.7.1.        =<><<=>>=子查詢... 47

4.7.1.1.             ALLANYSOME. 48

4.7.2.        [NOT] IN子查詢... 48

4.7.3.        [NOT] EXISTS子查詢... 48

4.7.4.        相關子查詢... 48

4.8.           統計函數... 48

4.9.           分組過濾... 48

4.10.         遊標... 49

4.11.         三種緩存... 49

4.12.         Native SQL. 50

4.12.1.     查詢... 50

4.12.2.     存儲過程... 50

4.12.3.     遊標... 50

4.13.         SAP... 51

5.      SAP/DB LUW.. 51

5.1.           DB LUW.. 51

5.1.1.        顯式提交... 52

5.1.2.        隱式提交... 52

5.1.3.        顯示回滾... 52

5.1.4.        隱式回滾... 52

5.2.           SAP LUW.. 53

5.2.1.        SAP LUW的綁定方式... 54

5.2.1.1.             Function. 54

5.2.1.2.             subroutine. 55

5.2.2.        開啓新的SAP LUW.. 55

5.2.3.        同步或異步更新(提交)... 55

5.2.4.        本地、非本地方式提交... 55

6.      邏輯數據庫... 56

6.1.           組成... 56

6.2.           結構... 56

6.3.           選擇屏幕(Selections... 57

6.3.1.        PARAMETERS屏幕參數擴充... 58

6.3.2.        SELECTION-SCREEN格式化屏幕... 58

6.3.3.        DYNAMIC SELECTIONS動態選擇條件... 58

6.3.3.1.             DYN_SEL. 60

6.3.3.1.1.          RSDS_TYPE-CLAUSES. 60

6.3.3.1.2.          RSDS_TYPE-TRANGE. 61

6.3.4.        FIELD SELECTION動態選擇字段... 62

6.3.4.1.             SELECT_FIELDS. 63

6.4.           數據庫程序中重要FORM.. 65

6.5.           LDB選擇屏幕:靜()態選擇屏幕、動態選擇視圖... 66

7.      ALV. 70

7.1.           Layout重要字段... 70

7.2.           FIELDCATALOG重要字段... 70

7.3.           指定雙擊觸發的FunCode. 71

7.4.           相關函數... 71

7.5.           重要參數接口... 71

7.6.           讓預置按鈕回調I_CALLBACK_USER_COMMAND.. 72

7.7.           顏色... 72

7.8.           可編輯... 72

7.9.           單元格數據修改後當即自動刷新... 73

7.10.         數據有效性驗證事件:data_changed. 73

7.11.         金額、數字類型輸入問題... 74

7.12.         排序、分類彙總... 74

7.13.         可打印的表頭輸出... 75

7.14.         佈局變式讀取、切換、根據佈局格式導出數據... 75

7.15.         動態內表... 76

8.      OO ALV. 77

8.1.           相關類... 77

8.2.           控制區域、容器、Grid關係... 77

8.3.           CL_GUI_ALV_GRID重要方法... 77

8.4.           set_table_for_first_dispaly()方法重要參數... 77

8.5.           事件綁定、觸發、回調處理... 77

8.6.           CL_GUI_DOCKING_CONTAINER容器... 78

8.7.           覆蓋(攔截)預設按鈕的功能FunCodeBEFORE_USER_COMMAND.. 78

8.8.           數據改變事件data_changeddata_changed_finished. 79

8.9.           單元格可編輯... 79

9.      問題... 79

9.1.           ALV自帶導出文件時字段數據末尾被截斷問題... 79

9.2.           Smartform Template沒法顯示減號後面內容... 80

9.3.           Smartform金額或者數量字段顯示不出來... 80

9.4.           更新數據庫表時,工做區或內表的結構需參考數據庫表來定義... 80

9.5.           DELETE ADJACENT DUPLICATES…去重複... 80

9.6.           Text使用Excel打開亂碼問題... 80

9.7.           VBFAEKPO聯合查詢問題... 81

10.             技巧... 81

10.1.         READ TABLE...WITH KEY可以使用OR條件或其餘非「=」操做符... 81

10.2.         SELECT SINGLE ... WHERE...沒法排序問題... 82

10.3.         小心Where後的條件內表爲空時... 82

10.4.         快速查找SO所對應的交貨單DNPO.. 82

10.5.         X類型的C類型視圖... 82

10.6.         字符串鏈接:&& 替代 CONCATENATE. 83

10.7.         Variant變式中動態日期... 83

11.             優化... 84

11.1.         數據庫... 84

11.2.         程序... 86

12.             屏幕... 88

12.1.         AT SELECTION-SCREENPAIAT USER-COMMAND觸發時機... 88

12.2.         SELECTION-SCREEN格式化屏幕、激活預設按鈕... 88

12.3.         PARAMETERS. 88

12.4.         SELECT-OPTIONS. 89

12.4.1.     輸入ABAP程序默認值時,須要加上「=」. 89

12.4.2.     選擇條件內表多條件組合規則... 89

12.4.3.     使用SELECT-OPTIONS替代PARAMETERS. 90

12.5.         各類屏幕元素演示... 91

12.6.         按鈕、單選複選框、下拉框的FunCode. 91

12.6.1.     選擇屏幕中的按鈕... 92

12.6.2.     選擇屏幕中的單選/複選按鈕:點擊時顯示、隱藏其餘屏幕元素... 92

12.6.3.     選擇屏幕中下拉列表:AS LISTBOX. 93

12.7.         屏幕流邏輯... 93

12.7.1.     FIELD.. 93

12.7.2.     MODULE. 94

12.7.3.     ON INPUTON CHAIN-INPUT區別... 94

12.8.         EXIT-COMMAND.. 95

12.8.1.     MODULE <mod> AT EXIT-COMMAND.. 95

12.8.2.     AT SELECTION-SCREEN ON EXIT-COMMAND.. 95

12.9.         OK_CODE. 95

12.9.1.     ok_code使用前需拷貝... 95

12.10.       Search help F4... 95

12.10.1.            VALUE CHECKfixed ValuesValue Table. 95

12.10.2.            檢查表Check Table --- Value Table. 96

12.10.3.            SE11檢查表與搜索幫助關係... 96

12.10.4.            F4搜索幫助聯動的決定因素... 98

12.11.       搜索幫助參數說明... 100

12.12.       F4IF_SHLP_EXIT_EXAMPLE幫助出口... 102

12.12.1.            修改數據源... 102

12.12.2.            刪除重複... 103

12.13.       搜索幫助優先級... 103

12.14.       搜索幫助建立函數... 103

12.15.       POV事件裏讀取屏幕字段中的值函數... 104

12.16.       動態修改屏幕... 104

12.17.       子屏幕... 105

12.18.       屏幕跳轉... 106

12.18.1.            CALL SCREEN誤用... 106

12.18.2.            CALL SCREEN/SET SCREEN/LEAVE TO SCREEN區別... 107

12.19.       修改標準選擇屏幕的GUI Status. 107

12.20.       事件分類... 107

12.20.1.            報表事件... 107

12.20.2.            選擇屏幕事件... 107

12.20.3.            邏輯數據庫事件... 108

12.20.4.            列表事件... 108

12.20.5.            事件流圖... 109

12.21.       事件終止... 110

12.21.1.            RETURN.. 110

12.21.2.            STOP. 110

12.21.3.            EXIT. 110

12.21.4.            CHECK. 110

12.21.5.            LEAVE. 111

12.21.5.1.         REJECT. 111

13.             列表屏幕... 111

13.1.         標準LIST. 112

13.2.         自定義LIST. 112

13.3.         LIST事件... 113

13.4.         Detail Lists 建立... 113

13.5.         標準的 List Status. 113

13.6.         列表屏幕上的數據與程序間的傳遞... 114

13.6.1.     SY-LISEL. 114

13.6.2.     HIDE. 114

13.6.3.     READ LINE. 114

13.7.         Screen Processing 屏幕處理切換到Lists列表輸出... 115

13.8.         LIST 打印輸出... 115

14.             Messages. 115

14.1.         00消息ID中的通用消息... 115

14.2.         消息常量... 116

14.3.         靜態指定... 116

14.4.         動態指定... 116

14.5.         消息拼接MESSAGE …INTO.. 116

14.6.         修改消息顯示性爲…DISPLAY LIKE….. 116

14.7.         RAISING <exc>:消息以異常形式拋出... 116

14.8.         CALL FUNCTION…EXCEPTIONS. 117

14.8.1.     error_message = n_error捕獲消息... 118

14.9.         各類消息的顯示及處理... 118

14.10.       異常處理... 119

14.10.1.            RAISE [EXCEPTION]…觸發異常... 119

14.10.1.1.         觸發類異常... 119

14.10.1.2.         RESUMABLE選項... 120

14.10.2.            捕獲異常... 121

14.10.2.1.         類異常捕獲TRY…CATCH.. 121

14.10.2.2.         老式方式捕獲runtime errors(運行時異常)121

14.10.3.            向上拋出異常... 121

14.10.4.            類異常... 122

15.             數據格式化、轉換... 123

15.1.         數據輸入輸出轉換... 123

15.1.1.     輸出時自動轉換... 123

15.1.2.     輸入時自動轉換... 124

15.1.3.     經過轉換規則輸入輸出函數手動轉換... 124

15.2.         數量小位數格式化... 125

15.2.1.     案例... 126

15.3.         單位換算:UNIT_CONVERSION_SIMPLE. 128

15.4.         貨幣格式化... 129

15.4.1.     從表中讀取日元並正確的格式化輸出... 130

15.4.2.     SAP 貨幣轉換因子... 131

15.4.3.     貨幣內外格式轉換... 133

16.             業務... 134

16.1.         表、業務流程... 134

16.2.         MM.. 138

16.2.1.     經常使用表... 138

16.2.2.     庫存... 139

16.2.3.     物料憑證... 139

16.3.         SD.. 139

16.3.1.     ... 139

16.3.2.     訂價過程... 141

16.3.2.1.           條件技術七要素... 141

16.3.2.2.           條件表V/03V/04V/05. 142

16.3.2.3.           存取順序 V/07. 142

16.3.2.4.           條件類型 V/06. 142

16.3.2.5.           訂價過程V/08與肯定OVKK. 143

16.3.2.6.           VK11:價格主數據維護... 146

16.3.2.7.           訂價計算:KONV. 147

16.3.2.7.1.       條件類型的計算公式... 147

16.3.2.8.           訂價過程示例... 148

16.3.2.9.           銷售訂單中的訂價示例... 148

16.3.2.10.         訂價通訊表KOMKKOMP. 151

16.3.3.     銷售相關的憑證類型、類型... 151

16.4.         業務概念... 154

16.4.1.     售達方、送達方、開票方、付款方... 154

16.4.2.     進項稅、銷項稅... 154

16.4.3.     訂單日期、憑證日期、過帳日期... 155

16.5.         業務知識... 155

16.5.1.     客戶聯繫人相關信息... 155

16.5.2.     銷售訂單合做夥伴功能... 156

17.             加強... 157

17.1.         第一代:基於源碼加強(子過程subroutine... 157

17.2.         第二代:基於函數出口加強(Function... 157

17.2.1.     示例:採購訂單屏幕加強... 159

17.2.1.1.           定義全局變量... 161

17.2.1.2.           子屏幕... 161

17.2.1.3.           屏幕與業務表數據間傳遞... 162

17.2.1.4.           相關函數說明... 163

17.2.2.     如何快速找到加強... 163

17.3.         第三代:基於類的加強(BADI... 165

17.3.1.     新式BADI建立... 166

17.3.1.1.           定義... 166

17.3.1.2.           實現... 168

17.3.1.3.           過濾器... 170

17.3.1.3.1.       調用... 171

17.3.1.4.           多個BADI/ Enhancement實現時究竟調誰... 172

17.3.2.     經典BADI建立... 173

17.3.2.1.           Filter-Depend.過濾器... 174

17.3.2.1.1.       調用... 175

17.3.2.2.           經過經典BADI擴展自定義程序(菜單、屏幕、功能)... 176

17.3.3.     示例:經過BADI實現採購訂單屏幕加強... 179

17.4.         第四代:Enhancement-Point. 179

17.4.1.     爲本身程序建立顯示加強... 180

17.4.2.     隱式與顯示加強... 182

18.             數據批量維護... 182

18.1.         BDCSM35SHDB... 182

18.2.         LSMW.. 184

18.3.         業務對象和BAPI184

18.3.1.     SAP業務對象(SWO1... 184

18.3.1.1.           業務對象類型的組成... 185

18.3.1.2.           業務對象(BO)設計... 185

18.3.1.2.1.       建立業務表... 185

18.3.1.2.2.       建立業務對象類型... 186

18.3.1.2.3.       添加(繼承)接口... 186

18.3.1.2.4.       添加關鍵字段Key. 187

18.3.1.2.5.       添加屬性... 187

18.3.1.2.6.       經過報表程序來實現業務對象的方法... 189

18.3.1.2.6.1.    報表程序... 189

18.3.1.2.6.2.    重定義接口與方法實現... 190

18.3.1.2.6.3.    測試... 191

18.3.1.2.7.       經過BAPI函數來實現業務對象方法... 192

18.3.1.2.7.1.    建立BAPI參數結構... 192

18.3.1.2.7.2.    建立BAPI函數、BAPI調用返回RETURN結果處理... 193

18.3.1.2.7.3.    BAPI函數綁定到相應的業務方法... 195

18.3.2.     BAPI197

18.3.2.1.           BAPI瀏覽器... 197

18.3.2.2.           SE37查找:BAPI函數的命名規則... 198

18.3.2.3.           查找某事務碼所對應的BAPI198

18.3.2.4.           經常使用BAPI函數... 199

18.3.2.5.           調用BAPI199

18.3.2.5.1.       BAPI事務處理... 200

18.3.2.5.2.       外部系統(Java)調用BAPI函數... 201

18.3.2.5.2.1.    直連、鏈接池... 201

18.3.2.5.2.2.    訪問結構... 202

18.3.2.5.2.3.    訪問表 (Table)203

18.3.2.5.2.4.    Java多線程調用有/無狀態RFM.. 204

18.3.2.5.3.       ABAP訪問Java服務... 204

18.3.2.5.4.       ABAP建立遠程目標... 204

18.3.2.5.5.       鏈接異常registrationnot allowed. 205

18.3.2.5.6.       帶狀態訪問... 206

18.4.         IDoc. 206

18.4.1.     數據段類型和數據段定義(WE31... 206

18.4.2.     IDoc定義(WE30... 207

18.4.3.     自定義IDoc發送與接收實例... 208

18.4.3.1.           發送端800outbound)配置... 208

1、建立segmentWE31... 208

2、建立IDOC TypeWE30... 209

3、建立Message TypeWE81... 210

4、關聯Message TypeIDOC TypeWE82... 210

5、建立接收端RFC DestinationSM59... 210

6、建立到收端的端口(WE21... 211

7、建立發送端Logical System並分配(SALE... 211

8、建立接收端Logical SystemSALE... 212

9、建立接收端合做和伴配置文件Partner profileWE20... 212

10、經過ABAP程序發送IDOC. 213

18.4.3.2.           接收端810Inbound)配置... 216

1、建立發送端RFC DestinationSM59... 216

2、建立發送端的端口(WE21... 217

3、將接收端Logical System分配到Client 810SALE... 217

4、建立入站處理函數... 218

5、註冊入站處理函數(BD51... 219

6、將入站函數與IDOC Type/Message Type關聯(WE57... 219

7、建立入站處理代碼Inbound Process CodeWE42... 219

8、建立發送端合做和伴配置文件Partner profileWE20... 219

9、測試 BD87. 220

19.             數據共享與傳遞... 222

19.1.         程序調用、會話、SAP/ABAP內存 關係... 222

19.2.         ABAP Memory數據共享... 224

19.2.1.     EXPORT. 224

19.2.2.     IMPORT. 226

19.2.3.     DELETE. 227

19.3.         SAP MEMORY數據共享... 228

19.3.1.     PARAMETERS/SELECT-OPTIONS選項MEMORY ID.. 228

19.3.2.     GET/SET PARAMETER ID.. 228

19.4.         DATABASE. 229

19.4.1.     將文件存入表中... 230

19.4.2.     從表中讀取文件... 232

19.5.         JOB間數據傳遞... 233

20.             拾遺... 233

20.1.         Function調用... 233

20.1.1.     更新FMLUW.. 233

20.1.2.     RFC函數:遠程調用... 234

20.1.2.1.           同步... 234

20.1.2.2.           異步... 234

20.1.2.2.1.       事務性RFC調用... 234

20.1.2.3.           DESTINATION 取值... 234

20.2.         函數、類... 235

20.3.         FTP. 235

20.4.         文件讀寫... 235

20.5.         Email236

20.6.         XML. 236

20.6.1.     生成... 237

20.6.2.     解析... 240

20.7.         OLE. 242

20.7.1.     導出Exel文件多種方式... 243

20.8.         ABAP示例代碼... 244

20.9.         長文本... 244

20.9.1.     物料長文本... 244

20.9.2.     生產定單長文本... 245

20.9.3.     採購定單長文本... 246

20.9.4.     銷售定單長文本... 246

20.10.       Smart Forms. 246

20.11.       BOM.. 247

20.12.       傳輸請求SE01SE09SE10. 247

20.13.       Script Form傳輸:SCC1. 247

20.14.       權限檢查... 247

20.15.       容許對錶數據維護... 248

20.16.       SE93建立事務碼... 248

20.17.       表字段初始值、NULL等問題... 249

20.17.1.            SE11表設置中的Initial Values. 249

20.17.2.            底層數據庫表字段默認值... 249

20.17.3.            ABAP初始值、底層數據庫表默認值相互轉換... 250

20.17.3.1.         向表中插入初始值... 250

20.17.3.2.         讀取數據... 251

20.17.4.            SAP系統中的表字段不容許爲NULL的緣由... 251

20.18.       ABAP中的「空」、INITIAL. 251

20.19.       調試工具... 252

20.19.1.            ST05. 252

20.20.       程序建立Job(報表自已設置後臺運行,先後臺數據共享)... 253

20.21.       SE78SWM0. 254

20.22.       客戶端文本文件或Excel文件上傳與下載... 255

20.22.1.            讀取客戶端TxtExcel文件到內表:TEXT_CONVERT_XLS_TO_SAP. 255

20.22.2.            將數據內表導出爲EXCEL文件:SAP_CONVERT_TO_XLS_FORMAT. 256

20.23.       Unicode字符串互轉... 256

20.24.       字符編碼與解碼... 256

20.25.       ABAP中的特殊字符列表... 257

20.26.       下載文件... 257

20.26.1.            BIN二進制下載... 257

20.26.2.            以字符模式下載... 258

20.27.       將文件上傳到數據庫表中,並可郵件發送... 259

20.28.       AppendInclude系統表結構加強... 261

20.29.       結構複用(INCLUDE... 262

20.30.       經常使用事務碼... 263

21.             經常使用Function. 265

21.1.         日期函數... 265

21.1.1.     日期、時間驗證... 265

21.1.2.     內部轉換外部格式... 265

21.1.3.     外部轉內部格式... 266

21.1.4.     獲取Client格式... 267

21.1.5.     日期加減... 267

21.1.6.     轉成工廠日期... 267

21.1.7.     日期屬性... 269

21.1.8.     節假日... 270

21.1.9.     年月選擇框... 271

21.1.10.            財政年... 271

21.1.11.            星期翻譯對照表... 271

21.1.12.            日期所在週末、天/周、周/... 272

 

 

1.   基礎

1.1.  基本數據類型

CNDTIFPXstringXstring

P默認爲8字節,最大容許16字節。最大整數位:16*2 = 32 - 1 = 31 -14(容許最大小數位數) = 17位整數位

類型

最大長度(字符數)

默認長度

說明

C

1~262143個字符

1 字符

 

N

1~262143個字符

1 字符

09之間字符組成的數字字符串

D

8 個字符

 

日期格式必須爲 YYYYMMDD

T

6 個字符

 

格式爲 24-hour HHMMSS

I

4 bytes

 

-2.147.483.648 to +2.147.483.647

F

8 bytes

 

小數位最大能夠到17位,便可精確到小數點後17

P

1 to 16 bytes

8 bytes

兩個數字位壓縮後才佔一個字節,因爲0-9的數字只須要4Bit位,因此一個字節實質上容許存儲二位數字,這就是P數據類型爲壓縮數據類型的由來。並借用半個字節來存儲小數點位置、正號、負號相關信息

X

1~524,287 bytes

1 byte

十六進制字符 0-9, A-F具體的範圍爲:00~FF

類型X是十六進制類型,可表示內存字節實際內容,使用兩個十六制字符表示一個字節中所存儲的內容。但直接打印輸出時,輸出的仍是賦值時字面意義上的值,而不是Unicode解碼後的字符

若是未在 DATA 語句中指定參數<length>,則建立長度爲 1

注:若是值是字母,則必定要大寫

1.1.1.P類型(壓縮型)數據

是一種壓縮的定點數,其數據對象佔據內存字節數和數值範圍取定義時指定的整個數據大小和小數點後位數,若是不指定小數位,則將視爲I類型。其有效數字位大小能夠是從1~31位數字(小數點與正負號佔用一個位置,半個字節),小數點後最多容許14個數字

P類型的數據,可用於精確運算(這裏的精確指的是存儲中所存儲的數據與定義時字面上所看到的大小相同,而不存在精度丟失問題——看到的就是內存中實實在在的大小)。在使用P類型時,要先選擇程序屬性中的選項 Fixed point arithmetic(即定點算法,通常默認選中),不然系統將P類型看用整型。其效率低於IF類型。

"16 * 2 = 32表示了整個字面意義上容許的最大字面個數,而14表示的是字面上小數點後面容許的最大小數位,而不是指14個字節,只有這裏定義時的16才表示16個字節

DATAp(16TYPE DECIMALS 14 VALUE '12345678901234567.89012345678901'.

"正負符號與小數點固定要佔用半個字節,一個字面上位置,幷包括在這16個字節裏面。
"16 * 2 = 32位包括了小數點與在正負號在內
"在定義時字面上容許最長能夠達到32位,除去小數點與符號需佔半個字節之後
"有效數字位可容許31位,這31位中包括了整數位與小數位,再除去定義時小
"數位爲14位外,整數位最多還可達到17位,因此下面最多隻能是179
DATAp1(16TYPE DECIMALS 14 VALUE '-99999999999999999'.

 

"P類型是以字符串來表示一個數的,與字符串不同的是,P類型中的每一個數字位只會佔用4Bit位,因此兩個數字位纔會佔用一個字節。另外,若是定義時沒有指定小數位,表示是整型,但小數點固定要佔用半個字節,因此不帶小數位與符號的最大與最小整數以下(最多容許319,而不是32個)
DATA: p1(16TYPE p  VALUE '+9999999999999999999999999999999'.
DATA: p2(16TYPE p  VALUE '-9999999999999999999999999999999'.

 

其實P類型是以字符串形式來表示一個小數,這樣才能夠做到精確,就像Java中要表示一個精確的小數要使用BigDecimal同樣,不然會丟失精度。

DATAp(9TYPE DECIMALS VALUE '-123456789012345.12'.
WRITE/ p."123456789012345.12-

 

DATAf1 TYPE VALUE '2.0',
      f2 
TYPE VALUE '1.1',
      f3 
TYPE f.
f3  
=  f1 f2."不能精確計算
"2.0000000000000000E+00 1.1000000000000001E+00 8.9999999999999991E-01
WRITE/ f1   f2 f3.

DATAp1 TYPE DECIMALS VALUE '2.0',
      p2 
TYPE DECIMALS VALUE '1.1',
      p3 
TYPE DECIMALS 1.
p3  
=  p1 p2."能精確計算
WRITE/ p1   p2 p3. "2.0               1.1               0.9

 

Java中精確計算:

    publicstaticvoid main(String[] args) {

        System.out.println(2.0 - 1.1);// 0.8999999999999999

        System.out.println(sub(2.0, 0.1));// 1.9

    }

    publicstaticdouble sub(double v1, double v2) {

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.subtract(b2).doubleValue();

    }

1.2.TYPELIKE

透明表(還有其它數據詞典中的類型,如結構)便可看做是一種類型,也可看做是對象,因此便可使用TYPE,也能夠使用LIKE

TYPES type6 TYPE mara-matnr.
TYPES type7 LIKE mara-matnr.
DATA obj6 TYPE mara-matnr.
DATA obj7 LIKE mara-matnr.

"SFLIGHT爲表類型
DATA plane LIKE sflight-planetype.
DATA plane2 TYPE sflight-planetype.
DATA plane3 LIKE sflight.
DATA plane4 TYPE sflight.
"syst爲結構類型
DATA sy1 TYPE syst.
DATA sy2 LIKE syst.
DATA sy3 TYPE syst-index.
DATA sy4 LIKE syst-index.

 

注:定義的變量名千萬別與詞典中的類型相同,不然表面上便可使用TYPE也可以使用LIKE,就會出現這兩個關鍵字(TypeLike)均可用的奇怪現像下面是定義一個變量時與詞典中的結構同名的後果(致使)

DATA : BEGIN OF address2,
  street(
20TYPE c,
  city(
20TYPE c,
END OF address2.
DATA obj4 TYPE STANDARD TABLE OF address2."這裏使用的實質上是詞典中的類型address2
DATA obj5 LIKE STANDARD TABLE OF address2."這裏使用是的上面定義的變量address2

上面程序編譯經過,按理obj4定義是經過不過的(只能使用LIKE來引用另外一定義變量的類型,TYPE是不能夠的),但因爲address2是數字詞典中定義的結構類型,因此obj4使用的是數字詞典中的結構類型,而obj5使用的是LIKE,因此使用的是address2變量的類型

1.3.  DESCRIBE

DESCRIBE FIELD dobj 
  [
TYPE typ [COMPONENTS com]] 
  [
LENGTH ilen IN {BYTE|CHARACTERMODE
  [
DECIMALS dec] 
  [
OUTPUT-LENGTH olen] 
  [
HELP-ID hlp] 
  [
EDIT MASK mask].


DESCRIBE TABLE itab [KIND knd] [LINES lin] [OCCURS n].

1.4.字符串表達式

能夠使用&&&將多個字符模板串連接起來,能夠突破255個字符的限制,下面兩個是等效的:

|...| &  |...|

|...| && |...|

若是內容只有字面常量文本(沒有變量表達式或控制字符\r \n \t),則不須要使用字符模板,可這樣(若是包含了這些控制字符時,會原樣輸出,因此有這些控制字符時,請使用 |...|將字符包起來):

`...` && `...`

可是上面3個與下面3個是不同的:

`...` &  `...`

'...' &  '...'

'...' && '...'

上面前兩個仍是會受255個字符長度限制,最後一個雖然不受255限制,但尾部空格會被忽略

字面常量文本literal text)部分,使用 ||括起來,不能含有控制字符(如 \r \n \t這些控制字符),特殊字符 |{ } \須要使用 \進行轉義:

txt |Characters \|\{and \} have to be escaped by \\ in literal text.|.

字符串表達式

str |{ }|."算術計算表達式
str |{ |aa| && 'bb' }|."字符串表達式

str |{ str }|."變量名

str |{ strlenstr }|."內置函數

1.5.  Data elementDomain

數據元素是構成結構、表的基本組件域又定義了數據元素的技術屬性Data element主要附帶Search HelpParameter ID、以及標籤描述,而類型是由Domain域來決定的。Domain主要從技術方面描述了Data element,如Data Type數據類型、Output Length輸出長度、Convers. Routine轉換規則、以及Value Range取值範圍

將技術信息從Data element提取出來爲Domain域的好處:技術信息造成的Domain能夠共用,而每一個表字段的業務含意不同,會致使其描述標籤、搜索幫助不同,因此牽涉到業務部分的信息直接Data element中進行描述,而與業務無關的技術信息部分則分離出來造成Domain

 

 

 

1.6.  詞典預約義類型與ABAP類型映射

當你在ABAP程序中引用了ABAPDictionary則預置Dictionary類型則會轉換爲相應的ABAP類型,預置的Dictionary類型轉換規則表以下

 

Dictionarytype

Meaning

Maximumlengthn

ABAPtype

DEC

Calculation/amountfield

1-31, 1-17intables

P((n+1)/2)

INT1

Single-byte integer

3

Internalonly

INT2

Two-byteinteger

5

Internalonly

INT4

Four-byteinteger

10

I

CURR

Currencyfield貨幣字段

1-17

P((n+1)/2)

CUKY

Currencykey貨幣代碼

5

C(5)

QUAN

Amount金額

1-17

P((n+1)/2)

UNIT

Unit單位

2-3

C(n)

PREC

Accuracy

2

X(2)

FLTP

Floating pointnumber

16

F(8)

NUMC

Numeric text數字字符

1-255

N(n)

CHAR

Character字符

1-255

C(n)

LCHR

Long character

256-max

C(n)

STRING

Stringofvariable length

1-max

STRING.

RAWSTRING

Byte sequence of variable length

1-max

XSTRING

DATS

Date

8

D

ACCP

Accounting period YYYYMM

6

N(6)

TIMS

Time HHMMSS

6

T

RAW

Byte sequence

1-255

X(n)

LRAW

Long byte sequence

256-max

X(n)

CLNT

Client

3

C(3)

LANG

Language

internal 1, external 2

C(1)

這裏的「容許最大長度m」表示的是字面上容許的字符位數,而不是指底層所佔內存字節數,如

int1的取值爲0~255,因此是3位(不包括符號位)

int2的取值爲-32768~32767,因此是5

lLCHR and LRAW類型容許的最大值爲INT2 最大值

lRAWSTRING and STRING 具備可變長度,最大值能夠指定,但沒有上限

lSSTRING 長度是可變的,其最大值必須指定且上限爲255。與CHAR類型相比其優點是它與ABAP type string進行映射。

這些預置的Dictionary類型在建立Data elementDomain時能夠引用

Unicode系統中,一個字符佔兩個字節

1.7.字符串處理

SPLIT dobj AT sep INTO { {result1 result2 ...} | {TABLE result_tab} }必須指定足夠目標字段。不然,用字段dobj的剩餘部分填充最後目標字段幷包含分界符;或者使用內表動態接收

SHIFT dobj {[{BY num PLACES}|{UP TO sub_string}][[LEFT|RIGHT][CIRCULAR]]}
           | { 
{LEFT DELETING LEADING}|{RIGHT DELETING TRAILING} pattern

對於固定長度字符串類型,shift產生的空位會使用空格或十六進制的0(若是爲X類型串時)來填充

向右移動時前面會補空格,固定長度類型字符串與String結果是不同:String類型右移後不會被截斷,只是字串前面補相應數量的空格,但若是是C類型時,則會截斷;左移後後面是否被空格要看是不是固定長度類型的字符串仍是變長的String類型串,左移後C類型會補空格,String類型串不會(會縮短)

CIRCULAR:將移出的字符串放在左邊或者左邊

pattern:只要前導或尾部字符在指定的pattern字符集裏就會被去掉,直到第一個不在模式pattern的字符止

CONDENSE <c> [NO-GAPS].若是是C類型只去掉前面的空格(由於是定長,即便後面空格去掉了,左對齊時後面會補上空格),若是是String類型,則後面空格也會被去掉;字符串中間的多個連續的空格使用一個空格替換(String類型也是這樣)NO-GAPS:字符串中間的全部空格都也都會去除(String類型也是這樣);空格去掉後會左對齊[kənˈdens] 

CONCATENATE {dobj1 dobj2 ...}|{LINES OF itab}[kənˈkatɪneɪt]
            INTO result
            [
SEPARATED BY sep]
            [
RESPECTING BLANKS].

CDNT類型的前導空格會保留,尾部空格都會被去掉,但對String類型全部空格都會保留;對於c, d, n, t類型的字符串有一個RESPECTING BLANKS選項可以使用,表示尾部空格也會保留。注:使用 `` String類型進行賦值時纔會保留尾部空格  字符串鏈接能夠使用 && 來操做,具體請參考這裏

strlen(arg)Xstrlen(arg)String類型的尾部空格會計入字符個數中,但C類型的變量尾部空格不會計算入

substringval TEXT [off off] [len len] )

count( val TEXT {sub substring}|{regex regex} )匹配指定字符串substring或正則式regex出現的子串次數,返回的類型爲i整型類型

containsval TEXT REGEX REGEX)是否包含。返回布爾值,注:只能用在ifWhile等條件表達式中

matchesval TEXT REGEX REGEX)regex表達式要與text徹底匹配,這與contains是不同的。返回布爾值,也只能用在ifWhile等條件表達式中

matchval TEXT REGEX REGEX occ occ)返回的爲匹配到的字符串。注:每次只匹配一個。occ:表示需匹配到第幾回出現的子串。若是爲正,則從頭日後開始計算,若是爲負,則從尾部向前計算

findval TEXT {sub substring}|{regex regex}[occ occ] )查找substring或者匹配regex的子串的位置。若是未找到,則返回 -1,返回的爲offset,因此從0開始

FIND ALL OCCURRENCES OF REGEX regex IN  dobj
  [
MATCH COUNT  mcnt]   成功匹配的次數
  { {[MATCH OFFSET moff][MATCH LENGTH mlen]}最後一次總體匹配到的串(總體串,最外層分組,而不是指正則式最內最後一個分組)起始位置與長度
  | [RESULTS result_tab|result_wa] } result_tab接收全部匹配結果,result_wa只能接收最後一次匹配結果
  [SUBMATCHES s1 s2 ...].一般與前面的MATCH OFFSET/ LENGTH一塊兒使用。只會接收使用括號進行分組的子組。若是變量s1 s2 ...比分組的數量多,則多餘的變量被initial;若是變量s1 s2 ...比分組的數量少,則多餘的分組將被忽略;且只存儲第一次或最後一次匹配到的結果

replaceval TEXT  REGEX REGEX  WITH NEW)使用new替換指定的子符串,返回String類型

REPLACE ALL OCCURRENCES OF REGEX regex IN  dobj WITH new

1.7.1.   countmatch結合

DATAtext TYPE string VALUE `Cathy's cat with the hat sat on Matt's mat.`,
      regx 
TYPE string VALUE `\<.at\>`."\< 單詞開頭\> 單詞結尾
DATAcounts TYPE i,
index TYPE i,
      substr 
TYPE string.
WRITE text.
NEW-LINE.
counts 
countval text regex regx )."返回匹配次數
DO counts TIMES.
index findval   text regex regx occ sy-index )."返回匹配到的的起始位置索引
  substr 
matchval  text regex regx occ sy-index )."返回匹配到的串
index index 1.
WRITE AT index substr.
ENDDO.

1.7.2.FIND …SUBMATCHES 

DATAmoff TYPE i,
       mlen 
TYPE i,
       s1   
TYPE string,
       s2   
TYPE string,
       s3   
TYPE string,
       s4   
TYPE string.
FIND ALL OCCURRENCES OF REGEX `((\w+)\W+\2\W+(\w+)\W+\3)`"\2 \3 表示反向引用前面匹配到的第二與第三個子串
IN `Hey hey, my my, Rock and roll can never die Hey hey, my my`"會匹配二次,但只會返回第二次匹配到的結果,第一次匹配到的子串不會存儲到s1s2s3中去
IGNORING CASE
MATCH OFFSET moff
 MATCH LENGTH mlen
SUBMATCHES s1 s2 s3 s4."根據從外到內,從左到右的括號順序依次存儲到s1 s2…中,注:只取出使用括號括起來的子串,如想取總體子串則也要括起來,這與Java不一樣
WRITE/  s1/ s2,/ s3 ,/ s4,/ moff ,/ mlen."s4會被忽略

1.7.3.   FIND …RESULTS  itab

DATAresult TYPE STANDARD TABLE OF string WITH HEADER LINE .
"Java不一樣,只要是括號括起來的都稱爲子匹配(即便用總體也用括號括起來了),
"無論括號嵌套多少層,統稱爲子匹配,且匹配到的全部子串都會存儲到,
"MATCH_RESULT-SUBMATCHES中,即便最外層的括號匹配到的子串也會存儲到SUBMATCHES
"內表中。括號解析的順序爲:從外到內,從左到右的優先級順序來解析匹配結構。
"Java中的group(0)存儲的是總體匹配串,即便總體未(或使用)使用括號括起來
PERFORM get_match TABLES result
USING '2011092131221032' '(((\d{2})(\d{2}))(\d{2})(\d{2}))'.
LOOP AT result .
WRITE/ result.
ENDLOOP.
FORM get_match  TABLES p_result"返回全部分組匹配(括號括起來的表達式)
USING    p_str
                         p_reg
.
DATAresult_tab TYPE match_result_tab WITH HEADER LINE.
DATAsubresult_tab TYPE submatch_result_tab WITH HEADER LINE.
"注意:帶表頭時 result_tab 後面必定要帶上中括號,不然激活時出現奇怪的問題
FIND ALL OCCURRENCES OF REGEX p_reg IN p_str RESULTS result_tab[].
"result_tab中存儲了匹配到的子串自己(與Regex總體匹配的串,存儲在
"result_tab-offsetresult_tab-length中)以及所子分組(括號部分,存儲在
"result_tab-submatches中)
LOOP AT result_tab .
"如需取總體匹配到的子串(與Regex總體匹配的串),則使用括號將總體Regex括起來
"來便可,括起來後也會自動存儲到result_tab-submatches,而不須要在這裏像這樣讀取
*    p_result = p_str+result_tab-offset(result_tab-length).
*    APPEND p_result.
    subresult_tab[] 
result_tab-submatches.
LOOP AT subresult_tab.
      p_result 
p_str+subresult_tab-offset(subresult_tab-length).
APPEND p_result.
ENDLOOP.
ENDLOOP.
ENDFORM.

 

1.7.4.正則式類

regex = Regular expression   [ˈreɡjulə]

cl_abap_regexJava中的 java.util.regex.Pattern的類對應

cl_abap_matcherJava中的 java.util.regex.Matcher的類對應

1.7.4.1.matchesmatch

是否徹底匹配正則式中沒必要使用 ^ $);matches爲靜態方法match爲實例方法做用都是同樣

DATAmatcher TYPE REF TO cl_abap_matcher,
      match 
TYPE match_result,
      match_line 
TYPE submatch_result.
"^$能夠省略由於matches方法自己就是徹底匹配整個Regex
IF cl_abap_matcher=>matchespattern '^(db(ai).*)$' text 'dbaiabd' ) = 'X'.
  matcher 
cl_abap_matcher=>get_object( )."獲取最後一次匹配到的 Matcher 實例
  match 
matcher->get_match( ). "獲取最近一次匹配的結果(是總體匹配的結果)
WRITE / matcher->text+match-offset(match-length).
LOOP AT  match-submatches INTO match_line"提取子分組括號括起來的部分
WRITE/20 match_line-offsetmatch_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDIF.

DATAmatcher TYPE REF TO cl_abap_matcher,
      match 
TYPE match_result,
      match_line 
TYPE submatch_result.
"^$能夠省略,由於matche方法自己就是徹底匹配整個Regex
matcher 
cl_abap_matcher=>createpattern '^(db(ai).*)$' text 'dbaiabd' ).
IF matcher->match(  ) = 'X'.
  match 
matcher->get_match( ). "獲取最近一次匹配的結果
WRITE / matcher->text+match-offset(match-length).
LOOP AT  match-submatches INTO match_line"提取子分組(括號括起來的部分)
WRITE/20 match_line-offsetmatch_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDIF.

1.7.4.2.contains

是否包含也可在正則式中使用 ^ $ 用於徹底匹配檢查或者使用 ^ 檢查是否匹配開頭或者使用 $ 匹配結尾

DATAmatcher TYPE REF TO cl_abap_matcher,
      match 
TYPE match_result,
match_line 
TYPE submatch_result.
IF cl_abap_matcher=>containspattern '(db(ai).{2}b)' text 'dbaiabddbaiabb' ) = 'X'.
  matcher 
cl_abap_matcher=>get_object( ). "獲取最後一次匹配到的 Matcher 實例
  match 
matcher->get_match( ). "獲取最近一次匹配的結果
WRITE / matcher->text+match-offset(match-length).
  
LOOP AT  match-submatches INTO match_line"提取子分組(括號括起來的部分)
WRITE/20 match_line-offsetmatch_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDIF.

1.7.4.3.find_all

一次性找出全部匹配的子串,包括子分組(括號括起的部分)

DATAmatcher TYPE REF TO cl_abap_matcher,
       match_line 
TYPE submatch_result,
      itab 
TYPE match_result_tab WITH HEADER LINE.
matcher 
cl_abap_matcher=>createpattern '<[^<>]*(ml)>' text '<html>hello</html>' )."建立 matcher 實例
":子分組存儲在itab-submatches字段裏
itab[] matcher->find_all( ).
LOOP AT itab .
WRITE/ matcher->textitab-offsetitab-length,matcher->text+itab-offset(itab-length).
  LOOP AT  itab-submatches INTO match_line"提取子分組(括號括起來的部分)
WRITE/20 match_line-offsetmatch_line-length,matcher->text+match_line-offset(match_line-length).
ENDLOOP.
ENDLOOP.

1.7.4.4.find_next

逐個找出匹配的子串,包括子分組(括號括起的部分)

DATAmatcher TYPE REF TO cl_abap_matcher,
      match 
TYPE match_result, match_line TYPE submatch_result,
      itab 
TYPE match_result_tab WITH HEADER LINE.
matcher 
cl_abap_matcher=>createpattern '<[^<>]*(ml)>' text '<html>hello</html>' ).
WHILE matcher->find_next( ) = 'X'.
  match 
matcher->get_match( )."獲取最近一次匹配的結果
WRITE/ matcher->textmatch-offsetmatch-length,matcher->text+match-offset(match-length).  
  
LOOP AT  match-submatches INTO match_line. "提取子分組(括號括起來的部分)
 
WRITE/20 match_line-offsetmatch_line-length,matcher->text+match_line-offset(match_line-length).
  ENDLOOP.
ENDWHILE.

1.7.4.5.get_lengthget_offsetget_submatch

DATAmatcher TYPE REF TO cl_abap_matcher,
      length 
TYPE i,offset TYPE i,
      submatch 
TYPE string.
matcher 
cl_abap_matcher=>createpattern '(<[^<>]*(ml)>)' text '<html>hello</html>' ).
WHILE matcher->find_next( ) = 'X'. "循環2
"0時,表示取整個Regex匹配到的子串,這與Java同樣,但若是整個Regex使用括號括起來後,
"則分組索引爲1,這又與Java不同(Java無論是否使用括號將整個Regex括起來,分組索引號都爲0
  "
上面Regex中共有兩個子分組,再加上整個Regex爲隱含分組,因此一共爲3
DO TIMES.
"在當前匹配到的串(整個Regex相匹配的串)中返回指定子分組的匹配到的字符串長度
    length 
matcher->get_lengthsy-index ).
"在當前匹配到的串(整個Regex相匹配的串)中返回指定子分組的匹配到的字符串起始位置
    offset 
matcher->get_offsetsy-index ).
"在當前匹配到的串(整個Regex相匹配的串)中返回指定子分組的匹配到的字符串
    submatch 
matcher->get_submatchsy-index ).
WRITE:/ length offset,matcher->text+offset(length),submatch.
ENDDO.
SKIP.
ENDWHILE.

1.7.4.6.replace_all

DATAmatcher TYPE REF TO cl_abap_matcher,
      count
 TYPE i,
      repstr 
TYPE string.
matcher 
cl_abap_matcher=>createpattern '<[^<>]*>' text '<html>hello</html>' ).
count
 matcher->replace_all``)."返回替換的次數
repstr 
matcher->text. "獲取被替換後的新串
WRITEcount repstr.

1.8.CLEARREFRESHFREE

內表:若是使用有表頭行的內表,CLEAR 僅清除表格工做區域。要重置整個內表而不清除表格工做區域,使用REFRESH語句或 CLEAR 語句CLEAR <itab>[].REFRESH加不加中括號都是隻清內表,另外REFRESH是專爲清內表的,不能清基本類型變量,但CLEAR能夠

以上都不會釋放掉內表所佔用的空間,若是想初始化內表的同時還要釋放所佔用的空間,請使用:FREE <itab>.

1.9.ABAP程序中的局部與全局變量

報表程序中選擇屏幕事件塊(AT SELECTION-SCREEN)與邏輯數據庫事件塊、以及methods(類中的方法)、subroutinesFORM子過程)、function modulesFunction函數)中聲明的變量爲局部的,即在這些塊裏聲明的變量不能在其餘塊裏使用,但這些局部變量能夠覆蓋同名的全局變量;除這些處理塊外,其餘塊裏聲明的變量都屬於全局的(如報表事件塊列表事件塊、對話Module),效果與在程序最開頭定義的變量效果是同樣的,因此能夠在其餘處理塊直接使用(但要注意的是,需遵照先定義後使用的原則,這種前後關係是從語句書寫順序來講的,與事件塊的自己運行順序沒有關係);另外,局部變量聲明時,無論在處理塊的任何地方,其效果都是至關於處理塊裏的全局變量,而不像其餘語言如Java那樣:局部變量的做用域能夠存在於任何花括號{}之間(這就意味着局部變量在處理過程範圍內是全局的),以下面的i,在ABAP語言中仍是會累加輸出,而不會永遠是1(在Java語言中會是1):

FORM aa.
DO 10 TIMES.
DATAi TYPE i VALUE 0.
1.
WRITEi.
ENDDO.
ENDFORM.

1.10.FormFunction

FormFunction中的TABLES參數,TYPELIKE後面只能接標準內表類型或標準內表對象,若是要使用排序內表或者哈希內表,則只能使用USINGForm)與CHANGING方式來代替。當把一個帶表頭的實參經過TABLES參數傳遞時,表頭也會傳遞過去,若是實參不帶表頭或者只傳遞了表體(使用了[]時),系統會自動爲內表參數變量建立一個局部空的表頭

無論是以TABLES仍是以USINGForm非值CHANGE非值方式傳遞時,都是以引用方式(即別名,不是指地址,注意與Java中的傳引用區別:Java實爲傳值,但傳遞的值爲地址的值,而ABAP中傳遞的是否爲地址,則要看實參是不是經過Type ref to定義的)傳遞;但若是USING值傳遞,則對形參數的修改不會改變實參,由於此時不是引用傳遞;但若是CHANGE值傳遞,對形參數的修改仍是會改變實參,只是修改的時機在Form執行或Function執行完後,纔去修改

Form中經過引用傳遞時,USINGCHANGING徹底同樣;但CHANGING爲值傳遞方式時,須要在Form執行完後,纔去真正修改實參變量的內容,因此CHANGING傳值與傳引用其結果都是同樣:結果都修改了實參內容,只是修改的時機不太同樣而已

1.10.1.FORM

FORM subr [TABLES t1 [{TYPE itab_type}|{LIKE itab}|{STRUCTURE struc}] 
t2 […]] 

[USING VALUE(p1)|p1 } [ { TYPE generic_type } 

| { LIKE <generic_fs>|generic_para }
TYPE {[LINE OF] complete_type}|{REF TO type} } 
| { 
LIKE {[LINE OF] dobj} | {REF TO dobj} }
STRUCTURE struc] 

{ VALUE(p2)|p2 } […]] 

[CHANGING{ VALUE(p1)|p1 } [ { TYPE generic_type } 

| { LIKE <generic_fs>|generic_para }  

| { TYPE {[LINE OF] complete_type} | {REF TO type} } 
| { 
LIKE {[LINE OF] dobj} | {REF TO dobj} } 
|
STRUCTURE struc] 

{ VALUE(p2)|p2 } […]] 

[RAISING {exc1|RESUMABLE(exc1)} {exc2|RESUMABLE(exc2)} ...].

generic_type:爲通用類型

complete_type:爲徹底限制類型

<generic_fs>:爲字段符號變量類型,以下面的 fs 形式參數

generic_para:爲另外一個形式參數類型,以下面的 b 形式參數

DATAd(10VALUE'11'.
FIELD-SYMBOLS<fs> LIKE d.
ASSIGN TO <fs>.
PERFORM aa USING <fs> d d.
FORM aa USING fs like <fs>  a like b like a.
WRITE:fs,/ a / b.
ENDFORM.

若是沒有給形式參數指定類,則爲ANY類型

若是TABLESUSINGCHANGING一塊兒使用時,則必定要按照TABLESUSINGCHANGING順序聲明

值傳遞中的VALUE關鍵字只是在FORM定義時出現,在調用時PERFORM語句中無需出現,也就是說,調用時值傳遞和引用傳遞不存在語法格式差異

 

DATA : i TYPE i VALUE 100.
WRITE: / 'frm_ref===='.
PERFORM frm_ref USING i .
WRITE: / i."200

WRITE: / 'frm_val===='.
i = 100.
PERFORM frm_val USING i .
WRITE: / i."100

WRITE: / 'frm_ref2===='.

"不能將下面的變量定義到frm_ref2過程當中,若是這樣,下面的dref指針在調用frm_ref2 後,指向的是Form中局部變量內存,爲不安全發佈,運行會拋異常,由於From結束後,它所擁有的全部變量內存空間會釋放掉
DATA: i_frm_ref2 TYPE i VALUE 400.
i = 100.
DATA: dref TYPE REF TO i .
get REFERENCE OF i INTO dref.
PERFORM frm_ref2 USING dref ."傳遞的內容爲地址,屬於別名引用傳遞
WRITE: / i."4000

field-SYMBOLS : <fs> TYPE i .
ASSIGN dref->* to <fs>."因爲frm_ref2過程當中已修改了dref的指向,現指向了i_frm_ref2 變量的內存空間
WRITE: / <fs>."400

WRITE: / 'frm_val2===='.
i = 100.
DATA: dref2 TYPE REF TO i .
get REFERENCE OF i INTO dref2.
PERFORM frm_val2 USING dref2 .
WRITE: / i."4000
ASSIGN dref2->* to <fs>.
WRITE: / <fs>."4000

FORM frm_ref  USING  p_i TYPE i ."C++中的引用參數傳遞p_i爲實參i的別名
WRITE: /  p_i."100
  p_i = 
200."p_i爲參數i的別名,因此能夠直接修改實參
ENDFORM.   

FORM frm_val  USING   value(p_i)."傳值p_i爲實參i的拷貝
WRITE: /  p_i."100
  p_i = 
300."因爲是傳值,因此不會修改主調程序中的實參的值
ENDFORM.
FORM frm_ref2 USING p_i TYPE REF TO i ."p_i爲實參dref的別名,相似C++中的引用參數傳遞(傳遞的內容爲地址,而且屬於別名引用傳遞)
field-SYMBOLS : <fs> TYPE i .
"如今<fs>就是實參所指向的內存內容的別名,表明實參所指向的實際內容
ASSIGN p_i->* to <fs>.
WRITE: /  <fs>."100
<fs> = 
4000."直接修改實參所指向的實際內存


DATA: dref TYPE REF TO i .
get REFERENCE OF i_frm_ref2 INTO dref.
"因爲USINGC++的引用參數,因此這裏修改的直接是實參所存儲的地址內容,這裏的p_i爲傳進來的dref的別名,是同一個變量,因此實參的指向也發生了改變(這與Java中傳遞引用是不同的,Java中傳遞引用時爲地址的拷貝,即Java中永遠也只有傳值,但C/C++/ABAP中能夠傳遞真正引用——別名)
  p_i = dref.
"此處會修改實參的指向 
ENDFORM.

FORM frm_val2 USING VALUE(p_i) TYPE REF TO i ."p_i爲實參dref2的拷貝,相似Java中的引用傳遞(雖然傳遞的內容爲地址,但傳遞的方式屬於地址拷貝——值傳遞)
field-SYMBOLS : <fs> TYPE i .
"如今<fs>就是實參所指向的內存內容的別名,表明實參所指向的實際內容
ASSIGN p_i->* to <fs>.
WRITE: /  <fs>."100
<fs> = 
4000."但這裏仍是能夠直接修改實參所指向的實際內容


DATA: dref TYPE REF TO i .
get REFERENCE OF i_frm_ref2 INTO dref.
"這裏與過程 frm_ref2 不同,該過程 frm_val2 參數的傳遞方式與java中的引用傳遞是原理是同樣的:傳遞的是地址拷貝,因此下面不會修改主調程序中實參dref2的指向,它所改變的只是拷貝過來的Form中局部形式參數的指向
  p_i = dref.  
ENDFORM.

1.10.2.FUNCTION

1.10.2.1.       Function Group結構

當使用Function Builder建立函數組時,系統會自動建立main program與相應的include程序:

l<fgrp>Function Group的名稱

lSAPL<fgrp>爲主程序名,它將Function Group裏的全部Include文件包括進來,除了INCLUDE語句以外,沒有其餘語句了

lL<fgrp>TOP,裏面有FUNCTION-POOL語句,以及全部Function Module均可以使用的全局數據定義

lL<fgrp>UXX,也只有INCLUDE語句,它所包括的Include文件爲相應具體Function Module所對應Include文件名:L<fgrp>U01L<fgrp>U02...這些Include文件實際上包含了所對應的Function Module代碼(即雙擊它們進去就是對應的Function,而顯示的不是真正Include文件所對應的代碼)

lL<fgrp>U01L<fgrp>U02中的0102編號對應L<fgrp>UXX中的「XX」,表明其建立前後的序號,例如L<fgrp>U01L<fgrp>U02是頭兩個被建立的函數,在函數組中建立出的函數代碼就放在相應的L<fgrp>UXX(這裏的XX表明某個數字,而不是字面上的XXInclude頭文件中

lL<fgrg>FXX,用來存一些Form子過程,而且能夠被全部Function Modules所使用(不是針對某個Function Module的,但通常在設計時會針對每一個Function Module設計這樣單獨的Include文件,這是一個好習慣),而且在使用時不須要在Function Module中使用INCLUDE語句包含它們(由於這些文件在主程序SAPL<fgrp>裏就已經被Include進來了)。另外,L<fgrg>FXX中的F是指Form的意思,這是一種名稱約束而已,在建立時咱們能夠隨便指定,通常還有IXX(表示些類Include文件包括的是一些PAI事件中調用的Module,有時乾脆直接使用L<fgrg>PAI或者L<fgrg>PAIXX),OXX(表示些類Include文件包括的是一些PBO事件中調用的Module,有時乾脆直接使用L<fgrg>PBO或者L<fgrg>PBOXX)。注:若是Form只被某一函數單獨使用,實質上還可直接將這些Form定義在Function Module裏的ENDFUNCTION語句後面

 

當你調用一個function module時,系統加將整個function group(包括Function ModuleInclude文件等)加載到主調程序所在的internal session中,而後該Function Module獲得執行,該Function Group一直保留在內存中,直到internal session結束。Function Group中的所定義的Include文件中的變量是全局,被全部Function Module共享,因此Function Group比如Java中的類,而Function Module則比如類中的方法,因此Function Group中的Include文件中定義的東西是全局型的,能被全部Function Module所共享使用

1.10.2.2.Function參數傳值、傳址

function fuc_ref .
*"-------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(I_I1) TYPE  IREFERENCE別名爲參數的默認傳遞類型
*"     VALUE(I_I2) TYPE  I        定義時勾選了Pass Value選項纔會是 VALUE類型
*"     REFERENCE(I_I3) TYPE REF TO  I
*"     VALUE(I_I4) TYPE REF TO  I
*"  EXPORTING
*"     REFERENCE(E_I1) TYPE  I
*"     VALUE(E_I2) TYPE  I
*"     REFERENCE(E_I3) TYPE REF TO  I
*"     VALUE(E_I4) TYPE REF TO  I
*"  TABLES
*"      T_1 TYPE  ZJZJ_ITAB
*"  CHANGING
*"     REFERENCE(C_I1) TYPE  I
*"     VALUE(C_I2) TYPE  I
*"     REFERENCE(C_I3) TYPE REF TO  I
*"     VALUE(C_I4) TYPE REF TO  I
*"-------------------------------------------------------------------
write: / i_i1."1
"因爲i_i1爲輸入類型參數且又是引用類型實參不能被修改。這裏i_i1是以C++中的引用(別名)參數方式傳遞參數,因此若是修改了i_i1就會修改實際參數,因此函數中不能修改REFERENCE  IMPORTING類型的參數,若是去掉下面註釋則編譯出錯
"i_i1 = 10.

write: / i_i2."2
"雖然i_i2是輸入類型的參數,但不是引用類型,因此能夠修改,編譯能經過但不會修改外面實參的值,只是修改了該函數局部變量的值
i_i2 = 20.

field-symbols: <fs> type i .
assign i_i3->* to <fs>.
"因爲i_i3存儲的是地址,因此先要解引用再能使用
write: / <fs>.
"同上面,REFERENCEIMPORTING類型的參數不能被修改:這裏即不能修改實參的指向"GET REFERENCE OF 30 INTO i_i3."雖然不能夠修改實參的指向,但能夠修改實參所指向的實際內容
<fs> = 
30.

assign i_i4->* to <fs>.
"i_i4存儲也的是地址,因此先要解引用再能使用
write: / <fs>.
"雖然i_i4是輸入類型的參數,但不是引用類型,因此能夠修改,只會修改函數中的局部參數i_i4的指向,但並不會修改實參的指向
get reference of 40 into i_i4.
"雖然不能修改實參的指向,但能夠直接修改實參的所指向的實際內容
<fs> = 
400.

WRITE: / c_i1."111
"c_i1爲實參的別名,修改形參就等於修改實參內容
c_i1 = 
1110.

WRITE: / c_i2."222
"c_i2爲實參的副本,因此不會影響實參的內容,可是,因爲是CHANGING類型的參數,且爲值傳遞,在函數正常執行完後,仍是會將該副本再次拷貝給實參,因此最終實參仍是會被修改
c_i2 = 
2220.
ENDFUNCTION.

 

調用程序:

DATA: i_i1 TYPE i VALUE 1,
      i_i2 
TYPE i VALUE 2,
      i_i3 
TYPE REF TO i ,
      i_i4 
TYPE REF TO i ,
      c_i1 
TYPE i VALUE 111,
      c_i2 
TYPE i VALUE 222,
      c_i3 
TYPE REF TO i ,
      c_i4 
TYPE REF TO i ,
      t_1 
TYPE zjzj_itab WITH HEADER LINE.

DATA: i_i3_ TYPE i VALUE 3.
GET REFERENCE OF i_i3_ INTO i_i3.
DATA: i_i4_ TYPE i VALUE 4.
GET REFERENCE OF i_i4_ INTO i_i4.
DATA: c_i3_ TYPE i VALUE 333.
GET REFERENCE OF c_i3_ INTO c_i3.
DATA: c_i4_ TYPE i VALUE 444.
GET REFERENCE OF c_i4_ INTO c_i4.

CALL FUNCTION 'FUC_REF'
EXPORTING
    i_i1 = i_i1
    i_i2 = i_i2
    i_i3 = i_i3
    i_i4 = i_i4
TABLES
    t_1 = t_1
CHANGING
    c_i1 = c_i1
    c_i2 = c_i2
    c_i3 = c_i3
    c_i4 = c_i4.
WRITE: / i_i2."2
WRITE: / i_i3_."30
WRITE: / i_i4_."400
WRITE: / c_i1."1110
WRITE: / c_i2."2220

1.11.     字段符號FIELD-SYMBOLS

字段符號能夠看做僅是已經被解引用的指針(相似於C語言中帶有解引用操做符 * 的指針),但更像是C++中的引用類型(int i ;&ii= i;),即某個變量的別名,它與真正的指針仍是有很大的區別的,在ABAP中引用變量(經過TYPE REF TO定義的變量)才比如C語言中的指針

ASSIGN ... TO <fs>:將某個內存區域分配給字段符號,這樣字段符號就表明了該內存區域,即該內存區域別名

1.11.1.ASSIGN隱式強轉

TYPESBEGIN OF t_date,
  year(
4TYPE  n,
  month(
2TYPE n,
  day(
2TYPE n,
END OF t_date.

FIELD-SYMBOLS <fs> TYPE t_date."<fs>定義成了具體限定類型
ASSIGN sy-datum TO <fs> CASTING. "後面沒有指定具體類型,因此使用定義時的類型進行隱式轉換

1.11.2.ASSIGN顯示強轉

DATA txt(8TYPE c VALUE '19980606'.
FIELD-SYMBOLS <fs>.
ASSIGN txt TO <fs> CASTING TYPE d."因爲定義時未指定具體的類型,因此這裏須要顯示強轉

1.11.3.ASSIGN 動態分配

請參考動態語句à ASSIGN 動態分配

1.11.4.UNASSIGNCLEAR

UNASSIGN:該語句是初始化<FS>字段符號,執行後字段符號將再也不引用內存區域,<fs> is assigned返回假

CLEAR:與UNASSIGN不一樣的是,只有一個做用就是初始化它所指向的內存區域,而不是解除分配

1.12.數據引用、對象引用

TYPE REF TO data                     數據引用data references

TYPE REF TO object               對象引用object references

除了object全部的通用類型都能直接用TYPE後面TYPE data但沒有TYPE object,object不能直接跟在TYPE後面只能跟在TYPE REF TO後面

TYPE REF TO 後面可接的通用類型只能data(數據引用)或者是object對象引用通用類型其餘通用類型不行

1.12.1.數據引用Data References

DATAdref TYPE REF TO i ."dref即爲數據引用,即數據指針,指向某個變量或常量,存儲變量地址
CREATE DATA dref.
dref
->2147483647."可直接解引用使用不須要先經過分配給字段符號後再使用

DATABEGIN OF strct,
c,
END OF strct.
DATAdref LIKE REF TO strct .
CREATE DATA dref .
dref
->*-'A'.

 

TYPEStpy TYPE c.
DATAc1 TYPE REF TO tpy.
DATAc2 LIKE REF TO c1."二級指針
GET REFERENCE OF 'a' INTO c1.
GET REFERENCE OF c1 INTO c2.
WRITEc2->*->*."a

1.12.2.對象引用Object references

CLASS cl DEFINITION.
PUBLIC SECTION.
DATAi VALUE 1.
ENDCLASS.
CLASS cl IMPLEMENTATION.
ENDCLASS.

 

DATAobj TYPE REF TO cl.
CREATE OBJECT obj. "建立對象

DATAoref LIKE REF TO obj. "oref即爲對象引用,即對象指針,指向某個對象,存儲對象地址
GET REFERENCE OF obj INTO oref. "獲取對象地址
WRITEoref->*->i."1

1.12.3.GET REFERENCE OF獲取變量/對象/常量地址

DATAe_i3 TYPE REF TO i .
GET REFERENCE OF 33 INTO e_i3.
WRITEe_i3->*."33
"但不能修改常量的值
"e_i3->* = 44.

DATAi TYPE i VALUE 33,
      dref 
LIKE REF TO i."存儲普通變量的地址
GET REFERENCE OF i INTO dref.
dref
->44.
WRITEi"44

1.13.動態語句

1.13.1.內表動態訪問

SORT itab BY (comp1)...(compn)

 

READ TABLE itab WITH KEY(k1)=v1...(kn)=vn

READ TABLE itab...INTOwaCOMPARING(comp1)...(compn) TRANSPORTING(comp1)...

MODIFY [TABLE] itab TRANSPORTING(comp1)...(compn)

DELETE TABLEitabWITH TABLE KEY(comp1)...(compn)

DELETE ADJACENT DUPLICATES FROM itab COMPARING(comp1)...(compn)

 

AT NEW/END OF (comp)

1.13.2.動態類型

CREATE DATA ... TYPE (type)...

DATA: a TYPE REF TO i.
CREATE DATA a TYPE ('I').
a->* = 1.

CREATE OBJECT ... TYPE (type)...請參考類對象反射章節

1.13.3.動態SQL

Select請參照後面的動態SQL

MODIFY/UPDATE(dbtab)...

1.13.4.動態調用類的方法

CALL METHOD (meth_name)
            | cref->(meth_name)
            | iref->(meth_name)
            | (class_name)=>(meth_name)
            | class=>(meth_name)
            | (class_name)=>meth

實例請參考類對象反射章節

1.13.5.ASSIGN 動態分配

FIELD-SYMBOLS:<fs>.

DATA:str(20TYPE c VALUE 'Output String',
     name
(20TYPE c VALUE 'STR'.

"靜態分配:編譯時就知道要分配的對象名
ASSIGN name TO <fs>."結果<fs>name變量等同

"經過變量名動態訪問變量
ASSIGN (nameTO <fs>."結果是是<fs>的值爲str變量值

 

DATABEGIN OF line,
  col1 
TYPE i VALUE '11',
  col2 
TYPE i VALUE '22',
  col3 
TYPE i VALUE '33',
END OF line.
DATA comp(5VALUE 'COL3'.
FIELD-SYMBOLS<f1><f2><f3>.
ASSIGN line TO <f1>.
ASSIGN comp TO <f2>.

"還可以直接使用如下的語法訪問其餘程序中的變量
ASSIGN ('(ZJDEMO)SBOOK-FLDATE'TO <fs>.

"經過索引動態的訪問結構成員
ASSIGN COMPONENT sy-index OF STRUCTURE <f1> TO <f3>.

"經過字段名動態的訪問結構成員
ASSIGN COMPONENT <f2>OF STRUCTURE <f1> TO <f3>.

"若是定義的內表沒有組件名時,能夠使用索引爲0的組件來訪問這個無名字段(注:不是1)
ASSIGN COMPONENT 0 OF STRUCTURE itab TO  <fs>.

1.13.5.1.動態訪問類的屬性成員

ASSIGN oref->('attr') TO <attr>.
ASSIGN oref->('static_attr') TO <attr>.
ASSIGN ('C1')=>('static_attr') TO <attr>.
ASSIGN c1=>('static_attr') TO <attr>.
ASSIGN ('C1')=>static_attr TO <attr>.

實例請參考類對象反射章節

1.14.反射

CL_ABAP_TYPEDESCR

  |--CL_ABAP_DATADESCR

  |   |--CL_ABAP_ELEMDESCR

  |   |--CL_ABAP_REFDESCR

  |   |--CL_ABAP_COMPLEXDESCR

  |       |--CL_ABAP_STRUCTDESCR

  |       |--CL_ABAP_TABLEDESCR

  |--CL_ABAP_OBJECTDESCR

     |--CL_ABAP_CLASSDESCR

     |--CL_ABAP_INTFDESCR

DATA: structtype  TYPE REF TO cl_abap_structdescr.
structtype ?= cl_abap_typedescr=>describe_by_name'spfli' ).

*COMPDESC-TYPE ?= CL_ABAP_DATADESCR=>DESCRIBE_BY_NAME( 'EKPO-MATNR' ).

DATA: datatype TYPE REF TO cl_abap_datadescr,
field(5TYPE c.
datatype ?= cl_abap_typedescr=>describe_by_datafield ).

 

DATA: elemtype TYPE REF TO cl_abap_elemdescr.
elemtype = cl_abap_elemdescr=>get_i( ).
elemtype = cl_abap_elemdescr=>
get_c20 ).

 

DATAoref1 TYPE REF TO object.
DATAdescr_ref1 TYPE REF TO cl_abap_typedescr.
CREATE OBJECT oref1 TYPE ('C1'). "C1爲類名
descr_ref1 
cl_abap_typedescr=>describe_by_object_ref( oref1 ).

還有一種:describe_by_data_ref

1.14.1.TYPE HANDLE

handle只能是CL_ABAP_DATADESCR或其子類的引用變量只能用於Data類型,不能用於Object類型即不能用於CL_ABAP_ OBJECTDESCR因此沒有:

CREATE OBJECT dref TYPE HANDLE objectDescr.

 

DATAdref TYPE REF TO data,
c10type 
TYPE REF TO cl_abap_elemdescr.
c10type 
cl_abap_elemdescr=>get_c10 ).
CREATE DATA dref TYPE HANDLE c10type.

DATAx20type TYPE REF TO cl_abap_elemdescr.
x20type 
cl_abap_elemdescr=>get_x20 ).
FIELD-SYMBOLS<fs> TYPE any.
ASSIGN dref->TO <fs> CASTING TYPE HANDLE x20type.

1.14.2.動態建立數據Data或對象Object

  TYPESty_i TYPE i.
DATAdref TYPE REF TO ty_i .
 CREATE DATA dref TYPE ('I')."根據基本類型名動態建立數據
  dref->1.
WRITE/ dref->*." 1

  CREATE OBJECT oref TYPE ('C1')."根據類名動態建立實例對象

1.14.3.動態建立基本類型變量、結構、內表

DATAdref_str TYPE REF TO data,
      dref_tab 
TYPE REF TO data,
      dref_i 
TYPE REF TO data,
  itab_type 
TYPE REF TO cl_abap_tabledescr,
  struct_type 
TYPE REF TO cl_abap_structdescr,
  elem_type 
TYPE REF TO cl_abap_elemdescr,
  table_type 
TYPE REF TO cl_abap_tabledescr,
  comp_tab 
TYPE cl_abap_structdescr=>component_table WITH HEADER LINE.
FIELD-SYMBOLS :<fs_itab> TYPE ANY TABLE.

**=========動態建立基本類型
elem_type ?= cl_abap_elemdescr=>get_i( ).
CREATE DATA dref_i TYPE HANDLE elem_type ."動態的建立基本類型數據對象

**=========動態建立結構類型
struct_type ?= cl_abap_typedescr
=>describe_by_name'SFLIGHT' )."結構類型
comp_tab[] 
struct_type->get_components( )."組成結構體的各個字段組件
向結構中動態的新增一個成員
comp_tab-name 'L_COUNT'."爲結構新增一個成員
comp_tab-type elem_type."新增成員的類型對象
INSERT comp_tab INTO comp_tab INDEX 1.
動態建立結構類型對象
struct_type 
cl_abap_structdescr=>createcomp_tab[] ).
CREATE DATA dref_str TYPE HANDLE struct_type."使用結構類型對象來建立結構對象

**=========動態建立內表
基於結構類型對象建立內表類型對象
itab_type cl_abap_tabledescr=>createstruct_type ).
CREATE DATA dref_tab TYPE HANDLE itab_type."使用內表類型對象來建立內表類型
ASSIGN dref_tab->TO <fs_itab>."將字段符號指向新建立出來的內表對象

"**========給現有的內表動態的加一列
table_type ?= cl_abap_tabledescr
=>describe_by_dataitab ).
struct_type ?= table_type
->get_table_line_type( ).
comp_tab[] 
struct_type->get_components( ).
comp_tab
-name 'FIDESC'.
comp_tab
-type cl_abap_elemdescr=>get_c120 ).
INSERT comp_tab INTO comp_tab INDEX 2.
struct_type 
cl_abap_structdescr=>createcomp_tab[] ).
itab_type 
cl_abap_tabledescr=>createstruct_type ).
CREATE DATA dref_tab TYPE HANDLE itab_type.

1.14.4.類對象反射

CLASS c1 DEFINITION.
PUBLIC SECTION.
DATAc VALUE 'C'.
METHODStest.
ENDCLASS.

CLASS c1 IMPLEMENTATION.
METHOD:test.
WRITE:'test'.
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
TYPESty_c.
DATAoref TYPE REF TO object .
DATAoref_classdescr TYPE REF TO cl_abap_classdescr .
CREATE OBJECT oref TYPE ('C1')."根據類名動態建立實例對象
"至關於Java中的Class類對象
 oref_classdescr ?= cl_abap_classdescr
=>describe_by_object_reforef ).

DATAt_attrdescr_tab TYPE abap_attrdescr_tab WITH HEADER LINE,"類中的屬性列表
        t_methdescr_tab 
TYPE abap_methdescr_tab WITH HEADER LINE."類中的方法列表
FIELD-SYMBOLS <fs_attr> TYPE any.
  t_attrdescr_tab[] 
oref_classdescr->attributes.
  t_methdescr_tab[] 
oref_classdescr->methods.
LOOP AT t_attrdescr_tab."動態訪問類中的屬性
ASSIGN oref->(t_attrdescr_tab-name) TO <fs_attr>.
    WRITE/ <fs_attr>.
ENDLOOP.
LOOP AT t_methdescr_tab."動態訪問類中的方法
CALL METHOD oref->(t_methdescr_tab-name).
  ENDLOOP.

2.面向對象

2.1.  類與接口定義

CLASS class DEFINITION [ABSTRACT][FINAL]
  [
PUBLIC SECTION
    [
components]] 
  [
PROTECTED SECTION
    [
components]] 
  [
PRIVATE SECTION
    [
components]] 
ENDCLASS

INTERFACE intf
  [
components
ENDINTERFACE

2.1.1.   components

²TYPES, DATA, CLASS-DATA, CONSTANTS  for data types and data objects

²METHODS, CLASS-METHODS, EVENTS, CLASS-EVENTS for methods and events

²  INTERFACES若是在類中,表示須要實現哪一個接口;若是是在接口中,表示繼承哪一個接口 for implementing interfaces

²  ALIASESfor alias names for interface components給接口組件取別名

2.2.類定義、實現

CLASS math DEFINITION.
PUBLIC SECTION.
METHODS divide_1_by
IMPORTING operand TYPE i
EXPORTING result  TYPE f
RAISING cx_sy_arithmetic_error.
ENDCLASS.
CLASS math IMPLEMENTATION.
METHOD divide_1_by.
    result 
/ operand.
ENDMETHOD.
ENDCLASS.

2.3.接口定義、實現

INTERFACEint1.

ENDINTERFACE.

CLASSclass DEFINITION.                        [ˌdefiˈniʃən]
PUBLICSECTION.
INTERFACES: int1,int2."實現多個接口
ENDCLASS.

CLASS class IMPLEMENTATION.                     [ˌɪmplɪmənˈteɪ-ʃən]
METHOD
intf1~imeth1.
ENDMETHOD.
ENDCLASS.

2.4.類、接口繼承

CLASS<subclass> DEFINITIONINHERITINGFROM<superclass>.[inˈherit]

 

INTERFACE i0.
METHODS m0.
ENDINTERFACE.
INTERFACE i1.
INTERFACES i0.
  
"能夠有相同的成員名由於繼承過來後成員仍是具備各自的命名空間在實現時
"被繼承過來的叫 i0~m0這裏的名爲i1~m0因此是不一樣的兩個方法
METHODS m0.
METHODS m1.
ENDINTERFACE.

2.5.  向下強轉型 ?=

CLASS person DEFINITION.

ENDCLASS.

CLASS stud DEFINITION INHERITING FROMperson.

ENDCLASS.

 

START-OF-SELECTION.

  DATA p TYPE REF TO person.

  DATA s TYPE REF TO stud.

  CREATE OBJECT s.

  p = s. "向上自動轉型

  "拿開註釋運行時拋異常,由於P此時指向的對象不是Student,而是Person因此能強轉的前提是P指向的是Student

  "CREATE OBJECT p.

  s ?= p."向下強轉型

2.6.  方法

METHODS/CLASS-METHODS meth [ABSTRACT|FINAL
    [
IMPORTING parameters [PREFERRED PARAMETER p]] 
    [
EXPORTING parameters
    [
CHANGING parameters
    [{
RAISING|EXCEPTIONS} exc1 exc2 ...].

應該還有一個Returning選項,RETURNING不能與EXPORTINGCHANGING同時使用

2.6.1.parameters

... { VALUE(p1) | REFERENCE(p1) | p1 }
{ TYPE generic_type }
|{TYPE{[LINE OF]
complete_type}|{REF TO {data|object|complete_type |class|intf}}}
|{LIKE{[LINE OF] dobj}|{REF TO dobj} }
[OPTIONAL|{DEFAULT def1}]
     { VALUE(p2) | REFERENCE(p2) | p2 }...

²dataobject表示是通用數據類型dataobject

²complete_type爲徹底限定類型

²OPTIONALDEFAULT兩個選項不能同時使用且對於EXPORTING類型的輸入參數不能使用

²若是參數名p1前沒有使用VALUEREFERENCE默認爲仍是REFERENCE即引用傳遞

²方法中的輸入輸出參數是否能修改請參考FormFunction參數的傳值傳址

2.6.2.   PREFERRED PARAMETER首選參數

設置多個IMPORTING類型參數中的某一個參數爲首選參數。

首選參數的意義在於:當全部IMPORTING類型都爲可選optional時,咱們能夠經過PREFERRED PARAMETER選項來指定某一個可選輸入參數爲首選參數,則在如下簡單方式調用時:[CALL METHOD] meth). 實參a的值就會傳遞給設置的首選參數,而其餘不是首參數的可選輸入參數則留空或使用DEFAULT設置的默認值

注:此選項只能用於IMPORTING類型的參數;若是有必選的IMPORTING輸入參數,則沒有意義了

2.6.3.   普通調用

[CALL METHOD]  meth|me->meth|oref->meth|super->meth|class=>meth[(]

[EXPORTING  p1 = a1 p2 = a2 ...]

{ {[IMPORTING  p1=a1 p2=a2 ...][CHANGING p1 = a1 p2 = a2 ...]}

|[RECEIVING  r  = a  ] } RECEIVING不能與EXPORTINGCHANGING同時使用

[EXCEPTIONS [exc1 = n1 exc2 = n2 ...]

[OTHERS = n_others] ] [)].

若是省略CALL METHOD,則必定要加上括號形式若是經過CALL METHOD來調用,則括號可加可不加

RECEIVING:用來接收METHODS /CLASS-METHODS RETURNING選項返回的值

若是EXPORTINGIMPORTINGCHANGINGRECEIVINGEXCEPTIONSOTHERS同時出現時,應該按此順序來編寫

使用此種方式調用(使用 EXPORTINGIMPORTING等這些選項)時,若是原方法聲明時帶了返回值RETURNING,只能使用RECEIVING來接受,而不能使用等號來接收返回值,下面用法是錯誤的:

num2 o1->m1EXPORTING p1 num1 ).

2.6.4.   簡單調用

此方式下輸入的參數都只能是IMPORTING類型的參數,若是要傳CHANGINGEXPORTINGRAISINGEXCEPTIONS類型的參數時,只能使用上面通用調用方式

²meth( )

此種方式僅適用於沒有輸入參數IMPORTING輸入\輸出參數CHANGING或者有但都是可選的、或者不是可選時但有默認值也可

²meth( a )

此種方式僅適用於只有一個必選輸入參數IMPORTING)(若是還有其餘輸入參數,則其餘都爲可選,或者不是可選時但有默認值也可),或者是有多個可選輸入參數IMPORTING)(此時沒有必選輸入參數狀況下)的狀況下但方法聲明時經過使用PREFERRED PARAMETER選項指定了其中某個可選參數爲首選參數(首選參數即在使用meth( a )方式傳遞一個參數進行調用時,經過實參a傳遞給設置爲首選的參數

²meth( p1 = a1 p2 = a2 ... )

此種方式適用於有多個必選的輸入參數IMPORTING)方法的調用(其它如CHANGINGEXPORTING沒有,或者有但可選),若是輸入參數(IMPORTING)爲可選,則也能夠沒必要傳

2.6.5.函數方法

Return惟一返回值

METHODS meth
    [IMPORTING
parameters [PREFERRED PARAMETER p]]
    RETURNINGVALUE(r) typing
    [{RAISING|EXCEPTIONS} exc1 exc2 ...].

 

RETURNING 用來替換EXPORTINGCHANGING不能同時使用。定義了一個形式參數 r 來接收返回值而且只能是值傳遞

具備惟一返回值的函數方法能夠直接用在如下語句中邏輯表達式IFELSEIFWHILECHECKWAITCASELOOP、算術表達式、賦值語句

函數方法能夠採用上面簡單調用方式來調用meth( )meth( a )meth( p1 = a1 P2 = a2 ... )

 

  ref->mRECEIVING  r ).
CALL METHOD ref->mRECEIVING r ).
CALL METHOD ref->RECEIVING r i.

2.7.mesuper

等效於Java中的 thissuper

2.8.  事件

2.8.1.   事件定義

EVENTS|CLASS-EVENTS evt [EXPORTING VALUE(p1)
{ TYPE generic_type }
|{TYPE {[LINE OF] complete_type} |
{ REF TO {data|object|complete_type|class|intf}} }
| {LIKE{[LINE OF] dobj} | {REF TO dobj} }
[OPTIONAL|{DEFAULT def1}]

VALUE(p2) ...].

²dataobject:表示是通用數據類型dataobject

²complete_type:爲徹底限定類型

²  OPTIONALDEFAULT兩個選項不能同時使用

²EXPORTING:定義了事件的輸出參數,而且事件定義時只能有輸出參數,且只能是傳值

 

非靜態事件聲明中除了明確使用EXPORTING定義的輸出外,每一個實例事件其實還有一個隱含的輸出參數sender,它指向了事件源對象,當使用RAISE EVENT語句觸發一個事件時,事件源的對象就會分配給這個sender引用,可是靜態事件沒有隱含參數sender

 

事件evt的定義也是接口定義部分進行定義的

非靜態事件只能在非靜態方法中觸發,而不能在靜態方法中觸發;而靜態事件便可在靜態也可在非靜態方法中進行觸發,或者反過來講:實例方法既可觸發靜態事件,也可觸發非靜態事件,但靜態方法就只能觸發靜態事件

2.8.2.   事件觸發

RAISE EVENT evt [EXPORTING p1 = a1 p2 = a2 ...].

該語句只能在定義evt事件的同一類或子類或接口實現方法中進行調用

 

當實例事件觸發時若是在event handler事件處理器聲明語句中指定了形式參數sender則會自動接收事件源但不能在RAISE EVENT …EXPORTING語句中明確指定它會自動傳遞(若是是靜態事件,則不會傳遞sender參數)

CLASS c1 DEFINITION.
PUBLIC SECTION.
      EVENTS e1 EXPORTING value(p1TYPE string value(p2TYPE i OPTIONAL. "定義
METHODS m1.
ENDCLASS.
CLASS c1 IMPLEMENTATION.
METHOD m1.
RAISE EVENT e1 EXPORTING p1 '...'."觸發
ENDMETHOD.
ENDCLASS.

2.8.3.事件處理器Event Handler

靜態或非靜態事件處理方法均可以處理靜態或非靜態事件,與事件的靜態與否沒有直接的關係

INTERFACE window. "窗口事件接口
 
EVENTS: minimize EXPORTINGVALUE(status) TYPE i."最小化事件
ENDINTERFACE.

CLASS dialog_window DEFINITION. "
窗口事件實現
 PUBLIC SECTION.
  INTERFACES window.
ENDCLASS.

INTERFACE window_handler. "
窗口事件處理器接口
  METHODS: minimize_window 
FOR EVENT window~minimize OF dialog_window
IMPORTING status sender. "事件處理器方法參數要與事件接口定義中的一致
ENDINTERFACE.

2.8.4.   註冊事件處理

實例事件處理器(方法)註冊(注:被註冊的方法只能是用來處理非靜態事件的方法):

SET HANDLER handler1 handler2 ... FOR oref|{ALL INSTANCES}[ACTIVATION act].

靜態事件處理器(方法)註冊(注:被註冊的方法只能是用來處理靜態事件的方法):

SET HANDLER handler1 handler2 ... [ACTIVATION act].

oref:只將事件處理方法handler1 handler2註冊到 oref 這一個事件源對象

ALL INSTANCES:將事件處理方法註冊到全部的事件源實例中

ACTIVATION act:表示是註冊仍是註銷

2.8.5.   示例

CLASS c1 DEFINITION."事件源
PUBLIC SECTION.
EVENTSe1 EXPORTING value(p1TYPE c,e2.
CLASS-EVENTS ce1 EXPORTING value(p2TYPE i.
METHODS:trigger."事件觸發方法
ENDCLASS.

CLASS  c1 IMPLEMENTATION.
METHOD trigger.
RAISE EVENTe1 EXPORTING p1 'A',e2,ce1 EXPORTING p2 1.
ENDMETHOD.
ENDCLASS.

靜態(以下面的h1方法)或非靜(以下面的h2方法)態事件處理方法均可以處理靜態或非靜態事件,事件的處理方法是否只能處理靜態的仍是非靜態事件事件的靜態與否沒有關係,但事件的觸發方法事件的靜態與否有關係實例方法既可觸發靜態事件,也可觸發非靜態事件,但靜態方法就只能觸發靜態事件);可是,事件處理方法雖然能處理的事件與事件的靜態與否沒有關係,但若是處理的是靜態事件,那此處理方法就成爲了靜態處理器,只能採用靜態註冊方式對此處理方法進行註冊。若是處理的是非靜態事件,那此處理方法就是非靜態處理器,只能採用非靜態註冊方式對此處理方法進行註冊

處理器的靜態與否與處理方法自己是否靜態沒有關係,只與處理的事件是否靜態有關


CLASS c2 DEFINITION."監聽器即事件處理器
PUBLIC SECTION.
"靜態方法也能夠處理非靜態事件此方法屬於非靜態處理器只能採用非靜態註冊方式
CLASS-METHODS h1 FOR EVENT e1 OF c1 IMPORTING p1 sender.
"非靜態方法處理非靜態事件此方法屬於非靜態處理器只能採用非靜態註冊方式
METHODSh2 FOR EVENT e2 OF c1 IMPORTING sender
"非靜態方法固然更能夠處理靜態事件此方法屬於靜態處理器只能採用靜態註冊方式
             h3 
FOR EVENT ce1 OF c1 IMPORTING p2.
ENDCLASS.
CLASS c2 IMPLEMENTATION.
METHOD h1 .
WRITE'c2=>h1'.
ENDMETHOD.
METHODh2.
WRITE'c2->h2'.
ENDMETHOD.
METHODh3.
WRITE'c2->h3'.
ENDMETHOD.
ENDCLASS.

DATAtrigger TYPE REF TO c1,
      trigger2 
TYPE REF TO c1,
handler TYPE REF TO c2.
START-OF-SELECTION.
CREATE OBJECT trigger.
CREATE OBJECT trigger2.
CREATE OBJECT handler.
  "因爲h1h2兩個處理方法分別是用來處理非靜態事件e1e2的,因此只能採用實例註冊方式
SET HANDLERc2=>h1 handler->h2 FOR trigger,
"h3處理方法是用來處理靜態事件ce1的,屬於靜態處理器,因此只能採用靜態註冊方式
                 handler
->h3.
  trigger
->trigger( ).
  "雖然trigger( )方法會觸發 e1,e2,ce1 三種事件,但h1h2未向實例trigger2註冊,而h3屬於靜態處理器,與實例無關,即比如向全部實例註冊過了同樣
  trigger2
->trigger( ).

3.   內表

3.1.LOOP AT循環內表

LOOP AT itab {INTO wa}|{ASSIGNING <fs> [CASTING]}|{TRANSPORTING NO FILDS
[[
USING KEY key_name|(name)] [FROM idx1] [TO idx2] [WHERE log_exp|(cond_syntax)]]

ENDLOOP.

FROM … TO: 只適用於標準表與排序表          WHERE …  : 適用於全部類型的內表

若是沒有經過USING KEY選項的key_name則循環讀取的順序與表的類型相關

l標準表與排序表會按照primary table index索引的順序一條條的循環且在循環裏SY-TABIX爲當前正在處理行的索引號

l  哈希表因爲表沒有排序因此按照插入的順序來循環處理,注,此時SY-TABIX 老是0

能夠在循環內表時增長與刪除當前行If you insert or delete lines in the statement block of a LOOP , this will have the following effects:

  • If you insert lines behind(後面) the current line, these new lines will be processed in the subsequent loop(新行會在下一次循環時被處理) passes. An endless loop(可能會引發死循環)can result
  • If you delete lines behind the current line, the deleted lines will no longer be processed in the subsequent loop passes
  • If you insert lines in front(前面) of the current line, the internal loop counter is increased by one with each inserted line. This affects sy-tabix in the subsequent loop pass(這會影響在隨後的循環過程SY-TABIX)
  • If you delete lines in front of the current line, the internal loop counter is decreased by one with each deleted line. This affects sy-tabix in the subsequent loop pass

3.1.1.循環中刪除行

DATA : BEGIN OF gt_table OCCURS 0,

       c,

END OF gt_table.

 

APPEND 'a' TO gt_table.

APPEND 'b' TO gt_table.

APPEND 'c' TO gt_table.

APPEND 'd' TO gt_table.

APPEND 'e' TO gt_table.

APPEND 'f' TO gt_table.

APPEND 'g' TO gt_table.

APPEND 'h' TO gt_table.

 

LOOP AT gt_table .

  IF gt_table-c = 'b' OR gt_table-c = 'c' OR gt_table-c = 'e'.

    WRITE : /  sy-tabix COLOR = 6 INTENSIFIED ON INVERSE OFF ,

               gt_table COLOR = 6 INTENSIFIED ON INVERSE OFF .

  ELSE.

    WRITE : /  sy-tabix, gt_table.

  ENDIF.

ENDLOOP.

 

SKIP 2.

DATA count TYPE i .

LOOP AT gt_table .

  count = count + 1.

  "當循環到第三次時刪除,即循環到 C 時進行刪除

  IF count = 3.

    DELETE gt_table WHERE c = 'b' OR c = 'c' OR c = 'e'.

  ENDIF.

  "刪除以後sy-tabix會從新開始對內表現有的行進行編號

  WRITE :/ sy-tabix, gt_table.

ENDLOOP.

 

SKIP 2.

 

LOOP AT gt_table .

    WRITE : /  sy-tabix, gt_table.

ENDLOOP.

 

 

3.1.2.SUM

若是在 AT - ENDAT 塊中使用 SUM則系統計算當前行組中全部行的數字字段之和並將其寫入工做區域中相應的字段中

3.1.3.    AT...ENDAT

<line>

含義

FIRST

內表的第一行時觸發

LAST

內表的最後一行時觸發

NEW <f>

相鄰數據行中相同<f>字段構成一組,在循環到該組的開頭時觸發

END Of <f>

相鄰數據行中相同<f>字段構成一組,在循環到該組最末時觸發

在使用AT...... ENDAT以前,一這要先按照這些語句中的組件名進行排序,且排序的順序要與在AT...... ENDAT語句中使用順序一致,排序與聲明的順序決定了先按哪一個分組,接着再按哪一個進行分組,最後再按哪一個進行分組,這與SQL中的Group By 類似

用在AT...... ENDAT語句中的中的組件名不必定要是結構中的關鍵字段,但這些字段必定要按照出如今AT關鍵字後面的使用順序在結構最前面進行聲明,且這些組件字段的聲明之間不能插入其餘組件的聲明如如今須要按照<f1>, <f2>, ....多個字段的順序來使用在AT...... ENDAT語句中,則首先須要在結構中按照<f1>, <f2>, ....,多字段的順序在結構最前面都聲明,而後按照<f1>, <f2>, ....,多字段來排序的,最後在循環中按以下的順序塊書寫程序(請注意書寫AT END OF的順序與AT NEW 是相反的,像下面這樣):

LOOP AT <itab>.

AT FIRST. ... ENDAT.

AT NEW <f1>. ...... ENDAT.

AT NEW <f2>. ...... ENDAT.

.......

<single line processing>

.......

AT END OF <f2>.... ENDAT.

AT END OF <f1>. ... ENDAT.

AT LAST. .... ENDAT.

ENDLOOP.

一旦進入到 AT...<f1>...ENDAT 塊中時,當前工做區(或表頭)中的從<f1>日後,但不包括<f1>(按照在結構中聲明的次序)全部字段的字符類型字段會以星號(*)號來填充,而數字字設置爲初始值(注:在測試過程當中發現String類型不會使用*來填充,而是設置成empty String,因此只有固定長度類型的非數字基本類型才設置爲*)。若是在 AT 塊中使用了SUM,則會將全部數字類型字段統計出來將存入當前工做區(或表頭);但一旦離開AT....ENDAT塊後,又會將當前遍歷的行恢復到工做區(或表頭)中

  DATABEGIN OF th_mseg OCCURS 10,
matnr 
TYPE mard-matnr, werks TYPE mard-werks,
lgort 
TYPE mard-lgort, shkzg TYPE mseg-shkzg,
      menge 
TYPE mseg-menge, budat TYPE mkpf-budat,
LOOP AT th_mseg.
AT END OF shkzg."會根據shkzg及前面全部字段來進行分組
sum.
WRITE: / th_mseg-matnr, th_mseg-werks,th_mseg-lgort,
             th_mseg-shkzg,th_mseg-menge,th_mseg-budat.
ENDAT.
ENDLOOP.

AS-101             2300 0001 S           10.000  ****.**.**

AS-100             2300 0002 S           10.000  ****.**.**

AS-100             2300 0001 S           20.000  ****.**.**

上面因爲沒有根據matnr + werks + lgort + shkzg 進行排序,因此結果中的第三行其實應該與第一行合併。其實這個統計與SQL裏的分組(Group By)統計原理是同樣的,Group By 後面須要明確指定分組的字段,如上面程序使用SQL分組寫法應該爲 Group Bymatnr werks lgort shkzg,但在ABAP裏你只須要按照 matnr werks lgort shkzg按照前後順序在結構定義的最前面進行聲明就可表達了Group By那種意義,並且不必定要將matnr werks lgort shkzg這四個字段所有用在AT語句塊中AT NEWAT END OF shkzg 才正確,其實像上面程序同樣,只寫AT END OF shkzg這一個語句,前面三個字段matnr werks lgort均可以不用在AT語句中出現,由於ABAP默認會按照結構中聲明的順序將shkzg前面的字段也全都用在了分組中了

 

DATABEGIN OF line,
"C2C3組件名聲明的順序必定要與在AT...... ENDAT塊中使用的次序一致,即這裏不能將C3聲明在C2以前,且不能在C2C3之間插入其餘字段的聲明
      c2
(5TYPE c,
      c3
(5TYPE c,
      c4
(5TYPE c,
      i1 
TYPE i,
      i2 
TYPE i,
      c1
(5TYPE c,
END OF line.

"使用在AT...... ENDAT語句中的字段不必定要是關鍵字段
DATAitab LIKE TABLE OF line WITH HEADER LINE WITH NON-UNIQUE KEY i1.
PERFORM append USING 'b' 'bb' 'bbb' '2222' 22.PERFORM append USING 'c' 'aa' 'aaa' '3333' 33.
PERFORM append USING 'd' 'aa' 'bbb' '4444' 44.PERFORM append USING 'e' 'bb' 'aaa' '5555' 55.
PERFORM append USING 'f' 'bb' 'bbb' '6666' 66.PERFORM append USING 'g' 'aa' 'aaa' '7777' 77.
PERFORM append USING 'h' 'aa' 'bbb' '8888' 88.
SORT itab ASCENDING BY c2 c3.
LOOP AT itab.
WRITE/ itab-c2,itab-c3,itab-c1,itab-c4,itab-i1,itab-i2.
ENDLOOP.
SKIP.
LOOP AT itab.
AT FIRST.
WRITE:'>>>> AT FIRST'.
ENDAT.
  AT NEW c2.
WRITE'    >>>> Start of' itab-c2.
ENDAT.
  AT NEW c3.
WRITE'        >>>> Start of' itab-c2itab-c3.

相關文章
相關標籤/搜索