SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

Передача range как параметра в Perform


Goto page 1, 2  Next
 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP
View previous topic :: View next topic  
Author Message
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Mon Dec 10, 2007 1:28 pm    Post subject: Передача range как параметра в Perform Reply with quote

Добрый день!
Подскажите, как передать range в качестве параметра в подпрограмму?

Внутри этот range нужно заполнить значениями из SET и вернуть.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 45
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Mon Dec 10, 2007 2:03 pm    Post subject: Reply with quote

К примеру так:
Code:
DATA: LT_SFLIGHT TYPE TABLE OF SFLIGHT WITH HEADER LINE.
DATA: R_CONNID TYPE RANGE OF S_CONN_ID WITH HEADER LINE.

START-OF-SELECTION.
  PERFORM CREATE_RANGE TABLES R_CONNID.

  SELECT * FROM SFLIGHT INTO TABLE LT_SFLIGHT
    WHERE CONNID IN R_CONNID.

*&---------------------------------------------------------------------*
*&      Form  CREATE_RANGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_R_CONNID  text
*----------------------------------------------------------------------*
FORM CREATE_RANGE  TABLES P_R_CONNID STRUCTURE APPL_RANGE.
   P_R_CONNID-SIGN = 'I'.
   P_R_CONNID-OPTION = 'EQ'.
   P_R_CONNID-LOW = '0400'.
   APPEND P_R_CONNID.
ENDFORM.                    " CREATE_RANGE
Back to top
View user's profile Send private message Blog
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Mon Dec 10, 2007 2:20 pm    Post subject: Reply with quote

Мне нужно любой range нужно передать, потому что в качестве второго параметра нужно передать имя set, а он может быть любым.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 45
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Mon Dec 10, 2007 2:55 pm    Post subject: Reply with quote

Не совсем понятно, что нужно... Может это?
Code:
DATA: LT_SFLIGHT TYPE TABLE OF SFLIGHT WITH HEADER LINE.
DATA: R_CONNID   TYPE RANGE OF S_CONN_ID,
      RANGE_NAME TYPE FIELDNAME.

START-OF-SELECTION.
  RANGE_NAME = 'R_CONNID'.
  PERFORM CREATE_RANGE USING RANGE_NAME.

  SELECT * FROM SFLIGHT INTO TABLE LT_SFLIGHT
    WHERE CONNID IN R_CONNID.

*&---------------------------------------------------------------------*
*&      Form  CREATE_RANGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_RANGE_NAME  text
*----------------------------------------------------------------------*
FORM CREATE_RANGE USING P_RANGE_NAME TYPE FIELDNAME.
  DATA: HEADER TYPE APPL_RANGE.

  FIELD-SYMBOLS: <T_RANGE> TYPE TABLE.

  ASSIGN (P_RANGE_NAME) TO <T_RANGE>.
  CHECK SY-SUBRC IS INITIAL.

  HEADER-SIGN   = 'I'.
  HEADER-OPTION = 'EQ'.
  HEADER-LOW    = '0400'.
  APPEND HEADER TO <T_RANGE>.

ENDFORM.
Back to top
View user's profile Send private message Blog
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Mon Dec 10, 2007 4:30 pm    Post subject: Reply with quote

Вот такой код не универсален, потому что в параметрах функции явно определен тип ranges r_hkont. Хотел от него избавиться.
Сейчас попробую через assign, но это тоже не очень красиво.

PS: В мой системе нет TYPE APPL_RANGE.

Code:

DEFINE RANGE_COPY.
*&1 range source.
*&2 range target.
  REFRESH &2.
  LOOP AT &1.
    MOVE-CORRESPONDING &1 TO &2.
    APPEND &2.
  ENDLOOP.
END-OF-DEFINITION.

DATA: g_range TYPE RANGE OF SETVAL WITH HEADER LINE.
CONSTANTS:
  c_set_hkont LIKE rgsbm-shortname VALUE 'Z_EXCL_HKONT'.

RANGES: r_hkont FOR bseg-hkont.

PERFORM f_get_set_single_type
        USING c_set_hkont.
RANGE_COPY g_range r_hkont.

*---------------------------------------------------------------------*
*       FORM f_get_set_single_type                                    *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
*  -->  SHORTNAME                                                     *
*---------------------------------------------------------------------*
FORM f_get_set_single_type
         USING shortname.

  REFRESH g_range. CLEAR: g_range.
  DATA setnr LIKE rgsbs-setnr.
  DATA:
       loc_set_lines_basic LIKE rgsbv OCCURS 0 WITH HEADER LINE,
       loc_set_lines_single LIKE rgsb1 OCCURS 0 WITH HEADER LINE.

  CALL FUNCTION 'G_SET_GET_ID_FROM_NAME'
         EXPORTING
              shortname                = shortname
         IMPORTING
              new_setid                = setnr
         EXCEPTIONS
              no_set_found             = 1
              no_set_picked_from_popup = 2
              wrong_class              = 3
              wrong_subclass           = 4
              OTHERS                   = 5.
  check sy-subrc = 0.

  CALL FUNCTION 'G_SET_FETCH'
       EXPORTING
            setnr            = setnr
       TABLES
*           formula_lines    = loc_formula_lines
            set_lines_single = loc_set_lines_single
            set_lines_basic  = loc_set_lines_basic
*           set_lines_data   = loc_set_lines_data
*           set_lines_multi  = loc_set_lines_multi
       EXCEPTIONS
            no_authority     = 1
            set_is_broken    = 2
            set_not_found    = 3
            OTHERS           = 4.
  check sy-subrc = 0.
* get single values
  LOOP AT loc_set_lines_basic.
    IF loc_set_lines_basic-from = loc_set_lines_basic-to
        OR loc_set_lines_basic-to IS INITIAL.
      g_range-sign = 'I'.
      IF loc_set_lines_basic-from CS '*'.
        g_range-option = 'CP'.
      ELSE.
        g_range-option = 'EQ'.
      ENDIF.
      g_range-low = loc_set_lines_basic-from.
      CLEAR g_range-high.
      APPEND g_range.
    ELSE.
      g_range-sign = 'I'.
      g_range-option = 'BT'.
      g_range-low = loc_set_lines_basic-from.
      g_range-high = loc_set_lines_basic-to.
      APPEND g_range.
    ENDIF.
* get values from subsets
  LOOP AT loc_set_lines_single.
    CALL FUNCTION 'G_SET_FETCH'
      EXPORTING
        setnr            = loc_set_lines_single-setnr
*      IMPORTING
*        set_header       = loc_set_header
      TABLES
*       formula_lines    = loc_formula_lines
        set_lines_basic  = loc_set_lines_basic
*       set_lines_data   = loc_set_lines_data
*       set_lines_multi  = loc_set_lines_multi
*       set_lines_single = loc_set_lines_single
      EXCEPTIONS
        no_authority     = 1
        set_is_broken    = 2
        set_not_found    = 3
        OTHERS           = 4.
      IF sy-subrc NE 0.
        EXIT.
      ENDIF.
      LOOP AT loc_set_lines_basic.
        IF loc_set_lines_basic-from = loc_set_lines_basic-to
            OR loc_set_lines_basic-to IS INITIAL.
          g_range-sign = 'I'.
          IF loc_set_lines_basic-from CS '*'.
            g_range-option = 'CP'.
          ELSE.
            g_range-option = 'EQ'.
          ENDIF.
          g_range-low = loc_set_lines_basic-from.
          CLEAR g_range-high.
          APPEND g_range.
        ELSE.
          g_range-sign = 'I'.
          g_range-option = 'BT'.
          g_range-low = loc_set_lines_basic-from.
          g_range-high = loc_set_lines_basic-to.
          APPEND g_range.
        ENDIF.
      ENDLOOP.
    ENDLOOP.
  ENDLOOP.
ENDFORM.                    " f_get_set_single_type


Last edited by Сергей on Tue Dec 11, 2007 11:38 am; edited 1 time in total
Back to top
View user's profile Send private message
vga
Мастер
Мастер


Age: 175
Joined: 04 Oct 2007
Posts: 1218
Location: Санкт-Петербург

PostPosted: Mon Dec 10, 2007 4:34 pm    Post subject: Reply with quote

Здесь посмотрите
http://www.sapnet.ru/viewtopic.php?t=455
Back to top
View user's profile Send private message Blog Visit poster's website
John Doe
Модератор
Модератор


Age: 45
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Mon Dec 10, 2007 4:35 pm    Post subject: Reply with quote

Сергей wrote:
PS: В мой системе нет TYPE APPL_RANGE.

Не важно, поиск по структурам с маской *RANGE* даст большое число доступных структур для range.

ЗЫ Ничего универсальнее FIELD-SYMBOLS еще не придумали.
Back to top
View user's profile Send private message Blog
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Mon Dec 10, 2007 5:02 pm    Post subject: Reply with quote

Возможно, я не прав, но проверка показала наличие проблемы в куске:
John Doe wrote:

Code:

  HEADER-SIGN   = 'I'.
  HEADER-OPTION = 'EQ'.
  HEADER-LOW    = '0400'.
  APPEND HEADER TO <T_RANGE>.


Типы header и <T_RANGE> не совпадают и при добавлении параметр high портится.
Попробую создавать динамически структуру P_RANGE_NAME с кастингом.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 45
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Mon Dec 10, 2007 5:33 pm    Post subject: Reply with quote

Сергей wrote:

Типы header и <T_RANGE> не совпадают и при добавлении параметр high портится.

Они не могут не совпадать, при условии что диапазон правильно объявлен. Структура HEADER должна быть такая же как у диапазона, т.е. всего 4 поля: sign(1), option(2), low и high - должны быть типизированы под нужный элемент (в конкретном случае тип HKONT). Структуру можно сделать самому...
Back to top
View user's profile Send private message Blog
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Mon Dec 10, 2007 5:47 pm    Post subject: Reply with quote

John Doe wrote:
Сергей wrote:

Типы header и <T_RANGE> не совпадают и при добавлении параметр high портится.

Они не могут не совпадать, при условии что диапазон правильно объявлен. Структура HEADER должна быть такая же как у диапазона, т.е. всего 4 поля: sign(1), option(2), low и high - должны быть типизированы под нужный элемент (в конкретном случае тип HKONT). Структуру можно сделать самому...



Так такая задача стояла изначально, отказаться от какой либо статической типизации внутри подпрограммы. В крайнем случае передавать тип в качестве агрумента, как ты предложил.
Back to top
View user's profile Send private message
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Tue Dec 11, 2007 12:00 pm    Post subject: Reply with quote

Побился, побился, динамически создать range в подпрограмме на основе передаваемого в строке имени range, не получилось. Crying or Very sad Поэтому решил через макросы. В подпрограмме заполнил range с заведомо длинными low, high а при выходе перекопирую через макрос.

Код исправил в сообщении выше.

Хотя вопрос динамического создания range остается открытым, решение найти все равно хочется. На sapforum был подобный вопрос, но вроде тоже остался без решения.
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 45
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Tue Dec 11, 2007 12:41 pm    Post subject: Reply with quote

Последний вариант:
Code:
DATA: LT_SFLIGHT TYPE TABLE OF SFLIGHT WITH HEADER LINE.
DATA: R_CONNID   TYPE RANGE OF S_CONN_ID,
      R_CARRID   TYPE RANGE OF S_CARR_ID,
      RANGE_NAME TYPE FIELDNAME.

START-OF-SELECTION.
  RANGE_NAME = 'R_CONNID'.
  PERFORM CREATE_RANGE USING RANGE_NAME.

  RANGE_NAME = 'R_CARRID'.
  PERFORM CREATE_RANGE USING RANGE_NAME.

  SELECT * FROM SFLIGHT INTO TABLE LT_SFLIGHT
    WHERE CONNID IN R_CONNID
    AND   CARRID IN R_CARRID.

*&---------------------------------------------------------------------*
*&      Form  CREATE_RANGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_RANGE_NAME  text
*----------------------------------------------------------------------*
FORM CREATE_RANGE USING P_RANGE_NAME TYPE FIELDNAME.
  DATA: RANGE LIKE RANGE OF P_RANGE_NAME WITH HEADER LINE.
  FIELD-SYMBOLS: <T_RANGE> TYPE TABLE.

* Create dynamic values
  ASSIGN (P_RANGE_NAME) TO <T_RANGE>.
  CHECK SY-SUBRC IS INITIAL.

* Create range
  CASE P_RANGE_NAME.
    WHEN 'R_CONNID'.
      RANGE-SIGN   = 'I'.
      RANGE-OPTION = 'EQ'.
      RANGE-LOW    = '0820'.
    WHEN 'R_CARRID'.
      RANGE-SIGN   = 'I'.
      RANGE-OPTION = 'EQ'.
      RANGE-LOW    = 'AC'.
  ENDCASE.

  APPEND RANGE TO <T_RANGE>.

ENDFORM.                    "CREATE_RANGE
Back to top
View user's profile Send private message Blog
Сергей
Участник
Участник



Joined: 25 Oct 2007
Posts: 49

PostPosted: Tue Dec 11, 2007 1:42 pm    Post subject: Reply with quote

John Doe, последний вариант самый интересный, но есть вопрос по строке:

DATA: RANGE LIKE RANGE OF P_RANGE_NAME WITH HEADER LINE.

У меня система 4.7. НЕзависимо от того, какой бы range не указавал в качестве аргумента в P_RANGE_NAME, создается всегда одинаковый с длиной low и high = 30 символам. Соотественно APPEND правильно не работает. У тебя точно динамически тип range меняется?
Back to top
View user's profile Send private message
John Doe
Модератор
Модератор


Age: 45
Joined: 05 Nov 2007
Posts: 725
Location: КраснАдар

PostPosted: Tue Dec 11, 2007 2:59 pm    Post subject: Reply with quote

У меня этот текст программы в erp2005 отрабатывает корректно. Автоматически типизация char30 присваивается, но после апенда все нормально выравнивается. В примере, я на вход подаю один тип char2, а другой numc4 - и все работает.
Back to top
View user's profile Send private message Blog
Lord
Профессионал
Профессионал



Joined: 10 Sep 2007
Posts: 168

PostPosted: Thu Dec 13, 2007 2:15 pm    Post subject: Reply with quote

Рабочий пример, проверен в 4.6C.
Присваивает полю low = 1.

Code:

RANGES: day for sy-datum,
              money for bkpf-waers,
              price for konv-kbetr.

PERFORM fill_range USING:
                          'DAY',
                          'MONEY',
                          'PRICE'.

FORM FILL_RANGE USING RANGE.
   DATA: RANGE_TAB(15) VALUE '&[]'.
   FIELD-SYMBOLS: <TRANGE> TYPE TABLE,
                               <W_RANGE> TYPE ANY,
                               <VALUE>       TYPE ANY.


   REPLACE '&' WITH RANGE INTO RANGE_TAB.

   ASSIGN (RANGE_TAB) TO <TRANGE>.
   ASSIGN (RANGE)         TO <W_RANGE>.

   <W_RANGE>(3) = 'IEQ'.

   ASSIGN COMPONENT 'LOW' OF STRUCTURE <W_RANGE> TO <VALUE>.
  <VALUE> = '1'.
  APPEND <VALUE> TO <TRANGE>.

ENDFORM.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP All times are GMT + 4 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.