我有一个动态内部表<ft_dyn_tab>
。我想通过字段符号string
将内部表的每一行转换为类型<lf_string>
:
LOOP AT <ft_dyn_tab> ASSIGNING <fs_dyn_wa>.
ASSIGN <fs_dyn_wa> to <lf_string> CASTING.
...
"other logic
...
ENDLOOP.
通常,当结构的所有字段均为字符类型时,CASTING
可以正常工作。但是,当一个字段的类型为string
时,它将给出运行时错误。谁能解释为什么?以及如何解决这个问题?
答案 0 :(得分:3)
String
组件的结构作为文本变量“投射” 原因由Strings的ABAP文档给出:
“包含字符串的结构是 deep 结构,不能像 flat 结构一样用作字符型字段。” / p>
和Deep中的
:“深度:[...]内容[...]是使用引用([...],字符串...在内部寻址的。”
和Memory Requirement for Deep Data Objects中的
::“该引用的内存要求为8字节。[...]在字符串中,在内部创建一个隐式引用。”
“如果通过CASTING确定的数据类型是深层的,或者如果深层数据对象存储在分配的存储区中,则深层组件必须在分配的存储区中以完全相同的类型和位置出现。特别是,这意味着单个参考变量只能分配给一个字段符号,而该字段符号由相同的静态类型输入为参考变量。”
现在,编译器和运行时不允许您这样做的原因是,如果强制转换整个深度结构,则可以更改8字节引用以访问内存中的任何位置,这样可以危险(How dangerous is it to access an array out of bounds?),并且很难分析随后的错误。在所有编程语言中,编译器都尽可能防止越界访问或在运行时进行检查(Bounds checking)。
您的问题在运行时发生,因为您使用的是动态创建的数据对象,但是在编译时使用静态定义的数据对象会遇到完全相同的问题。以下是具有静态定义结构的简单解决方案。
您可以访问结构的每个字段并将其连接为字符串:
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
RESPECTING BLANKS
保留尾随空格,以模仿ASSIGN ... CASTING
。
答案 1 :(得分:1)
想要将完整的结构化行分配给纯字符串字段符号的声音。这行不通。您只能将结构化行的各个类型兼容的组件分配给字符串字段符号。
否则,这种分配工作正常。对于单列类型为字符串的表:
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.
对于具有结构化行类型的表:
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.
答案 2 :(得分:0)
我刚刚对此进行了测试,当结构没有任何字符串类型的字段时,它也会给出运行时错误。
我将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.