Abap 当结构包含字符串字段时,将结构转换为字符串失败

Abap 当结构包含字符串字段时,将结构转换为字符串失败,abap,Abap,我有一个动态的内部表。我想通过字段符号将内部表的每一行转换为类型字符串: 分配时循环。 分配给演员。 ... “其他逻辑 ... 结束循环。 通常,当结构的所有字段都是字符类型时,CASTING可以正常工作。但是当一个字段是string类型时,它会给出运行时错误。有人能解释一下原因吗?以及如何解决这个问题吗?我刚刚测试了这个问题,当结构没有任何字符串类型的字段时,它也会给出运行时错误d 我将ASSIGN更改为一个简单的MOVE到一个字符串变量g_string,并在运行时失败。如果失败,则意味着

我有一个动态的内部表
。我想通过字段符号
将内部表的每一行转换为类型
字符串

分配时循环。
分配给演员。
...
“其他逻辑
...
结束循环。

通常,当结构的所有字段都是字符类型时,
CASTING
可以正常工作。但是当一个字段是
string
类型时,它会给出运行时错误。有人能解释一下原因吗?以及如何解决这个问题吗?

我刚刚测试了这个问题,当结构没有任何字符串类型的字段时,它也会给出运行时错误d

我将
ASSIGN
更改为一个简单的
MOVE
到一个字符串变量
g_string
,并在运行时失败。如果失败,则意味着无法进行此类分配,因此也不会进行强制转换

REPORT ZZZ.

TYPES BEGIN OF t_test.
  TYPES: f1 TYPE c LENGTH 2,
  f2 TYPE n LENGTH 4,
  f3 TYPE string.
TYPEs END OF t_test.

TYPES BEGIN OF t_test2.
  TYPES: f1 TYPE c LENGTH 2,
  f2 TYPE n LENGTH 4,
  f3 TYPE c LENGTH 80.
TYPES END OF t_test2.

TYPES: tt_test TYPE STANDARD TABLE OF t_test WITH EMPTY KEY,
tt_test2 TYPE STANDARD TABLE OF t_test2 WITH EMPTY KEY.

DATA(gt_test) = VALUE tt_test( ( f1 = '01' f2 = '1234' f3 = `Test`) ).
DATA(gt_test2) = VALUE tt_test2( ( f1 = '01' f2 = '1234' f3 = 'Test') ).
DATA: g_string TYPE string.

FIELD-SYMBOLS: <g_any_table> TYPE ANY TABLE,
  <g_string> TYPE string.

ASSIGN gt_test2 TO <g_any_table>.
ASSERT <g_any_table> IS ASSIGNED.
LOOP AT <g_any_table> ASSIGNING FIELD-SYMBOL(<g_any_wa2>).
*  ASSIGN <g_any_wa2> TO <g_string> CASTING.
  g_string = <g_any_wa2>.
ENDLOOP.
UNASSIGN <g_any_table>.

ASSIGN gt_test TO <g_any_table>.
ASSERT <g_any_table> IS ASSIGNED.
LOOP AT <g_any_table> ASSIGNING FIELD-SYMBOL(<g_any_wa>).
*  ASSIGN <g_any_wa> TO <g_string> CASTING.
  g_string = <g_any_wa>.
ENDLOOP.
报告ZZZ。
类型开始t_测试。
类型:f1类型c长度2,
f2类型n长度4,
f3类型字符串。
类型t_测试结束。
类型开始于t_test2。
类型:f1类型c长度2,
f2类型n长度4,
f3 c型长度为80。
类型结束t_test2。
类型:tt_测试类型带空键的t_测试标准表,
tt_test2类型带有空键的t_test2的标准表。
数据(gt_测试)=值tt_测试(f1='01'f2='1234'f3='test`)。
数据(gt_test2)=值tt_test2((f1='01'f2='1234'f3='Test'))。
数据:g_字符串类型字符串。
字段符号:键入任何表格,
键入字符串。
将gt_测试2分配给。
断言被赋值。
在指定字段-SYMBOL()时循环。
*分配给演员。
g_字符串=。
结束循环。
取消分配。
将gt_测试分配给。
断言被赋值。
在指定字段-SYMBOL()时循环。
*分配给演员。
g_字符串=。
结束循环。

听起来像是要将完整的结构化行分配给普通字符串字段符号。这不起作用。只能将结构化行的各个类型兼容组件分配给字符串字段符号

否则,这种赋值可以正常工作。对于具有字符串类型的单列的表:

TYPES table_type TYPE STANDARD TABLE OF string WITH EMPTY KEY.
DATA(filled_table) = VALUE table_type( ( `Test` ) ).
ASSIGN filled_table TO FIELD-SYMBOL(<dynamic_table>).
FIELD-SYMBOLS <string> TYPE string.

LOOP AT <dynamic_table> ASSIGNING FIELD-SYMBOL(<row>).
  ASSIGN <row> TO FIELD-SYMBOL(<string>).
ENDLOOP.
类型表\u类型空键字符串的标准表。
数据(填充的表格)=值表格类型(`Test`)。
将填充的表格分配给字段-SYMBOL()。
字段符号类型字符串。
在指定字段-SYMBOL()时循环。
分配给字段-SYMBOL()。
结束循环。
对于具有结构化行类型的表:

TYPES:
  BEGIN OF row_type,
    some_character_field TYPE char80,
    the_string_field     TYPE string,
  END OF row_type.
TYPES table_type TYPE STANDARD TABLE OF row_type WITH EMPTY KEY.
DATA(filled_table) = VALUE table_type( ( some_character_field = 'ABC'
                                         the_string_field     = `Test` ) ).
ASSIGN filled_table TO FIELD-SYMBOL(<dynamic_table>).
FIELD-SYMBOLS <string> TYPE string.

LOOP AT <dynamic_table> ASSIGNING FIELD-SYMBOL(<row>).
  ASSIGN <row>-the_string_field TO <string>.
ENDLOOP.
类型:
行类型的开始,
某些字符字段类型char80,
_字符串\u字段类型字符串,
行的结尾\u类型。
类型表类型行类型的标准表,键为空。
数据(填充表格)=值表格类型((某些字符字段='ABC'
_字符串_字段=`Test`)。
将填充的表格分配给字段-SYMBOL()。
字段符号类型字符串。
在指定字段-SYMBOL()时循环。
将\u字符串\u字段指定给。
结束循环。
为什么只有类似字符和
字符串的结构不能作为文本变量“强制转换”
ABAP文件中给出了原因:

“包含字符串的结构是结构,不能像结构那样用作类似字符的字段。”

“Deep:[…]内容[…]是使用引用([…],字符串…)在内部寻址的。”

引用的内存要求为8字节。[…]在字符串中,[…]在内部创建一个隐式引用

"如果通过强制转换确定的数据类型为deep,或者如果deep数据对象存储在分配的内存区域中,则deep组件必须在分配的内存区域中以完全相同的类型和位置出现。特别是,这意味着单个引用变量只能分配给一个作为引用变量类型的字段符号可由相同的静态类型创建。”

现在,编译器和运行时不允许您这样做的原因是,如果您强制转换整个深层结构,您可以更改8字节的引用以访问内存中的任何位置,这可能是危险的()在所有编程语言中,编译器尽可能防止越界访问或在运行时进行检查()

变通办法 您的问题发生在运行时,因为您使用动态创建的数据对象,但在编译时使用静态定义的数据对象时,您会遇到完全相同的问题

您可以访问结构的每个字段并将其连接到字符串:

DATA: BEGIN OF dyn_wa,
         country TYPE c LENGTH 3,
         city    TYPE string,
       END OF dyn_wa,
       lf_string TYPE string.
FIELD-SYMBOLS: <lf_field> TYPE clike.

dyn_wa = VALUE #( country = 'FR' city = 'Paris' ).

DO.
  ASSIGN COMPONENT sy-index OF STRUCTURE dyn_wa TO <lf_field>.
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.
  CONCATENATE lf_string <lf_field> INTO lf_string RESPECTING BLANKS.
ENDDO.

ASSERT lf_string = 'FR Paris'. " one space because country is 3 characters
DATA:dyn_wa的开始,
国家类型c长度3,
城市类型字符串,
迪努瓦的尽头,
lf_字符串类型字符串。
字段符号:键入clike。
dyn_wa=VALUE(国家='FR'城市='Paris')。
做
将结构dyn_wa的组件sy索引指定给。
如果sy subrc为0。
出口
恩迪夫。
将lf_字符串连接到lf_字符串中的空格。
恩多。
断言lf_字符串='FR Paris'。“一个空格,因为国家是3个字符。”

尊重空格
保留尾随空格,以模仿
赋值…强制转换

这是因为任何类型在强制转换时都需要类型声明。例如,它将强制转换类型c。您如何处理这串串联字段值?也许有更好的解决方案可以在不工作的情况下实现您的目标有了这样一个字符串…你对试图帮助你的人说“无论如何,我已经找到了解决方案”。因此,请友善地发布解决方案(:“Stack Exchange是一个问答网站网络,而不是帮助论坛。这意味着,除了帮助提问者之外,所有帖子都对以后的访问者有价值。”)@SandraRossi futu的解决方案被我标记为已接受。我在评论中写道,我已经找到了相同的解决方案。同样,发布相同的解决方案并不能解决问题
DATA: BEGIN OF dyn_wa,
         country TYPE c LENGTH 3,
         city    TYPE string,
       END OF dyn_wa,
       lf_string TYPE string.
FIELD-SYMBOLS: <lf_field> TYPE clike.

dyn_wa = VALUE #( country = 'FR' city = 'Paris' ).

DO.
  ASSIGN COMPONENT sy-index OF STRUCTURE dyn_wa TO <lf_field>.
  IF sy-subrc <> 0.
    EXIT.
  ENDIF.
  CONCATENATE lf_string <lf_field> INTO lf_string RESPECTING BLANKS.
ENDDO.

ASSERT lf_string = 'FR Paris'. " one space because country is 3 characters