ABAP 的关键字 VALUE

举报
雨绸缪 发表于 2023/07/31 17:01:15 2023/07/31
【摘要】 VALUE 语句介绍VALUE 语句是一个构造函数表达式,这意味着将创建新的数据类型。与 CORTUNE 一样,表达式可用于初始化目标变量。值主要用于结构和表,可用于各种位置,例如内联声明、插入或导入参数。比如看一下如下的代码:TYPES: td_field TYPE c LENGTH 20, tt_r_field TYPE RANGE OF td_field, BEGIN OF...

VALUE 语句介绍

VALUE 语句是一个构造函数表达式,这意味着将创建新的数据类型。与 CORTUNE 一样,表达式可用于初始化目标变量。值主要用于结构和表,可用于各种位置,例如内联声明、插入或导入参数。

比如看一下如下的代码:

TYPES:
  td_field   TYPE c LENGTH 20,
  tt_r_field TYPE RANGE OF td_field,

  BEGIN OF ts_structure,
    ident        TYPE i,
    text         TYPE string,
    last_changed TYPE timestamp,
  END OF ts_structure,
  tt_structure TYPE SORTED TABLE OF ts_structure WITH UNIQUE KEY ident,

  tt_unsorted  TYPE STANDARD TABLE OF ts_structure WITH NON-UNIQUE KEY ident.

定义

如果我们在源代码头文件或者其他位置中定义了一个变量,则可以使用 Value 重新初始化该变量并用新信息填充它。在下面的示例中,变量已在标头中定义,现在正在填充。

DATA:
  ls_predefined TYPE ts_structure.

ls_predefined = VALUE #( ident = 1 text = `Test value keyword` ).

可以在 Value 之后使用占位符 #,因为在赋值期间类型是已知的。在这种情况下,数据类型派生自目标变量。当然,也可以使用 value 语句指定数据类型并省略占位符。这允许使用内联声明定义变量:

DATA(ls_inline) = VALUE ts_structure( ident = 2 text = `Test 2` ).

在前面的示例中,我们创建了结构,也可以以相同的方式创建表。为此,我们在 Value 之后指定一个表类型,现在用一对括号分隔每条记录很重要。为简单起见,我们通过相应地设置语句的格式来支持可读性:

DATA(lt_inline) = VALUE tt_structure(
  ( ident = 3 text = `Test 3` )
  ( ident = 4 text = `Test 4` )
  ( ident = 5 text = `Test 5` )
).

默认值

在上一个示例中,我们用行填充了一个表,给出每行中的所有值,从而完全构建了表。但是,例如,范围呢?我们可以用同样的方式填写这些:

DATA(lt_r_full) = VALUE tt_r_field(
  ( sign = 'I' option = 'EQ' low = 'ABC' )
  ( sign = 'I' option = 'EQ' low = 'DEF' )
  ( sign = 'I' option = 'EQ' low = 'GHI' )
).

但值得注意的是,我们有很多重复的条目,我们必须用每一行填充。这样我们就不必在每一行中都填写“SIGN”和“OPTION”,我们还可以在行外定义默认值:

DATA(lt_r_default) = VALUE tt_r_field(
  sign = 'I' option = 'EQ'
    ( low = 'ABC' )
    ( low = 'DEF' )
    ( low = 'GHI' )
).

但是不再有效的是解决已经在括号外定义的元素。因此,我们无法为一行输入任何其他选项。但有效的方法是在外面“交换”默认值:

DATA(lt_r_switch) = VALUE tt_r_field(
  sign = 'I' option = 'EQ'
    ( low = 'ABC' )
    ( low = 'DEF' )
  option = 'BT'
    ( low = 'GHI' high = 'JKL' )
).

如果我们定义一个包含三条记录的库:

DATA(lt_base_table) = VALUE tt_structure(
  ( ident = 3 text = `Test 3` )
  ( ident = 4 text = `Test 4` )
  ( ident = 5 text = `Test 5` )
).

使用 BASE 后缀的使其具有现有数据记录的表的规范:

DATA(lt_base_extended) = VALUE tt_structure( BASE lt_base_table
  ( ident = 1 text = `Test 1` )
  ( ident = 2 text = `Test 2` )
).

ABAP 将基表的行加上新行复制到新创建的表中。这是一个具有排序键的表,这意味着该键被考虑在内并且不会发生错误。以下代码的情况有所不同:

TRY.
    DATA(lt_duplicate) = VALUE tt_structure( BASE lt_base_table
      ( ident = 1 text = `Test 1` )
    ).

  CATCH cx_sy_itab_duplicate_key.
ENDTRY.

我们希望在已经有前 5 条记录的表中插入一条重复的记录。在这种情况下,将引发异常CX_SY_ITAB_DUPLICATE_KEY,应将其捕获。

LINES OF

增加的 BASE 确保以表格为基础,并在末尾附加新的数据记录。如果表是排序表,则根据记录的顺序插入记录。但是我们如何将数据记录放在一个“标准”表中呢?为此,我们创建下表,这次没有主键:

DATA(lt_base_table) = VALUE tt_unsorted(
  ( ident = 3 text = `Test 3` )
  ( ident = 4 text = `Test 4` )
  ( ident = 5 text = `Test 5` )
).

在下一步中,我们要创建一个新表并包含上一步的数据记录,但这次是在非常具体的地方。为此,我们可以直接在新表的一行中使用添加的 LINES OF

DATA(lt_append_tab) = VALUE tt_unsorted(
  ( ident = 9 text = `Test 9` )
  ( ident = 7 text = `Test 7` )
  ( LINES OF lt_base_table )
  ( ident = 6 text = `Test 6` )
).

这些行将插入到其他行之间,并创建新表。

填充

VALUE 语句不仅可以用于创建本地表和结构,还可以与各种表达式组合。例如,您也可以直接将其与 INSERT 一起使用,而无需定义中间变量:

INSERT VALUE #( ident = 10 text = `Test 10` ) INTO TABLE lt_append_tab.

如果调用了某个方法并且相应的变量不可用,也可以使用 VALUE 创建该方法。此方法也适用于有时对正确数据类型做出更细致反应的功能块:

as_parameter(
  is_structure = VALUE #( ident = 10 text = `Test 10` )
).

数据类型

在大多数情况下,这些将是 CHAR 或 STRING 类型的表:

DATA:
  lt_char   TYPE STANDARD TABLE OF char25 WITH EMPTY KEY,
  lt_string TYPE STANDARD TABLE OF string WITH EMPTY KEY.

就可以利用 VALUE 字段这样填充:

lt_char = VALUE #( ( 'ABC' ) ( 'DEF' ) ).

如果我们现在想将整个东西用于 STRING 类型的表,我们会收到相应的编译器错误消息:

abap-deep-dive-value-02.png

填充表格时必须使用正确的语法,只有这样,此方法才能起作用:

lt_string = VALUE #( ( `ABC` ) ( `DEF` ) ).

最终示例:

CLASS zcl_bs_demo_value DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

    TYPES:
      td_field   TYPE c LENGTH 20,
      tt_r_field TYPE RANGE OF td_field,

      BEGIN OF ts_structure,
        ident        TYPE i,
        text         TYPE string,
        last_changed TYPE timestamp,
      END OF ts_structure,
      tt_structure TYPE SORTED TABLE OF ts_structure WITH UNIQUE KEY ident,

      tt_unsorted  TYPE STANDARD TABLE OF ts_structure WITH NON-UNIQUE KEY ident.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      create_variables
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      default_values
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      base_tables
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      append_table
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      correct_types
        IMPORTING
          io_out TYPE REF TO if_oo_adt_classrun_out,

      as_parameter
        IMPORTING
          is_structure TYPE zcl_bs_demo_value=>ts_structure.
ENDCLASS.


CLASS zcl_bs_demo_value IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    create_variables( out ).
    default_values( out ).
    base_tables( out ).
    append_table( out ).
    correct_types( out ).

    as_parameter(
      is_structure = VALUE #( ident = 10 text = `Test 10` )
    ).
  ENDMETHOD.


  METHOD create_variables.
    DATA:
      ls_predefined TYPE ts_structure.

    ls_predefined = VALUE #( ident = 1 text = `Test 1` ).
    io_out->write( `Predefined variable:` ).
    io_out->write( ls_predefined ).

    DATA(ls_inline) = VALUE ts_structure( ident = 2 text = `Test 2` ).
    io_out->write( `Inline declaration (structure):` ).
    io_out->write( ls_inline ).

    DATA(lt_inline) = VALUE tt_structure(
      ( ident = 3 text = `Test 3` )
      ( ident = 4 text = `Test 4` )
      ( ident = 5 text = `Test 5` )
    ).
    io_out->write( `Inline declaration (table):` ).
    io_out->write( lt_inline ).
  ENDMETHOD.


  METHOD default_values.
    DATA(lt_r_full) = VALUE tt_r_field(
      ( sign = 'I' option = 'EQ' low = 'ABC' )
      ( sign = 'I' option = 'EQ' low = 'DEF' )
      ( sign = 'I' option = 'EQ' low = 'GHI' )
    ).
    io_out->write( `Range with full values:` ).
    io_out->write( lt_r_full ).

    DATA(lt_r_default) = VALUE tt_r_field(
      sign = 'I' option = 'EQ'
        ( low = 'ABC' )
        ( low = 'DEF' )
        ( low = 'GHI' )
    ).
    io_out->write( `Range with default values:` ).
    io_out->write( lt_r_default ).

    DATA(lt_r_switch) = VALUE tt_r_field(
      sign = 'I' option = 'EQ'
        ( low = 'ABC' )
        ( low = 'DEF' )
      option = 'BT'
        ( low = 'GHI' high = 'JKL' )
    ).
    io_out->write( `Range with default switch:` ).
    io_out->write( lt_r_switch ).
  ENDMETHOD.


  METHOD base_tables.
    DATA(lt_base_table) = VALUE tt_structure(
      ( ident = 3 text = `Test 3` )
      ( ident = 4 text = `Test 4` )
      ( ident = 5 text = `Test 5` )
    ).

    DATA(lt_base_extended) = VALUE tt_structure( BASE lt_base_table
      ( ident = 1 text = `Test 1` )
      ( ident = 2 text = `Test 2` )
    ).
    io_out->write( `Add with base into sorted:` ).
    io_out->write( lt_base_extended ).

    TRY.
        DATA(lt_duplicate) = VALUE tt_structure( BASE lt_base_table
          ( ident = 1 text = `Test 1` )
        ).

      CATCH cx_sy_itab_duplicate_key.
        io_out->write( `Duplicate key inserted` ).
    ENDTRY.
  ENDMETHOD.


  METHOD append_table.
    DATA(lt_base_table) = VALUE tt_unsorted(
      ( ident = 3 text = `Test 3` )
      ( ident = 4 text = `Test 4` )
      ( ident = 5 text = `Test 5` )
    ).

    DATA(lt_append_tab) = VALUE tt_unsorted(
      ( ident = 9 text = `Test 9` )
      ( ident = 7 text = `Test 7` )
      ( LINES OF lt_base_table )
      ( ident = 6 text = `Test 6` )
    ).
    io_out->write( `Append table into base:` ).
    io_out->write( lt_append_tab ).

    INSERT VALUE #( ident = 10 text = `Test 10` ) INTO TABLE lt_append_tab.
    io_out->write( `After insert into base:` ).
    io_out->write( lt_append_tab ).
  ENDMETHOD.


  METHOD as_parameter.
  ENDMETHOD.


  METHOD correct_types.
    DATA:
      lt_char   TYPE STANDARD TABLE OF char25 WITH EMPTY KEY,
      lt_string TYPE STANDARD TABLE OF string WITH EMPTY KEY.

    lt_char = VALUE #( ( 'ABC' ) ( 'DEF' ) ).
    io_out->write( `Table with CHAR base:` ).
    io_out->write( lt_char ).

    lt_string = VALUE #( ( `ABC` ) ( `DEF` ) ).
    io_out->write( `Table with CHAR base:` ).
    io_out->write( lt_char ).
  ENDMETHOD.
ENDCLASS.
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。