"
Apoiado por

Criar RANGEs no DDIC sem ficar com os dentes a ranger

Cada vez uso mais RANGEs. Uso-os ao pequeno-almoço, ao almoço, ao jantar e fora das refeições. É como o molho de soja. Umas colheradas daquilo e fica logo tudo mais saboroso.

Mas a declaração dos tipos sempre me deu algum trabalho. Por exemplo, se eu quiser usar um range de um campo ZABC, preciso de uma estrutura ZS_RANGE_ABC (com os campos OPTION, SIGN, LOW, HIGH) e depois preciso de uma categoria de tabela (table type) ZT_RANGE_ABC que tenha ZS_ABC como “categoria de linha”. E fazer isto tudo à mão é chato.

Mas recentemente fiquei a saber que o DDIC tem uma funcionalidade que simplifica este processo. Esta simplificação consiste na manutenção automática da “categoria de linha”. Funciona assim:

  1. Partamos do princípio de que tens o elemento de dados ZABC;
  2. Na SE11, em “Categoria de dados” introduz o nome do tipo de dados do RANGE: ZT_RANGE_ABC;
  3. Carrega em F5 para o criar e escolhe a opção “Categoria de tabela”;
  4. Dá-lhe uma descrição senão, não consegues avançar;
  5. (agora é que vem o truque!!)
  6. No menu “Processar” escolhe a opção “Definir como categoria de table range”;
  7. (pimbas! o ecrã mudou!)
  8. Mete ZABC como “elemento de dados”;
  9. Mete ZS_RANGE_ABC como “tipo linha estruturado” (não carregues em “criar” ainda);
  10. Grava;
  11. Já gravaste? Então agora carrega em “criar”;
  12. (o DDIC cria automaticamente uma estrutura já com o SIGN, OPTION, LOW e HIGH!)
  13. Grava e activa a estrutura como farias com qualquer outra estrutura e volta para trás;
  14. Activas a categoria de tabela e pronto: agora tens uma categoria de tabela ZT_RANGE_ABC que é um RANGE do tipo ZABC.

Muito aprazível, não dirias?

Obrigado José Faria por me mostrares esta funcionalidade tão conveniente.

O Abapinho saúda-vos.

8 comentários a “Criar RANGEs no DDIC sem ficar com os dentes a ranger”

  1. Johnny Diz:

    Nuno,

    Type range of, na declaração do elemento de dados, faz o truque tambem :)

  2. Martin Diz:

    Acho mais facil declarar direto no programa:

    ranges lr_matnr for mara-matnr.

    Só isso…

  3. Nuno Godinho Diz:

    Martin, eu também acho mais fácil declarar directamente no programa, e faço-o sempre que posso.
    Mas se tiveres de passar um RANGE por parâmetro não há como evitar declará-lo como um tipo.
    Ainda assim podes declará-lo como um TYPE na classe.
    Mas se o quiseres retornar de um método (RETURNING) não há volta a dar, tem de estar no DDIC.
    Topas?

    De qualquer forma, se o declarares no programa aconselho-te a fazê-lo na nova sintaxe:
    DATA: xxx TYPE RANGE OF yyy.

    Ou:
    TYPES: ty_xxx TYPE RANGE OF yyy.

  4. Johnny Diz:

    Nuno,

    Não obrigatoriamente…

    Eu criava, amiude, ranges onde apenas indicava qual o campo de referencia, e o returning era um range do tipo “cl_abap_tabledescr”, o que nao obriga a ter de criar um tipo no DDIC.

    Exemplificando:

    METHOD create_range.
    ****Acc Jao Martins – Criação de Range dinamicamente

    DATA:
    gr_structdescr TYPE REF TO cl_abap_structdescr,
    gr_tabledescr TYPE REF TO cl_abap_tabledescr,
    gr_datadescr TYPE REF TO cl_abap_datadescr,
    gr_typedescr TYPE REF TO cl_abap_typedescr,
    gt_components TYPE abap_component_tab,
    gw_component TYPE LINE OF abap_component_tab,
    gr_wa TYPE REF TO data,
    gr_tab TYPE REF TO data.

    FIELD-SYMBOLS: TYPE ANY.
    FIELD-SYMBOLS: TYPE table.

    * Componentes da estrutura -> GT_COMPONENTS
    MOVE ‘SIGN’ TO gw_component-name.
    gw_component-type ?= cl_abap_elemdescr=>get_c( p_length = 1 ).
    INSERT gw_component INTO TABLE gt_components.

    MOVE ‘OPTION’ TO gw_component-name.
    gw_component-type ?= cl_abap_elemdescr=>get_c( p_length = 2 ).
    INSERT gw_component INTO TABLE gt_components.

    MOVE ‘LOW’ TO gw_component-name.
    gw_component-type ?= cl_abap_elemdescr=>describe_by_name( field ).
    INSERT gw_component INTO TABLE gt_components.

    MOVE ‘HIGH’ TO gw_component-name.
    gw_component-type ?= cl_abap_elemdescr=>describe_by_name( field ).
    INSERT gw_component INTO TABLE gt_components.

    * Descrição -> GR_STRUCTDESCR
    gr_structdescr ?= cl_abap_structdescr=>create( gt_components ).

    * WA da estrutura
    CREATE DATA gr_wa TYPE HANDLE gr_structdescr.
    ASSIGN gr_wa->* TO .

    gr_datadescr ?= gr_structdescr.
    gr_tabledescr ?= cl_abap_tabledescr=>create( gr_datadescr ).
    r_val = gr_tabledescr.
    ENDMETHOD.

    Para ler o range:

    * Criar Range baseando-se no tipo – RETURN DO Range
    me->create_range( EXPORTING field = fieldname
    IMPORTING r_val = gr_tabledescr ) .

    ** Criar range dinamica
    CREATE DATA ref_tab TYPE HANDLE gr_tabledescr.

    ASSIGN ref_tab->* TO .

    Abraço

  5. Johnny Diz:

    Nuno,

    Na parte final do meu comentário anterior faltava uma coisa importante.. :)
    FIELD-SYMBOLS: TYPE table.

    ** Criar range dinamica
    CREATE DATA ref_tab TYPE HANDLE gr_tabledescr.

    ASSIGN ref_tab->* TO .//(field symbol )

    Abraço

  6. Custodio Diz:

    Realmente a solucao do Johnny eh correcta. Mas nao consigo ver onde eh mais simples do que criar no dicionario.

  7. Nuno Godinho Diz:

    Bem, Johnny, não duvido de que funcione, mas, caramba, isso parece uma máquina de Rube Goldberg! Ou dito de outra forma, ergues uma montanha para parir um rato :)

    Eu uso e abuso do DDIC. Está lá para isso ;)

  8. Johnny Diz:

    Nuno,

    Sim a primeira vez custa, nao digo que nao, mas o racional que se aplixa é:

    1 – Criar os metodos numa classe
    2 – Herdar estes metodos em qualquer outra classe que crie
    3 – Usar e abusar :)

    em vez de estar a criar N elementos de dados, que no limite ao fim de uns quantos meses ja nem me lembro da existência deles, crio os atraves do metodo..

    Para mim, repito para mim, acho mais simples e practico, mas qualquer uma das maneiras é valida :)

    Abraços

Deixe um comentário


Acerca do Abapinho
O Abapinho é suportado pelo WordPress
Artigos (RSS) e Comentários (RSS).