ABAP程式設計 基本概念
tags: ABAP程式設計
- fn+insert 取消 modify
- ULINE."插入一行直線
- skip. "空格一行
- PARAMETERS 輸入(類似input)
ABAP的資料形態
- C Character(文本域)
- N Numeric Text
- D Date ( YYYYMMDD )
- T Time ( HHMMSS )
- I Integer
- F Floating Point Number
- X Byte (字節字段)
- P Packet Number ( 格式化數值 )
- STRING 文本字符串
自行宣告資料形態
types <user defined type> type <basic type>
<user defined type>
ABAP的三種變數
- Element Data Object(單值變數)
- Work Area(多值變數)
- Internal Table(多行多列)
單值變數宣告 Element Data Object
-
TYPE +形態
DATA TYPE or < user defined type> -
LIKE(參考)+資料(變數)物件
DATA LIKE
範例:
data pu(8) type c.
pu = '靜宜大學'.
data putel(10) type n VALUE '00000000'.
WRITE:/ pu,putel.
skip.
輸出 靜宜大學 00000000
types teltype(10) type n.
*自己定義了一個10個數字的電話形態
data millionTel type teltype value '0111111111' .
*宣告了名為milliontel的teltype資料形態的單值變數,值為0111111111
data gigiTel like milliontel value '0123456789' .
*gigitel 資料形態 參考(like)了milliontel的資料形態
WRITE:/ milliontel, gigitel.
輸出 0111111111 0123456789
data text_line type c length 40.
text_line ='a chapter on data types' .
WRITE:/ text_line.
data text_string type STRING.
text_string = 'a program in abap ' .
WRITE:/ text_string.
data date type D.
date = sy-datum.
WRITE:/ date.
輸出
chapter on data types
a program in abap
20221208
多值變數宣告 Work Area
- 以多個欄位表示多個值(類似record)(希望一個變數純好幾個欄位)
- 將多個變數組合在一個物件中,以利資料的處理
- 基本上就是一個Structure
- 直接參考ABAP Dictionary 的TABLE結構
DATA WA(這個work area的名字) TYPE Zpu111_57_art(參考的table 名字)
實例
data wa TYPE zpu111_57_art.
*宣告一個變數,參考了art這個table
wa-artid = 'x001'.
*設定wa,參考之前的table裡面的欄位-artid的值為x001
wa-artname = 'pu'.
wa-arturl = 'https://www.pu.edu.tw'.
wa-arttel = '0123456789'.
WRITE:/ wa-artid , wa-artname , wa-arturl , wa-arttel.
skip.
* 從zpu111_57_art 中讀取 *(全部)資料 (sql語法)
select * from zpu111_57_art
* into wa 表示 每讀一筆資料, 就把那筆資料複製到wa中
into wa.
WRITE:/ wa-artid , wa-artname , wa-arturl , wa-arttel.
ENDSELECT.
* 在abap 裡面 select是一個迴圈的變數,所以要有endselect
輸出
- 先定義 STRUCTURE TYPE,再提供給 WROK AREA 使用(自定結構形態,再宣告變數)
TYPES:
BEGIN OF <TYPE NAME>,
FIELD1(LENTH) TYPE <ABAP DICTIONARY TYPE>,
FIELD2(LENTH) TYPE <ABAP DICTIONARY TYPE>,
END OF <TYPE NAME>.
DATA <WA_NAME> TYPE <TYPE NAME>.
-
如果 FIELD 後面不接型態,就預設為 CHAR
-
如果 FIELD 後面不接(長度),就預設為 (1)
實例
- 多筆資料查詢
*PARAMETERS x1 type zpu111_57_art-artid.
*PARAMETERS x2 type zpu111_57_show-team.
PARAMETERS x type zpu111_57_look-artid.
* text element 設定x要輸入什麼 → 劇院編號 (直接打勾綁定資料庫設定的)
START-OF-SELECTION.
WRITE x.
data wa TYPE zpu111_57_show.
* 不能直接在ABAP裡面讀取,因為會不知道是哪筆資料,所以會不知道要印table裡的哪一筆欄位
*因此必須先寫一個workarea,每讀一筆資料,寫入一筆資料
SELECT * from zpu111_57_show
INTO wa
WHERE team = x .
WRITE :/ wa-showname.
ENDSELECT.
- 單一一筆資料查詢 SINGLE
PARAMETERS x type zpu111_57_look-artid.
START-OF-SELECTION.
WRITE x.
data wa2 TYPE zpu111_57_art.
* 只找一筆資料 single
SELECT SINGLE * from zpu111_57_art
into wa2
where artid = x .
WRITE:/ wa2-artid, wa2-artname, wa2-arttel, wa2-arturl.
* 因為只有一筆 所以不用select結束
- 直接使用 WORK AREA(直接宣告結構變數)
DATA:
BEGIN OF <WA_NAME>,
FIELD(LENTH) TYPE <ABAP DICTIONARY TYPE>,
FIELD(LENTH) TYPE <ABAP DICTIONARY TYPE>,
END OF <WA_NAME>.
實例
DATA:
BEGIN OF S1,
dep(4) type C,
no(10) type n,
name(10) TYPE c,
END OF s1.
s1-dep = '資管'.
s1-no = '410870419'.
s1-name = 'million'.
write :/ s1-dep , s1-no , s1-name.
多行多列變數宣告 Internal Table
-
類似table的概念(但是屬於記憶體變數),多行多列。
- 有多個欄位並且可儲存多筆資料(多個structure的集合)
- 類似MS ADO物件中的 Recordset
(一個workarea只能存一筆資料,一個internal table 可以存多筆資料)
-
internal table 有三種形態(typekind)
- standard table(一般常用的)
- sorted table
- hashed table
Internal Table Type形態定義
TYPES <itabtype> TYPE <tabkind> OF <structure type> [WITH <key>]
實例
DATA WA TYPE ZPU111_57_ART.
* 宣告一個internal table ,形態為 standard table ,參考了zpu111_57_art的結構
TYPES ITAB type STANDARD TABLE OF ZPU111_57_ART.
data itab1 TYPE itab.
skip.
與workarea的區別
1. workarea-只能存一筆
2. internal table-能存多筆
實例
DATA WA TYPE ZPU111_57_ART.
* 為了不頻繁讀取資料庫,把資料庫的內容都丟進一個變數
* 宣告一個internal table ,形態為 standard table ,參考了zpu111_57_art的結構
TYPES ITAB type STANDARD TABLE OF ZPU111_57_ART.
data itab1 TYPE itab.
select * from zpu111_01_art
INTO table itab1.
skip.
目前itab1內容
因為itab是多筆資料的變數,所以如果直接loop的話,假設要印出itab-artid,系統會不知道是itab1的哪筆artid資料
執行後
- 解決方法1 -透過寫入wa中
loop at itab1 into wa.
WRITE:/ wa-artid, wa-artname, wa-arturl , wa-arttel.
ENDLOOP.
- 解決方法2 WITH HEADER Line
(直接用WITH HEAD LINE就不需要在寫入wa)
TYPES ITAB type STANDARD TABLE OF ZPU111_57_ART.
DATA itab1 TYPE itab WITH header line.
select * from zpu111_01_art
INTO table itab1.
loop at itab1 .
WRITE:/ itab1-artid, itab1-artname, itab1-arturl , itab1-arttel.
ENDLOOP.
- 補充 如果想要把結果輸出排序
順序 SORT BY 欄位名字
倒敘 SORT BY 欄位名字 DESCENDING
TYPES ITAB type STANDARD TABLE OF ZPU111_57_ART.
DATA itab1 TYPE itab WITH header line.
select * from zpu111_01_art
INTO table itab1.
SORT itab1 by arttel.
loop at itab1 .
WRITE:/ itab1-artid, itab1-artname, itab1-arturl , itab1-arttel.
ENDLOOP.
SORT itab1 by arttel DESCENDING.
- 直接宣告、使用
DATA:
BEGIN OF <ITAB_NAME> OCCURS 0,
FIELD(LENTH) TYPE <ABAP DICTIONARY TYPE>,
FIELD(LENTH) TYPE <ABAP DICTIONARY TYPE>,
END OF <ITAB_NAME>.
- 使用 LIKE
DATA <ITAB_NAME> TYPE/LIKE <ITAB_TYPE> WITH HEAD LINE.
DATA <ITAB_NAME> TYPE/LIKE <TYPE_NAME> OCCURS 0 WITH HEAD LINE.
補充-變量
变量是用于在程序的分配的存储区域中存储值的命名数据对象。 顾名思义,用户可以在ABAP语句的帮助下更改变量的内容。
ABAP中的每个变量都有一个特定的类型,它决定了变量内存的大小和布局; 可以存储在该存储器内的值的范围; 以及可以应用于该变量的一组操作。
您必须先声明所有变量,然后才能使用它们。
变量声明的基本形式是
DATA <f> TYPE <type> VALUE <val>.
这里 指定变量的名称。 变量的名称最多可包含30个字符。
指定变量的类型。
具有完全指定的技术属性的任何数据类型被称为<type&gt></type&gt;.>;
指定的初始值变量。
在定义基本固定长度变量的情况下,DATA语句会自动使用类型特定的初始值填充变量的值。
的其他可能值可以是文字,常量或显式子句,例如Is INITIAL。
以下是变量声明的有效示例。
DATA d1(2) TYPE C.
DATA d2 LIKE d1.
DATA minimum_value TYPE I VALUE 10.
在上面的代码片段中,d1是C类型的变量,d2是d1类型的变量,minimum_value是ABAP整数类型的变量。
DATA ResearchRoom TYPE I VALUE 579.
DATA MoonToEarth TYPE F VALUE 384401.
CONSTANTS pi TYPE P DECIMALS 2 VALUE '3.14'.
WRITE:/ ResearchRoom, MoonToEarth, pi.
輸出
ABAP中有三種變量
- Static Variables 靜態變量
- Reference Variables 參考變量
語法為 DATA TYPE REF TO VALUE IS INITIAL. - System Variables 系統變量
常用的系統參數
- Sy-datum
- Date and time, current application server date
- Sy-uzeit
- Date and time, current application server time
- Sy-subrc
- Return value after ABAP statements
- Ex: 搜尋資料庫時,至少找到一筆資料,則其值為 0
- 如果subrc = 0 表示至少有找到一筆資料, 如果 不等於0 表示一筆資料都找不到。
- Sy-lsind
- List processing, details list index (表示Detail List處在第幾層)
ABAP 運算子與邏輯判斷
運算子
ABAP 運算子分為四類
- 比較運算子
=
(EQ) : 相等測試,檢查兩個操作數的值是否相等,如果是,則條件為真。示例(A=B)不為真。
<>
(NE) : 不等式檢驗,檢查兩個操作數的值是否相等,如果值不相等,則條件為真。示例(A<>B)為真。
>
(GT) : 大於測試,檢查左操作數的值是否大於右側的值,如果是,這條將變為TRUE。示例(A>B)不為真。
<
(LT) : 小於測試,檢查左操作數的值是否小於右側的值,如果是,則條件變為TRUE。示例(A<B)不為真。
<=
(LE) : 小於或等於測試
>=
(GE) : 大於等於測試
IS INITIAL
: 如果变量的内容没有改变,并且它已被自动赋予其初始值,则条件为真。 示例(A IS INITIAL)不为真。
實例:
DATA: A TYPE I VALUE 115,
B TYPE I VALUE 119.
IF A LT B.
WRITE: / 'A is less than B'.
ENDIF.
輸出A is less than B
DATA: A TYPE I.
IF A IS INITIAL.
WRITE: / 'A is assigned'.
ENDIF.
輸出A is assigned
- 邏輯運算子
AND , OR - 算數運算子
+, - , * , / , mod(餘數)
實例:
REPORT YS_SEP_08.
DATA: A TYPE I VALUE 150,
B TYPE I VALUE 50,
Result TYPE I.
Result = A / B.
WRITE / Result.
輸出3
- 字符串運算子
- CO 檢查A是否僅由B中的字符組成
- CN 檢查A是否包含不在B中的字符
- CA 檢查A是否至少包含一個字符B
- NA 檢查A是否不包含任何字符B
- CS 檢查A是否包含字符串B
- NS 檢查A是否不包含字符串B
實例:
DATA: P(10) TYPE C VALUE 'APPLE',
Q(10) TYPE C VALUE 'CHAIR'.
IF P CA Q.
WRITE: / 'P contains at least one character of Q'.
ENDIF.
輸出P contains at least one character of Q
控制式
- IF子句
IF <Logical Expression> .
<Statements>.
ELSEIF <Logical Expression> .
<Statements>.
ELSE .
<Statements>.
ENDIF .
實例
PARAMETERS x type i.
PARAMETERS opt type c.
PARAMETERS y type i.
START-OF-SELECTION.
*完成選擇屏幕上字段的初始值設定及檢查後,開始讀取數據之前觸發
WRITE:/ sy-datum, sy-uzeit.
data result type p decimals 2.
if opt = '+'.
result = x + y.
WRITE:/ 'result:' , result.
elseif opt = '-'.
result = x - y.
write:/ 'result', result.
elseif opt = '*'.
result = x * y.
write:/ 'result', result.
elseif opt = '/'.
result = x / y .
write:/ 'result', result.
else.
WRITE:/ '運算符號請輸入+、-、*、/ '.
ENDif.
- CASE 子句
CASE < variable > .
WHEN 'value1' .
<Statements>.
WHEN 'value2' OR 'value3' .
<Statements>.
WHEN OTHERS .
<Statements>.
ENDCASE .
實例
PARAMETERS x type i. //建立一個可以輸入值x,形態為i
PARAMETERS opt type c.
PARAMETERS y type i.
START-OF-SELECTION.
*完成選擇屏幕上字段的初始值設定及檢查後,開始讀取數據之前觸發
WRITE:/ sy-datum, sy-uzeit.
data result type p decimals 2.
case opt.
when'+'.
result = x + y.
WRITE:/ 'result:' , result.
when'-'.
result = x - y.
write:/ 'result', result.
when '*'.
result = x * y.
write:/ 'result', result.
when '/'.
result = x / y .
write:/ 'result', result.
when others.
WRITE:/ '運算符號請輸入+、-、*、/ '.
ENDCASE.
輸出
執行後
迴圈
- while loop
- do loop
- nested loop
WHILE LOOP
- 當給定條件為真時,重複一個語句或一組語句。
WHILE log_exp
[statement_block]
ENDWHILE.
實例 1
while i < 10.
i = i + 1.
WRITE :/ i .
ENDWHILE.
輸出
1
2
3
4
5
6
7
8
9
10
實例 2
data a TYPE i value 0.
while a <> 8.
*檢驗a 與右側值是否相等,如果值不相等,則條件為TRUE。
WRITE:/ 'this is the line:', a.
a = a + 1.
endwhile.
輸出
This is the line: 0
This is the line: 1
This is the line: 2
This is the line: 3
This is the line: 4
This is the line: 5
This is the line: 6
This is the line: 7
DO LOOP
- DO 語句對於特定任務重複特定次數很有用。
DO 整數變數 TIMES.
[statement_block]
ENDDO.
實例
data i TYPE i VALUE 0.
Do 10 times.
i = i + 1.
WRITE:/ i.
ENDDO.
輸出
1
2
3
4
5
6
7
8
9
10
NESTED LOOP
- 在任何一個WHILE 或DO 循環中使用一個或多個循環。
控制循環語句
- CONTINUE
導致循環跳過其身體的剩餘部分,並開始下一個循環傳遞。
範例
data a TYPE i value 0.
DO 5 TIMES.
a = a + 1 .
if a = 3 .
continue.
ENDIF.
WRITE :/ a.
ENDDO.
輸出
1
2
4
5
- CHECK
如果條件為假,則在CHECK之後的剩餘語句被忽略,並且系統開始下一循環通過。 - EXIT
完全終止循環,並將執行轉移到循環後立即執行的語句。
模塊化技術
- 模塊化
是程序的重要思想,主要作用有
1. 結構清晰、易讀、易於維護
2. 實現代碼複用
3. 實現數據封裝
目前大多數實例都放與 START-OF-SELECTION,這裡介紹幾種過程模塊化技術
- 子程序(Subroutine)
- 功能模塊(Function Modules)
SUBROUTINE 副程式
-
被視為程序內部的模塊化實現,值被定義為某一個程序調用。
-
第一行以FORM開始,最後一行以ENDFORM結束。
-
三種傳值方式
USING VALUE 呼叫一段副程式去執行,把值傳給他計算,算完後回來,就算值改變了也不會寫回去
CHANGING VALUE 把值傳給他 ,跑著跑著再改寫值(不同位置,但回傳後更改其值)
CHANGING 呼叫的時候傳同一個記憶體空間,變數改變之後,回來的值也會改變(相同記憶體位置)
實例 USING VALUE
data x type I VALUE 5.
* 第一種寫法 using value
* 主程式 perform 呼叫副程式第一種寫法 using
PERFORM square USING x .
WRITE :/ 'x=' , x.
* 定義一個form 名字為square
form square using value(y).
y = y * y .
WRITE :/ 'y=' , y.
* 結束
ENDFORM.
輸出
註:只是值傳給副程式計算,計算完後並不會改寫
EVENT BLOCK
-
類似視窗系統之事件,無一定之執行順序,而由runtime system 所決定
-
用法:
- 第一行以Keyword為起始,無結束keyword
- 直到遇到下一個event block 或 form keyword才結束
-
事件流(6個)
- INITIALIZATION(初始化)
- AT SELECTION-SCREEN(屏幕跳出前)
- START-OF-SELECTION(取数据)
- END-OF-SELECTION(展示数据)
- TOP-OF-PAGE(普通报表输出页头)
- END-OF-PAGE(普通报表输出页尾)
LOAD-OF-PROGRAM: 程式開始執行時候自動調用
這個事件在SUBMIT, CALL TRANSACTION, PERFORM 等執行的時候會自動調用這個事件,所以無需聲明即可。
INITIALIZATION
- 只能用於報表程序
- 在選擇屏幕出現之前執行,如果用邏輯數據庫的話,這個是唯一能夠修改屏幕初始值的地方
- 通常的用法是在這裡給選擇屏幕中的字段賦值
AT SELECTION-SCREEN
- 其实就像一个FORM,所以在这个事件里声明的变量都是局部变量。
- 根据SY-UCOMM这个系统变量可以判断用户的命令
- 在这个事件里响应的是屏幕上选择条件中的事件,例如CHECKBOX的选择与否,RADIOBUTTON的选择,LISTBOX的选择等等。所以分为以下几个方面:
- ON psel :在PARAMETER变化是触发的事件
- ON END OF sel :SELECT-OPTION触发的事件
- ON VALUE-REQUEST FOR psel_low_high :选择的帮助(F4)
- ON HELP-REQUEST FOR psel_low_high :选择的帮助(F1)
- ON RADIOBUTTON GROUP radi :单选按钮事件
- ON BLOCK block :框架的触发事件
- OUTPUT :响应屏幕上的事件,修改选择屏幕的唯一方法
START-OF-SELECTION
报表程序必须执行的事件,在进入第二屏幕之前触发。
END-OF-SELECTION
第二屏幕显示完毕,结束处理。