一 數據類型和對象
在ABAP中,可以使用與標准數據聲明相似的語法處理數據類型,而與數據對象無關。
在程序中必須聲明要使用的全部數據對象。聲明過程中,必須給數據對象分配屬性,其中最重要的屬性就是數據類型。
1.1 基本數據類型
| 數據類型 |
默認大小 |
有效大小 |
初始值 |
說明 |
| C |
1 |
1 - 65535 |
SPACE |
文本、字符(字母數字字符) |
| D |
8 |
8 |
'00000000' |
日期(格式: YYYYMMDD) |
| F |
8 |
8 |
0 |
浮點數 |
| I |
4 |
4 |
0 |
整型(整數) |
| N |
1 |
1 - 65535 |
'00...0' |
數字文本 |
| P |
8 |
1 - 16 |
0 |
壓縮號 |
| T |
6 |
6 |
'000000' |
時間(格式: HHMMSS) |
| X |
1 |
1 - 65535 |
X'00' |
十六進制 |
對算術運算的非整型結果(如分數)進行四舍五入,而不是截斷。
類型 P 數據允許在小數點后有數字。有效大小可以是從 1 到 16 字節的任何值。將兩個十進制數字壓縮到一個字節,而最后一個字節包含一個數字和符號。在小數點后最多允許 14 個數字。
1.2 系統定義的數據對象
| SPACE |
空白字符串 |
| SY-SUBRC |
系統執行傳回值,0表示成功 |
| SY-UNAME |
用戶 |
| SY-DATUM |
系統日期 |
| SY-UZEIT |
系統時間 |
| SY-TCODE |
當前執行程序的Transaction code |
| SY-INDEX |
當前LOOP循環過的次數 |
| SY-TABIX |
當前處理的是Internal Table(內部表)的第幾行 |
| SY-TMAXL |
Internal Table(內部表)的總行數 |
| SY-SROWS |
屏幕總行數 |
| SY-SCOLS |
屏幕總列數 |
| SY-VLINE |
畫豎線 |
| SY-ULINE |
畫橫線 |
| SY-PAGNO |
當前頁號 |
| SY-LINSZ |
當前報表寬度 |
| SY-LINCT |
當前報表長度 |
| SY-LISND |
列表索引頁 |
| SY-LISTI |
上一個列表的索引 |
| SY-LILLI |
絕對列表中選定的行號 |
| SY-CUROW |
屏幕上的行 |
|
|
光標列 |
|
|
真實行號 |
|
|
選擇行的內容,長度為255 |
|
|
當前行 |
1.3 確定數據對象的屬性
如果要查明數據對象的數據類型,或者要在程序的運行期間使用其屬性,可使用 DESCRIBE 語句。語法如下:
DESCRIBE FIELD <f> [LENGTH <l>] [TYPE <t> [COMPONENTS <n>]]
[OUTPUT-LENGTH <o>] [DECIMALS <d>]
[EDIT MASK <m>].
將由語句的參數指定的數據對象<f>的屬性寫入參數后的變量。
DESCRIBE FIELDS 語句具有下列參數:
|
參數 |
用途 |
| LENGTH |
確定字段長度 |
| TYPE |
確定數據類型 |
| OUTPUT-LENGTH |
確定輸出長度 |
| DECIMALS |
確定小數位 |
| EDIT MASK |
確定轉換例程 |
1.3.1 確定字段長度
要確定數據對象的長度,利用DESCRIBE FIELD 語句使用 LENGTH 參數,如下所示:
DESCRIBE FIELD <f> LENGTH <l>.
系統讀取字段<f>的長度,並將值寫入字段<l>。
1.3.2確定數據類型
要確定字段的數據類型,利用DESCRIBE FIELD 語句使用 TYPE 參數,如下所示:
DESCRIBE FIELD <f> TYPE <t> [COMPONENTS <n>].
系統讀取字段<f>的數據類型,然后將值寫入字段<t>。
除返回預定義數據類型 C、D、F、I、N、P、T 和 X 外,該語句還返回
s 對於帶前導符號的兩字節整型
b 對於無前導符號的一字節整型
h 對於內表
C 對於組件中沒有嵌套結構的結構
C 對於組件中至少有一個嵌套結構的結構
1.3.3確定輸出長度
要確定字段的輸出長度,利用 DESCRIBE FIELD 語句使用 OUTPUT-LENGTH 參數,如下所示:
DESCRIBE FIELD <f> OUTPUT-LENGTH <o>.
系統讀取字段<f>的輸出長度,並將值寫入字段<o>。
1.3.4確定小數位
若要確定類型P字段的小數位的個數,利用 DESCRIBE FIELD語句使用 DECIMALS參數,如下所示:
DESCRIBE FIELD <f> DECIMALS <d>.
系統讀取字段<f>的小數個數,並將值寫入字段<d>。
1.3.5 確定轉換例程
要確定 ABAP/4 詞典中某字段的轉換例程是否存在,如果存在,名稱是什么,利用 DESCRIBE FIELD 語句使用 EDIT MASK 參數,如下所示:
DESCRIBE FIELD <f> EDIT MASK <m>.
如果 ABAP/4 詞典中字段<f>的轉換例程存在,則系統將其寫入字段<m>,然后將系統字段 SY-SUBRC 中的返回代碼設為 0。
可以像下面所顯示的那樣,在 WRITE 語句中將字段<m>直接用作格式模板:
WRITE <f> USING EDIT MASK <m>.
如果字段<f>沒有轉換例程,則系統將返回代碼設為 4。
二數據輸出到屏幕
2.1 在屏幕上定位Write輸出
通過制定字段名稱前面的格式規范,可以在屏幕上定位 WRITE 語句的輸出:
WRITE AT [/][<pos>][(<len>)] <f>.
此處
斜線‘/’表示新的一行
<pos>是最長為三位數字的數字或變量,表示在屏幕上的位置
<len>是最長為三位數字的數字或變量,表示輸出長度
如果格式規范只包含直接值(即,不是變量),可以忽略關鍵字 AT。
2.2 格式化選項
對 WRITE 語句,可以使用不同的格式化選項。
WRITE ....<f><選項>.
(1)所有數據類型的格式化選項:
|
選項 |
用途 |
| LEFT-JUSTIFIED |
輸出左對齊 |
| CENTERED |
輸出居中 |
| RIGHT-JUSTIFIED |
輸出右對齊 |
| UNDER <g> |
輸出直接開始於字段<g>下 |
| NO-GAP |
忽略字段<f>后的空格 |
| USING EDIT MASK <m> |
指定格式模板<m> |
| USING NO EDIT MASK |
撤消對 ABAP/4 詞典中指定的格式模板的激活。 |
| NO-ZERO |
如果字段僅包含零,則用空格代替它們 對類型 C 和 N 字段,將自動代替前導零 |
(2)數字字段的格式化選項:
|
選項 |
用途 |
| NO-SIGN |
不輸出前導符號 |
| DECIMALS <d> |
<d>定義小數點后的數字位數。 |
| EXPONENT <e> |
在類型 F 字段中,在<e>中定義冪數 |
| ROUND <r> |
用10**(-r) 乘類型P 字段,然后取整 |
| CURRENCY <c> |
按表格 TCURX 中的貨幣<c>格式化。 |
| UNIT <u> |
按表格 T006 中為類型 P 字段所指定的單位<u>固定小數位數 |
(3)日期字段的格式化選項:
|
選項 |
用途 |
| DD/MM/YY |
用戶主記錄中定義的分隔符 |
| MM/DD/YY |
用戶主記錄中定義的分隔符 |
| DD/MM/YYYY |
用戶主記錄中定義的分隔符 |
| MM/DD/YYYY |
用戶主記錄中定義的分隔符 |
| DDMMYY |
無分隔符 |
| MMDDYY |
無分隔符 |
| YYMMDD |
無分隔符 |
2.3輸出符號和圖標
使用下列語法,可以在屏幕上輸出符號和 R/3 圖標:
WRITE <symbol-name> AS SYMBOL.
WRITE <icon-name> AS ICON.
符號和圖標的名稱(<符號名>和<圖標名>)是定義系統的常量,這些常量在包含程序<SYMBOL>和<ICON>(尖括號是名稱的一部分)中指定。這些包含程序也包含符號和圖標的簡短說明。輸出符號和圖標最簡單的方法是使用語句結構。
要使符號和圖標對程序可用,必須在程序中輸入恰當的包含程序或更易理解的包含程序<LIST>。
2.4 輸出線和空行
(1)水平線
用下列語法,可以在輸出屏幕上生成水平線:
ULINE [AT [/][<pos>][(<len>)]].
它等同於
WRITE [AT [/][<pos>][(<len>)]] SY-ULINE.
AT 后的格式規范,與在屏幕上定位 WRITE 輸出中為 WRITE 語句說明的格式規范完全一樣。如果沒有格式規范,系統則開始新的一行,並用水平線填充該行。否則,只按指定輸出水平線。
生成水平線的另一種方法,是在 WRITE 語句中鍵入恰當數量的連字符,如下所示:
WRITE [AT [/][<pos>][(<len>)]] '-----...'.
(2)垂直線
用下列語法,可以在輸出屏幕上生成垂直線:
WRITE [AT [/][<pos>]] SY-VLINE.
或
WRITE [AT [/][<pos>]] '|'.
(3)空行
用下列語法,可以在輸出屏幕上生成空行:
SKIP [<n>].
該語句從當前行開始,在輸出屏幕上生成<n>個空行。如果沒有指定<n>的值,就輸出一個空行。
(4)要將輸出定位在屏幕的指定行上,使用:
SKIP TO LINE <n>.
該語句允許將輸出位置向上或向下移動。
2.5 將字段內容作為復選框輸出
使用下列語法,可以將字段的第一個字符,作為復選框輸出到輸出屏幕上:
WRITE <f> AS CHECKBOX.
如果字段<f>的第一個字符是一個“ X”,就顯示復選框已填充。如果字段<f>的第一個字符是 SPACE,就顯示復選框為空。
該語句創建的復選框,默認狀態是可輸入的。就是說,用戶可以通過單擊鼠標來填充它們或使其為空。
三賦值
在 ABAP/4 中,可以在聲明語句和操作語句中給數據對象賦值。在聲明語句中,將初始值賦給聲明的數據對象。為此,可以在 DATA、常量或 STATICS 語句中使用 VALUE 參數。
要在操作語句中給數據對象賦值,可以使用:
MOVE 語句和 WRITE TO 語句,對應於賦值運算符(=)
3.1用MOVE 賦值
3.1.1 基本賦值操作
要將值(文字)或源字段的內容賦給目標字段,可以使用 MOVE語句或賦值運算符(=)。
MOVE 語句的語法如下所示:
MOVE <f1> TO <f2>.
MOVE 語句將源字段<f1>的內容傳送給目標字段<f2>。<f1>可以是任何數據對象。<f2>必須是變量,不能是文字或常量。傳送后,<f1>的內容保持不變。
賦值運算符(=)的語法如下所示:
<f2> = <f1>.
MOVE 語句和賦值運算符功能相同。
3.1.2 用指定偏移量賦值
可以在每條 ABAP/4 語句中為基本數據類型指定偏移量和長度。在這種情況下,MOVE語句語法如下:
MOVE <f1>[+<o1>][(<l1>)] TO <f2>[+<o2>][(<l2>)].
將字段<f1>從<o1>+1 位置開始且長度為<l1>的段內容賦給字段<f2>,覆蓋從<o2>+1 位置開始且長度為<l2>的段。
在 MOVE 語句中,所有偏移量和長度指定都可為變量。
3.1.3 在字符串組件之間賦值
描述的 MOVE 語句賦值方法適用於基本數據對象和結構化數據對象。另外,還有一種 MOVE 語句變體,允許將源字段串組件內容復制到目標字段串組件中。語法如下:
MOVE-CORRESPONDING <string1> TO <string2>.
該語句將字段串<string1>組件的內容賦給有相同名稱的字段串<string2>組件。
對於每對名稱,系統都執行 MOVE 語句,如下所示:
MOVE STRING1-<component> TO STRING2-<component>.
系統分別執行所有必要類型轉換。該處理不同於包括整個字段串的賦值。在這種情況下,應用不兼容的字段串和基本字段所述的轉換規則。
3.2 用WRITE TO 賦值
要將值(文字)或源字段內容寫入目標字段,可以使用 WRITE TO 語句:
WRITE <f1> TO <f2> [<option>].
WRITE TO 語句將源字段<f1>內容寫入目標字段<f2>。<f1>可以是任何數據對象,<f2>必須是變量,不能是文字或常量。寫入后,<f1>內容保持不變。
對於<option>,可以使用 WRITE 語句的所有格式化選項(UNDER 和 NO-GAP 除外)。
WRITE TO 語句總是檢查用戶主記錄中的設置。例如,這些設置指定是將小數點顯示為句號(.),還是逗號(,)。
WRITE TO 語句並不遵循類型轉換中所述的轉換規則。目標字段解釋為類型 C 字段。系統總是將源字段內容轉換為類型 C,它不將結果字符串轉換為目標字段的數據類型,而直接寫入目標字段。因此,不應使用數值數據類型的目標字段。
3.2.1 運行時指定源字段
可以使用 WRITE TO 語句在運行時指定源段。為此,需用括號將包含源字段名的數據對象名括起來,並將其放在源字段位置:
WRITE (<f>) TO <g>.
系統將賦給<f>的數據對象值放到<g>中。
然而,如果要在運行時指定目標字段,則必須按使用字段符號中所述,使用字段符號。
3.2.2用指定偏移量寫入值
可以指定每條 ABAP/4 語句中基本數據對象的偏移量和長度。WRITE TO 語句語法如下:
WRITE <f1>[+<o1>][(<l1>)] TO <f2>[+<o2>][(<l2>)].
將字段<f1>中從<o1>+1 位置開始且長度為<l1>的內容賦給字段<f2>,覆蓋從<o2>+1 位置開始且長度為<l2>的段。
在 WRITE TO 語句中,目標字段的偏移量和長度指定可為變量。
四數值運算
要處理數值數據對象並將結果值賦給數據對象,可以用 COMPUTE 語句或賦值運算符(=)。COMPUTE 語句語法如下所示:
COMPUTE <n> = <expression>.
關鍵字 COMPUTE 可選。
4.1 基本算術運算
ABAP/4 支持四種基本算術運算,同時還支持乘方計算。可以用數學表達式指定以下算術運算符:
| + |
加法 |
| - |
減法 |
| * |
乘法 |
| / |
除法 |
| DIV |
整除 |
| MOD |
求余 |
| ** |
求冪 |
可以用關鍵字 ADD、SUBTRACT、 MULTIPLY和 DIVIDE進行基本算術運算,而不使用數學表達式中的運算符。
4.2 字符串的算術運算
類似於用 MOVE-CORRESPONDING 語句在字段串之間復制值,可以用以下關鍵字,執行字段串的算術運算:
ADD-CORRESPONDING
SUBTRACT-CORRESPONDING
MULTIPLY-CORRESPONDING
DIVIDE-CORRESPONDING
對於所有同名字段串組件,ABAP/4 進行相應算術運算。然而,僅當所有相關組件都是數值型數據類型時,該運算才有意義。
4.2.1 添加字段順序
除基本算術運算中所述的基本加法之外,ADD 語句有幾個變體,用於添加字段順序。例如,添加字段順序並將結果賦給另一個字段:
ADD <n1> THEN <n2> UNTIL <nz> GIVING <m>.
如果<n1>、<n2>、 ... 、<nz>是在內存中相同類型和長度的等距字段序列,則進行求和計算並將結果賦給<m>
添加字段順序並將結果添加到另一個字段內容中:
ADD <n1> THEN <n2> UNTIL <nz> TO <m>.
該語句除了將字段總和添加到<m>的舊內容中之外,與上面語句的工作方式相同。
4.3 數學函數
以下內部函數使用所有三種數值數據類型(F、 I 和 P)作為參數。
|
函數 |
結果 |
| ABS |
參數的絕對值 |
| SIGN |
參數符號:1 X > 0 SIGN( X) = 0 if X = 0 -1 X < 0 |
| CEIL |
不小於參數的最小整數值 |
| FLOOR |
不大於參數的最大整數值 |
| TRUNC |
參數的整數部分 |
| FRAC |
參數的分數部分 |
4.4 浮點函數
以下內部函數用浮點數據類型(F)作為參數。
|
函數 |
解釋 |
| ACOS、 ASIN、 ATAN; COS、SIN、 TAN |
三角函數 |
| COSH、 SINH、 TANH |
反三角函數 |
| EXP |
基數為 e 的求冪函數(e=2.7182818285) |
| LOG |
基數為 e 的自然對數 |
| LOG10 |
基數為 10 的對數 |
| SQRT |
平方根 |
對於所有函數,正常數學約束適用。否則,會產生運行錯誤。
五字符串
5.1 移動字符串
5.1.1 按給定位置數移動字符串
要按給定位置數移動字段內容,使用 SHIFT 語句,用法如下:
SHIFT <c> [BY <n> PLACES] [<mode>].
該語句將字段<c>移動<n>個位置。如果省略 BY <n> PLACES,則將<n>解釋為一個位置。如果<n>是 0 或負值,則<c>保持不變。如果<n>超過<c>長度,則<c>用空格填充。<n>可為變量。
對不同(<mode>)選項,可以按以下方式移動字段<c>:
LEFT: 向左移動<n>位置,右邊用<n>個空格填充(默認設置)。
RIGHT: 向右移動<n>位置,左邊用<n>個空格填充。
CIRCULAR:向左移動<n>位置,以便左邊<n>個字符出現在右邊。
5.1.2移動字符串到給定串位置
要移動字段內容以到給定串位置,則使用 SHIFT 語句,用法如下:
SHIFT <c> UP TO <str><mode>.
ABAP/4 查找<c>字段內容直到找到字符串<str>並將字段<c>移動到字段邊緣。<mode>選項與按給定位置數移動字符串中所述相同。<str>可為變量。
如果<c>中找不到<str>,則將 SY-SUBRC 設置為 4 並且不移動<c>。否則,將 SY-SUBRC 設置為0。
5.1.3 根據第一個或最后一個字符移動字符串
假設第一個或最后一個字符符合一定條件,則可用 SHIFT 語句將字段向左或向右移動。為此,請使用以下語法:
SHIFT <c>LEFT DELETING LEADING <str>.
SHIFT <c> RIGHT DELETING TRAILING <str>.
假設左邊的第一個字符或右邊的最后一個字符出現在<str>中,該語句將字段<c>向左或向右移動。字段右邊或左邊用空格填充,<str>可為變量。
5.2 替換字段內容
要用其它字符串替換字段串的某些部分,使用 REPLACE 語句。
REPLACE <str1> WITH <str2> INTO <c> [LENGTH <l>].
ABAP/4 搜索字段<c>中模式<str1>前<l>個位置第一次出現的地方。如果未指定長度,按全長度搜索模式<str1>。然后,語句將模式<str1>在字段<c>中第一次出現的位置用字符串<str2>替換。
如果指定長度<l>,則只替換模式的相關部分。如果將系統字段 SY-SUBRC 的返回代碼設置為0,則說明在<c>中找到<str1>且已用<str2>替換。非 0 的返回代碼值意味着未替換。<str1>、<str2>和<len>可為變量。
5.3 大小寫轉換並替換字符串
可以將字母轉換大/小寫或使用替換規則。要轉換大/小寫,使用 TRANSLATE 語句,用法如下:
TRANSLATE <c> TO UPPER CASE.
TRANSLATE <c> TO LOWER CASE.
這些語句將字段<c>中的所有小寫字母轉換成大寫或反之。
使用替換規則時,使用以下語法:
TRANSLATE <c> USING <r>.
該語句根據字段<r>中存儲的替換規則替換字段<c>的所有字符。<r>包含成對字母,其中每對的第一個字母用第二個字母替換。<r>可為變量。
5.4 轉換為可排序格式
可以將字符字段轉換為可按字母順序排列的格式:
CONVERT TEXT <c> INTO SORTABLE CODE <sc>.
該語句為字符字段<c>填充可排序目標字段<sc>。字段<c>必須是類型 C且字段<sc>必須是類型 X ,最小長度為<c>長度的16倍。
該語句目的是為字符字段<c>創建相關字段<sc>,作為<c>的按字母順序排列的排序關鍵字。在內表的內容和已解壓縮的數據中進行排序。
如果對未轉換的字符字段進行排序,則系統創建與各字母的特定平台內部編碼相對應的順序。在對目標字段進行排序之后,轉換 CONVERT TEXT 按這樣的方式創建目標字段,相應的字符字段順序按字母排序。例如,在德語中,順序為‘ Miller、 Moller、 Mller、 Muller’,而不是‘ Miller、 Moller、 Muller、 Mller’。
轉換方法依賴於運行 ABAP/4 程序的文本環境。文本環境在用戶主記錄中定義。例外的是可以使用如下語句,在程序中設置文本環境:
SET LOCALE LANGUAGE <lg> [COUNTRY <cy>] [MODIFIER <m>].
該語句根據語言<lg>設置文本環境。對於選項 COUNTRY,只要特定國家語言不同,就可以在語言以外指定國家。對於選項 MODIFIER,只要一個國家內語言不同,就可以指定另一個標識符,例如,排序順序在電話簿和詞典之間不同。
字段<lg>、<cy>和<m>必須是類型 C 且長度必須與表 TCP0C 的關鍵字段長度相等。表 TCP0C 是一個表格,從中進行平台相關的文本環境維護。在語句 SET LOCALE 期間,系統根據 TCP0C中的條目設置文本環境。除了內部傳送的平台特性之外,用 SET 語句指定表關鍵字。如果<lg>等於 SPACE ,則系統根據用戶主記錄設置文本環境。如果對於指定的關鍵字在表中無條目,則系統將產生運行錯誤。
文本環境影響 ABAP/4 中依賴於字符集的所有操作。
5.5 覆蓋字符字段
要用另一字符字段覆蓋字符字段,使用 OVERLAY 語句,用法如下:
OVERLAY <c1> WITH <c2> [ONLY <str>].
該語句用<c2>的內容覆蓋字段<c1>中包含<str>中字母的所有位置。<c2>保持不變。如果省略 ONLY <str>,則覆蓋字段<c1>中所有包含空格的位置。
如果至少要替換<c1>中的一個字符,則將 SY-SUBRC 設置為 0。對於所有其它情況,將SY-SUBRC 設置為 4。如果<c1>比<c2>長,則只覆蓋<c2>中的長度。
5.6 搜索字符串
要搜索特定模式的字符串,請使用 SEARCH 語句,用法如下:
SEARCH <c> FOR <str><options>.
該語句在字段<c>中搜索<str>中的字符串。如果成功,則將 SY-SUBRC 的返回代碼值設置為0並將 SY-FDPOS 設置為字段<c>中該字符串的偏移量。否則將 SY-SUBRC 設置為4。
搜索串<str>可為下列格式之一:
|
<str> |
目的 |
| <pattern> |
搜索<pattern>(任何字符順序)。忽略尾部空格 |
| .<pattern>. |
搜索<pattern>,但是不忽略尾部空格 |
| *<pattern> |
搜索以<pattern>結尾的詞 |
| <pattern>* |
搜索以<pattern>開始的詞 |
單詞之間用空格、逗號、句號、分號、冒號、問號、嘆號、括號、斜杠、加號和等號等分隔。
搜索字符字段<c>的各種選項(<options>)如下
(1)ABBREVIATED
在字段<c>中搜索包含<str>中指定字符串的單詞,其中字符可能被其它字符隔開。單詞和字符串的第一個字母必須相同。
(2)STARTING AT <n1>
在字段<c>中搜索從<n1>開始的<str>。結果 SY-FDPOS 參照相對於<n1>的偏移量而不是字段的開始。
(3)ENDING AT <n2>
在字段<c>搜索<str>直到位置<n2>。
(4)AND MARK
如果找到搜索串,則將搜索串中的所有字符(和使用 ABBREVIATED 時的所有字符)轉換為大寫形式。
5.7 獲得字符串長度
要決定字符串到最后一個字符而不是 SPACE 的長度,使用內部函數 STRLEN,用法如下:
[COMPUTE] <n> = STRLEN(<c> ).
STRLEN 將操作數<c>作為字符數據類型處理,而不考慮其實際類型。不進行轉換。關鍵字 COMPUTE 可選。
5.8 壓縮字符串去空格
要刪除字符字段中多余空格,使用 CONDENSE 語句,用法如下:
CONDENSE <c> [NO-GAPS].
該語句去除字段<c>中的前導空格並用一個空格替換其它空格序列。結果是左對齊單詞,每個單詞用空格隔開。如果指定附加的 NO-GAPS,則去除所有空格。
5.9 連接字符串
要將單個字符串連接成一體,使用 CONCATENATE 語句,用法如下:
CONCATENATE <c1> ... <cn> INTO <c> [SEPARATED BY <s>].
該語句連接字符串<c1>與<cn>並將結果賦給<c>。
該操作忽略尾部空格。附加 SEPARATED BY <s>允許指定字符字段<s>,它放置在單個字段間已定義的長度中。
如果結果符合<c>,則將 SY-SUBRC 設置為0。然而,如果結果必須被截斷,則將 SY-SUBRC設置為4。
5.10 拆分字符串
要將字符串拆分成兩個或更多小串,使用 SPLIT 語句,用法如下:
SPLIT <c> AT <del> INTO <c1> ... <cn>.
該語句在字符字段<c>搜索分界字符串<del>,並將分界符之前和之后的部分放到目標字段<c1> ... <cn>中。
要將所有部分放到不同目標字段中,必須指定足夠目標字段。否則,用字段<c>的剩余部分填充最后目標字段並包含分界符。
如果所有目標字段足夠長且不必截斷任何部分,則將 SY-SUBRC 設置為0。否則,將其設置為4。
5.11 分配字符串部分
MOVE 語句的以下變體只使用類型 C 字段:
MOVE <c1> TO <c2> PERCENTAGE <p> [RIGHT].
將左對齊的字符字段<c1>的百分比<p>(或如果用 RIGHT選項指定,則為右對齊)復制到<c2>。
<p>值可為 0 和 100 之間的任何數。將要從<f1>復制的長度取整為下一個整數。
如果語句中某一參數不是類型 C,則忽略參數 PERCENTAGE。
六邏輯流控制
6.1 比較運算符
要比較所有的字段類型,可以在邏輯表達式中使用下列運算符:
|
<運算符> |
含義 |
| EQ |
等於 |
| = |
等於 |
| NE |
不等於 |
| <> |
不等於 |
| >< |
不等於 |
| LT |
小於 |
| < |
小於 |
| LE |
小於等於 |
| <= |
小於等於 |
| GT |
大於 |
| > |
大於 |
| GE |
大於等於 |
| >= |
大於等於 |
操作數可以是數據庫字段、內部字段、文字或常數。
除基本字段外,還可以將結構數據類型和上表中的運算符結合起來作為操作數。字段串逐個組件進行比較,嵌套的結構分為基本的字段。
如果有意義,可以對不同數據類型的字段進行比較。如果字段可轉換,就可以進行比較。在比較之前,系統將按照下列層次規則執行自動類型轉換:
(1)如果操作數之一是浮點數(類型 F),則系統將其它操作數轉換為類型 F。
(2)如果操作數之一是壓縮字段(類型 P),則系統將其它操作數轉換為類型 P。
(3)如果操作數之一是日期字段(類型 D)或時間字段(類型 T),則系統將其它操作數轉換為類型 D 或 T。不支持日期和時間字段之間的比較,這會導致程序中斷。
(4)如果操作數之一是字符字段(類型 C)且其它操作數是十六進制字段(類型 X),則系統將類型 X 的操作數轉換為類型 C。
(5)如果操作數之一是字符字段(類型 C),其它操作數為數字字段(類型 N),則系統將這兩種操作數都轉換為類型 P。
6.2 比較字符串和數字串
要比較字符串(類型 C)和數字文本(類型 N),可以在邏輯表達式中使用下列運算符。
|
<運算符> |
含義 |
| CO |
僅包含 |
| CN |
不僅包含 |
| CA |
包含任何 |
| NA |
不包含任何 |
| CS |
包含字符串 |
| NS |
不包含字符串 |
| CP |
包含模式 |
| NP |
不包含模式 |
因為除類型 N 和 C 外,系統不能執行任何其它類型轉換,所以,在進行包含這些運算之一的比較時,操作數應該是類型 N 或 C。
運算符的功能如下:
(1)CO (僅包含)
如果<f1>僅包含<f2>中的字符,則邏輯表達式<f1> CO <f2>為真。該比較區分大小寫,並包括尾部空格。如果比較結果為真,則系統字段 SY-FDPOS 包括<f1>的長度。如果為假,則 SY-FDPOS 包含<f1>中第一個未在<f2>內出現的字符的偏移量。
(2)CN (不僅包含 )
如果<f1>還包含<f2>之外的其他字符,則邏輯表達式<f1> CN <f2>為真。該比較區分大小寫,並包括尾部空格。如果比較結果為真,則系統字段 SY-FDPOS 包含<f1>中第一個未同時在<f2>中出現的字符的偏移量。如果為假,SY-FDPOS 包含<f1>的長度。
(3)CA (包含任何 )
如果<f1>至少包含<f2>的一個字符,則邏輯表達式<f1> CA <f2>為真。該比較區分大小寫。如果比較結果為真,則系統字段 SY-FDPOS 包含<f1>中第一個也在<f2>中出現的字符的偏移量。如果為假,SY-FDPOS 包含<f1>的長度。
(4)NA (不包含任何)
如果<f1>不包含<f2>的任何字符,則邏輯表達式<f1> NA <f2>為真。該比較區分大小寫。如果比較結果為真,則系統字段 SY-FDPOS 包含<f1>的長度。如果為假,則 SY-FDPOS 包含<f1>中在<f2>內出現的第一個字符的偏移量。
(5)CS (包含字符串)
如果<f1>包含字符串<f2>,則邏輯表達式<f1> CS <f2>為真。忽略尾部空格並且比較不區分大小寫。如果比較結果為真,則系統字段 SY-FDPOS 包含<f2>在<f1>中的偏移量。如果為假,SY-FDPOS 包含<f1>的長度。
(6)NS (不包含字符串)
如果<f1>不包含字符串<f2>,則邏輯表達式<f1> NS <f2>為真。忽略尾部空格且比較不區分大小寫。如果比較為真,系統字段 SY-FDPOS 包含<f1>的長度。如果為假,系統字段 SY-FDPOS 包含<f2>在<f1>中的偏移量。
(7)CP (包含模式 )
如果<f1>包含模式<f2>,則邏輯表達式<f1> CP <f2>為真。如果<f2>屬於類型 C,則可以在<f2>中使用下列通配符:
* 用於任何字符串
+ 用於任何單個字符
忽略尾部空格且比較不區分大小寫。如果比較結果為真,系統字段 SY-FDPOS 包含<f2>在<f1>中的偏移量。如果為假,SY-FDPOS 包含<f1>的長度。
如果要對<f2>中的特殊字符進行比較,請將換碼符 # 放到其前面。可以使用換碼字符 # 指定:
大小寫字符
通配符 "*"(輸入 #*)
通配符 "+" (輸入 #+)
換碼符號本身 (輸入 ##)
字符串結尾的空格 (輸入 #___)
(8)NP (不包含模式)
如果<f1>不包含模式<f2>,則邏輯表達式<f1> NP <f2>為真。在<f2>中,可以使用與 CP 相同的通配符和換碼字符。忽略尾部空格且比較不區分大小寫。如果比較結果為真,則系統字段 SY-FDPOS 包含<f1>的長度,如果為假,SY-FDPOS 包含<f2>在<f1>中的偏移量。
6.3 比較二進制位結構
要將邏輯表達式初始操作數第一字節的二進制位結構與第二操作數的進行比較,請使用下列操作符。
|
<運算符> |
含義 |
| O |
二進制位是 1 |
| Z |
二進制位是 0 |
| M |
混合二進制位 |
第二操作數的長度應為一個字節。
沒有必要對第二操作數使用長度為 1 的十六進制字段(類型 X),但卻較方便,因為其長度為一個字節且數字值直接與二進制位結構相關。
操作符功能如下:
O (二進制位是 1)
如果<hex>中二進制位是 1 的位置,在<f>中是 1,則邏輯表達式<f> O <hex>為真。
Z (二進制位是0)
如果<hex>中二進制位是 1 的位置,在<f>中是 0,則邏輯表達式<f> Z <hex>為真。
M (混合二進制位)
如果從<hex>中二進制位是 1 的位置起,<f>中至少一個是 1,一個是 0,則邏輯表達式<f> M <hex>為真。
6.4 編程分支和循環
6.4.1 IF條件分支
IF 語句允許依據條件將程序流轉到特定的語句塊中。該語句塊包括 IF 語句及其后面的 ELSEIF、 ELSE 或 ENDIF 之間的所有命令。
IF <condition1>.
<statement block>
ELSEIF <condition2>.
<statement block>
ELSEIF <condition3>.
<statement block>
.....
ELSE.
<statement block>
ENDIF.
如果第一個條件是真,系統將執行所有語句直到第一個語句塊結束,然后繼續處理 ENDIF 語句之后的程序。要采用選擇性條件,可以使用 ELSEIF語句。如果第一個條件是假,系統使用與 IF 語句一樣的方式處理后面的 ELSEIF 語句。如果 IF 或 ELSEIF 條件都為假,則執行 ELSE 開始的語句塊。最后的語句塊必須用 ENDIF 結束。
要用公式表達 IF 和 ELSEIF 語句中的條件,可以使用任何編程邏輯表達式描述的邏輯表達式。
6.4.2CASE條件分支
要根據特殊數據字段的內容執行不同的語句塊,可以如下使用 CASE 語句:
CASE <f>.
WHEN <f1>.
<statement block>
WHEN <f2>.
<statement block>
WHEN <f3>.
<statement block>
WHEN ...
......
WHEN OTHERS.
<statement block>
ENDCASE.
系統執行 WHEN 語句之后的語句塊,如果<f>內容等於<fi>的內容,且繼續處理 ENDCASE 語句后面的語句。如果<f>的內容不等於<fi>的內容,則執行選項 WHEN OTHERS 后面的語句塊。最后的語句塊必須用 ENDCASE 結束。
6.4.3DO無條件循環
如果想要多次執行語句塊,則可以如下使用 DO 語句編程循環:
DO [<n> TIMES] [VARYING <f> FROM <f1> NEXT <f2>].
<statement block>
ENDDO.
在發現 EXIT、 STOP 或 REJECT語句之前,系統繼續執行由 DO 引導、ENDDO 結束的語句塊。
可以使用 TIMES 選項限制循環次數。<n>可以是文字或變量。如果<n>是 0 或負數,系統不執行該循環。
系統字段 SY-INDEX 中包含已處理過的循環次數。
6.4.4WHILE條件循環
如果只要條件為真,就不止一次執行語句,可以如下使用 WHILE 語句編程:
WHILE <condition> [VARY <f> FROM <f1> NEXT <f2>].
<statement block>
ENDWHILE.
只要<condition>是真,或系統發現 EXIT、 STOP 或 REJECT 語句,系統將繼續執行由 WHILE 語句引導、 ENDWHILE 結束的語句塊。
對於<condition>,可以使用編程邏輯表達式中描述的任何邏輯表達式。
系統字段 SY-INDEX 中包含已執行的循環次數。
可以任意嵌套 WHILE 循環,也可與其他循環結合使用。
WHILE 語句的 VARY 選項與 DO 循環的 VARYING 選項工作方式一樣。允許每次執行循環時為變量<f>重新賦值。<f1>、<f2>、<f3>、 ... 必需是內存中類型相同和長度相等的一系列等距字段。第一次循環時,將<f1>分配給<f>,第二次循環時,將<f2>分配給<f>,以此類推。可以在一個 WHILE 語句中使用多個 VARY 選項。
6.5 終止循環
要終止循環過程,請使用下列關鍵字之一。
|
關鍵字 |
用途 |
| CONTINUE |
無條件終止循環過程 |
| CHECK |
有條件終止循環過程 |
| EXIT |
完全終止循環 |
在循環中只能使用 CONTINUE,但在循環外還可使用關鍵字 CHECK 和 EXIT,分別完成不同的功能。
6.5.1無條件終止
要立即無條件終止循環,請如下使用 CONTINUE 語句:
CONTINUE.
在CONTINUE 語句之后,系統跳過當前語句塊中所有剩余語句塊,繼續該語句后面的循環。
6.5.2有條件終止
要有條件終止循環過程,請如下使用 CHECK 語句:
CHECK <condition>.
如果條件是假,系統跳過當前語句塊中所有剩余語句塊,繼續后面的循環過程。對於<condition>,可使用編程邏輯表達式中描述的任何邏輯表達式。
6.5.3完全終止
要無條件完全終止循環,請如下使用 EXIT 語句:
EXIT.
EXIT語句之后,系統立即退出循環,繼續結束語句 (ENDDO、 ENDWHILE、 ENDSELECT)后面的處理。在嵌套循環中,系統僅退出當前循環。
七內表
7.1 創建內表
TYPES: BEGIN OF <f> OCCURS <n>,
<component declaration>,
..............
END OF <f>.
DATA: <itab> TYPE STANDARD OF <f>,
<wa> TYPE <f>.
其作用與先創建字段串<f>,然后再創建與該字段串行結構相同的內表<f>相同。<n>指定行的初始號。將第一行寫入用類型<t>創建的內表數據對象之后,就為指定行保留內存。如果添加到內表中的行比<n>指定的要多,則自動擴展保留的內存。如果內存中沒有足夠空間可用於內表,則將其寫入緩沖區或磁盤(分頁區域)。
7.2 填充內表
要填充內表,既可逐行添加數據,也可復制另一個表格的內容。要逐行填充內表,可以使用 APPEND、 COLLECT 或 INSERT 語句。
要將內表僅用於存儲數據,出於性能方面的考慮,建議使用 APPEND。用 APPEND 也可以創建序列清單。
7.2.1無關鍵字附加行
要將行附加到內表中,使用 APPEND 語句,用法如下:
APPEND [<wa> TO|INITIAL LINE TO] <itab>.
該語句將新行附加到內表<itab>中。
通過使用<wa> TO 選項,指定要附加的源區域<wa>。對於帶表頭行的表格,可以忽略 TO 選項。這樣,表格工作區域就成了源區域。
可以使用 INITIAL LINE TO 選項替代<wa> TO,將用其類型的正確值初始化的行添加到表格中。
APPEND 不考慮是否存在標准關鍵字相同的行。這樣,可能會出現相同條目。系統字段 SY-TABIX 在每個 APPEND 語句之后包含附加行的索引。
7.2.2根據標准關鍵字附加行
要用有唯一標准關鍵字的行填充內表,使用 COLLECT 語句,用法如下:
COLLECT [<wa> INTO] <itab>.
該語句通過使用 INTO 選項指定想附加的源區域<wa>。如果表格有表頭行,則可以忽略 INTO 選項。這樣,表格工作區域就成了源區域。
系統檢查表格條目的標准關鍵字是否相同。如果沒有,COLLECT 語句的作用與 APPEND 語句相似,並將新行添至表格中。
如果存在關鍵字相同的條目,COLLECT 語句不附加新行,但將工作區域中數字字段的內容添加到現有條目中數字字段的內容中。系統字段 SY-TABIX 包含處理過的行的索引。
為 COLLECT 指定的工作區域必須與內表的行類型兼容,不僅僅是可轉換為內表的行類型。COLLECT 語句無法用於帶深層結構的內表,例如,將內表作為組件的行。
如果僅使用 COLLECT 語句填充內表,則不會出現重復條目。因此要填充沒有重復條目的內表,應該使用 COLLECT 而不是 APPEND 或 INSERT。
7.2.3插入行
要在內表行之前插入新行,使用 INSERT 語句,用法如下:
INSERT [<wa> INTO|INITIAL LINE INTO] <itab> [INDEX <idx>].
該語句通過使用 INTO 選項指定想插入的源區域<wa>。如果表格有表頭行,則可以忽略 INTO 選項。這樣,表格工作區域就成了源區域。
可以使用 INITIAL LINE TO 選項替代<wa> TO,將用其類型的正確值初始化的行添至表格中。
如果使用 INDEX 選項,則將新行插入到有索引<idx>的行之前。插入之后,新條目索引為<idx>,下行索引加 1。
如果表格包含<idx> - 1 條目,系統將新條目附加到最后的現有表格行之后。如果表格的條目小於<idx> - 1,系統無法插入條目並將 SY-SUBRC 設置為4。如果操作成功,將 SY-SUBRC 設置為0。
如果使用不帶 INDEX 選項的 INSERT 語句,系統只能在 LOOP - ENDLOOP 循環內通過在當前行(例如帶 SY-TABIX 返回索引的行)前插入新條目來處理它。
7.2.4附加內表行
要將部分或全部內表附加到另一個內表中,使用 APPEND 語句,用法如下:
APPEND LINES OF <itab1> [FROM <n1>] [TO <n2>] TO <itab2>.
如果沒有 FROM 和 TO 選項,該語句將整個表格 ITAB1 附加到 ITAB2 中。如果使用這些選項,則可通過索引<n1>或<n2>指定 ITAB1 中要附加的第一或最后一行。
用該方式將表格行附加到另一個表格中的速度比在循環中逐行進行附加快3到4倍。在 APPEND 語句之后,系統字段 SY-TABIX 包含附加的最后一行的索引。
7.2.5插入內表行
要將部分或全部內表插入到另一個內表中,使用 INSERT 語句,用法如下:
INSERT LINES OF <itab1> [FROM <n1>] [TO <n2>]
INTO <itab2> [INDEX <idx>].
如果沒有 FROM 和 TO 選項,該語句將整個表格 ITAB1 附加到 ITAB2 中。如果使用這些選項,則可通過索引<n1>或<n2>指定 ITAB1 中要附加的第一或最后一行。
如果使用 INDEX 選項,將<itab1>的行插入到<itab2>中索引為<idx>的行之前。如果不使用 INDEX 選項,系統只能在 LOOP - ENDLOOP 塊中通過在當前行(例如,其索引在SY-TABIX 中返回的行)之前插入新條目來處理它。
7.2.6復制內表
如果想一次將內表的全部內容復制到另一內表中,請使用 MOVE 語句或賦值操作符 (=),用法如下:
MOVE <itab1> TO <itab2>.
該語句等價於:<itab2> = <itab1>.也可進行多重賦值,例如,<itab4> = <itab3> = <itab2> = <itab1>.也是可能的。ABAP/4 從右到左進行處理:<itab2> = <itab1>.<itab3> = <itab2>.<itab4> = <itab3>.這些語句執行完整操作。復制整個表格內容,包括作為表格組件的任何其它內表的數據。覆蓋目標表格原來的內容。
對於有表頭行的表格,表格工作區域和表格本身同名。要在上述語句中進行區分,必須在名稱之后輸入兩個方括號 ([]) 來定位內表而不是表格工作區域。
7.3 讀取內表
7.3.1逐行讀取內表
要將內表逐行讀入工作區域,可以使用 LOOP 語句編一個循環。語法如下所示:
LOOP AT <itab> [INTO <wa>] [FROM <n1>] [TO <n2>]
[WHERE <condition>].
.....
ENDLOOP.
用 INTO 選項指定目標區域<wa>。如果表格有表頭行,則可以忽略 INTO選項。這樣,表格工作區域就成了目標區域。
逐行將內表<itab>讀入<wa>或表格工作區域<itab>。對於讀取的每一行,系統都處理以 LOOP 開始,以 ENDLOOP 結束的語句塊。可以用控制關鍵字 AT 在 LOOP - ENDLOOP 塊內控制語句塊流。
在語句塊內,系統字段 SY-TABIX 包含當前行的索引。處理完表格的所有行之后循環結束。在 ENDLOOP 語句之后,如果至少讀取了一行,則將系統字段 SY-SUBRC 設置為0。否則,將其設置為4。
可以使用 FROM、 TO 或 WHERE 選項限制要在循環中進行處理的行數。
使用 FROM 選項,可以用<n1>指定要讀取的第一行。
使用 TO 選項,可以用<n2>指定要讀取的最后一行。
用 WHERE 選項,可以指定<condition>的任何邏輯表達式。第一個操作數必須是內表行結構的組件。如果在循環中使用控制關鍵字 AT ,則不能使用 WHERE 選項。
FROM 和 TO 選項限制系統必須讀取的行數。WHERE 選項僅避免對工作區域進行不必要的填充。用 WHERE 選項,系統必須讀取所有行。為了提高效率,應該盡可能使用 FROM 和 TO 選項。在某些條件下用 EXIT 語句而不是 WHERE 選項跳出循環也十分有效。
7.3.2用索引讀取單行
要用索引從內表中讀取單行,使用 READ 語句,用法如下:
READ TABLE <itab> [INTO <wa>] INDEX <idx>.
用 INTO 選項指定目標區域<wa>。如果表格有表頭行,可以忽略 INTO 選項。這樣,表格工作區域就成了目標區域。
系統用索引<idx>從表格<itab>中讀取行。這比用關鍵字訪問表格要快。
如果找到有指定索引的條目,則將系統字段 SY-SUBRC 設置為0,而且 SY-TABIX 包含該行的索引。否則,SY-SUBRC 包含非0值。
如果<idx>小於或等於 0,則會發生實時錯誤。如果<idx>超過表格大小,系統將 SY-SUBRC 中的返回代碼值設置為 4。
7.3.3 讀取自定義關鍵字的單行
要從有自定義關鍵字的內表中讀取單行,使用 READ 語句的 WITH KEY 選項,用法如下:
READ TABLE <itab> [INTO <wa>] WITH KEY <key> [BINARY SEARCH].
用 INTO 選項可以指定目標區域。如果表格有表頭行,則可以忽略INTO 選項。這樣,表格工作區域就成了目標區域。
系統讀取<itab>中匹配<key>中所定義的關鍵字的第一個條目。如果找到有適當關鍵字的條目,則將系統字段 SY-SUBRC 設置為0,並且 SY-TABIX 包含該行的索引。否則,將 SY-SUBRC 設置為非0值。
如下所述,可以定義多個關鍵字<key>:
(1)定義一系列關鍵字段
要定義自己的一系列關鍵字段,使用 WITH KEY 選項,用法如下:
....WITH KEY <k1> = <f1> ... <kn> = <fn> ...
自定義關鍵字包含表格組件<k1>...<kn>。字段<f1>...<fn>是關鍵字段的內容必須匹配的值。如果<fi>的數據類型與數據類型<ki>不兼容,則<fi>轉換為類型<ki>。可以用 (<ni>) 代替<ki>來實時設置關鍵字段。關鍵字段是字段<ni>的內容。如果在運行時<ni>為空,則系統忽略該關鍵字段。如果<ni>包含無效的組件名稱,則發生實時錯誤。
用戶可以為任何在關鍵字中使用的組件指定偏移量和長度。
(2)將整行定義為關鍵字
通過使用 WITH KEY 選項可將內表整行定義為其關鍵字,如下所示:
....WITH KEY = <value> ...
如果<value>的數據類型與表格行的數據類型不兼容,則將<value>轉換為表格行的數據類型。
對於此類關鍵字,也可以選擇由某個基本數據類型或內表直接定義的,而不是由字段串直接定義的特定內表行。
(3)將行首定義為關鍵字
要將內表的行首定義為關鍵字,使用 WITH KEY 選項,用法如下:
....WITH KEY <k> ...
系統將(左對齊)的行首與<k>進行比較。<k>不能包含內表或包含內表的結構。與上面兩個選項不同之處在於用<k>的數據類型進行比較。
7.3.4 讀取標准關鍵字的單行
要從內表中讀取有特定標准關鍵字的第一行,使用 READ 語句,用法如下:
READ TABLE <itab> [INTO <wa>] [BINARY SEARCH].
用戶必須指定要從<itab>的表格工作區域中讀取行的關鍵字。
讀取語句的該變式只能用於有表頭行的內表。
系統在表格中搜索第一個條目以匹配表格工作區域中的所有標准關鍵字段並將該行讀入表格工作區域。如果使用 INTO 選項,則將該行讀入工作區域<wa>。
標准關鍵字包含內表關鍵字中所述的全部關鍵字段,其中不包含 SPACE。如果找到有匹配關鍵字的條目,則將系統字段 SY-SUBRC 設置為0並且 SY-TABIX 包含該行的索引。否則,將 SY-SUBRC 設置為4。
7.3.5 二分法搜索
用關鍵字讀取單行時,可以執行二分法搜索以代替標准順序搜索。為此,使用 READ 語句的二分法搜索選項。
READ TABLE <itab> .....BINARY SEARCH.
如果使用二分法搜索選項,則必須按關鍵字中指定的次序對內表進行排序。
如果系統找到匹配指定關鍵字的多行,則讀取索引最低的行。
二分法搜索比線性搜索要快。因此,應盡可能將內表排序並且使用二分法搜索選項。
7.3.6 比較單行的內容
要將使用 READ 語句讀取的單行內容與目標區域的內容進行比較,可使用 READ 語句的 COMPARING 選項,用法如下:
READ TABLE <itab> [INTO <wa>] <key-option> COMPARING <fields>.
系統讀取由關鍵字或<key option>中的索引指定的單行。讀取行之后,將<fields>中指定的組件與目標區域中的相應組件進行比較。可以用 INTO 選項指定目標區域<wa>。如果表格有表頭,則可以忽略 INTO 選項。這樣,表格工作區域就成了目標區域。
對於<field>,可以編寫一系列組件... <f1> ...<fn>。也可以用... ALL FIELDS指定所有組件。
如果系統找到包含指定<key-option>的條目,且進行比較的字段內容相同,則將 SY-SUBRC 設置為0。如果進行比較的字段內容不同,則返回值 2。如果系統找不到條目,則包含 4。
如果系統找到條目,則無論比較結果如何,都將其讀入目標區域。
7.3.7 讀取一行部分列內容
要讀取一行部分列的內容,使用 READ 語句的 TRANSPORTING 選項,用法如下:
READ TABLE <itab> [INTO <wa>] <key-option> TRANSPORTING <fields>.
系統讀取由關鍵字或<key option>中索引指定的單行。讀取行之后,將<fields>中指定的組件傳輸給目標區域。可以使用 INTO 選項指定目標區域<wa>。如果表格有表頭行,可以忽略 INTO 選項。這樣,表格工作區域就成了目標區域。
對於<fields>,可以用... <f1> ...<fn>指定一系列組件。也可以用... NO FIELDS指定不傳輸任何組件。
對於后一種情況,READ 語句只影響系統字段 SY-SUBRC 和 SY-TABIX。
7.3.8 確定內表屬性
如果在處理過程中想知道內表一共包含多少行,或者想知道定義的 OCCURS 參數的大小,使用 DESCRIBE 語句,用法如下:
DESCRIBE TABLE <itab> [LINES <lin>] [OCCURS <occ>].
如果使用 LINES 參數,則將填充行的數量寫入變量<lin>。如果使用 OCCURS 參數,則將行的初始號寫入變量<occ>。
7.4 修改和刪除內表行
7.4.1 用MODIFY更改行
要用 MODIFY 語句更改行,使用:
MODIFY <itab> [FROM <wa>] [INDEX <idx>].
FROM 選項中指定的工作區域<wa>代替<itab>中的行。如果表格有表頭行,可以忽略 FROM 選項。這樣,表格工作區域就代替行。
如果使用 INDEX 選項,則新行代替索引為<idx>的現有行。如果替換成功,則將 SY-SUBRC 設置為0。如果內表包含的行少於<idx>,則不更改任何行並且 SY-SUBRC 包含4。
如果使用沒有 INDEX 選項的 MODIFY 語句,則系統只能在 LOOP - ENDLOOP 塊中通過更改當前行(例如由 SY-TABIX 返回其索引的行)來處理它。
7.4.2 用WRITE TO更改行
要用 WRITE TO 語句更改行,請使用下列語法:
WRITE <f>[+<o1>][(<l1>)] TO <itab>[+<o2>][(<l2>)] INDEX <idx>.
將字段<f>中偏移量為<o1>,長度為<l1>部分的內容復制到索引為<idx>的表格行中,覆蓋偏移量為<o2>,長度為<l2>的部分。請注意,即使對於有表頭行的表格,帶 INDEX 選項的 WRITE TO 語句也不訪問表格工作區域,而是訪問表格的某一行。
WRITE TO 語句不能識別表格行的結構。SAP 建議只在轉換已知其確切位置的標志時才使用該語句。另一種情況是用一個基本字符字段定義的內表。該結構的表格非常重要,例如,用於程序的動態生成。
7.4.3 在循環中刪除行
要在循環中從內表中刪除行,使用 DELETE 語句,用法如下:
DELETE <itab>.
系統只能在 LOOP - ENDLOOP 塊中處理該語句。刪除第一行后,可以取消當前行的定義並取消其對 SY-TABIX 內容的賦值。要在該循環內進一步處理行,需使用有 INDEX 選項的語句。
7.4.4 用索引刪除行
要使用索引刪除行,使用有 INDEX 選項的 DELETE 語句,用法如下:
DELETE <itab> INDEX <idx>.
如果使用 INDEX 選項,則從 ITAB 中刪除索引為<idx>的行。刪除行之后,下面行的索引減1。如果操作成功,則將 SY-SUBRC 設置為0。否則,如果不存在索引為<idx>的行,則 SY-SUBRC 包含 4。
如果在 LOOP - ENDLOOP 塊中刪除某一條目,則當前行及其對 SY-TABIX 內容的賦值可成為未定義。要在該循環內進一步處理行,需使用有 INDEX 選項的語句。
7.4.5 刪除鄰近的重復條目
要刪除鄰近重復條目,使用 DELETE 語句,用法如下:
DELETE ADJACENT DUPLICATE ENTRIES FROM <itab> [COMPARING <comp>].
系統從內表<itab>中刪除所有鄰近重復條目。
如果沒有 COMPARING 選項,則標准關鍵字段的內容必須相同。
如果有 COMPARING 選項.... COMPARING <f1><f2>... ,指定字段<f1><f2> ... 的內容必須相同。也可以通過寫入 (<name>) 代替<f1>在運行時在括號中指定字段名。字段<name>包含排序關鍵字段的名稱。如果<name>在運行時為空,則系統將其忽略。如果包含無效的組件名,則會發生實時錯誤。
如果有 COMPARING 選項.... COMPARING ALL FIELDS ,所有字段的內容必須相同。如果系統找到並刪除至少一個重復條目,則將 SY-SUBRC 設置為0。否則,將其設置為4。
如果表格根據指定的比較標准進行過排序,則可使用該語句從內表中刪除所有重復條目。
7.4.6 刪除選定行
要刪除一組選定行,使用 DELETE 語句,用法如下:
DELETE <itab> [FROM <n1>] [TO <n2>] [WHERE <condition>].
用戶必須至少指定三個選項之一。如果使用沒有 WHERE 選項的該語句,則系統從<itab>中刪除所有索引在<n1>和<n2>之間的行。如果不使用 FROM 選項,則系統從第一行開始刪除。如果不使用 TO 選項,則系統刪除所有行直到最后一行。
如果使用 WHERE 選項,則系統僅從<itab>中刪除滿足條件<condition>的行。對於<condition>,可指定任何邏輯表達式。第一個操作數必須是內表行結構的組件。
如果系統至少刪除一行,則將 SY-SUBRC 設置為0。否則,將其設置為4。
7.5 內表排序
要將內表排序,使用 SORT 語句,用法如下:
SORT <itab> [<order>] [AS TEXT]
[BY <f1> [<order>] [AS TEXT] ... <fn> [<order>] [AS TEXT]].
如果不使用 BY 選項,則根據其標准關鍵字對內表<itab>進行排序。要定義不同的排序關鍵字,使用 BY 選項。系統就根據指定組件<f1> ... <fn>對數據集進行排序。這些字段可以是任何類型,包括類型 P、I 和 F 字段,或者表格。排序關鍵字段的數目限制在 250 以內。如果指定多個關鍵字段,則系統首先根據<f1>,然后根據<f2>,以此類推對記錄進行排序。系統使用 BY 之前指定的選項作為 BY 之后指定的所有字段的缺省選項。在單個字段之后指定的選項覆蓋選項在 BY之前指定的這些字段。
如果在運行時排序標准仍然未知,可以通過寫入 (<name>) 代替<fi>進行動態設置。字段<name>包含排序關鍵字段的名稱。如果<name>在運行時為空,系統就將其忽略。如果包含無效的組件名,則發生實時錯誤。對於任何在排序字段中使用的字段,用戶都可指定偏移量和長度。
用戶可以通過在<order>選項中輸入 DESCENDING 或 ASCENDING 來指定排序順序。標准順序是升序。
用戶可以用選項 AS TEXT 影響字符字段的排序方式。如果沒有 AS TEXT,則系統二分排序字符字段並根據它們的平台相關內部編碼。如果有選項 AS TEXT,系統根據當前文本環境按字母順序排序字符字段。用戶可用語句 SET LOCAL LANGUAGE 設置文本環境,這是例外。使用選項 AS TEXT,用戶可免除在排序之前將字符字段轉換為可排序格式之勞。此類轉換僅在下列情況下才有必要:
首先按字母順序對內表進行排序,然后二分法進行搜索。按字母順序排序后的內表次序與按二分法排序后的次序不同。
用字母關鍵字多次對內表進行排序。在這種情況下效率更佳,因為只進行一次轉換。在程序中為數據庫表格創建字母索引。
如果在 BY 之前指定 AS TEXT,則選項僅影響排序關鍵字中的字符字段。如果在字段名之后指定 AS TEXT,則該字段必須為類型 C。
如果自己指定排序關鍵字,通過使關鍵字相對短些可提高效率。但是,如果排序關鍵字包含內表,則排序進程可能會慢很多。
排序並不穩定。這意味着也許沒有必要保留排序關鍵字相同的行的舊次序。
如果主內存中沒有足夠的空間用於排序,系統就將數據寫入臨時外部文件。該文件名在 SAP 參數文件參數 DIR_SORTTMP 中定義。
7.6 創建順序表
內表適合於生成順序表。為此,從空的內表開始,然后使用 APPEND 語句的 SORTED BY 選項,用法如下:
APPEND [<wa> TO] <itab> SORTED BY <f>.
如果使用有 SORTED BY 選項的 APPEND 語句,則並不將新行附加為內表<itab>的最后一行。而是系統插入新行,這樣內表<itab>就根據字段<f>以降序排序。
要生成包含多達 100 個條目的順序表,則應該使用 APPEND 語句。在處理更大的表時,由於效率方面的原因,建議用 SORT 語句對表格進行排序。
如果使用 SORTED BY 選項,表格只能包含 OCCURS 參數中指定的行數。這是一般規則的一個例外。如果添加的行數比指定的要多,則丟棄最后一行。這對於創建長度有限的次序表十分有用。
使用 APPEND 語句的 SORTED BY 選項指定的工作區域必須與內表的行類型兼容。可轉換性對該選項不充分。
7.7 AT……ENDAT行組控制級別
用控制級別語句 AT 可以打開語句塊,用控制級別語句 ENDAT 可以關閉它。語法如下所示:
AT <line>.
<statement block>
ENDAT.
在處理 AT- ENDAT 內語句塊的行條件<line>可以是:
|
<line> |
含義 |
| FIRST |
內表的第一行 |
| LAST |
內表的最后一行 |
| NEW <f> |
行組的開頭,與字段<f>和<f>剩余字段中的內容相同 |
| END Of <f> |
行組的結尾,與字段<f>和<f>剩余字段中的內容相同 |
AT - ENDAT 塊中的語句塊使用這些行條件代表預定義的控制結構。用戶可以使用它們處理內表中的控制斷點,而不必使用編程分支和循環中所述的語句自己編程。
在 AT - ENDAT 語句塊中,工作區域沒有用當前表格行進行填充。初始化所有不是標准關鍵字部件的字段。對於行條件 FIRST 和 LAST,系統用星號 (*) 改寫所有標准關鍵字段。對於行條件 NEW <f>和 END OF <f>,系統用星號 (*) 改寫所有出現在工作區域中指定字段<f>右邊的標准關鍵字段。用戶可根據自己的需求在 AT - ENDAT 語句塊中填充工作區域。
使用AT NEW f和 AT END OF f時需注意:
(1)f必須是內表的第一個字段;
(2)內表中f之后的字段的值都會變成“*”。
使用AT NEW, AT FIRST, AT LAST,AT END OF時需注意:LOOP的時候不能加條件;AT和ENDAT之間不能使用LOOP INTO 的working aera。手動實現AT NEW,AT END OF的時候,需要注意,尤其是在AT END OF的時候。
7.8 比較內表
可以將內表用做邏輯表達式的操作數:
.... <itab1><operator><itab2> ...
對於<operator>,可以使用比較所有的字段類型中的表格內列出的所有操作符(EQ、 =、 NE、<>、><、 GE、>=、 LE、<=、 GT、>、 LT、<)。
進行內表比較的第一個條件是它們包含的行數。內表包含的行數越多,則內表就越大。如果兩個內表行數相同,則逐行、逐個組件進行比較。如果表格行的組件本身就是內表,則進行遞歸比較。如果使用等於操作符以外的操作符,則系統找到一對不相等的組件后就立即停止比較並返回該結果。
對於有表頭行的內表,則可在表格名之后使用方括號[]以將表格工作區域和表格體區別開來。
7.9 初始化內表
要初始化有或沒有表頭的內表,使用 REFRESH 語句,用法如下:
REFRESH <itab>.
該語句將內表重置為填充它以前的狀態。這意味着表格將不包含任何行。如果使用沒有表格工作區域的內表,可以使用 CLEAR 語句代替 REFRESH 語句,用法如下:
CLEAR <itab>.
如果使用有表頭行的內表,CLEAR 語句僅清除表格工作區域。要重置整個內表而不清除表格工作區域,使用 REFRESH 語句或 CLEAR 語句,用法如下:
CLEAR <itab>[].
內表名稱之后的方括號指內表體。
使用 REFRESH 或 CLEAR 初始化內表后,系統保持在內存中保留的空間。可以用 FREE 語句釋放內存,用法如下:
FREE <itab>.
也可以使用 FREE 語句重置內表並直接釋放其內存,而不必先使用 REFRESH 或 CLEAR。與 REFRESH 一樣,FREE 在表格體上,而不在表格工作區域上工作。
在 FREE 語句之后,可以再次定位內表。這樣,系統就再次保留內存空間。可以使用如下邏輯表達式檢查內表是否為空:
... <itab> IS INITIAL ...
八模塊化
8.1 宏的定義和調用
要定義包含部分源代碼的宏,使用 DEFINE 語句,用法如下:
DEFINE <macro>.
<statements>
END-OF-DEFINITION.
這就定義了宏<macro>。必須在 DEFINE 和 END-OF-DEFINITION 之間指定完整的語句。這些語句最多可以包含九個占位符(&1,&2,…,&9)。
完成宏定義之后,就可以進行調用,方法如下:
<macro> [<p1><p2> ... <p9>].
在生成程序期間,系統用已定義的語句替換<macro>,用<pi>替換每個占位符&i。可以從宏中調用另一個宏,但宏不能調用自己。
8.2 使用包含程序
要從另一個 ABAP/4 程序中調用包含程序,使用 INCLUDE 語句,用法如下:
INCLUDE <incl>.
在語法檢查期間和生成期間,該語句將源代碼<incl>插入到 ABAP/4 程序中。INCLUDE 語句的功能類似於把<incl>源代碼復制到調用程序中語句的位置上。
INCLUDE 語句必須單獨占一行,並且不能擴展到多行。
包含程序不是運行時裝載的,而是在程序生成前就被解析。程序生成后,則包含所用全部包含程序的源代碼。
8.3 調用子程序
8.3.1 調用內部子程序
要調用內部子程序,使用 PERFORM 語句,用法如下:
PERFORM <subr> [<pass>].
調用子程序<subr>。在<pass>選項中,指定如何與子程序進行數據傳遞。如果不使用<pass>選項,子程序也可以訪問主 ABAP/4 程序中聲明的所有數據類型和對象。該數據叫做全局數據,如果不被同名局域數據隱藏,該數據對子程序可見。
8.3.2 調用外部子程序
要調用外部子程序,使用 PERFORM 語句,用法如下:
PERFORM <subr>(<prog>) [<pass>] [IF FOUND].
調用程序<prog>中定義的子程序<subr>。如果希望與子程序進行數據傳遞,必須定義<pass>選項或者使用公用部分。如果使用 IF FOUND 選項,並且程序<prog>中沒有子程序<sub>,系統就忽略 PERFORM 語句。
啟動調用外部子程序的程序時,如果定義了子程序的程序不在內存中,ABAP/4就將其裝載到內存中。為了節省存儲空間,盡量將不同程序中定義的子程序數目限制到最小。
8.3.3 運行時指定子程序名
運行時,可以指定要調用的子程序名以及存儲子程序的程序名。為此使用 PERFORM 語句,用法如下:
PERFORM (<fsubr>) [IN PROGRAM (<fprog>)] [<pass>] [IF FOUND].
系統執行字段<fsubr>中存儲的子程序。如果使用 IN PROGRAM 選項,系統在字段<fprog>中存儲的程序內查找子程序(外部調用)。否則,系統在當前程序中查找子程序(內部調用)。
使用該語句還可在程序代碼中指定子程序名和外部程序名。為此請忽略括弧。<pass>選項指定如何與子程序進行數據傳遞。如果使用 IF FOUND 選項,找不到子程序<sub>時,系統就忽略 PERFORM 語句。
8.3.4 從列表中調用子程序
要從列表中調用特定子程序,使用 PERFORM 語句,用法如下:
PERFORM <idx> OF <form1><form2> ....<formn>.
系統執行子程序列表中位於<idx>處的子程序。PERFORM 語句的這一變量只對內部調用有效。字段<idx>既可以是變量也可以是文字。
8.4 通過參數進行數據傳遞
可以用參數在調用程序和子程序之間進行數據傳遞。
在定義子程序期間用 FORM 語句定義的參數叫做形式參數。
在調用子程序期間用 PERFORM 語句指定的參數叫做實參數。
可以區分不同種類的參數:輸入參數用於向子程序傳遞參數;輸出參數用於從子程序傳遞參數;輸入/輸出參數用於與子程序進行參數傳遞
在 FORM 和 PERFORM 語句的<pass>選項中定義參數,方法如下:
FORM <subr> [TABLES <formal table list>]
[USING <formal input list>]
[CHANGING <formal output list>]....
PERFORM <subr>[(<prog>)] [TABLES <actual table list>]
[USING <actual input list>]
[CHANGING <actual output list>]....
選項 TABLES、 USING 和 CHANGING 必須按上述順序編寫。
列表中 USING 和 CHANGING 后面的參數可以是所有類型的數據對象和字段符號。列表中 TABLES 后面的參數既可以是有表頭行的內表,也可以是不帶表頭行的內表。可以采用 TABLES、 USING 或 CHANGING 傳送內表。
對於 FORM 語句中 USING 和 CHANGING后面列表中的每個形式參數,可以指定不同數據傳遞方式:
通過參考值調用:在子程序調用期間,僅將實參數的地址傳送給形式參數。形式參數本身沒有內存。在子程序中使用調用程序的字段。更改形式參數之后,調用程序中的字段內容也會變動。
通過值調用:在子程序調用期間,形式參數是作為實參數的副本創建的。形式參數有自己的內存。更改形式參數並不影響實參數。
通過值和結果調用:在子程序調用期間,形式參數是作為實參數的副本創建的。形式參數有自己的內存空間。在子程序末尾,將對形式參數的更改復制給實參數。
8.4.1 通過參考傳遞
要通過參考值在調用程序和子程序之間進行數據傳遞,使用 FORM 和 PERFORM 語句<pass>選項的 USING 或 CHANGING,用法如下:
FORM ..... [USING <fi1> ... <fin>] [CHANGING <fo1> ... <fon>] ...
PERFORM... [USING <ai1> ... <ain>] [CHANGING <ao1> ... <aon>] ...
在 USING 和 CHANGING 后面的列表中指定形式參數和實參數,而不需附加任何內容。
FORM 語句中形式參數的名稱可以與 PERFORM 語句中實參數<ai1> ... <ain> and <ao1> ... <aon>的名稱不同。PERFORM 語句列表中的第一個參數傳遞給 FORM 語句相應列表中的第一個參數,以此類推。
對於通過參考值調用,USING 和 CHANGING 完全相同。對於文檔,USING 用於子程序中的固定輸入參數,而 CHANGING 則用於子程序中變化的輸出參數。
8.4.2 通過值傳遞
要確保輸入參數在調用程序中保持不變(即使子程序中已被更改),可以通過值將數據傳遞給子程序。為此,使用 FORM 和 PERFORM 語句<pass>選項的 USING,用法如下:
FORM ..... USING ...VALUE(<fii>) ..
PERFORM... USING .......<aii> ..
通過對 FORM 語句中 USING后面列表中的形式輸入參數寫入 VALUE(<fii>)而不是<fii>,相應參數就通過值進行傳遞。與實字段<ai>屬性相同的 PERFORM 語句調用該子程序時,就會創建一個新的局域字段<fi>。系統處理獨立於調用程序中參考字段的該字段。
8.4.3 通過值和結果進行傳遞
如果僅希望在子程序運行成功之后,才將更改過的輸出參數從子程序返回給調用程序,使用 FORM 和 PERFORM 語句<pass>選項的 CHANGING,用法如下:
FORM ..... CHANGING ...VALUE(<fii>) ..
PERFORM... CHANGING .......<aii> ..
通過對 FORM 語句中 CHANGING后面列表中的形式輸入參數寫入 VALUE(<fii>)而不是<fii>,相應參數通過值和結果調用進行傳遞。與實字段<ai>屬性相同的 PERFORM 語句調用該子程序時,就會創建一個新的局域字段<fi>。系統處理獨立於調用程序中參考字段的字段。
僅在運行到 ENDFORM 語句時,系統才將<fii>的當前值傳遞給<aii>。如果子程序因為某個對話信息而中斷,則實參數<aii>保持不變。
8.5 在子程序中定義局部數據類型和對象
8.5.1 定義動態局部數據類型和對象
可以用 TYPES 和 DATA 語句,按照創建數據對象和數據類型中的說明,在子程序內創建局部數據類型和數據對象。為每個子程序調用新近定義的這些類型和對象將在退出子程序時刪除。
每個子程序均有自己的局域命名空間。如果用與全局數據類型或對象相同的名稱定義局部數據類型或對象,則不能在子程序中訪問全局數據類型或對象。局部數據類型或數據對象會隱藏同名全局數據類型或對象。這意味着,如果在子程序中使用某個數據類型或對象名,則總是定址局部聲明的對象(如果存在),否則,定址全局聲明的對象。
8.5.2 定義靜態局部數據類型和對象
如果想在退出子程序后保留局部數據對象之值,必須使用 STATICS 語句而非 DATA 語句進行聲明。使用 STATICS 聲明已全局定義,但僅在定義它的子程序中局部可見的數據對象。
8.5.3 顯示定義全局數據對象
要避免全局數據對象值在子程序內被更改,使用 LOCAL 語句,用法如下:
LOCAL <f>.
只能在 FORM 語句和 ENDFORM 語句之間使用該語句。對於 LOCAL ,可以保存無法被子程序內的數據聲明隱藏的全局數據對象值。
8.6 調用功能模塊
要從 ABAP/4 程序調用功能模塊,使用 CALL 語句,用法如下:
CALL FUNCTION <module>
[EXPORTING f1 = a1 .... fn = an]
[IMPORTING f1 = a1 .... fn = an]
[CHANGING f1 = a1 .... fn = an]
[TABLES f1 = a1 .... fn = an]
[EXCEPTIONS e1 = r1 .... en = rn [OTHERS = ro]].
可以將功能模塊<module>的名稱指定為文字或變量。通過將實參數顯式指定給 EXPORTING、 IMPORTING、 TABLES 或 CHANGING 選項后面列表中的形式參數,與功能模塊之間進行參數傳遞。
分配總是有以下格式:<formal parameter> = <actual parameter>
(1)EXPORTING 選項允許將實參數 ai 傳遞給形式輸入參數 fi。在功能模塊中,必須將形式參數聲明為輸入參數。
(2)IMPORTING 選項允許將形式輸出參數 fi 傳遞給實參數 ai。在功能模塊中,必須將形式參數聲明為輸出參數。
(3)CHANGING 選項允許將實參數 ai 傳遞給形式參數 fi,並在處理功能模塊后,系統將(更改過的)形式參數 fi 傳遞回實參數 ai。在功能模塊中,必須將形式參數聲明為更改參數。
(4)TABLES 選項允許在實參數和形式參數間傳遞表格。借助該選項,內表總是通過參考值傳遞。
EXPORTING、 IMPORTING 和 CHANGING 選項的參數可以是任意類型的數據對象。這些選項的功能類似於子程序的 FORM 和 PERFORM 語句中的 USING 和 CHANGING 選項。TABLES 選項的參數必須為內表。TABLES 選項對應於 FORM 和 PERFORM 語句的 TABLES 選項。
用 EXCEPTIONS 選項,可以處理功能模塊處理過程中發生的例外。例外是功能模塊的特殊參數。有關如何定義和出現例外的內容,創建和編程功能模塊中有專門說明。如果出現 ei 例外,則系統停止執行功能模塊,並且不將任何值從功能模塊傳遞給程序,通過參考值傳遞的值例外。如果在 EXCEPTION 選項中指定了 ei ,則調用程序通過將 ri 分配給 SY-SUBRC 來處理例外。必須將 ri 指定為數字文字。可以使用 EXCEPTION 列表中的 OTHERS 處理列表中沒有顯式指定的所有例外,並且可將同一數值 ri 用於多個例外。
九數據庫
9.1開放式SQL
|
關鍵字 |
用途 |
| SELECT |
從數據庫表讀取數據 |
| INSERT |
將行添加到數據庫表 |
| UPDATE |
更改數據庫表中的行 |
| MODIFY |
添加或刪除行 |
| DELETE |
從數據庫表刪除行 |
| OPEN CURSOR, |
用光標從數據庫表中讀取行 |
| COMMIT WORK, |
確認或撤消對數據庫表的更改 |
在ABAP/4 程序中使用開放式 SQL 語句時,必須保證:
(2)被定址的數據庫系統必須是 SAP 支持的;
(2)必須已經在 ABAP/4 詞典中定義了被定址的數據庫表
下列系統字段在開放式 SQL 操作中起着重要的作用:
(1)SY-SUBRC
和使用其它 ABAP/4 語句一樣,系統字段 SY-SUBRC 中的返回代碼值表示在每個開放式 SQL 操作之后該操作是否成功。如果操作成功,SY-SUBRC 的值就等於 0;如果操作失敗,SY-SUBRC 的值就不等於 0。
(2)SY-DBCNT
SY-DBCNT 字段中的值表明受該操作影響的行數,或已被處理的行數。
9.2 讀取數據
要從數據庫表讀取數據,使用 SELECT 語句:
SELECT <result> FROM <source> [INTO <target>] [WHERE <condition>]
[GROUP BY <fields>] [ORDER BY <sort_order>].
該語句有幾個基本子句。下表中列出了每一個子句:
|
子句 |
說明 |
| SELECT <result> |
定義選擇的結果 |
| FROM <source> |
指定將讀取的數據庫表 |
| INTO <target> |
選定數據指定目標區 |
| WHERE <condition> |
選擇即將讀取的行 |
| GROUP BY <fields> |
行分組 |
| ORDER BY <sort_order> |
指定行的順序 |
9.2.1 定義選擇結果 SELECT
SELECT 子句定義是選擇單行還是選擇多行、是否去掉重復行以及將選擇哪些列。
(1)選擇多行中的所有數據
要從數據庫表中讀取所有列和多行,按如下方式在循環中使用 SELECT 語句。
SELECT [DISTINCT] * ............ENDSELECT.
必須用 ENDSELECT 語句結束該循環。該循環依次讀取所選行,並為每個讀取的行執行循環中的 ABAP/4 語句。SELECT 循環的結果是與被讀取的數據庫表的格式完全相同的表。
DISTINCT 選項將自動的去掉重復的行。如果至少讀取了一行,系統字段 SY-SUBRC 就返回 0。如果沒有讀取,系統字段 SY-SUBRC 就返回 4。系統字段 SY-DBCNT 給讀取的行計數。每執行一次 SELECT 語句,SY-DBCNT 都加 1。
(2)選擇單行中的所有數據
要從數據庫表中讀取單個行的所有列,按如下方式使用 SELECT 語句:
SELECT SINGLE [FOR UPDATE] * ....... WHERE <condition> ......
該語句的結果是一個單行。為了保證清楚地指定了一行,就必須在 WHERE 子句的條件<condition>中用 AND 鏈接形成數據庫表主碼的所有字段。
如果系統沒有找到具有指定關鍵字的行,系統字段 SY-SUBRC 將設置為 4。如果系統找到了一個完全符合指定條件的行,SY-SUBRC 就返回 0。
可以使用 FOR UPDATE 選項鎖定在數據庫表中選定的行。程序將一直等到接收到該鎖定。如果數據庫檢測到或懷疑有一個死鎖定,將產生運行時間錯誤。
(3)選擇指定列中的所有數據
要讀取顯式地包含規定的列的行,或要得到關於數據庫表特定列的摘要信息,按如下方法使用 SELECT 語句:
SELECT [SINGLE [FOR UPDATE]] [DISTINCT] <s1><s2> .....
9.2.2 指定數據表 FROM
(1)在程序中指定數據庫表
要在程序中指定即將讀取的數據庫表或視圖,按下列格式使用 FROM 子句:
...... FROM <dbtab> [CLIENT SPECIFIED] [BYPASSING BUFFER]
[UP TO <n> ROWS].........
數據庫表或視圖<dbtab>必須對 ABAP/4 詞典有效,並且必須在 ABAP/4 程序中包含相應的 TRABLES 語句。
CLIENT SPECIFIED 選項用於關閉自動集團處理,BYPASSING BUFFER 選項使得不用讀取 SAP 表緩沖區就可直接讀取數據庫。
(2)在運行時指定數據庫表
可以在運行時指定數據庫表的名稱。為此,按如下格式使用 FROM 子句:
......FROM (<dbtabname>) [CLIENT SPECIFIED] [BYPASSING BUFFER]
[UP TO <n> ROWS].. INTO <target> .....
該格式的 FROM 子句只能與 INTO 子句一起使用。
字段<dbtabname>的內容確定了數據庫表的名稱。在該情況下,程序不必包含 TABLES 語句。選項 CLIENT SPECIFIED、 BYPASSING BUFFER 和 UP TO <n> ROWS 同樣是用於在程序中指定數據庫表的名稱。
9.2.3 指定目標區 INTO
(1)將數據讀到工作區
可以將數據從數據庫表讀到與 TABLES 語句中定義的默認工作區不同的工作區(通常是字段串)中。為此,按照如下格式在 SELECT 語句的 INTO 子句中指定工作區:
SELECT ... INTO <wa> ............
必須為工作區<wa>聲明一個至少與將讀取的行一樣大的數據對象。
(2)將數據讀到內表
可以在單個操作中將數據庫表中行選擇的結果集寫入內表中。為此,按照如下格式在 SELECT 語句的 INTO 子句中指定內表:
SELECT .....INTO TABLE <itab>.
在該情況下,SELECT 並不啟動循環,並且不允許使用 ENDSELECT 語句。如果內表<itab>不是空的,那么,SELECT 語句將用讀取的數據覆蓋其中的內容。
(3)將數據讀到預定義包大小的內表
如果需要將所選行按已預定義大小的包的形式讀到內表中,按如下格式使用 INTO 子句的 PACKAGE SIZE 選項:
SELECT * .....INTO TABLE <itab> PACKAGE SIZE <n>.....
該語句打開一個循環,必須使用 ENDSELECT 語句結束該循環。對於讀取的每個包含<n>行的包,系統都將執行一次循環。如果<n>小於或等於零,將出現運行時間錯誤。
(4)將數據行附加到內表中
為了避免覆蓋內表中的內容,可將所選行附加到此表中。為此,按如下格式使用 APPENDING 子句,而不是 INTO 子句:
SELECT ..... APPENDING TABLE <itab>.....
與上面描述的 INTO 子句的唯一區別是它是將行附加到內表<itab>中,而不是替換。也可以在該語句中使用 PACKAGE SIZE 選項。
(5)逐個組件的讀取數據
要一個組件接一個組件地將數據讀到目標區中,請使用 INTO 子句的 CORRESPONDING FIELDS 選項。語法如下所示:
對於將數據讀到工作區中:
SELECT ... INTO CORRESPONDING FIELDS OF <wa> ........
對於將數據讀到內表中:
SELECT ... INTO CORRESPONDING FIELDS OF TABLE <itab> ........
對於將數據附加到內表中:
SELECT ... APPENDING CORRESPONDING FIELDS OF TABLE <itab> ........
這些語句不會將所選行的所有字段放進目標區中。系統只將列的內容傳送到目標區的對應組件中。如果可能,在傳送過程中,可將值轉換成目標字段的數據類型。
9.2.4 選擇讀取行 WHERE
(1)在程序中為行選擇指定條件
要在程序中為行選擇指定條件,按如下格式使用 WHERE 子句:
..... WHERE <condition> ........
有六個基本條件可用於限制行選擇。描述如下:
1)<f><operator><g>
<f>是不帶作為前綴的表名稱的數據庫字段名(數據庫表的列),<g>是任意字段或字母。字段名稱和操作符必須用空格隔開。
2)<f> NOTBETWEEN <g1> AND <g2>
數據庫字段<f>的值必須(不能)處於字段或字母<g1>和<g2>的值之間才符合該條件。
3)<f> NOTLIKE <g> [ESCAPE <h>]
該條件只能用於字符類型字段。要符合該條件,數據庫字段<f>中的值必須(不能)符合<g>的模式。在指定<g>時,可使用下列兩個通配符:
_(下划線)表示單個字符%(百分號)表示任意字符串,包括空字符串
4)<f>NOTIN (<g1>, ......, <gn>)
要滿足該條件,數據庫字段<f>中的值必須(不能)等於括號內列表中的一個值。
在該變式中,在括號和比較字段<gi>之間不能有空格,但在比較字段之間可以有空格。
5)<f> IS [NOT] NULL
數據庫字段<f>中的值必須(不能)等於 NULL 值。
6)<f> NOTIN <seltab>
要滿足該條件,數據庫字段<f>的值必須(不能)符合選擇表<seltab>中指定的條件。選擇表是一個特殊的內表,報表用戶可在選擇屏幕上填充它。通常是使用 SELECT-OPTIONS 或 RANGES 來創建選擇表,但是也可以按照創建和處理內表中的說明定義。
(2)使用邏輯鏈接操作符組合條件
可以使用邏輯鏈接操作符 AND、OR 和 NOT 按照任意順序來組合六個基本 WHERE 條件。
如果希望指定幾個必須同時滿足的條件,可按照下列方法用 AND 組合它們:
....WHERE <condition1> AND <condition2> AND <condition3> AND...
如果需要指定幾個條件,至少要滿足其中的一個條件,就可按照下列方法用 OR 組合它們:
....WHERE <condition1> OR <condition2> OR <condition3> OR...
如果只希望選擇那些不符合指定條件的表條目,就可用 NOT 轉化條件,如下所示:
....WHERE NOT <condition>
NOT 的優先級比 AND 高,AND 的優先級比 OR 高。但是,可使用括號來定義處理的順序。這些括號都必須加空格。
9.2.5 指定行選擇條件
(1)指定條件的列表
要在運行時指定一系列條件來選擇一定數目的特定行,可在 SELECT 語句中使用下列 WHERE 子句的特殊變式:
SELECT......FOR ALL ENTRIES IN <itab> WHERE <condition> .....
在條件<condition>中,可按前面的敘述將內部字段或字母指定為比較值。也可以將內表<itab>的列或字母用作比較值。在 WHERE 條件中,這些列將用作占位符。
該SELECT 語句的結果集是 SELECT 語句的所有結果集的聯合,這些結果集是用<itab>中的相應值在每一行上替換占位符的結果,將從結果集中刪除重復行。
如果使用了 WHERE 子句的該變式,就不要使用 ORDER BY 子句。
(2)給行分組
要將數據庫表的一組行中的內容組合到單個行中,可按如下格式使用 SELECT 語句的 GROUP BY 子句:
SELECT [DISTINCT] <a1><a2> ..
FROM clause INTO clause GROUP BY <f1><f2> ....
SELECT [DISTINCT] <a1><a2> ...
FROM clause INTO clause GROUP BY (<itab>)
該組由<f1><f2> ..... 指定的列中包含有相同值的行組成。
(3)指定行的順序
在讀取行的集合時,可使用 SELECT 語句的 ORDER BY 子句指定這些行的順序,按該順序將這些行傳送給 ABAP/4 程序。
如果不使用 ORDER BY 子句,將不定義選擇的行的順序。
1)可根據主碼或明確指定的字段給這些行排序,可使用下列形式的 ORDER BY 子句:
SELECT * ..... ORDER BY PRIMARY KEY.
如果使用 ORDER BY PRIMARY KEY 選項,系統將按主碼以升序給所選行排序。
2)按指定的字段排序,可使用下列語法:
.. ORDER BY <f1> [ASCENDING|DESCENDING] <f2> [ASCENDING|DESCENDING] ...
按指定的表字段<f1>, <f2>, .... 給所選行排序。可以在每個字段名后指定選項 ASCENDING 或 DESCENDING 為每個表字段明確地指定排序順序。
標准的排序順序是升序。如果指定了多個字段,那么系統首先按<f1>給所選行排序,然后是<f2>,依此類推。
9.3 添加數據
9.3.1 添加單一行
要在數據庫表中添加一單行,可使用下列 INSERT 語句的任一變式。INSERT 語句的基本格式如下所示:
INSERT INTO <dbtab> [CLIENT SPECIFIED] VALUES <wa>.
工作區<wa>中的內容將寫進數據庫表<dbtab>中。必須在程序中使用 TABLES 語句聲明該數據庫表。工作區<wa>的長度至少要等於數據庫表的表工作區長度。為了保證工作區具有與數據庫表相同的結構,可通過 DATA 或 TYPES 語句用 LIKE <dbtab>選項來定義它。
9.3.2 添加多行
要使用 INSERT 語句將幾行從內表中添加到數據庫表中,使用下列語法:
INSERT <dbtab> [CLIENT SPECIFIED] FROM TABLE <itab>
[ACCEPTING DUPLICATE KEYS].
如果需要在運行時間指定數據庫表名,使用下列語法:
INSERT (<dbtabname>) [CLIENT SPECIFIED] FROM TABLE <itab>
[ACCEPTING DUPLICATE KEYS].
此語句在單個操作中將內表<itab>中的所有行添加到數據庫表中。
9.4 更新數據
9.4.1 更新單一行
要使用 UPDATE 語句更改單行,可使用UPDATE 語句的短格式,帶有 SET 子句並指定了完整的 WHERE 條件的 UPDATE 語句。
UPDATE 語句的短格式如下所示:
UPDATE <dbtab> [CLIENT SPECIFIED] FROM <wa>.
和
UPDATE <dbtab> [CLIENT SPECIFIED].
在第一個語句中,工作區<wa>中的內容將覆蓋數據庫表<dbtab>的行,該數據庫表與<wa>具有相同的主碼。必須在程序中用 TABLES 聲明該數據庫表。
在第二個語句中,沒有指定工作區<wa>。但表工作區<dbtab>中的內容將覆蓋具有相同主碼的數據庫表的行。
9.4.2 更新多行
要使用 UPDATE 語句在數據庫表中更改多行,使用下列語法:
UPDATE <dbtab> [CLIENT SPECIFIED] SET <S1> ..<Sn> [WHERE <condition>].
使用 WHERE 子句選定要更改的行。如果不指定 WHERE 子句,將更改所有的行。必須在程序中用 TABLES 語句聲明該數據庫表。 CLIENT SPECIFIED 選項用於關閉自動集團處理。
9.4.3 使用內表更新多行
要通過 UPDATE 語句使用內表在數據庫表中更改多行,使用下列語法:
UPDATE <dbtab> [CLIENT SPECIFIED] FROM TABLE <itab>.
如果需要在運行時間指定數據庫表的名稱,就要使用下列語法:
UPDATE (<dbtabname>) [CLIENT SPECIFIED] FROM TABLE <itab>.
內表<itab>中的行將覆蓋數據庫表中具有相同主碼的行。
內表中行的長度至少要等於數據庫表中行的長度。為了保證內表的結構與數據庫表的結構相同,就必須通過 DATA 或 TYPES 語句使用 LIKE <dbtab>選項來定義。
如果因為不存在帶有指定關鍵字的行而使系統不能更改行,那么,系統不會終止整個操作,而是繼續處理內表中的下一行。
9.5 添加或更改數據
要在數據庫表中插入一行,而不考慮該行的主碼是否已經存在,使用 MODIFY 語句。有兩種可能:
如果數據庫表中沒有哪一行的主碼與即將插入行的主碼相同,那么,MODIFY 的操作就與 INSERT 的操作相同,即添加該行。
如果數據庫中已經包含主碼與即將插入行的主碼相同的行,那么, MODIFY 的操作就與 UPDATE 的操作相同,即更改該行。
9.5.1 插入單行
要插入單行,使用下列語法:
MODIFY <dbtab> [CLIENT SPECIFIED] [FROM <wa>].
如果需要在運行時間指定數據庫表的名稱,使用下列語法:
MODIFY (<dbtabname>) [CLIENT SPECIFIED] [FROM <wa>].
9.5.2 插入多行
要插入多行,使用下列語法:
MODIFY <dbtab> [CLIENT SPECIFIED] FROM TABLE <itab>.
如果需要在運行時間指定數據庫表的名稱,使用下列語法:
MODIFY (<dbtabname>) [CLIENT SPECIFIED] FROM TABLE <itab>.
9.6 刪除數據
9.6.1 刪除單行
要使用 DELETE 語句刪除單行,可以將 DELETE 語句與完整的 WHERE 條件一起使用。使用 DELETE 語句的短格式。
DELETE <dbtab> [CLIENT SPECIFIED] FROM <wa>.
DELETE <dbtab> [CLIENT SPECIFIED].
在第一個語句中,將從數據庫表<dbtab>中刪除主碼與<wa>中指定的主碼相同的行。必須在程序中用 TABLES 語句聲明該數據庫表。
在第二個語句中,沒有指定工作區<wa>。而是從數據庫表中刪除主碼與表工作區<dbtab>中指定的主碼相同的行。
9.6.2 刪除多行
要在單個操作中從數據庫表<dbtab>中刪除多行,可使用如下格式的 DELETE 語句:
DELETE FROM <dbtab> [CLIENT SPECIFIED] WHERE <conditions>.
如果需要在運行時間指定數據庫表的名稱,使用下列語法:
DELETE FROM (<dbtabname>) [CLIENT SPECIFIED] WHERE <conditions>.
9.6.3 使用內表刪除多行
要通過 DELETE 語句用內表從數據庫表中刪除多行,使用下列語法:
DELETE <dbtab> [CLIENT SPECIFIED] FROM TABLE <itab>.
如果需要在運行時間指定數據庫表的名稱,使用下列語法:
DELETE (<dbtabname>) [CLIENT SPECIFIED] FROM TABLE <itab>.
這些語句從數據庫表中刪除主碼與內表<itab>中的某行相同的行。內表的長度至少與數據庫表的主碼的長度相同。
如果因為數據庫表中沒有哪一行的主碼與指定的相同,從而系統沒有刪除任何行,那么,系統不會終止整個操作,而是繼續處理內表的下一行。
如果已經處理了內表中所有的行, SY-SUBRC 將設置為 0。否則,設置為 4。在稍后的時候,從內表的總行數中減去 SY-DBCNT 中給出的實際已刪除的行數,就可計算系統尚未刪除的行數。如果內表是空的,那么 SY-SUBRC 和 SY-DBCNT 都將設置為 0。
9.7 使用光標讀取數據
9.7.1 打開光標
使用光標幾乎可從任何 SELECT 語句的結果集中獲得下一行(或一些行)。為此,按如下格式使用 OPEN CURSOR 語句將光標與相關的 SELECT 語句鏈接起來:
OPEN CURSOR [WITH HOLD] <c> FOR SELECT ........
[WHERE <conditions>].
首先必須將光標<c>定義為類型 CURSOR。如果使用 WITH HOLD 選項,那么在自身的 SQL 數據庫提交之后,該光標將保留打開狀態。
9.7.2 用光標讀取數據
在打開光標后,就可使用 FETCH 語句從 OPEN CURSOR 語句生成的結果集中讀取下一行,如下所示:
FETCH NEXT CURSOR <c> INTO <target>.
所選行都將讀到 INTO 子句指定的目標區中。
9.7.3 關閉光標
必須使用 CLOSE CURSOR 語句關閉不再需要的光標,如下所示:
CLOSE CURSOR <c>.
下列情況將自動關閉光標:
1)執行 COMMIT WORK 或 ROLLBACK WORK 語句時;
2)當執行自身的 SQL 數據庫提交或取消時;
3)更改屏幕時;
4)執行遠程功能調用時。
如果在 OPEN CURSOR 語句中使用 WITH HOLD 選項,自身的 SQL 中的數據庫提交將不會關閉光標。
9.8 數據簇
9.8.1 向內存中存儲數據對象
要將數據對象從 ABAP/4 程序寫入 ABAP/4 內存,使用下列語句:
EXPORT <f1> [FROM <g1>] <f2> [FROM <g2>] ... TO MEMORY ID <key>.
此語句將列表中指定的數據對象存儲為 ABAP/4 內存中的數據簇。如果忽略選項 FROM <gi>,則將數據對象<fi>存儲到自己的名稱之下。如果使用該選項,則將數據對象<gi>存儲到<fi>下面。 ID <key>用於標識內存數據,不得超過 32 個字符。
EXPORT 語句總是完全改寫 ID <key>相同的任何現有數據簇的內容。對於有表頭行的內表,只可以存儲表本身,而不能存儲表頭行。
9.8.2 從內存中讀取數據對象
要將 ABAP/4 內存中的數據對象讀到 ABAP/4 程序中,使用下列語句:
IMPORT <f1> [TO <g1>] <f2> [TO <g2>] ... FROM MEMORY ID <key>.
此語句從 ABAP/4 內存的數據簇讀取列表中指定的數據對象。如果忽略選項 TO <gi>,則將內存中的數據對象<fi>賦給程序中的同名數據對象。如果使用此選項,則將內存中的數據對象<fi>寫入字段<gi>中。 ID <key>用於標識內存數據,不得超過 32 個字符。
此語句不進行這種檢查:即內存中的對象結構與要寫入的結構是否匹配。因為數據是按位進行傳送的,所以不匹配的結構可能會引起不一致。
9.8.3 刪除內存中的數據簇
要刪除 ABAP/4 內存中的數據對象,使用下列語句:
FREE MEMORY [ID <key>].
如果不附加 ID <key>,則此語句刪除整個內存,包括此前用 EXPORT 存儲到 ABAP/4 內存中的所有數據簇。附加 ID <key>之后,該語句只刪除用此名稱命名的數據簇。
因為刪除整個內存會導致任何系統例程內存內容的丟失,所以應只使用附加有 ID 的 FREE MEMORY 語句。
十文件
10.1 打開文件
要在應用服務器上打開文件,使用如下 OPEN DATASET 語句:
OPEN DATASET <dsn> [options].
此語句打開文件<dsn>。如果不指定任何模式選項,則文件將按二進制模式打開。如果系統不能打開文件,則將系統字段 SY-SUBRC 設置為 0,否則 SY-SUBRC 返回 8。
可以將文件名<dsn>指定為字母或包含文件名的字段。如果未指定路徑,則系統將在應用服務器上 SAP 系統運行的目錄中打開文件。要打開文件,運行 SAP 系統的用戶必須在操作系統級有相應的權限。
10.1.1 接受操作系統消息
嘗試打開文件后,要接受操作系統消息,使用如下 OPEN DATASET 語句的 MESSAGE 選項:
OPEN DATASET <dsn> MESSAGE <msg>.
系統將在變量<msg>中放置相關的操作系統消息。
10.1.2 打開文件讀取
要打開文件進行讀訪問,使用如下 OPEN DATASET 語句的 FOR INPUT 選項:
OPEN DATASET <dsn> FOR INPUT.
此語句打開文件用於讀取。文件必須已經存在,否則系統將 SY-SUBRC 設置為 8 並且忽略此命令。如果文件已打開(可能用於讀、寫或追加),系統將復位到文件的起始位置。但是在重新打開文件之前使用 CLOSE 語句是良好的編程風格。
10.1.3 打開文件寫入
要打開文件進行寫訪問,使用如下 OPEN DATASET 語句的 FOR OUTPUT 選項:
OPEN DATASET <dsn> FOR OUTPUT.
此語句打開文件用於寫入。如果文件不存在,則創建文件。如果文件已存在但處於關閉狀態,則刪除其內容。如果文件已存在且已打開(可能為讀、寫或追加),則復位到文件的起始位置。如果系統可以打開文件,則 SY-SUBRC 設置為 0,否則 SY-SUBRC 返回 8。
10.1.4 打開文件追加
要打開文件追加數據,使用 OPEN DATASET 語句的 FOR APPENDING 選項:
OPEN DATASET <dsn> FOR APPENDING.
此語句打開文件在文件末尾寫入數據。如果文件不存在,則創建文件。如果文件已存在但處於關閉狀態,系統將打開文件並定位到文件末尾。如果文件已存在且已打開(可能為讀、寫或追加),將定位設置到文件末尾。SY-SUBRC 總是返回 0。
10.1.5 指定二進制模式
要用二進制模式處理文件,使用 OPEN DATASET 語句中的 IN BINARY MODE 選項:
OPEN DATASET <dsn> IN BINARY MODE [FOR ....].
如果從以二進制模式打開的文件中讀取數據或向此類文件中寫入數據,系統將逐字節地傳輸數據。在傳輸期間,系統不解釋文件內容。在將文件內容寫入到另一文件時,系統將傳輸源文件的所有字節。在從文件讀取數據到字段時,傳輸的字節數目取決於目標字段大小。在讀取之時或之后,可以用其它 ABAP/4 語句給目標字段定址,系統將根據數據類型解釋字段內容。
10.1.6 指定文本模式
要用文本模式處理文件,使用 OPEN DATASET 語句的 TEXT MODE 選項:
OPEN DATASET <dsn>FOR ....IN TEXT MODE.
如果從以文本模式打開的文件中讀取數據或向此類文件中寫入數據,數據將逐行傳輸。系統假定文件為行結構。
10.1.7 在指定位置打開文件
要在指定位置打開文件,使用 OPEN DATASET 語句的 AT POSITION 選項:
OPEN DATASET <dsn> [FOR ....] [IN ... MODE] AT POSITION <pos>.
此語句打開文件<dsn>並為讀寫數據定位位置<pos>,該位置從文件起始處起按字節計算。在文件起始處以前,不能指定位置。以二進制模式工作時,指定位置<pos>相當有用,因為文本文件的物理表示法取決於操作系統。
10.2 關閉文件
要在應用服務器上關閉文件,使用 CLOSE DATASET 語句:
CLOSE DATASET <dsn>.
此語句關閉文件<dsn>,文件命名在打開文件中有說明。
只有在下次為寫入打開文件期間要刪除文件內容時,關閉文件才有必要。為避免錯誤並使程序易於閱讀,在使用下一條 OPEN DATASET 語句之前應關閉文件。通過 CLOSE 語句,可將文件分成邏輯塊並易於維護。
10.3 刪除文件
要在應用服務器上刪除文件,使用 DELETE DATASET 語句:
DELETE DATASET <dsn>.
此語句刪除文件<dsn>。文件命名在打開文件中有說明。如果系統可以刪除文件<dsn>,則 SY-SUBRC 返回 0,否則 SY-SUBRC返回4。
10.4 向文件中寫入數據
要向在應用服務器上的文件寫入數據,使用 TRANSFER 語句:
TRANSFER <f> to <dsn> [LENGTH <len>].
此語句將字段<f>的值寫入文件<dsn>,可以用 OPEN DATASET 語句指定傳輸模式。如果不能打開文件以寫入,則系統將嘗試用二進制模式打開文件,或為此文件使用 OPEN DATASET 語句的選項。
字段<f>的數據類型可以是基本型,或者是不包含作為組件的內表格的字段字符串(內表數據需通過結構進行寫入)。內表格不能在一次執行中寫入文件。通過 LENGHT 選項,可以指定傳輸數據的長度<len>。系統將第一個<len>字節寫入文件。如果<len>太小,則截斷超出的字節。如果<len>太大,系統將在傳輸行的右端填入空格。
10.5 從文件中讀取數據
要從應用服務器上的文件中讀取數據,使用 READ DATASET 語句:
READ DATASET <dsn> INTO <f> [LENGTH <len>].
此語句從文件<dsn>中讀取數據賦值給變量<f>。要決定把從文件中讀取的數據賦值給哪個變量,必須清楚文件結構。
可以用 OPEN DATASET 語句指定傳輸模式。如果沒有打開文件以讀取,則系統將嘗試以二進制模式打開文件或為此文件使用 OPEN DATASET 語句的選項。在讀取操作成功后,SY-SUBRC 將返回 0。當到文件末尾時,SY-SUBRC 將返回 4。當不能打開文件時, SY-SUBRC 將返回 8。
如果以二進制模式工作,則可以使用 LENGTH 選項查找實際傳輸給字段<f>的數據長度。系統可用變量<len>值設置該長度。
10.6 使用服務器上的文件
(1)通過用戶對話向服務器寫入數據
CALL FUNCTION 'DOWNLOAD'
(2)不通過用戶對話向服務器寫入數據
CALL FUNCTION 'WS_DOWNLOAD'
(3)通過用戶對話從服務器讀取數據
CALL FUNCTION 'UPLOAD'
(4)不通過用戶對話從服務器讀取數據
CALL FUNCTION 'WS_UPLOAD'
(5)檢查服務器上的文件
CALL FUNCTION 'WS_QUERY'
十一報表
11.1 PARAMATERS為變量定義輸入字段
可以按照用 DATA 語句聲明字段的方式用 PARAMETERS 語句聲明字段。用 PARAMETERS 語句聲明的字段稱為參數。通常,輸入字段的所有參數都將出現在選擇屏幕上。系統處理輸入屏幕時,報表用戶在這些輸入字段中鍵入的值將被分配給相應的參數。
要聲明參數及其數據類型,使用 PARAMETERS 語句,如下所示:
PARAMETERS <p>[(<length>)] <type> [<decimals>].
該語句創建參數<p>。附加項<length>、<type>和<decimals>與 DATA 語句相同。
用戶啟動報表程序時,<p>的輸入字段將出現在選擇屏幕中。
11.1.1 給參數分配缺省值
要為將顯示在選擇屏幕上的輸入字段分配缺省值,使用 PARAMETERS 語句的 DEFAULT 選項。語法如下:
PARAMETERS <p> ...... DEFAULT <f> ......
<f>可以是文字或字段名。如果指定字段名,則系統將按缺省值處理該字段的內容,報表用戶可以在選擇屏幕中更改缺省值。
系統在初始化事件 INITIALIZATION之前將缺省值傳輸給參數。因此,對於那些在用戶啟動程序時已經被填充的字段,應該使用字段名而不是文字作為字段的缺省值。
11.1.2 禁止參數顯示
要禁止在選擇屏幕中顯示參數,使用 PARAMETERS 語句的 NO-DISPLAY 選項。語法如下:
PARAMETERS <p> ...... NO-DISPLAY ......
11.1.3 允許參數接收大小寫
要允許用戶用大寫或小寫字母輸入參數值,使用 PARAMETERS 語句的 LOWER CASE 選項。語法如下:
PARAMETERS <p> ...... LOWER CASE ......
如果沒有 LOWER CASE 選項,系統將所有輸入值更改為大寫。如果使用 LIKE 選項從 ABAP/4 詞典中引用字段,參數將接受 ABAP/4 字段的所有屬性,不能更改這些屬性,也不能使用 LOWER CASE 選項,必須在 ABAP/4 詞典中定義是否可以輸入大寫或小寫值。
11.1.4 必須輸入的參數字段
要保證參數必須輸入,使用 PARAMETERS 語句的 OBLIGATORY 選項。語法如下:
PARAMETERS <p> ......OBLIGATORY ......
使用該選項時,用戶如果不在選擇屏幕的這個字段上輸入值,程序就無法繼續執行。
11.1.5 創建復選框
要為參數輸入定義復選框,使用 PARAMETERS 語句的 AS CHECKBOX 選項。語法如下:
PARAMETERS <p> ...... AS CHECKBOX ......
參數<p>按長度為 1 的類型 C 創建。在這種情況下,不允許使用附加選項 TYPE 和 LIKE。<p>的有效值是‘’或‘X’,這些值在用戶單擊選擇屏幕上的復選框時賦給參數。
11.1.6 創建單選按鈕組
要為參數輸入定義單選按鈕組,使用 PARAMETERS 語句的 RADIOBUTTON GROUP 選項。語法如下:
PARAMETERS <p> ...... RADIOBUTTON GROUP <radi>......
參數<p>按類型 C,長度 1 創建,並分配到組<radi>。字符串<radi>的最大長度是 4。允許使用附加的 LIKE 選項,但是必須參閱類型為C、長度為 1 的字段。必須為每個<radi>組分配至少兩個參數,每個組中只有一個參數可以用 DEFAULT 選項分配的缺省值,該值必須是‘ X’。
當用戶單擊選擇屏幕中的單選按鈕時,相應的參數被激活(分配值‘ X’),同時同組的其它參數被設為非活動的(賦值‘’)。
11.1.7 使用內存缺省值
PARAMETERS 語句的 MEMORY-ID 選項允許從全局 SAP 內存使用缺省值。語法如下:
PARAMETERS <p> ...... MEMORY ID <pid>......
使用該選項時,以名稱<pid>存儲在全局用戶相關的 SAP 內存中的值將作為<p>的缺省值出現在選擇屏幕上。<pid>最長 3 個字符,並且不能用引號封閉。
可以使用全局 SAP 內存在程序間傳遞保留在事務限制以外的值。用戶在整個終端進程期間都可利用該內存,並且所有並行進程使用相同的內存。因此 SAP 內存包含的內容要比局限於事務的 ABAP/4 內存更廣泛。參數可以按用戶在名為<pid>的用戶主記錄中的說明 進行設置。
11.1.8 分配匹配的代碼對象
要給參數分配匹配代碼對象,使用 PARAMETERS 語句的 MATCHCODE OBJECT 選項。語法如下:
PARAMETERS <p> ...... MATCHCODE OBJECT <obj> ......
匹配代碼對象<obj>的名稱必須是 4 字符的變量名,並且不能用引號封閉。如果使用該選項,則可能的條目按鈕將在參數<p>的輸入字段之后出現。 用戶按下該按鈕時,其結果是為執行輸入字段的匹配代碼選擇。
11.1.9 分配修改組
要將參數分配給修改組,使用 PARAMTERS 語句的 MODIF ID 選項,如下所示:
PARAMETERS <p> ...... MODIF ID <key> ......
修改組<key>的名稱必須是不帶引號 的 3 字符變量名。MODIF ID 選項總是把<key>分配到內表 SCREEN 的 SCREEN-GROUP1 列。
在 AT SELECTION-SCREEN OUTPUT 事件中,分配給修改組的參數可以用 LOOP AT SCREEN/MODIFY SCREEN 語句按整個組進行處理 。
11.2 SELECT-OPTIONS定義選擇標准
系統為每個 SELECT-OPTIONS 語句創建選擇表。選擇表的目的是按標准化的方式保存復 合選擇限制。選擇表是一個帶表頭行的內表。它的行結構是字段字符串,由四個組件構成,即 SIGN、 OPTION、 LOW 和 HIGH。
SIGN表示保存在 OPTION 中的運算符是否需要翻轉,允許值 是 I 和 E;OPTION 包含選擇運算符;LOW 和 HIGH 中的內容為間隔選擇指定上界和下界。
要創建在選擇屏幕中填充的選擇標准,可以使用 SELECT-OPTIONS 語句,如下所示:
SELECT-OPTIONS <seltab> FOR <f>.
該語句創建選擇表<seltab>,該表與數據庫表的列<f>或內部字段<f>相連接。該 數據庫表必須在程序中用 TABLES 語句聲明。選擇表<seltab>由報表用戶在選擇屏幕中填充。
11.2.1 給選擇標准分配缺省值
要給將顯示在選擇屏幕的選擇標准分配缺省值,使用 SELECT-OPTIONS 語句的 DEFAULT 選項。語法如下:
SELECT-OPTIONS <seltab> FOR <f>
DEFAULT <g> [TO <h>]
[OPTION <op>]
SIGN <s>.
<g>和<h>的缺省值可以是實際值 (在單引號中)或是字段名,該字段的值將用做缺省值。<g>用於設定LOW字段,<h>用於設定HIGH字段。
對於單值選擇,<op>可以是 EQ、NE、GE、GT、LE、LT、CP 或 NP,缺省值是 EQ。對於期間選擇,<op>可以是 BT 或 NB,缺省值是 BT 。
SIGN <s>可以是 I(包括)和 E(排除),缺省值是 I。
11.2.2 限制為單行
要把用戶對選擇表的訪問限制在單行,使用 SELECT-OPTIONS 語句的 NO-EXTENSION 選項,語法如下所示:
SELECT-OPTIONS <seltab> FOR <f> ..... NO-EXTENSION .....
如果指定該選項,則選擇屏幕上不出現右箭頭,並且用戶不能訪問“ 復雜選擇” 窗口。
11.2.3 限制為單值
要將選擇屏幕上選擇標准的外觀限制為單值選擇,使用 SELECT-OPTIONS 語句的 NO INTERVALS 選項。語法如下所示:
SELECT-OPTIONS <seltab> FOR <f> ..... NO INTERVALS .....
如果指定該選項,則“ 到”字段不出現在選擇屏幕上,選擇屏幕上的輸入將限制為單值選擇。但是,用 戶可以在“ 復雜選擇” 屏幕中輸入間隔選擇。
11.3 空行、下划線和注釋
11.3.1 空行
要在選擇屏幕上產生空行,使用 SELECTION-SCREEN 語句的 SKIP 選項。語法如下:
SELECTION-SCREEN SKIP [<n>].
該語句產生<n>個空行,其中<n>的值可以是 1 到 9。要產生單個空行,可以省略<n>。
11.3.2 下划線
要在選擇屏幕中給一行或行中的一部分加下划線,使用 SELECTION-SCREEN 語句的 ULINE 選項。語法如下:
SELECTION-SCREEN ULINE [[/]<pos(len)>] [MODIF ID <key>].
該語句創建下划線。
如果不使用格式選項<pos(len)>,則在當前行下面創建新行。如果使用格式選項<pos(len)>,下划線將從當前行的位置<pos>處開始,連續<len>個字符。通過一行中的 幾個元素,也可以不通過<pos>來指定(<len>)。可以使用可選的斜杠 (/) 請求換行。
11.3.3 注釋
要在選擇屏幕中書寫文本,使用 SELECTION-SCREEN 語句的 COMMENT 選項。語法如下:
SELECTION-SCREEN COMMENT [/]<pos(len)><name> [FOR FIELD <f>]
[MODIF ID <key>].
使用該選項時必須定義格式(開始位置和長度)。對於<name>,可以指定文本符號或指定最大長度為 8 個字符的字段名。該字符字段不能用DATA 語句聲明,而是通常自動地按長度<len>生成。必須在 INITIALIZATION 事件中動態地填充該字符字段。
將顯示文本<name>,從列<pos>開始,長度為<len>。如果不使用斜杠 (/),注釋將寫到當前行,否則將創建新行 。
要把文本標簽分配給參數或選擇選項,使用 FOR FIELD <f>選項。<f>可以是參數或選擇標准的名稱。因此,如果用戶在選擇屏幕的注釋上請求幫助,則顯示分配給字段<f>的幫助文本。
選擇屏幕注釋的 MODIF ID <key>選項與為 PARAMETERS 語句所描述的相同。
11.4 將幾個元素放在同一行
要將參數或注釋集合定位在選擇屏幕的一行上,必須在由下列兩條語句封閉的塊中聲明元素:
SELECTION-SCREEN BEGIN OF LINE.
...
SELECTION-SCREEN END OF LINE.
使用該選項時不會顯示選擇文本,要顯示選擇文本,必須通過與 COMMENT 選項一起使 用 SELECTION-SCREEN 語句提供描述。另外,不要把斜杠與格式選項<pos(len)>一起使用。 在該格式選項中,可以在上述語句中省略位置說明<pos>。 隨后對象將定位在行中的當前位置。
11.5 創建元素塊
要在選擇屏幕上創建元素邏輯塊,使用 SELECTION-SCREEN 語句的 BEGIN OF BLOCK 選項選擇塊的開始,然后定義各個元素並用 END OF BLOCK 選項選擇塊的結束,如下所示:
SELECTION-SCREEN BEGIN OF BLOCK <block>
[WITH FRAME [TITLE <title>]]
[NO INTERVALS].
...
SELECTION-SCREEN END OF BLOCK <block>.
必須為每個塊定義名稱<block>,可以嵌套塊。
如果增加 WITH FRAME 選項,在塊的周圍將畫外框。最多可以嵌套 5 層帶外框的不同塊。可以使用 TITLE 選項給每個外框增加標題,<title>可以是文本符號或字符文字。該字符字段的長度是外框的 寬度,該寬度自動按照外框的嵌套深度進行設置。
11.6 在應用工具條上創建按鈕
在選擇屏幕的應用工具條中最多可以創建 5 個按鈕,這些按鈕自動與功能鍵相連接。語法如下所示:
SELECTION-SCREEN FUNCTION KEY <i>.
<i>必須在 1 到 5 之間。必須在 ABAP/4 詞典字段 SSCRFIELDS-FUNCTXT_0<i>中指定要在運行時間出現在按鈕上的文本。
必須用 TABLES 語句聲明 SSCRFIELDS。當用戶單擊該按鈕時,FC0<i>輸入到字段 SSCRFIELDS-UCOMM 中,可以在事件 AT SELECTION-SCREEN中檢查該字段。
11.7 在選擇屏幕上創建按鈕
要在選擇屏幕上創建按鈕,可以與 PUSHBUTTON 參數一起使用 SELECTION-SCREEN 語句。語法如下:
SELECTION SCREEN PUSHBUTTON [/]<pos(len)><name>
USER-COMMAND <ucom> [MODIF ID <key>].
在<name>中指定的文本是按鈕文本。對於<ucom>, 必須指定最多為 4 字符的代碼。當用戶在選擇屏幕上單擊按鈕時,<ucom>被輸入詞典字段 SSCRFIELDS-UCOMM。
必須使用 TABLES 語句聲明 SSCRFIELDS。可以在事件 AT SELECTION-SCREEN中檢查 SSCRFIELDS-UCOMM 字段的內容 。
十二事件
|
事件關鍵字 |
事件 |
| INITIALIZATION |
在顯示選擇屏幕之前的點 |
| AT SELECTION-SCREEN
|
選擇屏幕仍然活動時,處理用戶在 選擇屏幕上輸入之后的點 |
| START-OF-SELECTION |
處理選擇屏幕之后的點 |
| GET <table> |
點位於邏輯數據庫提供數據庫表<table>的行處 |
| GET <table> LATE
|
處理所有表之后的點,在邏輯數據庫的結構中, 使這些表位於數據庫表<table>的下層 |
| END-OF-SELECTION |
處理完邏輯數據庫提供的所有行之后的點 |
| TOP-OF-PAGE |
啟動新頁時,列表處理中的點 |
| END-OF-PAGE |
結束頁時,列表處理中的點 |
| AT LINE-SELECTION |
用戶在該點處選擇行 |
| AT USER-COMMAND |
用戶在該點處按下功能鍵或在命令字段中輸入命令 |
| AT PF<nn> |
用戶在該點處按下有功能代碼 PF<n>的功能鍵 |
12.1 INITIALZATION
啟動已定義選擇屏幕的程序時,系統通常首先處理此選擇屏幕。如果希望在處理選擇屏幕之前執行過程塊,可以把它分配到事件關鍵字 INITIALIZATION。
在此塊中, 指定初始化選擇屏幕的語句。
12.2 AT SELECTION-SCREEN
12.2.1 處理特殊輸入字段
要在處理選擇屏幕的特殊輸入字段之后啟動過程塊,按照下列方法使用關鍵字 AT SELECTION 屏幕:
AT SELECTION-SCREEN ON <field>.
系統處理了變量<field>的輸入字段之后,啟動相應過程塊。如果從此過程塊中發送 ERROR MESSAGE,則系統再次顯示選擇屏幕,用戶必須更改變量<field>的輸入字段。
12.2.處理多重選擇
將特殊選擇標准的復雜選擇輸入到選擇屏幕的“多重選擇 ”窗口,並處理此窗口之后,可以調用過程塊,按照下列方法使用 AT SELECTION-SCREEN 語句:
AT SELECTION-SCREEN ON END OF <seltab>.
在處理選擇標准<seltab>的“復雜選擇”窗口結束處啟動相應過程塊。 可以使用這些選項檢查內表<seltab>中的條目。
12.2.3 創建輸入值列表
通過按照下列方法使用 AT SELECTION-SCREEN 語句,可以為選擇屏幕上的輸入字段創建可能輸入值的列表:
AT SELECTION-SCREEN ON VALUE-REQUEST FOR <field>.
如果使用此語句,在選擇屏幕上選定參數或選擇標准<field>的輸入字段時,會自動 緊跟着該字段出現可能的登錄按鈕 。
只可以在報表程序中使用此語句。在邏輯數據庫程序中,可以使用 PARAMETERS 和 SELECT-OPTIONS 語句的 VALUE-REQUEST 選項。必須在 AT SELECTION-SCREEN ON VALUE REQUEST 語句的過程塊內為<field>編寫建議值列表程序。
12.2.4 創建輸入字段幫助
通過按照下列方法使用 AT SELECTION-SCREEN 語句,可以為選擇屏幕 上的輸入字段創建幫助:
AT SELECTION-SCREEN ON HELP-REQUEST FOR <field>.
如果使用此語句,用戶在選擇屏幕上選擇<field>的輸入字段,並按下 F1 鍵時,將顯示幫助文本。
只可以在報表程序中使用此語句。在邏輯數據庫程序中,可以使用 PARAMETERS 和 SELECT-OPTIONS 語句的HELP-REQUEST 選項。必須在 AT SELECTION-SCREEN ON HELP REQUEST 語句的過程塊內編寫幫助文本的程序。
12.2.5 處理單選按鈕組
在選擇屏幕上處理完單選按鈕組之后,要啟動過程塊,按照下列方法使用關鍵字 AT SELECTION 屏幕:
AT SELECTION-SCREEN ON RADIOBUTTON GROUP <radi>.
系統處理單選按鈕組<radi>后啟動相應過程塊。如果從過程塊中發送 ERROR MESSAGE, 則系統再次顯示選擇屏幕,用戶必須更改單選按鈕<radi>的輸入字段 。
12.2.6 處理輸入字段塊
在選擇屏幕上處理完元素塊之后啟動過程塊,按照下列方法使用關鍵字 AT SELECTION 屏幕:
AT SELECTION-SCREEN ON BLOCK <block>.
系統處理完元素塊<block>時啟動相應過程塊。如果從此過程塊中發送 ERROR MESSAGE, 則系統再次顯示選擇屏幕,用戶必須更改塊<block>的輸入字段。
12.2.7 選擇屏幕的PBO
要在每個 ENTER 的選擇屏幕 PBO 中啟動過程塊,使用下列 AT SELECTION-SCREEN 語句:
AT SELECTION-SCREEN OUTPUT.
12.3 START-OF-SELECTION
可能的事件過程塊。例如,可以使用這些過程塊設置內表的值,或將信息語句寫到輸出屏幕上。
在 START-OF-SELECTION 事件處,也處理沒有附加到事件關鍵字的所有語句,或在 FORM-ENDFORM 塊后寫這些語句。
12.4 GET<table>
對於有附加邏輯數據庫的報表程序,最重要的事件是邏輯數據庫程序從數據庫表中讀取了行的時刻。要在此事件處啟動過程塊,按照下列方法使用 GET 語句:
GET <table> [FIELDS <list>].
此語句之后,可以使用數據庫表<table>的當前行。在表工作區<table>中提供了數 據。
(1)指定數據表的字段
要指定在 GET 事件處使用數據庫表的哪一個字段,按照下列方法使用 GET 語句的 FIELDS 選項:
GET <table> [LATE] FIELDS <f1><f2> ...
使用 FIELDS 選項,從數據庫表<table>中,指定邏輯數據庫程序只讀取字段<f1><f2> ... 和關鍵字段。FIELDS 選項的使用可以引起相應性能改善。
12.5 GET<table> LATE
要在系統處理完邏輯數據庫的所有數據庫表之后啟動過程塊,按照下列方法使用事件關 鍵字 GET:
GET <table> LATE [FIELDS <list>].
與只使用 SELECT 語句的報表程序相似,在數據庫表<table>的 SELECT 循環中,GET <table> LATE 語句的過程塊直接出現在 ENDSELECT 語句的前面 。FIELDS 選項的作用與 GET <table>事件相同,
12.6 END-OF-SELECTION
要在系統讀取和處理完邏輯數據庫的所有數據庫表之后定義過程塊,使用關鍵字 END-OF-SELECTION。
12.7 終止過程塊
12.7.1 無條件的離開過程塊
(1)轉向END-OF-SELECTION
可以立即離開任何過程塊,並通過按照下列方法使用STOP語句轉向 END-OF-SELECTION 過程塊:
STOP.
運行 STOP 語句后,系統執行 END-OF-SELECTION 過程塊,並停止運行程序。
(2)轉向輸出屏幕
可以立即離開任何過程塊(除在 AT 事件以外),並通過按照下列方法使用 EXIT 語句轉向輸出屏幕:
EXIT.
EXIT 語句后,系統顯示輸出列表,並停止運行程序。它不執行 END-OF-SELECTION 過程塊。
(3)離開AT事件
如果在 AT 事件的過程塊中使用 EXIT 語句(有以 AT 開頭的事件關鍵字的所有事件),則系統離開此過程塊,並轉向下一個出現事件的過程塊。
12.7.2 有條件的離開過程塊
通過按照下列方法使用 CHECK 語句的兩個變式,可以有條件地離開任何過程塊:
CHECK <condition>.
如果 CHECK 語句中的條件為假,則系統離開過程塊並轉向下一個出現事件的過程塊。
CHECK <seltab>.
如果數據庫表的表工作區的內容與選擇表<seltab>中的條件不匹配,並且將選擇表<seltab>附加到該數據庫表,則系統離開過程塊 。
12.7.3 無條件離開GET事件
(1)轉向當前數據表的下一行
要離開 GET 語句的過程塊,並轉向邏輯數據庫同一層上的下一 GET 事件,按照下列方法 使用 REJECT:
REJECT.
此語句后,系統立即處理相同數據表的下一 GET 事件。這意味着它從當前表中啟動相同過程塊的新行。
(2)轉向上級數據表的下一行
要離開 GET 語句的過程塊,並執行邏輯數據庫高層的下一 GET 事件,按照下列方法使用 REJECT 語句:
REJECT <dbtab>.
執行此語句后,系統將立即處理數據庫表<dbtab>的下一 GET 事件。在鏈接到當前數 據庫表的分層結構中,相比之下, 數據庫表<dbtab>必須位於高層。
12.7.4 有條件離開GET事件
要有條件地離開 GET 事件,可以使用 CHECK 語句。用 CHECK 語句離開 GET 事件之后, 系統將執行邏輯數據庫相同層上的下一 GET 事件,它讀取當前表的下一行。沒有處理在邏 輯數據庫的分層順序中較靠后的數據庫表。
在 GET 事件中,可以使用 CHECK 語句的兩種變式:
CHECK <condition>.
如果 CHECK 語句中的條件為假,則系統離開過程塊。
CHECK SELECT-OPTIONS.
如果從當前數據庫表中讀取的行與所有選擇表中的條件不匹配,並且將這些選擇表連接到該數據庫表,則系統離開過程塊 。
十三摘錄數據集
由於內表具有固定的行結構,所以它不適於處理具有變化結構的數據集。出於這種考慮,ABAP/4 提供了創建所謂的摘錄數據集的可能性。
摘錄數據集是報表存儲區中的順序數據集,這意味着只能在循環中訪問它的數據,不能像對內表操作那樣通過索引訪問其單個行。在報表運行過程中,系統可以正確地創建一個摘錄數據集。至於內表,因為系統可根據需要展開它,所以原則上摘錄數據集的大小是沒有限制的。
摘錄數據集由一系列預定義的結構的記錄組成。但是,不是所有記錄的結構都必須相同。在一個摘錄數據集中,可以一個接一個地存儲不同長度和結構的記錄。不必為要存儲的不同結構創建單個的數據集。這實際上大大減少了維護工作。
與內表不同,系統在存儲摘錄數據集時,將部分壓縮摘錄數據集。這減少了所需的存儲空間。另外,不必在報表的開始處指定摘錄數據集的結構,而可以在程序流過程中動態決定其結構。
13.1 創建並填充摘錄數據集
13.1.1 定義摘錄數據集為字段組
摘錄數據集由一系列記錄組成,這些記錄可以有不同的結構。所有具有相同結構的記錄形成一個記錄類型。必須使用 FIELD-GROUPS 語句將摘錄數據集的每個記錄類型定義為字段組。
FIELD-GROUPS <fg>.
該語句定義了字段組<fg>,字段組將幾個字段組合到一個名稱下。出於可讀性的原因,最好在報表的開始處,即聲明段之后定義字段組。
字段組不為字段保留存儲空間,但它包含現有字段的指針。用記錄填充摘錄數據集時,這些指針將決定存儲記錄的內容。
可以定義特殊字段組 HEADER:
FIELD-GROUPS HEADER.
填充摘錄數據集時,系統將自動用該字段組給所有其它字段組加上前綴。這意味着在摘錄數據集中,字段組<fg>的記錄總是首先包含 HEADER 字段組的字段。在給摘錄數據集排序時,系統將使用這些字段作為缺省的排序關鍵字。
13.1.2 給字段組分配字段
要確定將哪個字段包含進字段組中,使用 INSERT 語句:
INSERT <f1> ... <fn> INTO <fg>.
該語句定義字段組<fg>的字段。在給字段組分配字段之前,必須用 FIELD-GROUPS 語句定義字段組<fg>。而對於字段<fi>,就只能使用全局數據對象。不能將在子程序或功能模塊中定義的局數據對象分配給字段組。
INSERT 語句與 FIELD-GROUPS 語句一樣,既不保留存儲空間,也不轉換值。執行報表時,可給字段組分配字段,直到首次使用該字段組填充摘錄記錄。從這時起,記錄的結構就已固定,不再改變。簡而言之,如果還沒有使用字段組,就可以動態地給它分配任意值。
由於特殊字段組 HEADER 是每個摘錄記錄的一部分,所以在填充了第一個摘錄記錄后,就不能再更改該字段組。不必用字段填充字段組,如果定義 HEADER 字段組,則只用 HEADER中的字段填充摘錄記錄。
13.1.3 創建摘錄數據集
要創建實際的摘錄數據集,使用 EXTRACT 語句:
EXTRACT <fg>.
系統用報表的第一個 EXTRACT 語句創建摘錄數據集並添加第一個摘錄記錄。並且每使用一個后續的 EXTRACT 語句,就向摘錄數據集填充另一個摘取記錄。
如果已經指定,則每個摘錄記錄都包含字段組 HEADER 中的字段,並用它作為排序關鍵字,其后緊跟那些包含在字段組<fg>中的字段。在摘錄過程中,系統用相應字段中的當前內容填充摘錄記錄。
13.2 處理摘錄數據集
13.2.1 讀取摘錄數據集
處理內表時,也可以使用循環讀取摘錄數據集的數據:
LOOP.
...
[AT FIRST | AT <fgi> [WITH <fgj>] | AT LAST.
...
ENDAT.]
...
ENDLOOP.
語句 LOOP-ENDLOOP 終止創建報表的摘錄數據集並在數據集的所有記錄上執行循環。在每個循環過程中,系統將讀取一個摘錄記錄並將其數據值直接放回到源字段中。可以連續執行多個循環。
與內表不同,對於摘錄數據集不必使用特殊的工作區作為接口。對於每個記錄的讀取,都可以使用它們原始字段名在循環的語句塊中處理讀取的數據。
與內表上的 LOOP AT-ENDLOOP 循環不同,在摘錄數據集上不能使用嵌套的 LOOP-ENDLOOP 循環,否則將產生運行時錯誤。在循環的語句塊中及處理循環后,不允許再使用 EXTRACT 語句,否則將產生運行時錯誤。
如果只需對數據集的某些記錄執行一些語句,則可使用控制語句 AT 和 ENDAT。系統將針對 AT 不同的選項處理控制語句之間的語句塊,如下所示:
AT FIRST.
系統將針對數據集的第一條記錄執行一次該語句塊。
AT <fgi> [WITH <fgj>].
如果當前讀取的摘錄記錄的記錄類型是用字段組<fgi>定義的,系統就處理該語句塊。使用 WITH <fgj>選項時,在摘錄數據集中,字段組<fgi>當前讀取的記錄后面必須緊跟字段組<fgj>的記錄。
AT LAST.
系統將針對數據集的最后一條記錄執行一次該語句塊。
13.2.1 排序摘錄數據集
和處理內表一樣,也可以使用 SORT 語句給摘錄數據集排序:
SORT [<order>][AS TEXT]
[BY <f1> [<order>][AS TEXT] ... <fn> [<order>][AS TEXT]].
SORT 語句終止創建報表的摘錄數據集,同時給數據集記錄排序。如果沒有 BY 選項,系統將根據在 HEADER 字段組中指定的關鍵字給數據集排序。要定義不同的排序關鍵字,請使用 BY 選項,然后系統將根據指定組件<f1> ... <fn>給數據集排序。
SORT 語句將摘錄過程中未定義的排序關鍵字中的所有字段按空值對待。系統不管指定的排序順序如何,總是將空值排在具有定義值的字段的前面。
在處理 SORT 語句以后,不能再執行 EXTRACT 語句。否則將產生運行時錯誤。
13.2.2 處理控制集
通過使用 SORT 語句給摘錄數據集排序,可定義一個控制級結構。摘錄數據集的控制級結構對應於 HEADER 字段組中的字段的順序。排序后,可在 LOOP-ENDLOOP 循環中使用 AT 語句編寫語句塊,使系統只在控制中斷時才處理它。
AT NEW <f> | AT END OF <f>.
...
ENDAT.
如果字段<f>或當前摘錄記錄中的排序關鍵字的較高層字段中包含其它值,並且該值與摘錄數據集前面的記錄(對於 AT NEW)或后續記錄(對於 AT END)中的值不同,將產生控制中斷,並且系統將處理 AT-ENDAT 中的語句塊。字段<f>必須是 HEADER 字段組的一部分。
13.2.3 計算序號和合計
在使用 LOOP-ENDLOOP 讀取已排序的摘錄數據集時,可以訪問兩個自動生成的字段 CNT(<f>) 和 SUM(<g>),這些字段提供了不同值的序號或數字字段的合計。系統將在控制級的最后以及讀取數據集的最后一個記錄后填充這些字段。如下所示:
CNT(<f>)
如果<f>是 HEADER 字段組的非數字字段,並且系統是根據<f>給摘錄數據集排序的,則 CNT(<f>) 包含了在控制級中或在整個數據集中分別設定的不同值<f>的序號。
SUM(<g>)
如果<g>是摘錄數據集的數字字段,SUM (<g>) 將包含控制級或整個數據集中<g>的值的合計。
十四列表
14.1 自定義列表
14.1.1 定義頁眉
要分別定義頁眉的格式,必須在緊隨事件關鍵字 TOP-OF-PAGE 的處理塊中定義:
TOP-OF-PAGE.
WRITE: ....
TOP-OF-PAGE 事件在系統開始處理列表新頁時出現。系統在輸出新頁首行之前處理 TOP-OF-PAGE 后面的語句。
自定義頁眉出現在標准頁眉之下。如果要取消標准頁眉,使用 REPORT 語句的 NO STANDARD PAGE HEADING 選項:
REPORT <rep> NO STANDARD PAGE HEADING.
使用該語句時,系統不在報表<rep>列表頁上顯示標准頁眉。如果使用 TOP-OF-PAGE 定義單個頁眉,則系統就將其顯示出來。
14.1.2 確定列表寬度
要確定輸出列表的寬度,使用 REPORT 語句的 LINE-SIZE 選項。
REPORT <rep> LINE-SIZE <width>.
該語句根據<width>字符確定報表<rep>輸出列表的寬度。如果將<width>設置為 0,則系統使用標准列表的寬度。
14.1.3 確定頁長
要確定輸出列表的頁長,使用 REPORT 語句的 LINE-COUNT 選項。
REPORT <rep> LINE-COUNT <length>[(<n>)].
該語句用<length>行確定報表<rep>輸出列表的頁長。如果指定選項號<n>,則系統為頁腳保留<n>行頁長。並不將這些頁腳行填寫到 END-OF-PAGE 事件中,而是作為空行顯示。
14.1.4 定義頁腳
要定義頁腳,使用 END-OF-PAGE 事件。在處理列表頁時,如果系統到達頁腳保留行,或者如果 RESERVE 語句觸發分頁則該事件發生。在緊接着 END-OF-PAGE 事件關鍵字的處理塊中填充頁腳的行:
END-OF-PAGE.
WRITE: ....
如果為 REPORT 語句的 LINE-COUNT 選項中的腳注保留行,則系統只處理緊接着END-OF-PAGE 的處理塊。
14.2 多頁列表
14.2.1 編程分頁
(1)無條件分頁
要在頁處理期間觸發分頁,請使用 NEW-PAGE 語句的基本格式:
NEW-PAGE.
該語句結束當前頁,在新頁上顯示所有其他輸出。如果輸出寫入到當前頁和 NEW-PAGE 之后的新頁,則只開始新頁,系統然后將 SY-PAGNO 系統字段家 1,不能產生空頁。
不能觸發 END-OF-PAGE 事件,這意味着即使定義了頁腳,系統也不輸出。
(2)條件分頁
要在少於某一頁剩余行數的條件下執行分頁,使用 RESERVE 語句:
RESERVE <n> LINES.
如果當前列表頁的最后輸出和頁腳之間剩余的自由行數少於<n>,則該語句觸發分頁。<n>可以是變量。在開始新頁之前,系統處理 END-OF-PAGE 事件。只有輸出寫入到后續頁時, RESERVE 才生效,不創建空頁。
14.2.2 單頁的標准頁眉
標准頁眉包括列表和列標題。要影響標准頁眉這些組件的表現形式,使用 NEW-PAGE 語句的下列選項:
NEW-PAGE [NO-TITLE|WITH-TITLE] [NO-HEADING|WITH-HEADING].
使用 NO-TITLE 或 WITH-TITLE 選項取消或者在以后所有頁上顯示標准表頭,基本列表的缺省值為 WITH-TITLE,輔助列表為 NO-TITLE。
使用 NO-HEADING 或 WITH-HEADING 選項取消或在以后所有頁上顯示列標題。基本列表的缺省值為 WITH-HEADING,輔助列表為 NO-HEADING。
即使使用 REPORT 語句的 NO STANDARD PAGE HEADING 選項取消標准頁眉,也能使用 WITH-TITLE 和 WITH-HEADING 激活單個組件的顯示。
14.2.3 單頁頁長
要分別確定每頁的頁長,使用 NEW-PAGE 語句:
NEW-PAGE LINE-COUNT <length>.
該語句將后續頁的頁長確定為<length>。<length>可以是變量。如果將<length>設置為 0,則系統使用標准頁長。頁眉是頁的部分,因此也是頁長的部分。
14.2.4 所有頁頁寬
不能更改列表級內單個頁寬。只能更改新列表級的所有頁寬。為此,使用 NEW-PAGE 語句:
NEW-PAGE LINE-SIZE <width>.
從新頁開始的所有列表級寬度都為<width>,而不是 REPORT 語句中定義的寬度。
如果將<width>設置為 0,則系統使用標准列表的寬度。如果將<width>設置為 SY-SCOLS,則可以使新列表級的寬度適配窗口寬度,即使該窗口小於標准窗口。 SY-SCOLS 系統字段包含當前窗口一行的字符數。
14.2.5 在程序之內滾動
在程序之內,可以垂直和水平滾動列表。使用 SCROLL 關鍵字。SCROLL 語句只對完成的列表生效。如果在列表的第一條輸出語句之前使用該語句,則不影響該列表。如果在列表的第一條輸出語句之后使用 SCROLL,則影響整個列表,包括以后的所有輸出語句。
在每條 SCROLL 語句之后,可以查詢 SY-SUBRC 以查看系統是否成功。如果系統成功滾動則 SY-SUBRC 為 0;如果滾動不可能則為 4,因為其超過列表邊界。
(1)通過窗口滾動
要以當前窗口大小垂直滾動列表並且與頁長無關,使用如下語句:
SCROLL LIST FORWARD|BACKWARD [INDEX <idx>].
不帶 INDEX 選項時,該語句以當前窗口大小向前或向后滾動當前列表。使用 INDEX 選項時,系統以列表級<idx>滾動列表。
(2)按頁滾動
要按頁滾動列表,即按頁長垂直滾動列表,SCROLL 語句提供下列選項:
1)滾動到某頁
要滾動到某頁,使用 SCROLL 語句的 TO 選項:
SCROLL LIST TO FIRST PAGE | LAST PAGE | PAGE <pag>
[INDEX <idx>] [LINE <lin>].
不用 INDEX 選項,語句將當前列表滾動到首頁、尾頁或<pag>頁。使用 INDEX 選項,則系統滾動列表級<idx>的列表。使用 LINE 選項時,系統顯示從實際列表的<lin>行開始滾動的頁,不包括頁眉行。
2)按頁數滾動
要按頁數滾動列表,使用 SCROLL 語句的下列選項:
SCROLL LIST FORWARD | BACKWARD <n> PAGES [INDEX <idx>].
不用 INDEX 選項時,語句向前或向后滾動<n>頁。
3)滾動到列表的頁邊緣
要水平滾到列表的左或右頁邊緣,使用 SCROLL 語句的下列選項:
SCROLL LIST LEFT | RIGHT [INDEX <idx>].
不用 INDEX 選項時,語句滾動到當前列表的左或右頁邊緣。使用 INDEX 選項時,系統滾動列表級<idx>的列表。
(3)按列滾動
要按列水平滾動列表, SCROLL 語句提供幾個選項。在此情況下,一列意味着列表行一個字符。
1)滾動到某列
要滾動到某列,使用 SCROLL 語句的 TO COLUMN 選項:
SCROLL LIST TO COLUMN <col> [INDEX <idx>].
不用 INDEX 選項時,系統顯示從列<col>開始的當前列。使用 INDEX 選項時,系統滾動列表級<idx>的列表。
2)按列數滾動
要按某一列數滾動列表,使用 SCROLL 語句的下列選項:
SCROLL LIST LEFT | RIGHT BY <n> PLACES [INDEX <idx>].
不用 INDEX 選項時,系統按<n>列將當前列表滾動到左邊或右邊。
14.3 列表頁面設置
14.3.1 定位輸出
可以在當前頁的任意位置定位 WRITE 和 ULINE 語句的輸出。緊接着位置規格的 WRITE、 SKIP或 ULINE 語句可以覆蓋現有輸出。
SY-COLNO (用於當前列)
SY-LINNO (用於當前行)
可以使用系統字段在頁上引導。ABAP/4 提供一些關鍵字以更改絕對和相對輸出位置。
(1)絕對定位
指定絕對位置之后,將后續輸出寫入在固定行和列開始的屏幕。
1)水平定位
要指定水平輸出位置, ABAP/4 提供兩種方法:
WRITE 和 ULINE 語句的 AT 選項以及 POSITION 語句。POSITION 語句的語法為:
POSITION <col>.
該語句將水平輸出位置和 SY-COLNO 系統字段設置為<col>。如果<col>超出頁面之外,則忽略后續輸出語句。系統將 POSITION 語句或使用 AT 格式化的 WRITE 語句的輸出寫入指定位置,不管是否有足夠空間。超出該行的輸出部分被截斷。其他 WRITE 輸出在下一行開始。
2)垂直定位
如下指定垂直輸出位置:
SKIP TO LINE <n>.
該語句將垂直輸出位置和 SY-LINNO 系統字段設置為<lin>。如果<lin>超出 1 和頁長范圍,則系統忽略該語句。
3)在頁眉之下定位
要將輸出定位到整個頁眉之后的第一行,使用 BACK 語句:
BACK.
如果該語句不是緊跟 RESERVE 語句,則后續輸出出現在頁眉之下。系統將 SY-COLNO 設置為 1 並根據頁眉的長度設置 SY-LINNO。如果在 TOP-OF-PAGE 事件中指定 BACK,則系統不將輸出位置設置到整個頁眉之下,而只在標准頁眉之下。寫入的任何輸出現在都覆蓋 TOP-OF-PAGE 中指定的自定義頁眉。
(2)相對定位
相對定位參考以前寫入列表的輸出。某些相對定位自動發生。使用無定位的 WRITE 時,在上一輸出之后空一列出現輸出。如果在當前行沒有足夠空間,則換行。不使用定位的 ULINE 和 SKIP 語句產生換行。
1)產生換行
要產生換行,可在 WRITE、 ULINE 或 NEW-LINE 語句的 AT 選項中使用反斜杠。
NEW-LINE.
該語句將輸出定位在新行中,將 SY-COLNO 設置為 1 並且將 SY-LINNO 加 1。如果自最后換行之后將輸出寫入屏幕,則系統只執行該語句。NEW-LINE 不創建空行。在 NEW-PAGE 語句和事件開始時發生自動換行。
2)將輸出定位到其他輸出之下
可以將 WRITE 輸出定位到上一 WRITE 輸出的列中。使用 WRITE 語句的格式化選項 UNDER:
WRITE <f> UNDER <g>.
系統從開始輸出字段<g>的同一列中開始輸出<f>。該語句不限於當前頁,即<g>不必出現在相同頁上。
3)將輸出定位在行塊的首行
要將下一輸出行定位到通過 RESERVE 語句定義的行塊的首行,按如下格式使用 BACK 語句:
RESERVE.
.....
BACK.
如果 BACK 緊隨 RESERVE,則后續輸出出現在 RESERVE 之后的第一行中。
14.3.2 格式輸出
(1)FORMAT語句
要在程序中靜態設置格式化選項,按如下格式使用 FORMAT 語句:
FORMAT <option1> [ON|OFF] <option2> [ON|OFF] ....
FORMAT 語句中設置的格式化選項<optioni>適用於所有后續輸出,直到使用 OFF 選項關閉。
要在運行時動態設置格式化選項,按如下格式使用 FORMAT 語句:
FORMAT <option1> = <var1><option2> = <var2> ....
1)列表中的顏色
FORMAT 語句的選項 COLOR、 INTENSIFIED 和 INVERSE 影響輸出列表的顏色。要在程序中設置顏色,使用:
FORMAT COLOR <n> [ON] INTENSIFIED [ON|OFF] INVERSE [ON|OFF].
要在運行時設置顏色,使用:
FORMAT COLOR = <c> INTENSIFIED = <int> INVERSE = <inv>.
這些格式化選項不適用於由 ULINE 創建的水平行。其功能如下所示:
COLOR 設置行背景的顏色,如果設置 INVERSE ON,則系統將更改前景顏色而不是背景顏色。下表匯總各種不同的選項:
|
|
<n> |
<c> |
顏色 |
用於 |
| OFF |
或 COL_BACKGROUND |
0 |
取決於 GUI |
背景 |
| 1 |
或 COL_HEADING |
1 |
灰藍 |
標題 |
| 2 |
或 COL_NORMAL |
2 |
淡灰 |
列表正文 |
| 3 |
或 COL_TOTAL |
3 |
黃 |
總計 |
| 4 |
或 COL_KEY |
4 |
藍綠 |
關鍵字列 |
| 5 |
或 COL_POSITIVE |
5 |
綠 |
正門限值 |
| 6 |
或 COL_NEGATIVE |
6 |
紅 |
負門限值 |
| 7 |
或 COL_GROUP |
7 |
紫 |
組級別 |
缺省值為 COLOR OFF。INTENSIFIED 確定行背景的顏色調色板。
2)使字段可接受輸入
要在程序中將輸出字段設置為“准備輸入”,按如下格式使用 FORMAT 語句:
FORMAT INPUT [ON|OFF].
要在運行時將輸出字段設置為“准備輸入”,使用:
FORMAT INPUT = <i>.
3)使字段輸入為熱點
要將某一區域輸出為熱點,使用 FORMAT 語句的下列選項:
FORMAT HOTSPOT [ON|OFF].
要在運行時將字段設置為熱點,使用:
FORMAT HOTSPOT = <h>.
14.3.3 特殊格式輸出
(1)國家或用戶特有格式輸出
使用下列語句可以在程序中更改這些設置:
SET COUNTRY <c>.
(2)貨幣格式輸出
要根據貨幣格式化數字字段的輸出,使用 WRITE 語句的 CURRENCY 選項:
WRITE <f> CURRENCY <c>.
(3)單位特有格式輸出
可以根據某一單位格式化類型 P 字段,使用 WRITE 語句的 UNIT 選項:
WRITE <f> UNIT <u>.
該語句根據單位<u>設置小數位。
十五邏輯數據庫
ABAP/4 報表使用邏輯數據庫讀取和處理數據。報表可用的數據順序取決於相關邏輯數據庫的層次結構。邏輯數據庫也提供用戶對話框(即選擇屏幕)的界面並且將用戶輸入檢查和錯誤對話組合起來,可以在報表中修改並擴展該界面。
邏輯數據庫包括至少下列三個組件:
(1)結構
結構是邏輯數據庫的基本組件。它決定其它組件的結構以及運行時邏輯數據庫的行為。
(2)選擇
該組件決定每個報表的用戶界面,其格式通常由結構決定。可以調整和擴展選擇以適應需要。
(3)數據庫程序
數據庫程序是選擇數據並將其傳遞到報表的子程序集合。數據庫程序的格式由結構和選擇共同決定,可以調整和擴展數據庫程序以適應需要。
15.1結構
通常,邏輯數據庫反映 SAP 系統中層次表格的外來關鍵字相關性。邏輯數據庫有定義如下的層次結構:
(1)最高層只有一個節點,稱為根節點。
(2)每個節點可以有一個或幾個分支。
(3)每個節點從其它節點派生。
15.2 選擇
在邏輯數據庫中,可以使用 SELECT-OPTIONS 和 PARAMETERS 語句在選擇屏幕上定義輸入字段。通過稱為選擇包含程序的特定包含程序的幫助可達此目的。在每個 ABAP/4 報表中,可以通過定義報表特定選擇擴展邏輯數據庫選擇。所有報表特定選擇都顯示在特定數據庫選擇之后。
生成報表的選擇屏幕時,系統只考慮數據庫的特定選擇標准和參數,其相應表格由報表中的 TABLES 語句聲明。
15.2 數據庫程序
邏輯數據庫<dba>的數據庫程序的名稱符合命名規則 SAPDB<dba>。重要的是,它包括系統在運行 ABAP/4 報表時調用的子程序集合。報表中帶事件關鍵字的子程序之間的相互作用,在邏輯數據庫和 ABAP/4 報表中進行了描述。
邏輯數據庫程序通常包含定義子程序中描述的下列子程序,並且都使用 FORM 語句定義。
(1)FORM INIT
在顯示選擇屏幕之前調用一次。
(2)FORM PBO
每次刷新選擇屏幕之前調用。
(3)FORM PAI
用戶每次在選擇屏幕上按 ENTER 時調用。
系統將參數 FNAME 和 MARK 傳遞給子程序,這些參數自動定義和填充。
(1)FNAME 包含選擇屏幕上選擇標准或參數的名稱。
(2)MARK 說明用戶所做的選擇:
MARK = SPACE 意味着用戶已經輸入簡單的單值或范圍選擇。
MARK = '*' 意味着用戶已經在“多重選擇”屏幕上制作條目。
(3)FORM PUT_<table>
以邏輯數據庫結構決定的順序調用子程序。使用 SELECT 語句讀取節點<table>的數據,並且 PUT 語句將程序流定向到報表中合適的 GET 語句中。
PUT 語句是該子程序的主語句:
PUT < table >.
只能在邏輯數據庫子程序中使用 PUT <table>語句,該邏輯數據庫包含以 PUT_< table >開頭的名稱的節點<table>。
15.3 邏輯數據庫的授權檢查
通常,可以在下列數據庫程序的子程序或者報表的處理塊中包括授權檢查:
數據庫程序中的子程序:
- PAI
- AUTHORITY_CHECK_<table>
報表中的事件關鍵字:
- AT SELECTION-SCREEN
- AT SELECTION-SCREEN ON <fname>
- AT SELECTION-SCREEN ON END OF <fname>
- GET <table>
在任何情況下,數據庫訪問和應用邏輯的分離允許在邏輯數據庫程序中集中地編碼所有授權,這使維護大的編碼系統更加容易。
15.4 邏輯數據庫的性能
因為在所有有關的 ABAP/4 報表中更改邏輯數據庫將立即生效,所以通過集中優化可以提高程序庫中的不同對象的響應時間。
通過允許用戶精確指定系統從數據庫中讀取哪個表格條目可以獲得最大的性能提高。為此,可以在數據庫程序中使用下列技術:
(1)選擇標准和參數,可能帶默認值和值列表。
(2)動態選擇。
(3)匹配碼選擇。
(4)查看從數據庫讀取的條目或者將其存儲在內表中。
另外,應該在早期進行授權檢查,即盡可能在選擇屏幕處理期間而不是等到數據選擇處理期間。因為它們依賴於讀取的數據,因此沒有優化的步驟規則。
十六事務
16.1 對話編程
16.1.1 事務
事務是實施與用戶對話的程序。在典型的對話中,用戶可以在系統顯示的屏幕上輸入或請求信息。作為對用戶輸入或請求的響應,程序執行適當的動作:轉到下一個屏幕,顯示輸出或更改數據庫。
16.1.2 對話程序的結構
對話程序包含下面的基本組件:
(1)屏幕(動態程序)
SAP 系統中的每個對話都是由動態程序控制的。動態程序包含一個屏幕和它的流邏輯,並且精確控制一個對話步驟。流邏輯決定在顯示屏幕前(輸出前的 PBO 處理)和接收到用戶在屏幕上制作的條目后(輸入后的 PAI 處理)進行的處理。
在屏幕繪制器中固定的屏幕格式決定輸入/輸出字段、文本字段和諸如單選按鈕以及復選框之類的圖形元素的位置。另外,菜單繪制器允許在一個或多個 GUI 狀態下存儲菜單、圖表、按鈕及功能鍵。動態程序和 GUI 狀態都指向控制動態程序和 GUI 狀態的運行順序的 ABAP/4 程序。
(2)ABAP/4 模塊池
每個動態程序都精確指向一個 ABAP/4 對話程序。這樣的對話程序也稱為模塊池,原因是它包含交互模塊。動態程序的流邏輯包含從相應模塊池中調用模塊。在 PBO 事件中調用的交互模塊依照上下文進行屏幕模板的准備,例如通過設置字段內容或通過禁止顯示不需要的字段等方式准備屏幕模板。在 PAI 事件中調用的交互模塊用於檢查用戶的輸入並觸發合適的對話步驟,例如更新任務。
從一個事務中調用的所有動態程序都指向一個公用模塊池,模塊池的動態程序是編號的。默認情況下,系統為每個動態程序存儲下一個要顯示的動態程序。該動態程序序列或鏈可以是線性的也可以是環型的。在動態程序鏈中甚至可以調用另一個動態程序鏈,並且在處理它之后返回原始。
16.1.3 傳輸字段數據
與報表編程相反,不能用 WRITE 語句將字段數據寫入屏幕。系統通過屏幕字段名和 ABAP/4 變量名的比較來代替數據傳輸。如果兩個名稱相同,它將屏幕字段值傳輸給 ABAP/4 程序字段,反之亦然。在顯示屏幕之前和之后立即發生上述過程。
16.1.4 字段屬性
在屏幕制作器中定義所有動態程序屏幕字段的屬性。如果屏幕中的字段名對應於某個 ABAP/4 詞典字段的名稱,則系統自動建立這兩個字段之間的參考,因此自動從 ABAP/4 詞典中復制動態程序中的大量字段屬性。字段屬性和數據元素以及分配的詞典字段形成了動態程序在對話中執行的標准函數的基礎。
16.1.5 錯誤對話
動態程序處理器的另一個任務是管理錯誤對話。使用 ABAP/4 詞典的檢查表格自動檢查輸入數據或者通過 ABAP/4 程序本身檢查。動態程序處理器包括接收屏幕中的錯誤消息並將屏幕返回用戶。消息可以是上下文敏感的,也就是說,系統用當前字段內容替換消息文本中的占位符。另外,只有內容與錯誤有關並且可以糾正錯誤的字段才可以接收輸入。
16.1.6 數據一致性
要在復雜的應用程序中保持數據一致性,ABAP/4 提供優化數據庫更新的技術,對它的操作獨立於下面的數據庫並符合對話編程的特殊請求。
16.2動態程序
每個屏幕都包含用於顯示或請求信息的字段。字段可以是文本串、輸入或輸出字段、單選按鈕、復選框或按鈕。
SAP 動態程序包含幾個組件:
(1)流邏輯:為屏幕調用 ABAP/4 模塊。
(2)屏幕格式:屏幕上文本、字段、按鈕等的位置。
(3)屏幕屬性:屏幕號、后續屏幕號及其它。
(4)字段屬性:屏幕上單獨字段的屬性定義。
16.3ABAP模塊池
在對象瀏覽器中,模塊池代碼屬於下列類別之一:
(1)全局字段:模塊池中所有模塊都可使用的數據聲明;
(2)PBO 模塊:顯示屏幕前調用的模塊;
(3)PAI 模塊:響應用戶輸入而調用的模塊;
(4)子程序:可以在模塊池中任何位置調用的子程序。
默認情況下,系統將模塊池分成一個或多個包含程序。一個包含程序可以包含相同類型的多個模塊(僅 PBO 模塊或 PAI 模塊),然后主程序包含一系列將模塊鏈接到模塊池的 INCLUDE 語句。
