quarta-feira, 21 de dezembro de 2011

'LEFT DELETING LEADING' e/ou 'RIGHT DELETING TRAILING'

  " As vezes precisamos trabalhar com valores que recebemos, principalmente
" para usar em Selects, funções e etc, mas temos que adaptar o valor no
" imput para não ter problema, abaixo segue um programa que mostra como
" os comandos LEFT DELETING LEADING' e 'RIGHT DELETING TRAILING' trabalham.
"  Debuggem e vejam o que acontece, mas vou dar uma resumo abaixo.

" 'LEFT DELETING LEADING' - Deleta o valor informado da Esquerda pra direita,
" quando chegar um valor diferente ele pára e fica com os dados alinhados a
" esquerda.
" 'RIGHT DELETING TRAILING' - Deleta o valor informado da direita pra
" esquerda, quando chegar um valor diferente ele pára e fica com os dados
" alinhados a direita.

REPORT zmj_ldl_rdt.

" Variáveis.
DATA varia1 TYPE string VALUE '000011110000111',
       varia2 TYPE string VALUE '010101010101010',
       varia3 TYPE string VALUE '000000000000001',
       varia4 TYPE string VALUE '100000000000000',
       varia5 TYPE string VALUE '111111111011111'
       .

" Tela de seleção.
*&---------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME.

PARAMETERS :
" Elemento de texto = 'LEFT DELETING LEADING'
rb_left  RADIOBUTTON GROUP rb_1 DEFAULT 'X',
" Elemento de texto = 'RIGHT DELETING TRAILING'
vb_right RADIOBUTTON GROUP rb_1
.

SELECTION-SCREEN END OF BLOCK   b1.
*&---------------------------------------------------------------------*

" Inicio do processo.
START-OF-SELECTION.

IF rb_left 'X'.
  PERFORM zf_left.
else.
  PERFORM zf_right.
ENDIF.

sexta-feira, 16 de dezembro de 2011

Função - SUSR_USER_READ

  *&---------------------------------------------------------------------*
"  Caso um dia precise trazer o email de algum usuário, então teremos que
" usar este função que pelo ID do usuário você consegue os campos chaves
" para fazer a busca dentro da tabela de Emails ( ADR6 ).

REPORT zmj_susr_user_read.

" Declaração estrutura
DATA st_address TYPE usaddress,
       st_adr6    TYPE adr6
       .

" Inicio.
START-OF-SELECTION.

PERFORM zf_busca_personal_number,
          zf_busca_email,
          zf_show_all.


*&---------------------------------------------------------------------*
*&      Form  ZF_BUSCA_PERSONAL_NUMBER
*&---------------------------------------------------------------------*
form ZF_BUSCA_PERSONAL_NUMBER .

"  Aqui estaremos executando a função, eu estou usando o sy-uname ( nome
" do usuário logado) mas caso queira saber de outro usuário que não seja
" voce é só colocar um parametro numa tela de seleção para que possa ser
" alimentado pelo usuário.

CALL FUNCTION 'SUSR_USER_READ'
  EXPORTING
    user_name            sy-uname
  IMPORTING
    user_address         st_address
  EXCEPTIONS
    user_name_not_exists 1
    internal_error       2
    OTHERS               3.

endform.                    " ZF_BUSCA_PERSONAL_NUMBER

*&---------------------------------------------------------------------*
*&      Form  ZF_BUSCA_EMAIL
*&---------------------------------------------------------------------*
form ZF_BUSCA_EMAIL .

"  Seleciona os dados de email do usuário pelo numero endereço e numero
" pessoal do usuário dentro do SAP.
SELECT SINGLE *
  FROM adr6
  INTO st_adr6
  WHERE addrnumber st_address-addrnumber
  AND   persnumber st_address-persnumber.

endform.                    " ZF_BUSCA_EMAIL

*&---------------------------------------------------------------------*
*&      Form  ZF_SHOW_ALL
*&---------------------------------------------------------------------*
form ZF_SHOW_ALL .

"  Mostra tudo rsrs, prestem atenção que eu coloquei (60) no final do campo
" que está o email porque este campo tem o tipo char(241) e por causa do
" tamanho da pagina a informação ficaria na linha abaixo se eu não colocasse
" este (60) no final limitando o tamanho do campo.

WRITE 'O email do Usuário'sy-uname ' é : 'st_adr6-smtp_addr(60).

endform.                    " ZF_SHOW_ALL

Função - MONTH_NAMES_GET

"  Agora vou passa pra vocês uma função muito facil e simples, ela traz
" os meses conforme a lingua que informar, tive que dar manutenção num
" programa onde eu teria que mostrar um relatorio onde o Titulo 'mês' estava
" em 'hardcode', mas o programa seria usado em varios paises e teria que
" mostrar conforme a lingua do acesso, então alem de criar elementos de
" textos e traduzí-los, preferi usar essa função e dar 'read table' na
" tabela it_mes e trazer os campos 'KTX' e 'LTX'.

REPORT zmj_month_names_get.

* Tipos
TYPES BEGIN OF ty_mes.
        INCLUDE STRUCTURE t247.
TYPES END   OF ty_mes.

* Tabela Internas
DATA it_mes TYPE TABLE OF ty_mes.

* Estruturas
DATA st_mes TYPE          ty_mes.

START-OF-SELECTION.

  PERFORM zf_month_names_get.

*&---------------------------------------------------------------------*
*&      Form  ZF_MONTH_NAMES_GET
*&---------------------------------------------------------------------*
FORM zf_month_names_get .

"  Executem uma vez com sy-langu e depois execute mudando o mesmo pra
" verem como retorna a tabela.
BREAK-POINT.

  CALL FUNCTION 'MONTH_NAMES_GET'
    EXPORTING
      language              sy-langu
    TABLES
" Tabela que receberá as informações.
      month_names           it_mes
    EXCEPTIONS
      month_names_not_found 1
      OTHERS                2.

  BREAK-POINT.
" Sussa né?

ENDFORM.                    " ZF_MONTH_NAMES_GET

segunda-feira, 5 de dezembro de 2011

OO - Herança

  *&---------------------------------------------------------------------*
"  Uma das grande vantagens da OO e a criação de classe que herdam informações
" de uma classe mais generica, fazer isso de se chama 'Hierarquia' que é
" passar atributos de uma classe generica ( classe mãe ) para uma classe mais
" especifica ( classe filho ).
"  Existe a classe Carro, mas existem varios tipos de carros... F1, kart, truck,
" e assim vai, mas todos tem os atributos de um carro como velocidade, rodas,
" modelo, mas seus atributos podem variar conforme o tipo de carro, aki nos
" vamos usar a velocidade como diferencial... mas primeiro vamos criar uma
" classe filho chamada 'ZCL_KART' conforme abaixo.
" Ahhhhh  antes disso tudo na classe mãe (ZCL_CAR) vá na aba 'Caract.' é tire
" o flag do campo 'Final', pois quando isso está com flag significa que ele não
" deixa ninguem herdar dele.



"  Entrem no aba 'Atributos' e verá que só existe o atributo 'Velocidade',
" não sei se vc se lembra mas a visibilidade deste atributo é 'Protect',
" porisso vc vê, rsrs vou explicar melhor a visibilidade de atributos...
" Private - Somente aquela classe consegue visualizar.
" Protect - Somente aquela classe e suas classes filha conseguem visualizar.
" Public  - Todo mundo visualiza. rs.

"  Agora entre na aba 'Metodos' o esquema de visibilidade e a mesma ideia.
"  Todos o metodos criados antes eram 'Public' porisso aparecem aki,

"  Perceba que o nome dos 'Atributos' e dos 'Metodos' estão em azul, o que
" mostra que aquilo não é da atual classe, pra ver somente o que é desta
" classe é soh colocar um flag no campo Filtro marcado na imagem abaixo.
"  Portanto a classe filha tem todos os Atributos 'Protect' e 'Public' da
" classe mãe, juntamente com todos os metodos 'Protect' e 'Public', mas
" não sei se vc concorda mas a velocidade que um carro é diferente da
" velocidade de um Kart portanto eles tem uma acelereção diferente, pois
" é isso que vamos fazer agora, usar o mesmo metodos de forma diferente
" pois a classe mesmo sendo filha e diferente da classe mãe.



" Clicando duas vezes na classe 'AUMENTA_VELO' você, logo de cara, verá
" que ele informa pra vc que aquele 'Metodo' e da classe mãe, portanto
" teremos que redefinir o metodo.
"  Para redefinir devemos selecionar o metodo e clicar no botão 'Redefinir'
" conforme na imagem acima. ( caso queira tirar a redefinição criada e só
" clicar nesse botão com uma setinha branca, do lado redefinir.)
" Coloque o código abaixo e volte.

*&---------------------------------------------------------------------*
method AUMENTA_VELO.
*CALL METHOD SUPER->AUMENTA_VELO
*    .

      add 3 to me->velocidade.
endmethod.
*&---------------------------------------------------------------------*

"  Agora execute o código abaixo e depois execute denovo só que trocando a
" classe de referencia do objeto.
"  Debbugem e veram que o metodo 'AUMENTA_VELO' reage de forma diferente 
" dependendo da classe mesmo sendo o mesmo metodo, dahora neh...



REPORT  zmj_oo_herança.

" Refenreciei um objeto a uma classe mas este objeto ainda não existe.
DATA: o_veiculo TYPE REF TO zcl_kart.

BREAK-POINT.

"  Agora o objeto tá criado, clique duas vezes neste objeto e vc verá seus
" atributos.
CREATE OBJECT o_veiculo.

" Metodo que informa a marca do carro.
CALL METHOD o_veiculo->set_marca
  EXPORTING
    marca = 'VW'.

BREAK-POINT.

" Faça três vezes ...
DO 3 TIMES.
" Metodo que adiciona +2 cada vez que executado.
  CALL METHOD o_veiculo->aumenta_velo.
ENDDO.

BREAK-POINT.

sexta-feira, 25 de novembro de 2011

Orientação a Objeto no ABAP - SE24

  "  Hoje vou tentar passar pra vocês um pouco de orinteção a Objeto ( OO ),
" usando a transação se24, vou ser bem sincero mexo pouco com OO e me
" esforço bastante pra aprender pois eu acho que OO eh o futuro do SAP
" para um ABAP, mas existem alguns conceitos dentro disso que são um pouco
" complexos de aprender e ainda mais de explicar, portanto estarei fazendo
" uma classe desde o começo e tentando passar o maximo que conseguir pra vcs,
" não vou fala que é facil, mas se você for um ABAP a frase 'se esforçar um
" pouco mais' já é cotidiano nosso, gostaria que comentassem caso eu não
" contemple ou me equivoque em algo durante esse post.

"  Primeiramente vamos entra na transação 'SE24' e vamos criar nossa primeira
" classe, no campo 'Classe' você informe 'ZCL_CAR', clique em 'CRIAR'
" aqui estaremos fazendo uma classe de carro.



"  Crie conforme condições acima reparando no campo 'Geraç.Istancia' e no
" no flag 'Final'.



"  Olha a cara do negocio,.. tenso rsrsrsr, hoje eu tentarei mostrar o básico
" de duas das abas que podemos considerar como principais que sãs as abas
" 'Atributos' e 'Metodos', primeiro vamos para o 'Atributos' que seriam como
" condições para aquela classe existir..  Exemplo : O que o carro precisa para
" ser chamado de carro, - motor, rodas, velocidade, marcha .... e assim vai,
" conforme imagem acima façam cada cada atributo com o mesmo tipo, visibilidade
" e tipo referencia, durante o uso dos métodos irei explicar melhor.




"  Agora faremos os métodos da nossa classe que são como coisas que ( no
" nosso caso ) carros podem fazer, nosso carro só aumenta e diminui a
" velocidade, Mas conforme imagem acima a gente só aumenta a velicidade,
" rsrs. Resumido muito por cima Metodos funcionam como functions...
"  Clicando duas vezes encima do metodo 'Aumenta_velo' iremos para o
" texto fonte daquele método, coloquem o código abaixo.

*&---------------------------------------------------------------------*
method AUMENTA_VELO.
"  Usado me-> para informar que é um atributo da classe, pois cada método
" pode ter seu proprio atributo (parametro), irei dar um exemplo nos
" metodos abaixo.
    add 2 to me->velocidade.
endmethod.
*&---------------------------------------------------------------------*

"  Agora precisamos informar a marca do carro ( SET_MODELO ) que estamos
" criando, e isso será informado no programa portanto deveremos criar um
" parametro de entrada para esse método, primeiro clique duas vezes no método
" vá no menu 'Ir Para/ Definição método' e crie um parametro de 'Importing'
" conforme imagem abaixo.



"  Depois de salvo repare que este parametro fica informado tipo num cabeçalho
" do metodo.
"  Só colocar o código abaixo no código fonte do método 'SET_MODELO'.

*&---------------------------------------------------------------------*
method SET_MODELO.
"  Agora espero que tenha ficado um pouco mais claro o uso da comando me->,
" no código abaixo eu to informando que o 'atributo' da classe está recebendo
" o valor do parametro do método.
  me->modelo = modelo.
endmethod.
*&---------------------------------------------------------------------*

"  Faça com o metodo 'SET_MARCA' o mesmo feito com o 'SET_MODELO', crie uma
" uma parametro para ela e o relacione com o atributo 'MARCA' da classe,
" codigo abaixo.

*&---------------------------------------------------------------------*
method SET_MARCA.

    me->marca = marca.

endmethod.
*&---------------------------------------------------------------------*

"  Criei um código simples para vcs debugarem pois o debug muda um pouco, 
" mais tarde estarei fazendo um post sobre o 'debug' para OO e uma continuação
" sobre esta mesma classe para poder exibir e tratar dados.

REPORT  zmj_oo2.

" Refenreciei um objeto a uma classe mas este objeto ainda não existe.
DATA: o_veiculo TYPE REF TO zcl_car.

BREAK-POINT.

"  Agora o objeto tá criado, clique duas vezes neste objeto e vc verá seus 
" atributos.
CREATE OBJECT o_veiculo.

" Metodo que informa a marca do carro.
CALL METHOD o_veiculo->set_marca
  EXPORTING
    marca = 'VW'.

BREAK-POINT.

" Faça três vezes ...
DO 3 TIMES.
" Metodo que adiciona +2 cada vez que executado.
  CALL METHOD o_veiculo->aumenta_velo.
ENDDO.

BREAK-POINT.

quinta-feira, 24 de novembro de 2011

Estamos contratando !!!

Uma ótima notícia para os Abapeiros de primeira viagem é que o Blog 'ABAP Junior' está fazendo alianças com empresas do mercado SAP para indicações para o cargo de ABAP, isso mesmo.... a partir de hoje estarei aceitando currículos de programadores ABAP,o blog irá passar para Setor de Recursos Humanos das empresas parceiras, não garantimos a contratação, mas como todos dizem, 'ajudamos a passar o Curriculo pra frente', esperamos nos encontrar em algum projeto por ae....  ahhhhh o email para enviar está abaixo.

maurorpjunior@gmail.com

terça-feira, 22 de novembro de 2011

Importando Imagem para ALV - Transação 'OAER'

"  Conforme prometido, estarei falando agora como inserir uma imagem para
" ser usado no top-of-page do seu ALV, deixando bem claro que o formato
" para trabalhar com ALV tem que ser JPEG ou GIF, Isso mesmo GIF rsrs...
"  Primeiramente vamos entrar na Transação 'OAER'...

"  Bunitão essa transação né? Não se esqueça que essa transação é usada
" pra um monte de coisa que nem sei, mas tambem é usada pra importação de
" imagens dentro do SAP de uma forma mais organizada.
"  Primeiramente vamos colocar no campo 'Nome da Classe' o dado 'PICTURES'
" e no campo 'Tipo de Classe' o dado 'OT' antes de informar a 'Chave do
" objeto', execute e você verá todas as imagens desta classe, falei isso
" porque as vezes a imagem que você quer adicionar é um logo e provavelmente
" isso já deve ter sido adicionado por alguem antes, caso contrário vamos
" voltar e informar a 'Chave do objeto', lembrando que a chave do objeto
" o nome do objeto dentro do SAP, é com esse nome que deveremos trabalhar na
" função 'REUSE_ALV_COMMENTARY_WRITE', Execute.
"  Não lembra dessa função acesse esse link :
http://abapjuniores.blogspot.com/2011/11/alv-top-of-page.html


 "  Dando f8 irá aparecer a tela acima, clique com o botão direito encima
" do menu 'Tela/ Importar file' irá aparecer um PopUp para você colocar o
" endereço da imagem e dê 'ENTER'.

 "  Irá aparecer o novo PopUp acima coloque uma descrição.

"  Na Imagem acima você consegue visualizar bem que a imagem já foi inclusa
" e pronta pra ser usada,.... Agora vou mostra como usar na função abaixo.
*&---------------------------------------------------------------------*
"  Você deve colocar a 'Chave do Objeto' ( figura 1 / campo 3) entre aspas
" simples no parametro 'I_LOGO', dessa forma a imagem ficará na parte superior
" direita do cabeçalho.
CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
  
EXPORTING
    it_list_commentary       = it_internaltable
    I_LOGO                   = 
'SUA_IMAGEM'
*   I_END_OF_LIST_GRID       =
*   I_ALV_FORM               =
          .

segunda-feira, 21 de novembro de 2011

ALV - Top of Page

  *----------------------------------------------------------------------*
"  Conforme pedido por email estarei falando sobre a inclusão de cabeçalho
" num ALV, basicamente e declarar um form no parametro 'i_callback_top_of_page'
" da função 'REUSE_ALV_GRID_DISPLAY', dentro deste form terá uma outra função
" chamada 'REUSE_ALV_COMMENTARY_WRITE' que é uma função muito simples, vamos lá.

REPORT z_topofpage_alv.

" Tabelas transparentes ....
TABLES : mara
  .
" type-pools .....
" Essa declaração e necessária pois e o grupo de tipos usados no ALV.
TYPE-POOLS: slis
           .

" Tipos .....
TYPES :

  BEGIN OF ty_mara,
    matnr TYPE mara-matnr,  " Nº do material
    ersda TYPE mara-ersda,  " Data de criação
    ernam TYPE mara-ernam,  " Nome do responsável que adicionou o objeto
    pstat TYPE mara-pstat,  " Status de atualização
    mtart TYPE mara-mtart,  " Tipo de material
  END OF   ty_mara .

" Estruturas ....
DATA : st_mara TYPE ty_mara
      .

" Tabelas Internas ....
DATA : it_mara TYPE TABLE OF ty_mara
      .

" Declarações usadas no ALV.
DATA : it_fieldcat TYPE slis_t_fieldcat_alv,
       st_fieldcat TYPE slis_fieldcat_alv,
       st_layout   TYPE slis_layout_alv
      .

" Tela de seleção .....
SELECTION-SCREEN BEGIN OF BLOCK b1.
SELECT-OPTIONS :
    so_matnr FOR mara-matnr NO INTERVALS,   " Nº do material
    so_pstat FOR mara-pstat NO INTERVALS    " Status de atualização
                .

SELECTION-SCREEN END OF BLOCK b1.

START-OF-SELECTION.

  PERFORM : z_feed_table,
            z_layout,
            z_fieldcat,
            z_alv
           .

*&---------------------------------------------------------------------*
*&      Form  z_feed_table
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM z_feed_table .

  SELECT matnr
         ersda
         ernam
         pstat
         mtart
    INTO TABLE it_mara
    FROM mara
    UP TO 100 ROWS
    WHERE matnr IN so_matnr
    AND   pstat IN so_pstat
    .

ENDFORM.                    " Z_feed_table


*&---------------------------------------------------------------------*
*&      Form  Z_LAYOUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*

FORM z_layout .

  st_layout-colwidth_optimize = 'X'.
  st_layout-zebra             = 'X'.

ENDFORM.                    " Z_LAYOUT


*&---------------------------------------------------------------------*
*&      Form  Z_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM z_fieldcat .

  PERFORM z_feed_fieldcat USING :
    "Fname  Seltext                 check   Edit  Col_pos
    'MATNR' 'Material'              ' '    ' '    0        ,
    'ERSDA' 'Data de criação'       ' '    ' '    1        ,
    'ERNAM' 'Nome do responsável'   ' '    ' '    2        ,
    'PSTAT' 'Status'                ' '    ' '    3        ,
    'MTART' 'Tipo de material'      ' '    ' '    4
            .

ENDFORM.                    " Z_FIELDCAT

*&---------------------------------------------------------------------*
*&      Form  Z_FEED_FIELDCAT
*&---------------------------------------------------------------------*
FORM z_feed_fieldcat  USING    fieldname
                               seltext_m
                               checkbox
                               edit
                               col_pos .

  st_fieldcat-fieldname   = fieldname.      " Nome do campo
  st_fieldcat-seltext_m   = seltext_m.      " texto do campo
  st_fieldcat-checkbox    = checkbox.       " se o campo é do tipo CheckBox
  st_fieldcat-edit        = edit.           " se o campo pode ser editavel
  st_fieldcat-col_pos     = col_pos.        "Em que posição fica a coluna
  " Coloca a estrutura alimentada na Tabela.
  APPEND st_fieldcat TO it_fieldcat.
  " Limpa a estrutura e volta pra poxima linha do form.
  CLEAR  st_fieldcat.
ENDFORM.                    " Z_FEED_FIELDCAT

*&---------------------------------------------------------------------*
*&      Form  Z_ALV
*&---------------------------------------------------------------------*

FORM z_alv .

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
     EXPORTING
*   I_INTERFACE_CHECK                 = ' '
*   I_BYPASSING_BUFFER                = ' '
*   I_BUFFER_ACTIVE                   = ' '
      i_callback_program                = sy-repid    " Nome do programa
*   i_callback_pf_status_set          = ' '
*   i_callback_user_command           = ' '

" Declare o form!!!!
     i_callback_top_of_page            = 'TOP-OF-PAGE'

*   I_CALLBACK_HTML_TOP_OF_PAGE       = ' '
*   I_CALLBACK_HTML_END_OF_LIST       = ' '
*   I_STRUCTURE_NAME                  =
*   I_BACKGROUND_ID                   = ' '
*   I_GRID_TITLE                      =
*   I_GRID_SETTINGS                   =
"  Post sobre Layout ALV -
" http://abapjuniores.blogspot.com/2011/07/alv-layout_14.html
      is_layout                         = st_layout
"  Post Sobre Fieldcat ALV -
" http://abapjuniores.blogspot.com/2011/06/alv-parte-1.html
      it_fieldcat                       = it_fieldcat
*   IT_EXCLUDING                      =
*   IT_SPECIAL_GROUPS                 =
*   IT_SORT                           =
*   IT_FILTER                         =
*   IS_SEL_HIDE                       =
*   I_DEFAULT                         = 'X'
*   i_save                            = 'X'
*   IS_VARIANT                        =
*   IT_EVENTS                         =
*   IT_EVENT_EXIT                     =
*   IS_PRINT                          =
*   IS_REPREP_ID                      =
*   I_SCREEN_START_COLUMN             = 0
*   I_SCREEN_START_LINE               = 0
*   I_SCREEN_END_COLUMN               = 0
*   I_SCREEN_END_LINE                 = 0
*   I_HTML_HEIGHT_TOP                 = 0
*   I_HTML_HEIGHT_END                 = 0
*   IT_ALV_GRAPHICS                   =
*   IT_HYPERLINK                      =
*   IT_ADD_FIELDCAT                   =
*   IT_EXCEPT_QINFO                   =
*   IR_SALV_FULLSCREEN_ADAPTER        =
* IMPORTING
*   E_EXIT_CAUSED_BY_CALLER           =
*   ES_EXIT_CAUSED_BY_USER            =
      TABLES
        t_outtab                          = it_mara   " Tabela com os dados
     EXCEPTIONS
       program_error                     = 1
       OTHERS                            = 2
              .
  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

ENDFORM.                    " Z_ALV

*&---------------------------------------------------------------------*
*&      Form  TOP-OF-PAGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM top-of-page.
* Declarações locais do cabeçalho do ALV
  DATA:
        it_header TYPE slis_t_listheader,
        st_header TYPE slis_listheader,
        t_line    LIKE st_header-info,
        ld_lines  TYPE i,
        ld_linesc(10TYPE c.

"  Entrando no tipo da estrutura do header (slis_listheader), você verá
" que esta estrutura tem 3 tipos e eu explicarei cada um deles abaixo.

"  Titulo ( H )
" Vai ser a linha que mais chama a atenção dentro do Cabeçalho, pois será
" maior e em negrito.
  st_header-typ  = 'H'.
  st_header-info = 'Titulo do ALV'.
  APPEND st_header TO it_header.
  CLEAR st_header.

" Informações ( S )
"  Como se fosse o texto para comentários, descrição de algo, somente no
" tipo 'S' o campo 'KEY' faz algo, ele serve como inicio da sua frase e fica
" em negrito se diferenciando do resto da linha.
  st_header-typ  = 'S'.
  st_header-key = 'Usuáio: '.
  st_header-info = sy-uname." User name
  APPEND st_header TO it_header.
  CLEAR: st_header.


* Total de linhas
  DESCRIBE TABLE it_mara LINES ld_lines.
  ld_linesc = ld_lines.
  CONCATENATE 'Total de linhas : ' ld_linesc
     INTO t_line SEPARATED BY space.


" Ação ( A )
"  Como se fosse informações extras, tem o tamanho menor que os outros e
" está em itálico, veja que o campo 'KEY' foi informado mas no final não
" servir´pa para nada pois não é do tipo  ( S ).

  st_header-typ  = 'A'.
  st_header-key  = 'Teste'.
  st_header-info = t_line.
  APPEND st_header TO it_header.
  CLEAR: st_header, t_line.

  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
    EXPORTING
      it_list_commentary       = it_header
*     I_LOGO                   =
*     I_END_OF_LIST_GRID       =
*     i_alv_form               = 'X'
            .

"  Ai está a função que vai junta tudo isso e mostra no inicio da página,
" podemos até adicionar uma imagem que esteja no banco SAP ( OAER ), Mas
" isso é assunto para um próximo Post,
" Qualquer dúvida estamos aih.

ENDFORM.                    "TOP-OF-PAGE

sexta-feira, 18 de novembro de 2011

Transação de transações

SEARCH_SAP_MENU

Transação que mostra transações ligados ao dado informado no parametro de entrada.

quinta-feira, 17 de novembro de 2011

' Loop where ' ou ' Do Read table '

  REPORT zloopwowhere.

" Declaração das tabelas internas
DATA : it_ekko TYPE TABLE OF ekko,
       it_ekpo TYPE TABLE OF ekpo
      .

" Declaração das estruturas
DATA : st_ekko TYPE ekko,
       st_ekpo TYPE ekpo
      .

" Seleciona Cabeçalho do documento de compra
SELECT *
  FROM ekko
  INTO TABLE it_ekko
  UP TO 20 ROWS.

"  Toda vez que for usar o 'for all entries' a tabela tem que ser ordenada
" e sem duplicidade do campo que faz a ligação entre as tabela pela cláusula
" 'where' do select. Eu não fiz isso na it_ekko porque ela soh tem uma chave
" portanto não teria duplicidade e tb por ter somente uma chave ela ja
" vem ordenada direitinho, mas vou aproveitar e mostrar como fazer caso o
" campo 'EBELN' não fosse chave completa da tabela.....

  DELETE ADJACENT DUPLICATES FROM it_ekko COMPARING ebeln.
  SORT : it_ekko by ebeln .

"  observe que NESTE CASO não mudou nada rsrsrs


" Seleciona Item do documento de compras
SELECT *
  FROM ekpo
  INTO TABLE it_ekpo
  FOR ALL ENTRIES IN it_ekko
  WHERE ebeln = it_ekko-ebeln.

"  Quando você dá um 'Sort' numa tabela sem especificar por qual campo,
" o programa adota as chaves da tabela como critério de ordenação.
SORT : it_ekpo.



*&-Loop com loop(where)------------------------------------------Errado*
"  Loop no cabeçalho
LOOP AT it_ekko INTO st_ekko.

" Loop nos itens que tenham o ebeln iguais.
  LOOP AT it_ekpo INTO st_ekpo
    WHERE ebeln = st_ekko-ebeln.

*    Procedimento

  ENDLOOP.

ENDLOOP.
*&Porque está errado ?-------------------------------------------------*
*  Quando você executa um 'Loop' com 'Where' ele irá passar por todos os
* registros da tabela verificando a condição, se a tabela for grande, isso
* com certeza irá demorar muito...



*&-loop com read e Do---------------------------------------------Certo*
" Criação de uma variável local para receber o indice do registro na tabela
data : vl_tabix TYPE sy-tabix.

"  Loop no cabeçalho
LOOP AT it_ekko INTO st_ekko.

"  Read table com a chave para identificar o index do primeiro registro
" na condição desejada.
READ TABLE it_ekpo INTO st_ekpo
  WITH KEY ebeln = st_ekko-ebeln
" Só use 'Binary Search' em uma tabela Ordenada.
    BINARY SEARCH.

IF sy-subrc = 0.

" Variavel armazena valor do index.
  vl_tabix = sy-tabix.

"  Faça a leitura do registro pelo index informado.
DO.
  READ TABLE it_ekpo INTO st_ekpo
    INDEX vl_tabix.

"  Caso o registro trazido pelo 'Read table' esteja fora do desejado será
" executado o commando 'Exit' que força a saída do commando 'Do'.
  IF st_ekko-ebeln <> st_ekpo-ebeln
    or sy-subrc <> 0.
    exit.
  ENDIF.

*  Procedimento

" Adiciona +1 para o index para que seja feito o read do proximo registro.
  add 1 to vl_tabix.

ENDDO.

ENDIF.

ENDLOOP.
*&Porque está certo ?--------------------------------------------------*
*  O primeiro 'Read table' Identifica que existe arquivo e aponta para o
* primeiro registro com a condição desejada, o comando 'do' serve como laço
* para que seja lido todos os itens da condição, estando fora disso ele
* sai do processo e termina, portando lendo somente os arquivos necessarios
* sem precisar passar por toda tabela.