Field-Symbols之间的无损分配

时间:2016-08-03 07:39:29

标签: abap

我目前正在尝试在ABAP 7.0v SP26环境中执行动态无损分配。

背景:

我想在csv文件中读取并将其移动到内部结构中而不会丢失任何数据。因此,我宣布了字段符号:

  • <lfs_field> TYPE any代表结构组件
  • <lfs_element> TYPE string,其中包含csv值

方法

我目前的解决方案&#34;是这个(lo_field<lfs_field>)的元素描述:

IF STRLEN( <lfs_element> ) > lo_field->output_length.
    RAISE EXCEPTION TYPE cx_sy_conversion_data_loss.
ENDIF.

我不知道它的精确程度,但似乎抓住了最明显的案例。

尝试:

MOVE EXACT <lfs_field> TO <lfs_element>.

...给我......

  

无法解释&#34; EXACT&#34;。可能的原因:拼写错误或逗号错误

...而...

COMPUTE EXACT <lfs_field> = <lfs_element>.

......导致......

  

不正确的陈述:&#34; =&#34;失踪 。

由于ABAP版本太旧,我也无法使用EXACT #( ... )

示例:

在这种情况下,我使用普通变量。让我们假装他们是字段符号:

DATA: lw_element TYPE string VALUE '10121212212.1256',
      lw_field   TYPE p DECIMALS 2.
lw_field = lw_element.

* lw_field now contains 10121212212.13 without any notice about the precision loss

那么,我如何使用字段符号进行完美有效的无损分配?

1 个答案:

答案 0 :(得分:0)

不要轻易解决这个问题。猜猜他们首先引入MOVE EXACT的原因。

  

请注意,output_length不是一个干净的解决方案。例如,string总是有output_length 0,但当然能够保存带有output_length 3的CHAR3。

如何解决问题的三个想法:

  1. 解析和比较类型。解析源字段以检测格式和长度,例如, &#34;字符般的&#34;,&#34; 60个地方&#34;。然后获取目标字段的元素描述符,并检查源是否适合目标。不要认为在这里开始收集可能很大的CASE是有意义的。如果您可以访问较新的ABAP,则可以尝试在其中生成大型测试数据集,并使用它来对MOVE EXACT中的兼容性规则进行反向工程。

  2. 来回转换。将值从源移动到目标并返回,然后查看它是否更改。如果它发生变化,则字段不兼容。这是不确定的,因为一些格式会改变,尽管价值保持不变;例如,-42可以更改为42-,但在ABAP中也是如此。

  3. 转换时间更长。将字段从源移动到目标。然后构建一个稍长的目标版本,并在那里移动源代码。如果两个目标相同,则字段是兼容的。这在边界处失败,即,如果不可能构建稍长的版本,例如,因为达到了P字段的最大小数位数。

    DATA target TYPE char3.
    DATA source TYPE string VALUE `123.5`.
    DATA(lo_target) = CAST cl_abap_elemdescr( cl_abap_elemdescr=>describe_by_data( target ) ).
    DATA(lo_longer) = cl_abap_elemdescr=>get_by_kind(
                          p_type_kind = lo_target->type_kind
                          p_length    = lo_target->length + 1
                          p_decimals  = lo_target->decimals + 1 ).
    DATA lv_longer TYPE REF TO data.
    CREATE DATA lv_longer TYPE HANDLE lo_longer.
    ASSIGN lv_longer->* TO FIELD-SYMBOL(<longer>).
    <longer> = source.
    target = source.
    IF <longer> = target.
      WRITE `Fits`.
    ELSE.
      WRITE `Doesn't fit, ` && target && ` is different from ` && <longer>.
    ENDIF.