/* POPUP INI */
/* POPUP FIM */

Conteúdo

SM30 - Incluir botão para importar arquivo CSV ou TXT - Horácio Mode

Certa vez um "Amigo" funcional me pediu pra colocar um botão na SM30 pra eu importar um excel e já visualizar/atualizar na SM30.

Chamei ele de preguiçoso, mas não teve como, tive que ajudar o Horácio (braço-curto).

Vai que vc tb tem um amigo Horácio, então isso pode ajudá-lo.

Vou utilizar como exemplo nossa tabela ZSAPEIROS:


Criar visão de atualização para mesma. Grupo de funções ZGFSAPEIROS foi criado:


Buscar o nome do Programa de nosso Grupo de funções. Para isto, ir na SE80 com o grupo de funções criado, e clicar em Programa básico:


Copiar a Interface de usuário do programa SAPLSVIM para nosso grupo de funções:



Veja como ficou agora o Grupo de funções. Veja que vários objetos foram adicionados:


Associar à interface criada, ou seja, iremos mudar a rotina standard pela individual:




No Status GUI EALX, crie o campo que dará ação no Importar o arquivo:



Após ativar todos os objetos do grupo, veja na SM30 que o botão já existe:


Agora é hora de dar ação no botão. Para isto crie o module ZIMPFILE dentro do PAI:




Duplo clique no módule, e basta copiar e colar o código abaixo:

*----------------------------------------------------------------------*
***INCLUDE LZGFSAPEIROSI01 .
*----------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Module  ZIMPFILE  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
MODULE zimpfile INPUT.
  DATA:
    lv_subrc      TYPE          sy-subrc,
    lv_tabix      TYPE          sy-tabix,
    lt_filetable  TYPE          filetable,
    wa_filetable  TYPE          file_table,
    lv_filename   TYPE          string,
    lt_zsapeiros  TYPE TABLE OF zsapeiros,
    wa_zsapeiros  TYPE          zsapeiros,
    lt_data_tab   TYPE          table_of_strings,
    wa_data_tab   TYPE          string.

  IF function EQ 'IMPFILE'.

* Popup para escolher o arquivo à ser importado
    CALL METHOD cl_gui_frontend_services=>file_open_dialog
      EXPORTING
        file_filter             = '(*.csv)|*.csv|(*.txt)|*.txt|'
      CHANGING
        file_table              = lt_filetable
        rc                      = lv_subrc
      EXCEPTIONS
        file_open_dialog_failed = 1
        cntl_error              = 2
        error_no_gui            = 3
        not_supported_by_gui    = 4
        OTHERS                  = 5.

    IF sy-subrc IS INITIAL.

* Importar o arquivo
      READ TABLE lt_filetable
            INTO wa_filetable
                 INDEX 1.

      IF sy-subrc IS INITIAL.

        lv_filename = wa_filetable-filename.

        CALL METHOD cl_gui_frontend_services=>gui_upload
          EXPORTING
            filename                = lv_filename
            has_field_separator     = ';'
          CHANGING
            data_tab                = lt_data_tab
          EXCEPTIONS
            file_open_error         = 1
            file_read_error         = 2
            no_batch                = 3
            gui_refuse_filetransfer = 4
            invalid_type            = 5
            no_authority            = 6
            unknown_error           = 7
            bad_data_format         = 8
            header_not_allowed      = 9
            separator_not_allowed   = 10
            header_too_long         = 11
            unknown_dp_error        = 12
            access_denied           = 13
            dp_out_of_memory        = 14
            disk_full               = 15
            dp_timeout              = 16
            not_supported_by_gui    = 17
            error_no_gui            = 18
            OTHERS                  = 19.

        IF sy-subrc IS NOT INITIAL.
          MESSAGE ID sy-msgid
                TYPE sy-msgty
              NUMBER sy-msgno
                WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        ENDIF.

* Passar valores importados para estrutura
        LOOP AT lt_data_tab INTO wa_data_tab.

* Quebra linha importada nos campos da estrutura
          SPLIT wa_data_tab
             AT ';'
           INTO wa_zsapeiros-matnr
                wa_zsapeiros-maktx.

* Converte o campo material
          CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
            EXPORTING
              input  = wa_zsapeiros-matnr
            IMPORTING
              output = wa_zsapeiros-matnr.

* Move os dados da estrutura pra view
          '' = wa_zsapeiros.
          PERFORM move_extract_to_view_wa.
          lv_subrc = 8.
          lv_tabix = lv_tabix + 1.
          nextline = nextline + 1.
          PERFORM check_key.
          PERFORM nicht_vorhanden USING lv_subrc lv_tabix.

        ENDLOOP.

      ENDIF.

    ENDIF.

  ENDIF.
ENDMODULE.                 " ZIMPFILE  INPUT

Agradecimentos ao "Amigo" Kazitoris

Copiar/Transportar conteúdo de tabelas entre mandantes

Sem muita explicação, vamos copiar alguns dados da tabela MARA, do ambiente DEV para QAS.

Para isto, precisaremos criar uma request de Workbench:




Feito isto, dê duplo clique na request e inclua, conforme imagem: R3TR TABU MARA, pressione <ENTER>:


Clique na chave amarela ao lado da imagem acima. E aparecerá as condições de seleção:


Dê duplo clique na linha amarela, para utilizar parâmetros de seleção. Neste caso vamos copiar apenas o material 200000390:


Caso queira copiar TODO o conteúdo, deixe * no material:



Após isto, clique no ícone de tabela, para entrar com a condição que preferir. Neste caso iremos copiar os dados de acordo com a condição (parâmetros) informados anteriormente (com material):


Clique em ok para visualizar os dados:


Clique em gravar e pronto!

Sua request tem conteúdo de tabela:


Agradecimentos Melari/Denis.

Tabela interna dentro de tabela interna


Nada mais é que uma tabela interna onde além de campos convencionais, tem outra tabela interna.

REPORT ZSAPeiros.

* A idéia é selecionar a VBAP, e retornar em UMA ÚNICA LINHA da tabela interna T_DADOS,
* o documento VBELN e TODOS os materiais com descrição do documento selecionado

* Definição da tabela com material e descrição
TYPES:
  BEGIN OF ty_matnrs,
    matnr               TYPE          mara-matnr, "Material
    maktx               TYPE          makt-maktx, "Descrição
    END OF ty_matnrs.

* Definição da tabela com documento e tabela de materiais
DATA: BEGIN OF t_dados OCCURS 0.
DATA:   vbeln           TYPE          vbap-vbeln. "Documento
DATA:   matnrs          TYPE TABLE OF ty_matnrs.  "Tabela de materiais
DATA: END OF t_dados.

* Declaração de tabelas internas diversas
DATA:
  t_matnrs              TYPE TABLE OF ty_matnrs,  "Tabela de materiais
  w_matnrs              TYPE          ty_matnrs,  "Tabela de materiais
  t_makt                TYPE TABLE OF makt,       "Material/Descrição
  w_makt                TYPE          makt,       "Material/Descrição
  t_vbap                TYPE TABLE OF vbap,       "Tabela VBAP
  w_vbap                TYPE          vbap.       "Estrutura VBAP

* Parâmetros
PARAMETERS p_vbeln TYPE vbap-vbeln.


* Seleção dos dados
START-OF-SELECTION.

  SELECT *
    FROM vbap
    INTO TABLE t_vbap
   WHERE vbeln EQ p_vbeln.

  IF sy-subrc IS INITIAL.

    SELECT *
      FROM makt
      INTO TABLE t_makt
       FOR ALL ENTRIES IN t_vbap
     WHERE matnr EQ t_vbap-matnr
       AND spras EQ sy-langu.

    IF sy-subrc IS INITIAL.
      SORT t_makt BY matnr.
    ENDIF.

    LOOP AT t_vbap INTO w_vbap.

* Monta tabela com campos matnr e maktx
      READ TABLE t_makt
            INTO w_makt
        WITH KEY matnr = w_vbap-matnr
                 BINARY SEARCH.

      IF sy-subrc IS INITIAL.
        w_matnrs-matnr = w_vbap-matnr.
        w_matnrs-maktx = w_makt-maktx.
        APPEND w_matnrs TO t_matnrs.
      ENDIF.

    ENDLOOP.

* Popula tabela T_DADOS com documento VBELN e TABELA de materiais
    t_dados-vbeln    = p_vbeln.
    t_dados-matnrs[] = t_matnrs[].
    APPEND t_dados.

  ENDIF.

  BREAK-POINT.

Alterar valores de um domínio


NÃO É ESSE DOMÍNIO QUE ESTAMOS FALANDO SEU ANIMAL!!! KKKKK

Caramba!!! Que Ogro!!!

Bom, a primeira pergunta é... Porquê e quando vou utilizar isto? Vcs devem me achar louco né? Acertaram! Eu sou =)

Mas pensa comigo... Você tem um relatório ou uma SM30, e tem um campo que precisa de matchcode, MAS os valores deste campo são variáveis.

Pensou já? Qual seria sua solução?

TEEEEEEMPO......
...
...
...

Ok vai, vou te ajudar...

Primeiro, sua tabela precisa ter um campo que referencie um elemento de dados com domínio. Pelamor de Deus, ELEMENTO E DOMÍNIO Z. Nada de sair alterando standard heim Zé!

Ok... Vamos chamar a tabela de ZSAPEIROS e o domínio de ZDSAPEIROS neste exemplo.

REPORT ZSAPeiros.

* Declaração de tabelas e estruturas
DATA:
  w_dd01v TYPE          dd01v, "Cabeçalho do domínio
  t_dd07v TYPE TABLE OF dd07v, "ïtens do domínio
  w_dd07v TYPE          dd07v. "ïtens do domínio

* Elimina dados do elemento
CALL FUNCTION 'DD_DOMA_DEL'
  EXPORTING
    domname   = 'ZDSAPEIROS'
    del_state = 'M'
    prid      = 0.

* Popula o cabeçalho do domínio
w_dd01v-domname        = 'ZDSAPEIROS'.
w_dd01v-ddlanguage     = sy-langu.
w_dd01v-datatype       = 'CHAR'.
w_dd01v-leng           = '10'.
w_dd01v-valexi         = 'X'.
w_dd01v-ddtext         = 'SAPeiros'.
w_dd01v-as4user        = sy-uname.

* Popula os ítens do domínio
DO 10 TIMES.

  w_dd07v-domname     = 'ZDSAPEIROS'.
  w_dd07v-valpos      = sy-index.
  w_dd07v-ddlanguage  = 'PT'.
  w_dd07v-domvalue_l  = sy-index.
  CONDENSE w_dd07v-domvalue_l NO-GAPS.
  CONCATENATE 'Sapeiros' w_dd07v-domvalue_l
         INTO w_dd07v-ddtext SEPARATED BY space.

  APPEND w_dd07v TO t_dd07v.
  CLEAR w_dd07v.

ENDDO.

* Atualiza o domínio
CALL FUNCTION 'DD_DOMA_PUT'
  EXPORTING
    dd01v_wa            = w_dd01v
    domain_name         = 'ZDSAPEIROS'
    prid                = '0'
    ctrl_doma_put       = 'N'
  TABLES
    dd07v_tab           = t_dd07v
  EXCEPTIONS
    illegal_value       = 1
    op_failure          = 2
    object_inconsistent = 3
    OTHERS              = 4.

IF sy-subrc IS INITIAL.

* Se atualizou, ativa o domínio
  CALL FUNCTION 'DD_DOMA_ACTIVATE'
    EXPORTING
      doma_name = 'ZDSAPEIROS'
      auth_chk  = ''
      prid      = 0.

ELSE.

* Se não atualizou, elimina os dados do domínio
  CALL FUNCTION 'DD_DOMA_DEL'
    EXPORTING
      domname   = 'ZDSAPEIROS'
      del_state = 'M'
      prid      = 0.

ENDIF.

Iae? Vai lá no seu relatório ou até mesmo na tabela e da uma olhadinha no campo.

Marretando tabelas - SE16 / SE16N

NÃO, você não precisa do martelo do Thor para marretar tabelas.

Marretar tabelas nada mais é do que alterar, criar ou eliminar dados de uma tabela na mão, ou seja, dar /H e sair fazendo

Então, bóra aprender, ou relembrar, a marretar:

- MODO 1) OLD SCHOOL - SE16:
- Acesse a transação SE16;
- Coloque os parâmetros e mande visualizar os dados;
- Selecione os dados que deseja alterar, pode ser mais que um;
- Dê 2 cliques em qualquer uma das linhas onde você vai alterar;
- Agora vem a perte boa, dê um /H e Enter;
- Altere o valor do CODE para EDIT, e então poderá alterar os dados da tabela que não são chave da mesma.
- Os demais codes não preciso nem falar nada né, (não sabe inglês básico, sai do SAP por favor). Bom, tem um Code interessante que é o ANVO, ele duplica a linha selecionada.

Mas pesquise bem, pois existem maneiras corretas de alterar dados de tabelas, como por exemplo a tabela KONV, onde existe a função KONV_UPDATE, que faz a alteração de maneira correta dos dados da mesma.

- MODO 2) 4 BABYES - SE16N:
- Acesse a transação SE16N;
- Coloque os parâmetros e mande visualizar os dados;
- Na linha de comando, digite: &SAP_EDIT;
- Pronto, sua SE16N virou um lindo relatório ALV editável.

Muito cuidado!!! Isto pode levar à sua demissão por justa causa se realizar este tipo de operação em ambiente produtivo ou que não seja de testes.

Como selecionar os dados de uma Visão ( View )

Uma View nada mais é que uma visão do banco de dados, podendo conter diversos campos, interligados ou não à outras tabelas. E para selecionar os dados, desta view, nada mais simples que utilizar uma função, em vez de select.

*Recomendado apenas quando não existem muitos registros, caso contrário utilizar o select normalmente.

*Lembrando que também só é possível selecionar quando não possuir restrição.
REPORT ZSAPeiros.

DATA: 
  gt_j_1b_errov TYPE TABLE OF j_1b_errov INITIAL SIZE 0.     "Tab.Cód.erro

CALL FUNCTION 'VIEW_GET_DATA'
  EXPORTING
    view_name = 'J_1B_ERROV'
  TABLES
    data      = gt_j_1b_errov.
/* POPUP INI */ /* POPUP FIM */