1

在 sap 我有一个表,有同名但数量不同的行。我想像这样总结这些行:

    SELECT c~aufnr
           p~matnr p~bdter p~meins p~baugr p~dbskz p~erfmg p~aufnr
           f~maktx
       INTO CORRESPONDING FIELDS OF TABLE it_tab
       FROM  afpo AS c
         INNER JOIN resb AS p ON c~aufnr = p~aufnr
         INNER JOIN makt AS f ON p~matnr = f~matnr.             

    LOOP AT it_tab INTO fs_tab.
       COLLECT fs_tab INTO it_tab_collected.
    ENDLOOP.
    it_tab = it_tab_collected.

但在这种情况下,它只对完全相同的行求和。我只需要总结具有相同名称的行。

我怎样才能做到这一点?

问候,亚历山大。

4

3 回答 3

4

正如 icbytes 已经说过COLLECT的,使用关键字段来确定要聚合的字段。我建议定义一些数据类型以匹配您的场景:

TYPES: BEGIN OF t_my_type,
         key_a TYPE foo,
         key_b TYPE foo,
         nokey_c TYPE foo,
         nokey_d TYPE foo,
       END OF t_my_type,
       tt_my_type_list TYPE STANDARD TABLE OF t_my_type WITH DEFAULT KEY,
       tt_my_type_hash TYPE HASHED TABLE OF t_my_type WITH KEY key_a key_b.

DATA: lt_result TYPE tt_my_type_list,
      lt_sums   TYPE tt_my_type_hash.

FIELD-SYMBOLS: <ls_result> TYPE t_my_type.

LOOP AT lt_result ASSIGNING <ls_result>.
  COLLECT <ls_result> INTO lt_sums.
ENDLOOP.

...或者您可能想首先使用聚合函数...

于 2014-05-14T11:44:26.723 回答
2

我会坚持远离COLLECT即使你可以节省几行代码,也不需要使用它,并且无缘无故地添加限制

我在维护/向以前编写的代码中添加功能时遇到了问题,COLLECT因为它不允许将非键非数字字段添加到内部表中,有时我不得不修改很多COLLECT句子或给代码引入不必要的复杂性(比如使用额外的内部表)。

示例(以 vwegert 的示例为基础,谁很好地解释了如何COLLECT正确使用):

TYPES: BEGIN OF t_my_type,
         key_a TYPE foo,
         key_b TYPE foo,
         """ with COLLECT all 'foo' types **has to be** numeric
         nokey_c TYPE foo,
         nokey_d TYPE foo,
         """ if you ever need to add something like a note field to the table
         """ you'll find out that you have to change all the COLLECT sentences
         """ because this new field wouldn't let the code compile
         nokey_notes(50) type c,
       END OF t_my_type,

       tt_my_type_list TYPE STANDARD TABLE OF t_my_type WITH DEFAULT KEY,
       tt_my_type_hash TYPE HASHED TABLE OF t_my_type WITH KEY key_a key_b.

DATA: lt_result TYPE tt_my_type_list,
      lt_sums   TYPE tt_my_type_hash.

FIELD-SYMBOLS: <ls_result> TYPE t_my_type.


""" just imagine you need the 'nokey_notes' field for an ALV for user input.
PERFORM show_alv USING lt_result.


""" and you don't care about this new field when doing
""" the sum/average or whatever you are trying to calculate
""" well, it won't work with COLLECT...
LOOP AT lt_result ASSIGNING <ls_result>.
  COLLECT <ls_result> INTO lt_sums.
ENDLOOP.

我的建议是使用AT... ENDAT(除了SELECT的聚合函数,这是一个不错的选择,特别是如果您不需要单独的数据)。

当然,代码会增加一些额外的行,但在我看来/经验它们是值得的,因为将来代码会更容易维护。

TYPES: BEGIN OF t_my_type,
         key_a TYPE foo,
         key_b TYPE foo,
         """ with COLLECT all 'foo' types **has to be** numeric
         nokey_c TYPE foo,
         nokey_d TYPE foo,
         """ without COLLECT you are able to add new non-key non-numeric fields
         nokey_notes(50) type c,
       END OF t_my_type,

       tt_my_type_list TYPE STANDARD TABLE OF t_my_type.

DATA: lt_result TYPE tt_my_type_list,
      lt_sum    TYPE tt_my_type_list.
      lwa_sum   TYPE t_my_type.

FIELD-SYMBOLS: <ls_result> TYPE t_my_type.


""" just imagine you need the 'nokey_notes' field for an ALV for user input.
PERFORM show_alv USING lt_result.


""" sorting is important when using AT... ENDAT, there are other gotchas too
""" make sure you read its documentation carefully if you never used it
""" (like everything right? :P)
SORT lt_result BY key_a key_b.
REFRESH lt_sum.

""" and you don't care about 'nokey_notes' field when doing calculation
LOOP AT lt_result ASSIGNING <ls_result>.

  AT NEW key_b.
    """ this get executed when the work area's primary keys
    """ change, good time to prepare the lwa_sum work area.
    CLEAR lwa_sum.
    lwa_sum-key_a = lwa_sum-key_a.
    lwa_sum-key_b = lwa_sum-key_b.
  ENDAT.

  """ do whatever math/logic is need with the fields
  lwa_sum-nokey_c = lwa_sum-nokey_c + <ls_result>-nokey_c.
  lwa_sum-nokey_d = lwa_sum-nokey_d + <ls_result>-nokey_d.

  AT END OF key_b.
    """ this get executed when the work area's primary keys
    """ is about to change (in next iteration) or at the last
    """ record of the table
    """ good place to save the results to a new internal table
    APPEND lwa_sum to lt_sums.
  ENDAT.

ENDLOOP.
于 2014-05-20T20:56:00.713 回答
0

AFAIK collect 使用键,因为它可以决定哪些行应该创建一个聚合。如果您在数值前面有其他字符值,请在另一个 itab 中删除它们,以便唯一填充的类似 c 的列将是“名称”。这将作为让abap处理器聚合的唯一关键。

那有帮助吗?

于 2014-05-14T11:18:09.580 回答