Reuse RP_PROVIDE_FROM_LAST macro for several info-types?

1.6k views Asked by At

We use HR macro to get first or last record from table. One of these are rp_provide_from_last. I need to get two subtypes (0010, 0004) from P0105 table:

Below is my code. The problem is that after the second macro, there are only records of 0004. How can I hold on them together?

GET pernr.
rp_provide_from_last p0105 '0010' pn-begda pn-endda.
CHECK pnp-sw-found eq '1'.
rp_provide_from_last p0105 '0004' pn-begda pn-endda.
CHECK pnp-sw-found eq '1'.

here is definition.

DEFINE rp_provide_from_last.

$PNNNN$ = &1. 
$SUBTY$ = &2.    
$BEGDA$ = &3.    
$ENDDA$ = &4.

pnp-sw-found = '0'.

clear pnp-sy-tabix.

loop at &1.  

 if &2 <> space.    
  check &1-subty = &2.    
 endif.    

 if &1-begda <= &4 and &1-endda >= &4.    
  pnp-sw-found = '1'.    
  exit.    
 endif.  

 if &1-begda <= &4 and &1-endda >= &3.    
  pnp-sy-tabix = sy-tabix.    
 endif.  

endloop. 

if pnp-sw-found = '0'.  

 if pnp-sy-tabix <> 0.    

  pnp-sw-found = '1'.   
  read table &1 index pnp-sy-tabix.    

 else.    
 clear &1.  

 endif.    
endif.

END-OF-DEFINITION.
2

There are 2 answers

0
Philipp On BEST ANSWER

What the code from this macro does is take the table with header line you passed to it (p0105 in your case), search through it, and when it finds an entry, it:

  1. put the result into the header-line of that table
  2. sets the global variable pnp-sw-found to 1
  3. sets the global variable pnp-sy-tabix to the line-number where the entry was found

When you then call the macro again, all those results get overwritten. If you want to keep them, then you need to store them in new variables.

DATA: ls_line_0010 TYPE p0105,
      ls_line_0004 TYPE p0105.

GET pernr.

rp_provide_from_last p0105 '0010' pn-begda pn-endda.
CHECK pnp-sw-found eq '1'.
ls_line_0010 = p0105.

rp_provide_from_last p0105 '0004' pn-begda pn-endda.
CHECK pnp-sw-found eq '1'.
ls_line_0004 = p0105.

You now have two structure-variables ls_line_0010 and ls_line_0004 which each contain the data of a different line of the table.

By the way: Macros are icky. I would really refactor the code from that macro into a FORM or a METHOD and do it in a way that it only communicates through parameters, not by setting globals. It will make your life and the life of everyone who will have to maintain that code later a lot easier. Another problem is the reliance of that code on tables with header line. Those are obsolete for over 20 years, and for good reason. When you have to work with tables with header-line, then it is usually best to ignore those header-lines and use them with work-areas instead.

0
Maxx C On

First off, the HR logical data based (LDB) PNPCE (do not use LDB PNP as it is considered deprecated) is in IMO the BEST and FASTEST way to read HR data from multiple HR infotypes in an object-oriented way, even though the code looks "old" and the tooling is not object-oriented.

As a nice bonus you get automatic authorizations built into your code as well as consistent selection screens. All this via setting the LDB in the report properties and one GET PERAS statement. Thereafter, you can use the RP__... macros to read individual entries as you like via internal tables or not. Macros are nothing more than code, just like methods are nothing more than code. The annoying thing to me about these macros is the usage of the same name for work areas (a.k.a. variables, header lines) as well as the internal tables (a.k.a. arrays).

To your particular point about reading two different subtypes from the same infotype just look at the abap infotypes documentation and read about the NAME addition. "https://help.sap.com/doc/abapdocu_752_index_htm/7.52/en-us/abapinfotypes.htm#!ABAP_ADDITION_1@1@"

Example:

INFOTYPES 0105 NAME p0105_email
INFOTYPES 0105 NAME p0105_tso1.

rp_provide_from_last p0105_email '0010' pn-begda pn-endda.

rp_provide_from_last p0105_tso1 '0004' pn-begda pn-endda.

"then just read the internal table normally

LOOP AT p0105_email[] ASSIGNING data(lv_email).