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

Conteúdo

ALV com Layout informado na tela de parâmetros

Basicamente você escolhe o layout do relatório já na tela de parâmetros.

Para isto é necessário que antes você tenha gravado um layout, claro!


REPORT ZSAPeiros.
* Global Declarations
DATA:
  gs_key      TYPE salv_s_layout_key,
  gs_layouts  TYPE salv_s_layout_info,
  gs_layout   TYPE lvc_s_layo,
  gt_saida    TYPE TABLE OF mara,
  gt_fieldcat TYPE lvc_t_fcat,
  gs_variant  TYPE disvariant.

* Parameters
PARAMETERS p_layout TYPE slis_vari.

* Action for Layout parameter field
AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_layout.
  gs_key-report = sy-repid.
  gs_layouts    = cl_salv_layout_service=>f4_layouts( s_key = gs_key
                                                      restrict = '1' ).
  p_layout      = gs_layouts-layout.

START-OF-SELECTION.
* Populate Data Report
  SELECT * UP TO 10 ROWS FROM mara INTO TABLE gt_saida.

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

* Layout
  gs_layout-col_opt    = abap_true.
  gs_layout-zebra      = abap_true.

* Layout Variant
  gs_variant-report    = sy-repid.
  gs_variant-variant   = p_layout.

* Get fields from structure/table
  CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
    EXPORTING
      i_structure_name       = 'MARA'
      i_client_never_display = abap_true
    CHANGING
      ct_fieldcat            = gt_fieldcat
    EXCEPTIONS
      inconsistent_interface = 1
      program_error          = 2
      OTHERS                 = 3.

* Display ALV Report Data
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program = sy-repid
      is_layout_lvc      = gs_layout
      it_fieldcat_lvc    = gt_fieldcat
      i_save             = abap_true
      is_variant         = gs_variant
    TABLES
      t_outtab           = gt_saida[]
    EXCEPTIONS
      program_error      = 1
      OTHERS             = 2.

  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.

Batch Input SHDB Exemplo

O usuário está de saco cheio de executar um processo padrão? Ou então você não está muito afim de procurar uma BAPI mas quer seguir as regras da transação, ou então precisa fazer uma carga, ou quer adiantar umas telas, olha, da pra fazer muito com Batch Input.

Batch Input é basicamente uma macro, onde você da os comandos para o SAP executar. O bom que ele pega todas as regras e validações standard, mas as vezes, um popup ou manejo diversificado entre telas pode quebrar suas pernas.

Começa executando a transação SHDB para mapear os campos e ações.

Não sabe executar um SHDB? Ummm... Já pensou em ser uber?

Abaixo exemplo simples chamando a transação IA06, que vai preencher a primeira tela e dar Enter.

REPORT SAPeiros.

DATA:
  gv_mode(1)        TYPE c VALUE 'N',
  gv_datum_char(10) TYPE c,
  gt_bdc_tab        TYPE TABLE OF bdcdata,
  gt_bdc_msg        TYPE TABLE OF bdcmsgcoll,
  gt_return         TYPE TABLE OF bapiret2.

CLEAR:
  gv_mode,
  gv_datum_char,
  gt_bdc_tab[],
  gt_bdc_msg[],
  gt_return[].

gv_datum_char = sy-datum+6(2) && '.' && sy-datum+4(2) && '.' && sy-datum+0(4).

PERFORM zf_dynpro USING:
'X' 'SAPLCPDI'              '3001',
' ' 'BDC_CURSOR'            'RC271-PROFIDNETZ',
' ' 'BDC_OKCODE'            '/00',
' ' 'RC271-PLNNR'           'TESTE_01',
' ' 'RC271-PROFIDNETZ'      'AR01',
' ' 'RC271-STTAG'           gv_datum_char.

CALL TRANSACTION 'IA06' USING gt_bdc_tab MODE gv_mode UPDATE 'S' MESSAGES INTO gt_bdc_msg.

LOOP AT gt_bdc_msg INTO DATA(ls_bdc_msg) WHERE msgtyp EQ 'E' OR msgtyp EQ 'A'.
  EXIT.
ENDLOOP.

IF sy-subrc IS NOT INITIAL.

  COMMIT WORK AND WAIT.

ELSE.

  APPEND INITIAL LINE TO gt_return ASSIGNING FIELD-SYMBOL(<fs_return>).
  <fs_return>-id         = ls_bdc_msg-msgid.
  <fs_return>-number     = ls_bdc_msg-msgnr.
  <fs_return>-message_v1 = ls_bdc_msg-msgv1.
  <fs_return>-message_v2 = ls_bdc_msg-msgv2.
  <fs_return>-message_v3 = ls_bdc_msg-msgv3.
  <fs_return>-message_v4 = ls_bdc_msg-msgv4.

ENDIF.

*---------------------------------------------------------------------
* BDC Table
*---------------------------------------------------------------------
FORM zf_dynpro USING dynbegin name value.
  APPEND INITIAL LINE TO gt_bdc_tab ASSIGNING FIELD-SYMBOL(<fs_bdc_tab>).
  IF dynbegin EQ abap_true.
    MOVE: name      TO <fs_bdc_tab>-program,
          value     TO <fs_bdc_tab>-dynpro,
          abap_true TO <fs_bdc_tab>-dynbegin.
  ELSE.
    MOVE: name      TO <fs_bdc_tab>-fnam,
          value     TO <fs_bdc_tab>-fval.
  ENDIF.
ENDFORM. 

Popup no estilo Standard com dados da tabela BAPIRET2

Montar um ALV só pra mostrar o os erros que retornaram na tabela BAPIRET?

Ou pensar em algo mirabolante num popup todo incrementado?

Para! É só usar UMA linha de código para ter este resultado:


REPORT SAPeiros.

DATA lt_return TYPE bapiret2_tab.

APPEND INITIAL LINE TO lt_return ASSIGNING FIELD-SYMBOL(<fs_return>).
<fs_return>-type   = 'E'.
<fs_return>-id     = '00'.
<fs_return>-number = 2.

APPEND INITIAL LINE TO lt_return ASSIGNING <fs_return>.
<fs_return>-type   = 'E'.
<fs_return>-id     = '00'.
<fs_return>-number = 4.

APPEND INITIAL LINE TO lt_return ASSIGNING <fs_return>.
<fs_return>-type       = 'E'.
<fs_return>-id         = '00'.
<fs_return>-number     = 60.
<fs_return>-message_v1 = 'MARA'.
<fs_return>-message_v2 = '1000'.
<fs_return>-message_v3 = '9999'.

cl_rmsl_message=>display( lt_return ).

Caminho Lógico / Logical Path

Antes de dar seu OPEN DATASET, é interessante, inclusive por questões de segurança, que você utilize um Caminho Lógico.

Para criar, acesse a transação FILE.

Clique 1 vez em Logical File Path Definition, e crie uma nova entrada:


Agora marque o item que acaba de criar, e duplo clique em Assignment of Physycal Paths to Logical Path, então crie uma nova entrada:


<SYSID> no caso é seu ambiente, então seja DEV, QAS ou PRD, ele vai entender. Lembre-se de  pedir para BASIS configurar este caminho nos 3 ambientes, afim de serem visualizados pela AL11 no caso.

Feito isso, agora é só utilizar o seguinte código:

REPORT ZSAPeiros.

* Local Declarations
DATA:
  lv_logical_filename TYPE filename-fileintern VALUE 'ZSAPEIROS',
  lv_filename         TYPE rlgrap-filename     VALUE 'ARQUIVO.TXT',
  lv_file             TYPE string,
  lt_file             TYPE TABLE OF char255.

* Physical File Name Using a Logical File Name
CLEAR lv_file.

CALL FUNCTION 'FILE_GET_NAME'
  EXPORTING
    logical_filename = lv_logical_filename
    parameter_1      = lv_filename
    including_dir    = 'X'
  IMPORTING
    file_name        = lv_file
  EXCEPTIONS
    file_not_found   = 1
    OTHERS           = 2.

IF sy-subrc IS NOT INITIAL.
  RETURN.
ENDIF.

* Physical File Name Based on a Logical Lile Name
CALL FUNCTION 'FILE_VALIDATE_NAME'
  EXPORTING
    logical_filename           = lv_logical_filename
    parameter_1                = lv_filename
  CHANGING
    physical_filename          = lv_file
  EXCEPTIONS
    logical_filename_not_found = 1
    validation_failed          = 2
    OTHERS                     = 3.

IF sy-subrc IS NOT INITIAL.
  RETURN.
ENDIF.

* File content
CLEAR lt_file[].

APPEND INITIAL LINE TO lt_file ASSIGNING FIELD-SYMBOL(<fs_file>).
<fs_file> = 'Linha 1'.

APPEND INITIAL LINE TO lt_file ASSIGNING <fs_file>.
<fs_file> = 'Linha 2'.

* Generate file in server
OPEN DATASET lv_file FOR OUTPUT IN TEXT MODE ENCODING DEFAULT.

IF sy-subrc IS INITIAL.

  LOOP AT lt_file INTO DATA(ls_file).
    TRANSFER ls_file TO lv_file.
  ENDLOOP.

  CLOSE DATASET lv_file.

ENDIF.

Abrir arquivo PDF em tela em vez de salvar

Antes da aplicação da nota 2525392, paa abrir um arquivo PDF por exemplo, bastava chamar a função CALL_BROWSER, porém agora não mais.

Segue um exemplo de como manter a chamada, pois pode vir por variável, e ainda sim fazer funcionar caso falhe na chamada da CALL_BROWSER:

REPORT SAPeiros.

DATA:
  lv_url  TYPE char255 VALUE 'C:\TEMP\Arquivo.PDF',
  lv_file TYPE string.

CALL FUNCTION 'CALL_BROWSER'
  EXPORTING
    url                    = lv_url
  EXCEPTIONS
    frontend_not_supported = 1
    frontend_error         = 2
    prog_not_found         = 3
    no_batch               = 4
    unspecified_error      = 5
    OTHERS                 = 6.
 
IF sy-subrc IS NOT INITIAL.
 
  lv_file = lv_url.
 
  CALL METHOD cl_gui_frontend_services=>execute
    EXPORTING
      document = lv_file
    EXCEPTIONS
      OTHERS   = 1.
 
ENDIF.

openSAP Sumiu 😲 Caaaaalma, só migraram

Desde julho de 2024 a plataforma openSAP foi descontinuada.

Os cursos gratuitos continuarão disponíveis no site de aprendizado.

Alguns dos cursos que estavam na openSAP foram migrados para plataforma.

Mais detalhes sobre a migração aqui:
https://learning.sap.com/opensap-course-migration

Cursos aqui:
https://learning.sap.com/courses

Certificados:
Meu amigo, ainda não sei, mas até o momento não consegui encontrá-los.
Então quem souber como recuperar os certificados anteriormente realizados na open.SAP me avise para atualizar o blog e ajudar aos demais.

Que tal uma tela de parâmetros diferentona?

Não tive muitas idéias de ícones ou utilidade disso na tela de parâmetros, mas aposto que você terá!


REPORT ZSAPeiros.

DATA l_field TYPE string.
FIELD-SYMBOLS <fs_tab> TYPE ANY.

SELECTION-SCREEN BEGIN OF TABBED BLOCK t1 FOR 10 LINES.
SELECTION-SCREEN TAB (50) tab1 USER-COMMAND tab1 DEFAULT SCREEN 101.
SELECTION-SCREEN TAB (50) tab2 USER-COMMAND tab2 DEFAULT SCREEN 102.
SELECTION-SCREEN TAB (50) tab3 USER-COMMAND tab3 DEFAULT SCREEN 103.
SELECTION-SCREEN END OF BLOCK t1.

SELECTION-SCREEN BEGIN OF SCREEN 101 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK 1 WITH FRAME TITLE text-t01.
PARAMETERS p_bukrs TYPE bukrs.
SELECTION-SCREEN END OF BLOCK 1.
SELECTION-SCREEN END OF SCREEN 101.

SELECTION-SCREEN BEGIN OF SCREEN 102 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK 2 WITH FRAME TITLE text-t02.
PARAMETERS p_werks TYPE werks_d.
SELECTION-SCREEN END OF BLOCK 2.
SELECTION-SCREEN END OF SCREEN 102.

SELECTION-SCREEN BEGIN OF SCREEN 103 AS SUBSCREEN.
SELECTION-SCREEN BEGIN OF BLOCK 3 WITH FRAME TITLE text-t03.
PARAMETERS p_kunnr TYPE kunnr.
SELECTION-SCREEN END OF BLOCK 3.
SELECTION-SCREEN END OF SCREEN 103.

INITIALIZATION.
  l_field = '(ZSAPEIROS)TAB1'.
  ASSIGN (l_field) TO <fs_tab>.
  CONCATENATE '@0Y@' 'Novo' INTO <fs_tab> RESPECTING BLANKS.

  l_field = '(ZSAPEIROS)TAB2'.
  ASSIGN (l_field) TO <fs_tab>.
  CONCATENATE '@0Z@' 'Alterar' INTO <fs_tab> RESPECTING BLANKS.

  l_field = '(ZSAPEIROS)TAB3'.
  ASSIGN (l_field) TO <fs_tab>.
  CONCATENATE '@0W@' 'Excluir' INTO <fs_tab> RESPECTING BLANKS.

Mudar de idioma sem precisar sair ou logar novamente

Precisa testar aquela tradução que está fazendo mas está com preguiça de sair e logar novamente?

Digite ZEN para mudar para o idioma Inglês, ou ZES para Espanhol, ZPT para Português, etc.

Crie as transações ZEN, ZPT, ZES direcionando para o mesmo programa.

REPORT ZSAPeiros.

CASE sy-tcode.

  WHEN 'ZEN'.
    SET LOCALE LANGUAGE 'E'.

  WHEN 'ZPT'.
    SET LOCALE LANGUAGE 'P'.
  
  WHEN 'ZES'.
    SET LOCALE LANGUAGE 'S'.
  
  WHEN OTHERS.
    RETURN.

ENDCASE.
 
CALL FUNCTION 'ABAP4_CALL_TRANSACTION' STARTING NEW TASK 'LANGUAGE'
  EXPORTING
    tcode = 'SESSION_MANAGER'.

Campo obrigatório de mentirinha - Screen-Required

Precisa que um parâmetro de tela apareça o simbolo de obrigatório, mas que não seja obrigatório?

Isso não é tão estranho... é?



REPORT ZSAPeiros.

PARAMETERS p_werks TYPE t001w-werks. "CADÊ O OBLIGATORY?

AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    FIND 'P_WERKS' IN screen-name.
    IF sy-subrc IS INITIAL.
      screen-required = '2'.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.
Pra validar valor ou obrigatório ( estranho já que não queria como obrigatório ), pode usar assim:

AT SELECTION-SCREEN.
  IF p_werks IS INITIAL.
    MESSAGE e032(ms) WITH 'Centro'.
  ENDIF.

Exibir opção de Gravar Layout em seu AlvOO

DATA wa_variant TYPE disvariant.

wa_variant-report = sy-repid. "Sim, só por causa disso!

CALL METHOD go_grid_0100->set_table_for_first_display
  EXPORTING
    i_save     = 'A' "E disso
    is_layout  = wa_layout
    is_variant = wa_variant
...
/* POPUP INI */ /* POPUP FIM */