ABAP Help Document(2):1.2 表达式


1.2 表达式

表达式类型:

1.逻辑表达式,返回boolean值;

2.算术表达式,返回数值型值;

3.字符串表达式,返回字符型值;

4.位表达式;

示例:

"supplied
CLASS c_supplied DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS m1 IMPORTING p1 TYPE i DEFAULT 0
                     EXPORTING p2 TYPE i.
ENDCLASS.
CLASS c_supplied IMPLEMENTATION.
  METHOD m1.
    IF p1 IS SUPPLIED.
      WRITE:/ 'p1 is supplied with default',p1.
    ELSE.
      WRITE:/ 'p1 is not supplied',p1.
    ENDIF.
    IF p2 IS NOT SUPPLIED.
      WRITE:/ 'p2 is not supplied'.
    ELSE.
      WRITE:/ 'p2 is supplied',p2.
    ENDIF.
  ENDMETHOD.
ENDCLASS.
"表达式
FORM f_abap_expression.
"1逻辑表达式
"语法:
*  {
*    { operand1
*     {=|EQ|<>|NE|>|GT|<|LT|>=|GE|<=|LE
*       |CO|CN|CA|NA|CS|NS|CP|NP
*       |BYTE-CO|BYTE-CN|BYTE-CA|BYTE-NA|BYTE-CS|BYTE-NS
*       |O|Z|M} operand2 }
*    | {operand  [NOT] BETWEEN operand1 AND operand2}
*    | {     IS [NOT] ASSIGNED}
*    | {ref      IS [NOT] BOUND}
*    | {operand  IS [NOT] INITIAL}
*    | {para     IS [NOT] REQUESTED}
*    | {para     IS [NOT] SUPPLIED}
*    | {[operand [NOT] IN] seltab}
*   }
"2.比较规则
"数字类型比较,自动类型转换
"数字之间比较时,自动数据类型从低到高转换
"decfloat16比较时,转换为decfloat34
*decfloat34>decfloat16>f>p>i>s>b 
"数字与字符串类型比较
"d,t,string,c,n,xstring,x
"数字类型和字符类型比较转换为对应数字类型,
"decfloat16转换为decfloat34,(i,s,b)转换为i类型;
"字符类型和字符类型比较
*string>c>n>d>t
"string和n比较转换为p类型,其余转换为string类型
"c和n比较转换为p类型,自动类型转换;
"d,t自动类型转换,d,t不能互相比较;
"3.逻辑运算符
"语法:NOT log_exp 
"语法:log_exp1 AND log_exp2
"语法:log_exp1 OR log_exp2
"语法:log_exp1 EQUIV log_exp2
"语法:( log_exp )
"between and
  DATA:lv_between_num TYPE I VALUE 12.
  IF lv_between_num BETWEEN 10 AND 20.
    WRITE:/ lv_between_num,'between 10~20'.
  ENDIF.
"assigned,判断是否有分配内存地址
  FIELD-SYMBOLS: TYPE C .
  DATA:lv_assign_c TYPE C VALUE 'A'.
  IF  IS NOT ASSIGNED.
    ASSIGN lv_assign_c TO .
    WRITE:/ .
  ENDIF.
"bound,是否有数据引用
  DATA:lre_bound TYPE REF TO DATA.
  DATA:lt_bound_tab TYPE TABLE OF sflight.
  FIELD-SYMBOLS: TYPE sflight.
  SELECT * INTO TABLE lt_bound_tab FROM sflight.
  READ TABLE lt_bound_tab REFERENCE INTO lre_bound INDEX 1.
  IF lre_bound IS BOUND.
    ASSIGN lre_bound->* TO .
    WRITE:/ -carrid,-connid,-fldate.
  ENDIF.
"initial,判断是否初始值
  "初始化
  REFRESH lt_bound_tab.
  IF lt_bound_tab IS INITIAL.
    WRITE:/ 'it is initial'.
  ENDIF.
"IS REQUESTED已经弃用,使用IS SUPPLIED替代
"IS REQUESTED在procedure中,检查输出param,是否requested
"IS SUPPLIED,在procedure中,检查输出param,是否filled,requested
"当使用以下调用function,IS SUPPLIED返回true
"CALL FUNCTION ... IN UPDATE TASK ...
"CALL FUNCTION ... STARTING NEW TASK ...
"from an external RFC interface
  DATA:lo_supplied TYPE REF TO c_supplied.
  DATA:lv_p1 TYPE I VALUE 10.
  DATA:lv_p2 TYPE I.
  CREATE OBJECT lo_supplied.
  "调用时,p1,p2有指定参数,IS SUPPLIED返回True
  "调用时,p1,p2没有指定参数,返回False
  lo_supplied->m1( EXPORTING p1 = lv_p1 IMPORTING p2 = lv_p2 ).
  WRITE:/ lv_p1,lv_p2.
" IN seltab
  DATA:lr_seltab TYPE RANGE OF C.
  DATA:lrs_seltab LIKE LINE OF lr_seltab.
  DATA:lv_seltab_c TYPE C VALUE 'E'.
  lrs_seltab-low = 'A'.
  lrs_seltab-high = 'Z'.
  lrs_seltab-option = 'BT'.
  lrs_seltab-sign = 'I'.
  APPEND lrs_seltab TO lr_seltab.
  IF lv_seltab_c IN lr_seltab.
    WRITE:/ lv_seltab_c,'in seltab'.
  ENDIF.
"算术表达式
"语法
*[+|-] operand1
*    [{+|-|*|/|DIV|MOD|**} [+|-] operand2
*    [{+|-|*|/|DIV|MOD|**} [+|-] operand3
*]]
"加+,减-,乘*,除/,DIV整除,MOD取余,**乘方

"字符串表达式
"语法
*{ |string_template| }
*  | { operand1 && operand2 [&&  operand3 ... ]
*}
"字符串模板:|[literal_text][embedded_expressions][control_characters]|
"[literal_text]固定字符
"[embedded_expressions]表达式
"[control_characters]控制字符,\n换行,\r返回,\t制表符
*\n:line break, 0A;
*\r:return, 0D;
*\t:tabulator,09;
*[embedded_expressions]表达式:{exp [format_options]}
"[format_options]设置
*[WIDTH     = len]
"显示宽度

*[ALIGN     = LEFT|RIGHT|CENTER|(val)]
"只在width大于最小需求宽度时生效;
"CL_ABAP_FORMAT类可以找到对应值。示例:CL_ABAP_FORMAT=>A_LEFT,left

*[PAD       = c]
"指定填充的字符,当宽度大于最小需求宽度时,其余位置用pad指定字符填充,默认为空

*[CASE = RAW|UPPER|LOWER|(val)]
"指定字符大小写,原样输出

*[SIGN = LEFT|LEFTPLUS|LEFTSPACE|RIGHT|RIGHTPLUS|RIGHTSPACE|(val)]
"指定数字类型,正负号位置
*LEFT:CL_ABAP_FORMAT=>S_LEFT "-" left without space, no "+"
*LEFTPLUS:CL_ABAP_FORMAT=>S_LEFTPLUS "-" and "+" left without space
*LEFTSPACE:CL_ABAP_FORMAT=>S_LEFTSPACE "-"left without space, blank left for "+"
*RIGHT:CL_ABAP_FORMAT=>S_RIGHT "-" right without space, no "+"
*RIGHTPLUS:CL_ABAP_FORMAT=>S_RIGHTPLUS "-"and"+" right without space
*RIGHTSPACE: CL_ABAP_FORMAT=>S_RIGHTSPACE "-"right without space, blank right for "+"

*[EXPONENT  = exp]
"指定浮点数指数,STYLE只能是SCIENTIFIC

*[DECIMALS  = dec]
"小数点后位数

*[ZERO = YES|NO|(val)]
"数字为0,是否显示0

*[STYLE =  SIMPLE|SIGN_AS_POSTFIX|SCALE_PRESERVING
* |SCIENTIFIC|SCIENTIFIC_WITH_LEADING_ZERO
* |SCALE_PRESERVING_SCIENTIFIC|ENGINEERING
* |(val)]
"设置正负号位置,前置0,以及是否科学表示法
"参考Demo:DEMO_STYLE

*[CURRENCY  = cur]
"币别表: TCURC,TCURX:配置小数不为2位的Currency code;
"根据币别设定小数字数,数据类型i, p,f

*[NUMBER    = RAW|USER|ENVIRONMENT|(val)]
"指定小数点,千分负号(decimal and thousand separators)
"RAW:不显示千分符号;USER:千分符号用户设定;ENVIRONMENT:显示千分符号
"参考Demo:DEMO_STRING_TEMPLATE_DATE_FORM
"不同国家,数字格式,日期,时间格式设置表:T005X
"字段:XDEZP
*'' 示例:1.234,56
*X 示例:1,234.56
*Y 示例:1 234,56
"字段:DATFM
*"1" dd.mm.yyyy
*"2" mm/dd/yyyy
*"3" mm-dd-yyyy
*"4" yyyy.mm.dd
*"5" yyyy/mm/dd
*"6" yyyy-mm-dd
*"7" ggyy.mm.dd, Japanese date   "gg天皇年号,yy第几年
*"8" ggyy/mm/dd, Japanese date
*"9" ggyy-mm-dd, Japanese date
"Islamic moon calendar 从16th July 622开始,穆罕默德麦地那时期开始
*"A" yyyy/mm/dd, Islamic date 1
"Islamic moon calendar A,B两种不同格式,Table:TISLCAL,program:I18N_MAINTAIN_TISLCAL维护
*"B" yyyy/mm/dd, Islamic date 2
*"C" yyyy/mm/dd, Iranian date    "Islamic sun calendar
"字段:TIMEFM
*0 24-hour format (default setting) hh:mm:ss
*1 12-hour format hh:mm:ss AM and hh:mm:ss PM
*2 12-hour format hh:mm:ss am and hh:mm:ss pm
*3 12-hour format hh:mm:ss AM and hh:mm:ss PM
*4 12-hour format hh:mm:ss am and hh:mm:ss pm
*"1" and "2", midnight and noon are displayed as 12:00:00.
*"3" and "4", midnight and noon are displayed as 00:00:00.
*处理时间类:CL_ABAP_TIMEFM

*[DATE      = RAW|ISO|USER|ENVIRONMENT|(val)]
"ISO:样式yyyy-mm-dd
*[TIME      = RAW|ISO|USER|ENVIRONMENT|(val)]
"ISO:样式hh:mm:ss
*[TIMESTAMP = SPACE|ISO|USER|ENVIRONMENT|(val)]
"SPACE:样式: "yyyy-mm-dd hh:mm:ss.zzzzzzz".
"ISO:"yyyy-mm-ddThh:mm:ss,zzzzzzz"
*[TIMEZONE  = tz]
"Timezone维护Table:TTZZ,数据类型:TZNZONE
"转换timestamp数据类型:TIMESTAMPL,TIMESTAMP
"默认为"UTC"
"夏季时间区间Table:TTZDV
"转换Timestamp 差异:TTZR
"语法:
*CONVERT TIME STAMP time_stamp TIME ZONE tz
*        INTO [DATE dat]
*             [TIME tim] [DAYLIGHT SAVING TIME dst].
"当前timezone: sy-zonlo
"根据当前时间日期,创建TimeStamp
"语法:
"GET TIME STAMP FIELD time_stamp.

*[COUNTRY   = cty]
"SET COUNTRY cntry
"如果cntry在T005X中能够找到,sy-subrc = 0,使用T005X配置
"如果没有找到,sy-subrc =4,日期默认:"mm/dd/yyyy" ,时间默认:0,

"可以使用&,&&连接两个字符串模板
"&的字符串模板长度不能超过255
"只能在UnionCode系统使用
"在字符模板中输出|,{,},\,需要\转义字符
  DATA:lv_str1 TYPE C LENGTH 10 VALUE 'hello'.
  DATA:lv_str2 TYPE C LENGTH 20 VALUE 'world'.
  DATA:lv_str3 TYPE string.
  DATA:lv_num1 TYPE I VALUE +123.
  DATA:lv_num2 TYPE I VALUE -123.
  DATA:lv_num3 TYPE F VALUE '1.24'.
  DATA:lv_num4 TYPE P VALUE '1.255' DECIMALS 3. "包装类型
  DATA:lv_num5 TYPE I VALUE 0.
  DATA:lv_num6 TYPE F VALUE '-12345.67890'.
  DATA:lv_date1 TYPE D.
  lv_date1 = sy-datum.
  DATA:lv_time1 TYPE T.
  lv_time1 = sy-uzeit.
  DATA:lv_time2 TYPE P LENGTH 8 DECIMALS 0. "只有两种格式P类型可以转换TIMESTAMP
  DATA:lv_time3 TYPE P LENGTH 11 DECIMALS 7. "类型:TIMESTAMPL,TIMESTAMP
  "获取timestamp
  GET TIME STAMP FIELD lv_time2.
  GET TIME STAMP FIELD lv_time3.
  DATA:lv_case_format_val TYPE I VALUE CL_ABAP_FORMAT=>C_UPPER.
  lv_str3 = lv_str1 && lv_str2.
  WRITE:/ lv_str3.
  lv_str3 = |Hello \| World!|.
  WRITE:/ lv_str3.
  lv_str3 = |Hello| & | | & |World| & |!|.
  WRITE:/ lv_str3.
  "使用表达式
  lv_str3 = |{ lv_str1 && lv_str2 }| &&  "exp可以变量,method返回值,计算表达式
  |{ lv_str1 WIDTH = 20 ALIGN = RIGHT PAD = '*' } \n| &&    "格式exp [format]
  |{ lv_str1 CASE = (lv_case_format_val) } \r| &&
  |{ lv_num1 SIGN = RIGHTSPACE } \t| &&
  |{ lv_num2 SIGN = RIGHTSPACE } \t| && "指定数字+,-符号显示
  |{ lv_num3 EXPONENT = 2 } \t| && "指定浮点数的指数,只能是浮点类型,不能和 TIMEZONE一起使用
  |{ lv_num4 DECIMALS = 2 } \t| &&  "指定保留小数位数,四舍五入,原数据类型需指定decimal,不能和 TIMEZONE一起使用
  |{ lv_num5 ZERO = YES } \t| &&  "当数字为0时,yes显示为0,no显示为空字符串,不能和 TIMEZONE一起使用
  |{ lv_num6 STYLE = SIMPLE } \t| &&   "STYLE属性和WRITE TO相同
  |{ lv_num6 STYLE = SIGN_AS_POSTFIX } \t| && "负号在右边
  |{ lv_num6 STYLE = SCIENTIFIC } \t| && "科学计数法
  |{ lv_num6 CURRENCY = 'USD' } \t|.
  WRITE:/ lv_str3.
  lv_str3 = |{ lv_num6 STYLE = SIMPLE NUMBER = USER } \t| && "NUMBER
   |{ lv_num6 STYLE = SIMPLE NUMBER = RAW } \t| &&
   |{ lv_date1 DATE = RAW } \t| && "日期RAW:无格式处理,ISO,使用:分隔yyyy-mm-dd
   |{ lv_date1 DATE = ISO } \t| &&
   |{ lv_time1 TIME = RAW } \t| && "时间RAW:无格式处理,ISO,使用:分隔hh:mm:ss
   |{ lv_time1 TIME = ISO } \t| &&
   |{ lv_time1 TIME = ENVIRONMENT } \t| &&
   |{ lv_time2 TIMESTAMP = SPACE } \t| &&
   |{ lv_time3 TIMESTAMP = ISO } \t|.
  WRITE:/ lv_str3.

  SET COUNTRY ''.
  lv_str3 = |{ lv_date1 } \t| &&
            |{ lv_num6 } \t|.
  WRITE:/ lv_str3.

  "转换Timestamp
  DATA:lv_timestamp TYPE timestamp.
  DATA:lv_timezone TYPE ttzz-tzone VALUE 'AFGHAN'.
  DATA:lv_timestamp_date TYPE D.
  DATA:lv_timestamp_time TYPE T.
  DATA:lv_timestamp_dst TYPE C. "如果是summer time,返回‘X’,否则''
  GET TIME STAMP FIELD lv_timestamp.
  "转换
  CONVERT TIME STAMP lv_timestamp TIME ZONE lv_timezone INTO
    DATE lv_timestamp_date
    TIME lv_timestamp_time
    DAYLIGHT SAVING TIME lv_timestamp_dst.
  WRITE:/ lv_timestamp_date,lv_timestamp_time,lv_timestamp_dst.


"位表达式
"语法
*[BIT-NOT] operand1
*[{BIT-AND|BIT-OR|BIT-XOR} [BIT-NOT] operand2
*[{BIT-AND|BIT-OR|BIT-XOR} [BIT-NOT] operand3
*...  ]]
  DATA:bit_num1 TYPE X VALUE '0F'.
  DATA:bit_num2 TYPE X VALUE 'F0'.
  DATA:bit_num3 TYPE X.
  "与运算
  bit_num3 = bit_num1 BIT-AND bit_num2.
  WRITE:/ bit_num3.
  "或运算
  bit_num3 = bit_num1 BIT-OR bit_num2.
  WRITE:/ bit_num3.
  "异或运算
  bit_num3 = bit_num1 BIT-XOR bit_num2.
  WRITE:/ bit_num3.
  "非运算
  bit_num3 = BIT-NOT bit_num3.
  WRITE:/ bit_num3.

ENDFORM.