No caso do ABAP, você pode efetuar a chamada do perform A estando dentro do próprio perform A.
Segue um exemplo simples de como este processo funciona utilizando de FIELD-SYMBOLS e ASSIGN. Quer saber mais sobre FIELD-SYMBOLS e ASSIGN? Clique aqui.
REPORT ZSAPeiros.
TYPES: BEGIN OF ty_mara,
matnr1 TYPE mara-matnr,
matnr2 TYPE mara-matnr,
matnr3 TYPE mara-matnr,
matnr4 TYPE mara-matnr,
matnr5 TYPE mara-matnr,
END OF ty_mara.
DATA: wa_mara TYPE ty_mara.
DATA: vg_str_atual TYPE string.
wa_mara-matnr1 = '1'.
wa_mara-matnr2 = '2'.
wa_mara-matnr3 = '3'.
wa_mara-matnr4 = '4'.
wa_mara-matnr5 = '5'.
CLEAR vg_str_atual.
PERFORM p_monta_str USING 1
CHANGING vg_str_atual.
WRITE: / vg_str_atual.
*----------------------------------------------------------------------*
* Monta string com os valores dos campos, separados por vírgula
*----------------------------------------------------------------------*
FORM p_monta_str USING value(vl_num) TYPE any
CHANGING value(vl_str) TYPE any.
FIELD-SYMBOLS: <campo> TYPE any,
<valor> TYPE any.
DATA: vl_campo TYPE string,
vl_num_aux(15) TYPE c.
vl_num_aux = vl_num.
CONDENSE vl_num_aux.
* Busca o nome do campo
CHECK vl_num LT 6.
CONCATENATE 'wa_mara-matnr' vl_num_aux INTO vl_campo.
ASSIGN (vl_campo) TO <campo>.
CHECK <campo> IS ASSIGNED.
* Busca o valor do campo
CONCATENATE 'wa_mara-matnr' <campo> INTO vl_campo.
ASSIGN (vl_campo) TO <valor>.
CHECK <valor> IS ASSIGNED.
IF vl_str IS INITIAL.
vl_str = <valor>.
ELSE.
CONCATENATE vl_str <valor> INTO vl_str SEPARATED BY ','.
ENDIF.
ADD 1 TO vl_num.
PERFORM p_monta_str USING vl_num
CHANGING vl_str.
ENDFORM. "p_monta_str