Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Field - Symbol - Abap HR

Former Member
0 Kudos

Hi expert , i need your clue.

to be honest, there is a field in my report that should be has the value related date-work.

just called this field with = field A.

field A value is taken from table pa0041.

at transparant table pa0041, there are 8 field from dar01 to dar08.

                                                also 8 field from dat01 to dat08.

dar01 related to dat01, also dar02 related to dat02,

in my case, i have to find the value 'Z1' from dar01 up to dar08.

just mention if the value of 'Z1' at field dar03. So i will take the value

of dat03 (related to dar03) into field A.

first, i use command "case and end case" for this matter.

but it is not recommended because too many case i have to mention,

Anybody know to solve this problem with Field Symbol ?

@admin : thanks for approve my question

1 ACCEPTED SOLUTION

freek_cavens2
Participant
0 Kudos

Hi Barnabas,

This does exactly what you are trying to do : the PO release strategy has 8 fields.  I want to know the first field that is filled (I have changed the code slightly so it fits your needs).  This is how it works.

  DATA :

    ls_t16fs TYPE t16fs,

    l_fname TYPE rollname,

    l_counter TYPE i VALUE 1.

  FIELD-SYMBOLS :

    <l_frgco> TYPE frgco.

**Get release strategy

  SELECT SINGLE * FROM t16fs

         INTO ls_t16fs

         WHERE frggr EQ i_header-frggr

           AND frgsx EQ i_header-frgsx.

**Get relevant release codes

  WHILE l_counter LE 8.

    l_fname = 'FRGC' && l_counter.

    ASSIGN COMPONENT l_fname OF STRUCTURE ls_t16fs TO <l_frgco>.

    IF <l_frgco> IS ASSIGNED.

      EXIT.

    ENDIF.

**..Increase counter for next release code

    ADD 1 TO l_counter.

  ENDWHILE.

Regards,

Freek

13 REPLIES 13

Sougata
Active Contributor
0 Kudos

You could try something like this...it doesn't need to use Field-Symbols.

LOOP AT P0041 INTO w_p0041.

   DO VARYING  w_darxx FROM w_p0041-dar01 NEXT w_p0041-dar02

         VARYING  w_datxx FROM w_p0041-dat01 NEXT w_p0041-dat02.

    IF w_darxx IS INITIAL.         "EXIT AFTER LAST DATE TYPE

      EXIT.

    ENDIF.

       IF w_darxx = `Z1`.         

        "your business logic here....

          EXIT.

       ENDIF.

  ENDDO.

    "further logic here...

ENDLOOP.

Hope this helps.

Sougata.

former_member184569
Active Contributor
0 Kudos

Hi Barnabas,

I have written a program that will fill a table with pernr, date type and date taking values from pa0041.  You can modify the program to suit your need.

REPORT  ZTEST_HR.
tables pa0041.

types : begin of it_type,
         pernr type pernr,
         dar like pa0041-dar01,
         dat like pa0041-dat01,
        end of it_type.

data : i_pa0041 type TABLE OF pa0041,
        wa_pa0041 like LINE OF i_pa0041,
        it_tab type TABLE OF it_type,
        wa_tab like line of it_tab.

DATA:       tb_struct TYPE REF TO cl_abap_structdescr,
                tb_comp   TYPE        abap_component_tab.

data : wa_field1(20), wa_field2(20).
 
FIELD-SYMBOLS : <fs>,<fs1> ,<fs2>,<fs_components>.

select-OPTIONS : s_pernr for pa0041-pernr.

  START-OF-SELECTION.

* Get the structure of pa0041
   tb_struct ?=
   cl_abap_typedescr=>describe_by_data( wa_pa0041 ).


select * from pa0041 into table i_pa0041 where pernr in s_pernr.

   loop at i_pa0041 into wa_pa0041.

* Loop through each field in pa0041.
        LOOP AT tb_struct->components ASSIGNING <fs_components>.
           assign component 'NAME' of STRUCTURE <fs_components> to <fs>.
           wa_field1 = <fs>.

* When the field is a 'DAR' field, take the corresponding 'DAT' field and append to the table for that pernr.
           if wa_field1 CS 'DAR'.
             ASSIGN COMPONENT wa_field1 of STRUCTURE wa_pa0041 to <fs1>.
              if not <fs1> is initial.
                concatenate 'DAT' wa_field1+3(2) into wa_field2.
                condense wa_field2.
               ASSIGN COMPONENT wa_field2 of STRUCTURE wa_pa0041 to <fs2>.
               wa_tab-pernr = wa_pa0041-pernr.
               wa_tab-dar = <fs1>.
               wa_tab-dat = <fs2>.
               append wa_tab to it_tab.
              clear wa_tab.
           endif.
           endif.
        UNASSIGN : <fs1> , <fs2>, <fs>.
        ENDLOOP.
     ENDLOOP.

In the example you have given, the condition would be as follows.


       if <fs1> = 'Z1'.
                concatenate 'DAT' wa_field1+3(2) into wa_field2.
                condense wa_field2.
               ASSIGN COMPONENT wa_field2 of STRUCTURE wa_pa0041 to <fs2>.
               wa_tab-pernr = wa_pa0041-pernr.
               wa_tab-dar = <fs1>.
               wa_tab-dat = <fs2>.
               append wa_tab to it_tab.
              clear wa_tab.
           endif.
           endif.

0 Kudos

Getting the index of component as suggested below would be a better alternative.

You would get the required output with a slight modification to the calculations.

FIELD-SYMBOLS : <fs>,<fs1> ,<fs2>,<fs_components>.
*
select-OPTIONS : s_pernr for pa0041-pernr.

START-OF-SELECTION.

ASSIGN  wa_pa0041 to <fs_components>.
select * from pa0041 into table i_pa0041 where pernr in s_pernr.
loop at i_pa0041 into wa_pa0041.
   dar_ind = 24.
   do 8 times.
         assign component dar_ind of structure <fs_components> to <fs1>.
         if  <fs1> is ASSIGNED .
           if <fs1> = 'Z1'.
           dat_ind = dar_ind + 1.
           assign component dat_ind of structure <fs_components> to <fs2>.
           if <fs2> is ASSIGNED.
             wa_tab-pernr = wa_pa0041-pernr.
             wa_tab-dar = <fs1>.
             wa_tab-dat = <fs2>.
             append wa_tab to it_tab.
             clear wa_tab.
           endif.
           endif.
         endif.
         UNASSIGN : <fs1> , <fs2>.
         dar_ind = dar_ind + 2.
     enddo.
    endloop.

0 Kudos

Dear all,

thanks for the answer. I found it.

Nice sharing

Former Member
0 Kudos

Hi Barnabas,


After getting the PA0041 table details into a internal table ( lt_tab 😞


1.   LOOP AT it_tab ASSIGNING <fs_tab>. ( This will assign 1st record to <fs_tab> in 1st iteration )

2.   Inside the loop assign the components ( dar01 ... dar08 ) to <fs_any1>, using do condition like:

      Assumption1: dar01  is the 5th component and dar08 is 12th component in lt_tab structure
      Assumption2: dat01  is the 15th component and dat08 is 22th component in lt_tab structure 
       { The below code must run for every record of your lt_tab }
  
      lv_var_dar = 5.
      lv_var_dat = 0.

      DO 8 TIMES.

      ASSIGN COMPONENT lv_var_dar OF STRUCTURE <fs_tab> TO <fs_any1>. ( Reading the value from 5th to 12th component )

      IF  <fs_any1>  EQ  'Z1'.
           
          lv_var_dat = lv_var_dar + 10.

      ASSIGN COMPONENT lv_var_dat OF STRUCTURE <fs_tab> TO <fs_any2>. ( <fs_any2 is your required value )
      EXIT.
      ENDIF.
      ENDDO. 

I hope it fits your requirement.

0 Kudos

Adding the, missing increment in my previous post before ENDDO.

After getting the PA0041 table details into a internal table ( lt_tab 😞


1.   LOOP AT it_tab ASSIGNING <fs_tab>. ( This will assign 1st record to <fs_tab> in 1st iteration )

2.   Inside the loop assign the components ( dar01 ... dar08 ) to <fs_any1>, using do condition like:

      Assumption1: dar01  is the 5th component and dar08 is 12th component in lt_tab structure
      Assumption2: dat01  is the 15th component and dat08 is 22th component in lt_tab structure 
       { The below code must run for every record of your lt_tab }
  
      lv_var_dar = 5.
      lv_var_dat = 0.

      DO 8 TIMES.

      ASSIGN COMPONENT lv_var_dar OF STRUCTURE <fs_tab> TO <fs_any1>. ( Reading the value from 5th to 12th component )

      IF  <fs_any1>  EQ  'Z1'.
           
          lv_var_dat = lv_var_dar + 10.

      ASSIGN COMPONENT lv_var_dat OF STRUCTURE <fs_tab> TO <fs_any2>. ( <fs_any2 is your required value )
      EXIT.
      ENDIF.

      lv_var_dar = lv_var_dar + 1.
      ENDDO. 

I hope it fits your requirement.

freek_cavens2
Participant
0 Kudos

Hi Barnabas,

This does exactly what you are trying to do : the PO release strategy has 8 fields.  I want to know the first field that is filled (I have changed the code slightly so it fits your needs).  This is how it works.

  DATA :

    ls_t16fs TYPE t16fs,

    l_fname TYPE rollname,

    l_counter TYPE i VALUE 1.

  FIELD-SYMBOLS :

    <l_frgco> TYPE frgco.

**Get release strategy

  SELECT SINGLE * FROM t16fs

         INTO ls_t16fs

         WHERE frggr EQ i_header-frggr

           AND frgsx EQ i_header-frgsx.

**Get relevant release codes

  WHILE l_counter LE 8.

    l_fname = 'FRGC' && l_counter.

    ASSIGN COMPONENT l_fname OF STRUCTURE ls_t16fs TO <l_frgco>.

    IF <l_frgco> IS ASSIGNED.

      EXIT.

    ENDIF.

**..Increase counter for next release code

    ADD 1 TO l_counter.

  ENDWHILE.

Regards,

Freek

0 Kudos

Hi Freek,

I have a question, If in case "<l_frgco>" is not assigned i think  " IF <l_frgco> IS ASSIGNED." statement will throw an runtime error.  Can you please correct me if i am wrong?

0 Kudos

The IF condition would fail in that case. It won't result in runtime error.

FIELD-SYMBOLS <fs> TYPE any.
IF <fs> IS ASSIGNED.
   BREAK-POINT.
ELSE.
   BREAK-POINT.
ENDIF.

0 Kudos

It's as Manish says.  The 'IS ASSIGNED' statement is designed to check if a field symbol is assigned.  It will not generate a dump.  When working with field symbols, it is very important to always check the sy-subrc of the ASSIGN (0 = succes, 4 = fail) or check the assignment itself by 'IS ASSIGNED'.

A nice little trick in this is : you can check the assignment and the value of the field symbol in one statement, e.g. :

if <FS> is assigned and <FS> is not initial.

endif.

The first condition will be checked first and only if this is validated, the second condition will also be checked.  You cannot reverse this statement (if <FS> is not initial and <FS> is assigned ), since this would lead to a dump if the field symbol is not assigned.

Regards,

Freek

0 Kudos

Thank you Manish and Freek.  

Former Member
0 Kudos

HI Maheenath,

Easiest way to read infotype pa0041 for a given date type is using FM HR_ECM_READ_IT0041_DATE_TYPE.

Pass Date type 'Z1' and P0041, then you get the output.

Thanks

Krishna

0 Kudos

Hi Barnabas,

This exactly what you are trying to do

*--Decleare internal table

TYPES : BEGIN OF ty_pa0041,

           pernr TYPE pa0041-pernr,

           dar01 TYPE pa0041-dar01,

           dat01 TYPE pa0041-dat01,

           dar02 TYPE pa0041-dar02,

           dat02 TYPE pa0041-dat02,

           dar03 TYPE pa0041-dar03,

           dat03 TYPE pa0041-dat03,

           dar04 TYPE pa0041-dar04,

           dat04 TYPE pa0041-dat04,

          END OF ty_pa0041.

DATA : lt_pa0041 TYPE STANDARD TABLE OF ty_pa0041,

            ls_pa0041 TYPE ty_pa0041.

*--Read Secondment end date ( For my case it's RG)


SELECT pernr

        dar01 dat01 dar02 dat02 dar03 dat03 dar04 dat04

   INTO TABLE lt_pa0041

   FROM pa0041

   WHERE pernr = gs_final-pernr AND

                endda = '99991231'.

*--Find out corrosponding date according to 'RG'

LOOP AT lt_pa0041 INTO ls_pa0041.

   IF ls_pa0041-dar01 = 'RG'.

     lv_date1 = ls_pa0041-dat01.

   ELSEIF ls_pa0041-dar02 = 'RG'.

     lv_date1 = ls_pa0041-dat02.

   ELSEIF ls_pa0041-dar03 = 'RG'.

     lv_date1 = ls_pa0041-dat03.

   ELSEIF ls_pa0041-dar04 = 'RG'.

     lv_date1 = ls_pa0041-dat04.

    ENDIF.

ENDLOOP.


I hope it fits your requirement