GPS
ABAP
DO
ANALISTA
FUNCIONAL
ByWagner Jefferson Binoto 06/2013
Indice
De funcional para funcional...4
OBJETIVO... 5
OVERVIEW... 5
DECLARAÇÕES... 6
Tipos de dados... 6
Quais tipos de dados vou encontrar pelo caminho ?...6
Variáveis... 7
Constantes... 7
Tipo de dados Elementar e Estruturado...8
Tabelas Internas... 8
Work-area... 9
COMANDOS... 10
Comandos lógicos... 10
Comandos mais frequentes...10
Lista de geral de comandos...20
MODULARIZAÇÃO... 24 Includes... 25 Perform e Form... 26 Funções... 27 Métodos... 28 Module Pool... 29 DEBUG... 30 Principais Comandos... 31 Dicas e macetes... 33 Palavras chaves...33
Pular linhas de códigos...33
Chegar mais rápido onde queremos...33
Acessar programas rapidamente...34
Pontos de parada com condição simples...36
Pontos de parada com condição complexa...38
Debugar regras do log da folha...40
BIBLIOGRAFIA E CRÉDITOS...46
De funcional para funcional
Vou chamar este curso de o “GPS ABAP do analista funcional”.
Porque ? Porque como analista funcional sabemos o que queremos mas muitas vezes não conseguimos chegar onde queremos dentro do código Abap por não conhecermos os caminhos. Normalmente um analista funcional precisa saber qual tabela o sistema está considerando para aplicar uma configuração, qual campo está sendo demonstrado no relatório, que conta o sistema está realizando para chegar no valor apresentado e se soubermos os caminhos para se chegar nessas informações, seria muito mais rápido, e não precisariamos depender de um programador Abap para nos ajudar, não que esteja pregando contra um trabalho em equipe, mas muitas vezes precisamos de respostas rápidas e se nós mesmos pudermos dar as respostas entregaríamos com muito mais agilidade nossos projetos e sem contar que as especificações funcionais seriam mais eficazes para o desenvolvedor.
Por falar em agilidade considero muito mais agil o analista funcional conhecer muito bem as regras de negócio e como o SAP trabalha do que ter que sair debugando programas, considerando que essa prática as vezes é mais demorada dependendo da complexidade do código, principalmente se for um código standard. Somente em ultimo caso, quando não estamos conseguindo chegar na informação desejada é que convém fazermos uso dos conhecimentos de ABAP para procurarmos o que queremos.
OBJETIVO
O Objetivo deste curso não é tornar um analista funcional em um programador ABAP, mas apresentar os comandos, funções, estruturas principais de forma que o analista funcional consiga se encontrar dentro de um código ABAP para poder encontrar o que ele deseja.
OVERVIEW
Para sabermos onde queremos chegar precisamos saber onde estamos para traçar o caminho desejado, e o GPS nos mostra isso através de um mapa, no nosso GPS ABAP, isso também é necessário, abaixo temos um mapa dos caminhos possiveis para chegarmos onde precisamos dentro do código ABAP e um resumo do que iremos ver nesse curso.
Este mapa mostra o que veremos no curso, é a estrutura principal, nosso norte. Todo programa basicamente possue a estrutura abaixo, declarações de tipos de dados, comandos, chamada de outros programas por meio de funções, includes ou forms.
Tendo isso em mente, nos ajuda a não nos perdermos dentro dos códigos ABAP, o que é muito comum depois de termos debugado um programa que chamou outro que chamou outro e ja não sabemos onde estamos, se no meio, começo ou fim do código.
DECLARAÇÕES
Tipos de dados
Tipos de dados são endereços de memória onde o sistema “guarda” dados para serem utilizados quando necessário. Normalmente muitas vezes nossas respostas estão nos dados guardados nestes tipos de dados, por isso a necessidade de conhecermos um pouco deste assunto.
Como nós seres mortais nascemos e morremos um tipo de dado também tem idade, ou seja, ele tem o tempo de “nascer” e de “morrer”, tem um tempo de vida util.
E como nós também temos um pai criador (quem nos idealizou) um tipo de dado também tem seu pai, que chamamos de seu criador, que seria o programa que da vida a ele, enquanto seu pai existir o tipo de dado também existe, quando o pai deixa de existir o tipo de dado “morre” junto com ele.
Quais tipos de dados vou encontrar pelo caminho ?
São varios os tipos de dados existentes dentro de um código Abap e normalmente eles se encontram no inicio de um programa, podem existir no “corpo” de um programa também, na verdade não importa muito onde as declarações de tipos de dados estão, o que importa é sabermos identificar uma declaração de tipo de dado, quando ela “nasce”, porque talvez vamos precisar “rastrear” esse tipo de dado que pode fornecer o valor que estamos procurando.
Antes de entrar nos tipos de dados existentes vamos falar um pouco dos comandos que são utilizados para “criar” os tipos de dados, pois com certeza iremos ver muitos deste comandos pelo caminho:
O comando DATA é utilizado para “criar” um tipo de dado, é nesse momento que o tipo de dado “nasce”.
O comando TYPE é utilizado para “criar”, um tipo de dado elementar, que será uma referencia para variaveis, tabelas e estrutura que veremos a seguir. O comando TABLE é utilizado para “criar” uma work-área de uma tabela
interna. Não se assuste com esses nomes vamos ver para que serve mais adiante.
O comando CONSTANTS é utilizado para “criar um tipo de dado que não muda durante o seu tempo de vida util.
Variáveis
As variavies são tipos de dados que podem mudar durante seu tempo de vida util, elas são declaradas com o comando DATA e podem sofrer alterações no meio do caminho.
Dica: As vezes precisamos saber quando uma variavel foi criada, quando recebeu alguma informação e de quem veio a informação, isso muitas vezes nos ajuda a encontrar o nome da tabela que estamos procurando.
Exemplo :
DATA s_nome_funcionario(40) TYPE c. “Variavel com 40 posições DATA i_numero_cpf TYPE i. “Variavel que receberá somente numeros.
DATA s_estado(2) TYPE c VALUE ‘PR’ “Variavel com 2 posições com valor default ‘PR’
Constantes
As constantes são um tipo de dado que nunca vai sofrer alteração durante seu tempo de vida util.
Exemplo:
Tipo de dados Elementar e Estruturado
O tipo de dado Elementar e Estruturado é utilizado para criar um “TIPO” de dado que servirá de referência ou modelo para outro tipo de dado.
Exemplo de tipo de dado Elementar:
TYPES v_valor TYPE p LENGTH 8 DECIMALS 2 “Aqui é criado um modelo chamado v_valor DATA v_salario TYPE v_valor “Aqui é usado a variavel modelo v_valor
Exemplo de tipo de dado Estruturado: TYPES: BEGIN OF ty_mara,
pernr TYPE mara-matnr, matnm TYPE mara-matnm, zeinr TYPE mara-zeinr, END OF ty_mara,
DATA: wa_mara TYPE ty_mara. “Aqui está sendo criado uma work-area com a mesma estrutura da tabela interna ty_mara.
Tabelas Internas
Tabela interna é um tipo de dado estruturado que armazena varios campos ou colunas em varias linhas ou registros. Para entender melhor imagine uma bandeja de ovo, cada recipiente de ovo seria um campo e as carreiras de ovos de uma bandeja fosse as linhas de uma tabela interna.
Work-area
Work-area é apenas uma linha de uma tabela interna, a work-area não possui muitas linhas ou registros, é como se da tabela interna retirássemos apenas uma carreira de ovos e utilizassemos ela para fazer o bolo.
Exemplo:
Neste exemplo vemos uma tabela interna e uma work-area sendo declaradas, a tabela interna sendo do tipo da estrutura de dados ty_ferias e a work-area sendo do tipo da tabela interna t_ferias, ou seja, a mesma estrutura da tabela interna.
Mais adiante no tópico Comandos veremos como as tabelas internas e work-areas são utilizadas, assim teremos uma visão melhor da sua aplicação e saberemos entender como elas trabalham, e esse entendimento é muito importante para identificarmos o que estamos procurando.
COMANDOS
Comandos são operações que o sistema ira realizar de acordo com cada instrução recebida.
Durante um debug iremos encontrar muitos comandos pelo caminho, as vezes teremos que entender o que ele faz, as vezes podemos simplesmente ignora-los, por não ter efeito sobre a informação que procuramos. Mas para sabermos quando ignorar o comando ou quando entende-lo precisamos conhece-los mesmo que superficialmente.
Sendo assim irei citar os comandos que encontraremos com mais frequencia durante um debug, e alguns que julgo ser importante o entendimento sobre ele, principalmente comandos que modificam dados.
Comandos lógicos
Nos códigos iremos nos deparar com comandos lógicos de decisão, que na verdade são comparações que estarão depois de comandos como IF, CASE, WHILE, LOOP. Os comandos são:
Operad
or Significado
=, EQ Igual: Compara se um valor é igual ao outro, se for verdadeiro entra na condição <>, NE Diferente: Compara se um valor é diferente do outro, se for verdadeiro entra na condição <, LT Menor que: Compara se um valor é menor que o outro, se for verdadeiro entra na condição. >, GT Maior que: Compara se um valor é maior que o outro, se for verdadeiro entra na condição. <=, LE Menor ou igual: Compara se um valor é menor ou igual o outro, , se for verdadeiro entra na condição. >=, GE Maior ou igual: Compara se um valor é maior ou igual o outro, , se for verdadeiro entra na condição.
Comandos mais frequentes
ADD var1 TO var2Comando usado para adicionar um valor a outro campo numérico. DATA wa TYPE I VALUE 3.
DATA wb TYPE I VALUE 4. ADD wa TO wb.
WRITE wa. “retorna 3 WRITE wb. “retorna 7
APPEND t_tabela
Comando usado para gravar em tabela interna APPEND t_tabela
AT SELECTION-SCREEN
Executa logo após sair da tela de seleção ou depois de teclar ENTER, utilizado para fazer tratamentos de obrigatoriedade de campos e similares.
AT SELECTION-SCREEN.
perform verifica_Periodo.
AUTHORITY-CHECK OBJECT objeto
Usado para verificar a autorizações de objetos AUTHORITY-CHECK OBJECT 'ZZC0307Y' (*)
ID 'actvt' FIELD 'DUMMY'. “Objetos da autorização IF SY-SUBRC NE 0.
MESSAGE E006 WITH TEXT-E01. ENDIF.
(*) comando para verificar autorização de objeto, usar junto com SU21 e SU24
CASE .. WHEN .. ENDCASE.
Comando usado para verificar condições CASE vl_okcode. WHEN 'SIM'. ... WHEN 'NAO'. ... WHEN OTHERS. ...
ENDCASE.
CHECK var
Semelhante ao comando IF. Se a condição for verdadeira continua logo após a verificação, se não aborta a execução.
FORM dados.
LOOP AT t_tabela.
t_tabela-campo = KUNNR.
CHECK t_tabela-campo = '0001'.
“se o conteúdo do campo for igual a '0001', continua executando a “instrução abaixo se for diferente abandona o loop e sai do form. t_tabela-campo = ‘0002’.
APPEND t_tabela. ENDDLOOP.
ENDFORM.
CLEAR var
Limpa o conteúdo de uma variável ou tabela CLEAR var.
CLEAR t_tabela. “limpa o header line
COMMIT WORK
Efetiva as alterações no Banco de dados COMMIT WORK.
CONCATENATE var1 var2 INTO var3
Agrupa varias variáveis em uma única variável. DATA var1 TYPE C(4) VALUE “GPS “.
DATA var2 TYPE C(5) VALUE “ABAP “.
CONCATENATE var1 var2 INTO var3. “ var3 = “GPS ABAP”
CONTINUE
Volta ao inicio de um loop após a verificação de uma condição. FORM dados. DO condição. t_tabela-campo = KUNNR. IF t_tabela-campo = ‘0001’. CONTINUE. ELSE. EXIT. ENDIF. ENDDO. ENDFORM. CONDENSE var
Remove os espaços em branco em um texto
DATA var2 TYPE C(4) VALUE “ ABAP GPS FUNCIONAL “ CONDENSE var2. “ o resultado será “ABAPGPSFUNCIONAL”
DO condição .. ENDDO.
Cria um laço e verifica a condição no inicio do laço
DO var1 < 10. “ a condição é verificado no inicio do laço e se for “ verdadeira continua dentro do loop
.... ENDDO.
END-OF-SELECTION
Evento usado para marcar o fim das seleções de dados. START-OF-SELECTION.
SELECT marc~matnr marc~werks t001w~name1
makt~maktx INTO TABLE t_marc FROM marc INNER JOIN t001w
ON marc~werks = t001w~werks INNER JOIN makt ON marc~matnr = makt~matnr
AND makt~spras = sy-langu WHERE t001w~werks IN S_CENTRO AND marc~matnr IN S_MATERI. END-OF-SELECTION.
EXIT
Comando usado para sair de um laço ou sub-rotina FORM dados. DO condição. t_tabela-campo = KUNNR. IF t_tabela-campo = ‘0001’. CONTINUE. ELSE. EXIT. ENDIF. ENDDO. ENDFORM. IF .. ELSE .. ENDIF. Comando de decisão
IF var = ‘A’. .... ELSE. .... ENDIF. IS INITIAL
Verifica se uma variável ou tabela interna esta vazia IF NOT var IS INITIAL.
.. ENDIF.
LOOP AT t_tabela.
Comando usado para ler uma tabela interna LOOP AT t_tabela.
.. .. ENDDLOOP.
MESSAGE
Comando usado para emitir mensagens
“Podemos encontrar 3 tipos de mensagens : W-> de avisos, E-> de erros, S-> de sucesso MESSAGE W001. “ mensagem com avisos ( warnigs )
MESSAGE E002. “ mensagem com erros. MESSAGE S003. “ mensagem de sucesso. "Podemos encontrar mensagens com parametros.
"Os parâmetros normalmente estarão acompanhados do símbolo & MESSAGE S003 WITH &PA0001-PERNR.
MODIFY t_tabela INDEX i_indice TRANSPORTING campos Comando usado para modificar uma tabela interna MODIFY t_tabela.
MOVE
Move todo o conteúdo de uma tabela para outra. Os campos devem ser os mesmos. LOOP AT t_tabela.
MOVE tabela. INSERT tabela. ENDLOOP.
COMMIT WORK.
MOVE-CORRESPONDING t_tabela TO tabela
Move apenas os campos correspondente entre 2 tabelas LOOP AT t_tabela.
MOVE-CORRESPONDING t_tabela TO tabela. INSERT tabela.
ENDLOOP. COMMIT WORK.
PARAMETERS
Cria parâmetros de seleção para janelas
"Podemos encontrar diversas maneiras de PARAMETERS como os exemplos abaixo PARAMETERS p_werks LIKE T_001W-WERKS.
PARAMETERS p_bot1 RADIOBUTTON GROUP g1. PARAMETERS p_bot2 RADIOBUTTON GROUP g1.
Dica: O que devemos observar nos PARAMETERS são as variaveis, pois serão elas que vamos rastrear durante um debug.
READ TABLE t_tabela WITH KEY campo = valor Usado para ler um registro especifico. SORT t_tabela1 BY campo.
LOOP AT t_tabela1.
"Podemos encontrar o comando BINARY SEARCH serve somente para deixar a pesquisa mais rápida.
READ TABLE t_tabela2 WITH KEY campo = t_tabela1-campo BINARY SEARCH. "após o READ TABLE devemos verificar o resultado
IF SY-SUBRC EQ 0.
.... "verdadeiro ( encontrou o dado ) ELSE.
.... ENDIF.
ENDLOOP.
Dica: Devemos sempre observar o resultado do SY-SUBRC se é igual a ZERO, se for diferente é porque o resultado de uma pesquisa NÃO foi satisfeito.
REFRESH t_tabela.
Limpa o conteúdo de uma tabela. REFRESH t_tabela.
SELECT
Utilizado para recuperar dados de tabelas.
"Podemos encontrar um SELECT simples que retorne os campos de toda tabela SELECT pernr begda endda INTO TABLE t_pa0001 FROM PA0001.
"Podemos encontrar um SELECT SINGLE que sempre vai retornar somente um registro, mesmo que exista mais de um.
SELECT SINGLE * FROM PA0001 WHERE ENDDA = ’31.12.9999’.
"Podemos encontrar SELECT com WHERE, a finalidade do WHERE é filtrar "Neste exemplo está filtrando todos funcionarios ativos
SELECT pernr begda endda INTO TABLE t_pa0001 FROM PA0001
WHERE endda = '31.12.9999'.
"Podemos encontrar o SELECT com o caracter ~ entre o nome da tabela e do campo. Isso sempre vai ocorrer quando existir uma busca em mais de uma tabela ao mesmo tempo
SELECT pa0001~pernr pa0001~begda pa0001~endda pa0002~nome INTO TABLE t_pa0001 FROM PA0001 inner join PA0002
ON pa0001~pernr = pa0002~pernr WHERE pa0001~endda = '31.12.9999'.
SELECTION-OPTIONS
Comando usado para colocar opções de seleção na tela.
SELECTION-SCREEN BEGIN OF BLOCK b_janela WITH FRAME TITLE text-001. SELECT-OPTIONS S_MATERI FOR T_MARC-MATNR.
SELECT-OPTIONS S_CENTRO FOR T_MARC-WERKS. SELECTION-SCREEN END OF BLOCK b_janela.
Dica: O que temos que observer aqui é o nome das variaveis, pois serão elas que vamos rastrear durante o debug.
START-OF-SELECTION
Evento usado para iniciar as seleções do programa ativado pelo F8. START-OF-SELECTION.
SELECT marc~matnr marc~werks t001w~name1
makt~maktx INTO TABLE t_marc FROM marc INNER JOIN t001w
ON marc~werks = t001w~werks INNER JOIN makt ON marc~matnr = makt~matnr
AND makt~spras = sy-langu WHERE t001w~werks IN S_CENTRO AND marc~matnr IN S_MATERI. END-OF-SELECTION.
Dica: Muitas vezes precisamos encontrar o START-OF-SELECTION para colocar um ponto de parada, pois pode existir muitos códigos de validação antes e não importa muito para nós e precisamos ir direto na seleção de dados.
TABLES tabela
Usado para declarar tabelas standards TABLES tabela.
TABLES : tabela1, tabela2, tabela3.
WHILE condição. ENDWHILE.
Cria um loop e verifica a condição no final do loop
WHILE condição. "a condição é verificada no final do laço e se for .... "verdadeira continua dentro do loop
Lista de geral de comandos
Abaixo uma lista geral da maioria dos comandos que encontraremos pelo caminho, como a lista é extensa servirá apenas para consultas futuras, na medida que vamos encontrando comandos desconhecidos, vale a pena verificar nesta tabela o seu significado rápido.
Comando/Função Descrição
ADD Adiciona um valor a um outro campo numérico
APPEND Gravar em tabela interna
APPEND LINES Copia um parte de uma tabela interna
APPEND SORTED BY Usado para classificar tabelas em ordem durante o APPEND
AT END OF Identifica o ultimo registro de uma seqüência
AT EXIT-COMMAND Usado para definir a execução de módulos com botões
AT FIRST Identifica o primeiro registro da tabela percorrida
AT LAST Identifica o ultimo registro da tabela percorrida
AT LINE-SELECTION Evento para abrir uma segunda tela dentro de um relatório
AT NEW Identifica o primeiro registro de uma seqüência
AT SELECTION-SCREEN Analisar o resultado de uma variável
AT USER-COMMAND Evento para inicializar os botões criados
AUTHORITY-CHECK OBJECT Para verificar a autorização de objeto
AS TEXT Usado para classificar caracteres acentuados
ASSING f1 TO <f> Atribuição Dinamica
CALL TRANSACTION Comando usado para chamar transações
CASE .. WHEN .. ENDCASE Comando para tomadas de desição
CHECK Substitui o comando IF
CLEAR Limpar o conteúdo de uma variável
CLOSE DATASET Fecha um arquivo externo
CLOSE_FORM Função usada para fechar um formulário SAPSCRIPT
COLLECT Organiza a tabela com todas as descrições a esquerda totalizando os campos numéricos COMMIT WORK Efetiva as alterações no banco
CONCATENATE Agrupa vários campos em um só
CONSTANTS Criar constantes para serem usadas em todo o programa
CONTINUE Volta ao inicio de um loop após a verificação de uma condição
CONDENSE Remove os espaços em branco em um texto
DATA Criar tabelas internas e variáveis
DELETE Deleta um registro de uma tabela interna
DESCRIBE TABLE Determina o numero de linhas de uma tabela interna
DO .. ENDDO Usado para criar loop
Comando/Função Descrição
END_FORM Função usada para finalizar um formulário SAPSCRIPT
END-OF-PAGE Marca o final de uma cabeçalho
END-OF-SELECTION Evento para marcar o fim das seleções de dados
EXIT Comando usado para sair de um laço ou sub-rotina
FORM Indica o inicio de uma sub-rotina
FORMAT COLOR Usado para formatar a saída do comando WIRTE (cor)
FREE Libera espaço utilizado por uma tabela interna na memória
FUNÇÕES MATEMATICAS Diversas funções matemáticas e operadores
GRAPH_MATRIX_3D Função pra criar gráficos
GUI_DOWNLOAD Função para fazer download de arquivos
HIDE Usado para definir campos para uma segunda janela em relatórios
ID .. FIELD .. Objetos de autorização
IF .. ELSE .. ENDIF. Comando de desição
IF NOT .. IS INITIAL Verifica se uma variável ou head liner esta vazio
INITIALIZATION Evento inicializar as variáveis
INSERT Insere o conteúdo de uma variável em uma tabela transparente
INSERT LINES Inserir linhas dentro de uma tabela interna de uma outra tabela.
LEAVE PROGRAM Comando que sai do programa. Termina a execução
LEAVE TO SCREEN Comando que direciona a ida de uma tela a outra
LINE-COUNT Numero de linhas por pagina
LINE-SIZE Numero de colunas por pagina
LOOP AT Ler o conteúdo de uma tabela
MESSAGE Usado para mostrar mensagens na tela
MESSAGE-ID Usado para definir uma classe de mensagens
MODIFY Modifica o conteúdo de uma tabela interna
MODULE Usado para a criação de módulos de programa
MOVE Move o conteúdo de uma tabela para outra
MOVE-CORRESPONDING Move apenas os campos com o mesmo nome
NEW-PAGE Inicia nova pagina em um relatório
NO STANDARD PAGE HEADING Ignora o cabeçalho STD do SAP
OPEN DATASET Para abrir arquivo externo (Somente para UNIX)
OPEN_FORM Função para abrir um formulário SAPSCRIPT
PARAMETERS Criar parâmetros de seleção
PERFOM Usado para chamar sub-rotinas
POPUP_TO_CONFIRM_WITH_MESSAGE Função para abrir uma janela de dialogo com opções de seleção READ DATASET .. INTO .. Usado para ler e importar de um arquivo externo
READ TABLE Ler uma tabela interna
READ_TEXT Função para ler texto de uma tabela
REFRESH Limpa todo o conteúdo de uma tabela interna
REPLACE Replica um texto dentro de um outro texto
REPORT Inicio de relatório
RESERVE Reserva linhas para quebra de pagina
SAPGUI_PROGRESS_INDICATOR Função para indicar o progresso de uma tarefa
SEARCH Procura um texto dentro de outro texto
SELECT Usado para selecionar dados de uma tabela
SELECTION-OPTIONS Para colocar as opções de seleção
SELECTION-SCREEN Criar um BOX na janela
SET PF-STATUS Comando usado para criar botões
SET TITLEBAR Criar títulos em janelas
SET PARAMETERS Passa parâmetros para chamada de função
SKIP Pular uma linha
SORT Ordenar o conteúdo de uma tabela interna
SPLIT .. AT .. INTO Comando usado para ler arquivo externo e gravar na tabela
STANDARD TOOLBAR Define os valores padrões para os botões do R/3
START_FORM Função para inicializar um formulário SAPSCRIPT
START-OF-SELECTION Evento para marcar o inicio das seleções de dados
STRLEN Volta o tamanho de um texto
SUBCTRACT Subtrai um valor numérico de outro valor
SUM Totaliza um campo numérico
SXPG_CALL_SYSTEM Função que executa comandos externos no servidor
SY-BATCH Indica a execução em Background
SY-DATUM Volta a data do sistema
SY-LANGU Retorna a linguagem do logon
SY-LINNO Linha corrente de um relatório
SY-LISEL Linha escolhida em relatórios interativos
SY-MANDT Volta o valor do mandante
SY-PAGNO Faz a paginação automática ( nr de paginas )
SY-SUBRC Volta o resultado de uma pesquisa
SY-TABIX Linha corrente de uma tabela interna
SY-TVAR0 .. SY-TVAR9 Elementos de textos, para títulos de relatórios
SY-UCOMM Variável do sistema que retorna o nome de um botão ou evento
SY-UNAME Retorna o nome do Usuário
SY-UZEIT Retorna a hora do sistema
SY-VLINE Serve para fazer o fechamento de bordas de um relatório
SY-ULINE Imprime uma linha com n posições
SY-CPROG Nome do programa principal
SY-TCODE Código da transação
SY-DBCNT Contador de interação para SELECT
TABLES Usado para abrir tabelas
Comando/Função Descrição
TRANSFER .. TO .. Usado para ler e gravar em arquivo externo
TRANSLATE Transforma texto minúsculo em maiúsculo
TYPES Define tipos e tabelas interna
ULINE Coloca uma linha continua na tela
UNPACK Coloca zeros a frente de um numero
UPDATE Atualiza uma tabela transparente
VARYING Obtem os componentes de uma string de campo e seguencia.
WHILE .. ENDWHILE Cria laços de execução
WRITE Saída de relatório
WRITE_FORM Função para escrever no formulário SAPSCRIPT
MODULARIZAÇÃO
Você já teve a sensação de estar perdido em uma cidade ? Você acha que está indo pra frente mas de repente percebe que está indo para trás ? Nunca passou por aquela rua, mas tem a sensação de que já passou por ali ?
Isso é o que acontece quando não conhecemos as modularizações dentro do código ABAP e tentamos debugar um sistema e vamos entrando dentro de um programa que chama outro programa que chama outro e já não sabemos onde estamos, se no meio, ou no final, ou quanto falta pra gente chegar onde queremos.
Conhecer a modularização dentro dos códigos ABAP é uma das partes mais importantes para nós funcionais meros mortais, porque por meio dela vamos nos encontrar dentro dos códigos ABAP, não ficaremos “tão” perdidos só “meio” perdido, brindairinha... e quanto mais a gente passar por um “módulo”, mais conhecido ele vai se tornar para nós.
Neste capítulo vamos conhecer quais tipos de modularização vamos encontrar pelo caminho. Conhecendo os tipos de modularização irá nos ajudar a saber que “rua” ou “avenida” estamos e pode nos orientar se falta muito ou pouco a chegar onde queremos.
Os tipos de modularização que veremos com frequência quando estivermos
debugando serão: Includes, Perform/Forms, Funções e Module. Existem outros porém esses serão os que veremos com mais frequência e serão os que iremos abordar nos próximos capítulos.
Includes
Uma include é um programa que pode ser usado por outro programa, normalmente veremos os Includes nos inicios dos programas, onde é comum ser utilizado para declarar as variáveis, infotipos tabelas, etc...
Exemplo de utilização de include
Programa executável (zvmtr_gpessoa_28)
*---* Exemplo de programa com INCLUDE
*---REPORT zvmtr_gpessoa_28. TABLES: lfa1, lfb1.
PARAMETERS p_lifnr LIKE lfa1-lifnr. WRITE: 'Início da lista'.
WRITE:/.
INCLUDE zvmtr_gpessoa_28_01. INCLUDE zvmtr_gpessoa_28_02. WRITE: 'Fim da lista'.
Primeiro programa include ( zvmtr_gpessoa_28_1)
*---*
* INCLUDE ZVMTR_GPESSOA_28_01 * *---*
select single * from lfa1 where lifnr = p_lifnr.
WRITE:/ 'Empresas p/ fornecedor', p_lifnr, '-', lfa1-name1.
Segundo programa include ( zvmtr_gpessoa_28_2)
*---*
* INCLUDE ZVMTR_GPESSOA_28_02 * *---*
select * from lfb1 where lifnr = lfa1-lifnr. write:/ lfb1-bukrs.
Perform e Form
Um Perform é uma sub-rotina de código reutilizável. É como um miniprograma que pode ser chamado de outro ponto no programa. Um Perform sempre estará
acompanhado de uma instrução FORM para indicar o início da sub-rotina e ENDFORM para indicar o fim.
Exemplo de um PERFOM.
*---* Exemplo de programa com sub-rotina
*---REPORT zvmtr_gpessoa_27.
* Tela de seleção
PARAMETERS: numero1(1) TYPE p, numero2(1) TYPE p, numero3(1) TYPE p. START-OF-SELECTION.
PERFORM imprime_tabuada USING numero1. PERFORM imprime_tabuada USING numero2. PERFORM imprime_tabuada USING numero3.
*---* * FORM imprime_tabuada * *---*
FORM imprime_tabuada USING p_num.
DATA: var1 TYPE i. DATA: var2 TYPE i.
WRITE:/ 'Tabuada de ', p_num. WRITE:/.
DO 9 TIMES. var1 = var1 + 1. var2 = var1 * p_num.
WRITE:/ p_num, ' X', var1, ' = ', var2.
ENDDO. ULINE. ENDFORM.
Funções
Uma função é um programa que recebe parâmetros de entrada e saída, e esses parâmetros serão utilizados pela função para alguma finalidade.
O que devemos observar em uma função são os parâmetros que a função está recebendo “importing” e qual informação ela vai devolver “exporting”, e que informação será alterada “changing”.
No parâmetro Importing estarão os parâmetros que a função irá receber. No parâmetro Exporting estarão os parâmetros que a função irá devolver. No parâmetro Changing estarão os parâmetros que a função irá alterar.
Dica: Normalmente o que estamos procurando pode estar no parâmetro changing, caso o importing esteja recebendo uma variável que estamos rastreando. Caso a função não esteja recebendo a variável que estamos rastreando nem vale a pena gastar tempo entrando na função.
*---* Exemplo de programa com FUNÇÃO
*---REPORT zvmtr_gpessoa_29 .
* Tela de seleção
PARAMETERS: numero1(2) TYPE p, numero2(2) TYPE p.
* Variável
DATA: usuario LIKE sy-uname.
START-OF-SELECTION.
CALL FUNCTION 'ZVMTR_FUNCTION001'
EXPORTING w_numero1 = numero1 IMPORTING w_user = usuario CHANGING w_numero2 = numero2. WRITE:/.
WRITE:/ 'Listagem do programa após execução da função'. WRITE:/ 'Parametro exportação:', numero1,
/ 'Parametro modificação:', numero2, / 'Parâmetro importação:', usuario.
Métodos
Um metodo realiza uma ação que recebe parâmetros de entrada e saída, e esses parâmetros serão utilizados pelo método para alguma finalidade.
O que devemos observar em um metodo são os parâmetros que estão recebendo “importing” e qual informação ela vai devolver “exporting”, e que informação será alterada “changing”.
No parâmetro Importing estarão os parâmetros que o método irá receber. No parâmetro Exporting estarão os parâmetros que o método irá devolver. No parâmetro Changing estarão os parâmetros que o método irá alterar.
Dica: Normalmente o que estamos procurando pode estar no parâmetro changing, caso o importing esteja recebendo uma variável que estamos rastreando. Caso o método não esteja recebendo a variável que estamos rastreando nem vale a pena gastar tempo entrando no método.
*---* Exemplo de uma chamada de método
*---REPORT zvmtr_abreExcel.
START-OF-SELECTION.
data: lt_filetab type filetable, l_rcode type i.
*
CALL METHOD cl_gui_frontend_services=>file_open_dialog EXPORTING
window_title = 'Select File'
default_filename = '*.xls' multiselection = ' ' CHANGING file_table = lt_filetab rc = l_rcode EXCEPTIONS file_open_dialog_failed = 1 cntl_error = 2 error_no_gui = 3 not_supported_by_gui = 4 OTHERS = 5. * if sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4. endif.
Module Pool
Module Pool são na sua maioria todos programas que acessamos e permitem manutenção em dados, um exemplo é a PA30, PO13, diferente de programas como HBRCALC0 que acessam e modificam dados mas não permite o usuário fazer isso, o sistema é quem vai modificar a informação seguindo regras e funções já
pré-estabelecidas.
O que devemos observar em programas Module Pool são os acessos antes dos dados serem apresentados na tela conhecidos como PBO (Process Before Output) e os acessos depois que os dados foram incluídos na tela conhecido como PAI
(Process After Input).
Quando vermos as instruções abaixo podemos debugar a linha do module, porque provavelmente tem regras de negocio aplicadas la dentro. Normalmente iremos ver algo assim:
PROCESS BEFORE OUTPUT.
MODULE STATUS_100. Aqui pode ter códigos e dá para debugar. PROCESS AFTER INPUT.
DEBUG
O Debug será nosso GPS que nos permitirá andar pelas ruas dos códigos ABAP. Ele é uma ferramenta que permite a execução do programa linha a linha, permitindo assim visualizar os dados conforme o programa é executado.
Existe duas maneiras de ativar o debug:
Através do /H na linha de comando, onde o debug irá ser ativado após as teclas Enter ou F8.
Através da transação SE38 informando o nome do programa desejado para debugar e em determinada linha incluímos um ponto de parada, assim quando o programa for executado o sistema irá parar automaticamente no ponto determinado sem ter utilizado o comando /H.
Ponto de parada em um programa
Principais Comandos
Quando debugamos utilizamos algumas funcionalidades que nos orienta a saber por onde estamos passando, quem “mora” ali, ou seja, qual o valor da variável em determinado momento, que tabela está sendo acessada, que conta está sendo realizada.
Para se movimentar dentro de um código ABAP iremos utilizar as teclas abaixo com frequência:
1) F5 Etapa individual, essa tecla entra em tudo quanto é rua que existir. 2) F6 Executa linha a linha, mas não entra em nenhuma rua (modulo,
sub-rotina, função, etc), apenas passa por ela sem a gente perceber e continua na próxima linha.
3) F7 Retorna na rua anterior, muito importante se entrarmos em alguma rua que percebemos que não tem nada de interessante.
4) F8 Vai para o fim da avenida principal e se não tiver nenhum sinal vermelho ele finaliza o processo, caso encontre algum sinal vermelho (ponto de
parada), ele obrigatoriamente faz a parada.
Abaixo veremos uma tela que se tornará comum para quem se aventurar a debugar um programa:
1) Conseguimos colocar pontos de paradas com condições.
2) Conseguimos ver todos módulos do programa, ou seja, quem chamou quem, muito útil para sabermos onde estamos.
3) Visão mais usada do debug que é essa tela que estamos vendo. 4) Conseguimos ver o conteúdo das tabelas encontradas pelo caminho. 5) Conseguimos ver todos pontos de paradas colocados nos programas. 6) Conseguimos ver os valores das variáveis.
Dicas e macetes
Palavras chaves
As vezes debugando um programa pode acontecer de ter chamadas de varios programas, funções, métodos, forms, ai ficamos na dúvida se entramos em todos eles para debugar ou não. Nestes casos vale a pena primeiro procurar as palavras chaves e dar uma atenção maior para os módulos que tenham alguma palavra relacionada ao que estamos procurando.
Pular linhas de códigos
As vezes é necessário pular uma parte do programa, porque não queremos que o sistema passe por ali só para saber como ele vai se comportar dali para frente ou forçar ele entrar em uma condição que não está entrando.
Para fazermos isso é só posicionar na linha em que queremos que ele esteja e clicar Shift+F12 e pronto o sistema irá “pular” todas linhas do ponto onde estava até o ponto onde paramos o cursor, isso funciona para frente e para trás, mas cuidado, por ele não passar em algumas linhas, pode não alimentar algumas variáveis, só preste atenção nisso.
No exemplo abaixo, estamos na linha 312, se eu for com o mouse e clicar na linha 318 e pressionar shift+F12, o debuger irá pular as 2 condições de IF, não vai fazer a verificação e ir direto para a linha 318.
Chegar mais rápido onde queremos
Normalmente quando debugamos utilizamos as teclas F5 ou F6, mas quando não sabemos ainda onde está nosso “endereço”, deixo uma dica:
Sempre utilize F6 primeiro assim chegaremos mais rápido onde queremos, porque o F6 executa a linha sem “entrar” nela, assim podemos passar em uma linha que
pode ser uma chamada de uma função, uma include ou um Perform, se passou daquela linha e deu o erro, ou o valor da nossa variavel conter a informação
esperada, ou a tabela foi preenchida, opa, é ali que está o que estamos procurando, ai sim, voltamos debugando novamente e naquele ponto, utilizamos o F5.
Acessar programas rapidamente
Normalmente se usa o /H para ativar o debug, mas vou deixar uma dica importante: Antes de ativar o /H acesse o programa via SE38 e veja o código antes, procure alguma palavra chave no programa, muitas vezes eu nem precisei debugar, somente olhando o código achei a tabela que eu queria encontrar e se fosse debugando iria demorar uma eternidade para chegar no ponto em que a tabela estava.
Procurar qualquer texto dentro de códigos ABAP
O programa RPR_ABAP_SOURCE_SCAN acessado via SE38, permite encontrar qualquer texto, tabela, campo, comentário dentro de um código abap, muito útil quando temos um nome já em mente.
A transação EWK1 tem a mesma finalidade, e mais simples de se usar e o resultado é mais simples também. Veja o exemplo abaixo onde vamos procurar em todo programa Z o texto “Hora Extra”.
Pontos de parada com condição simples
As vezes pode surgir a necessidade de saber quando uma variavel ou tabela está sendo alimentada, de onde está vindo a informação e o ponto de parada com condição será muito util para nos ajudar a saber isso.
Para colocar um ponto de parada com condição, primeiro temos que estar
executando o programa e nesse caso o ideal é colocarmos um ponto de parada fixa próximo do START-OF-SELECTION porque é onde começa a seleção dos dados , ou seja, antes da nossa variavel ou tabela receber qualquer informação.
Clicando no Watchpoint é aberta a janela para colocarmos a condição simples que desejamos. Podemos colocar uma tabela, uma variavel, uma work-area, qualquer tipo de dado que esteja “viva”, ou seja, o sistema precisa enxergar o tipo de dado, tem que estar criado.
Assim que o tipo de dado receber um valor o sistema para na próxima linha. No exemplo abaixo a work-area gs_saida acabou de receber um valor em um de seus campos e o debug parou imediatamente na linha seguinte.
Pontos de parada com condição complexa
Muitas vezes precisamos chegar em um valor especifico de um tipo de dado, e para conseguir isso precisamos criar uma condição mais complexa, onde informamos condições mais especificas.
Vamos supor que desejamos encontrar o momento em que o sistema grava uma data especifica em uma tabela, porque neste dia é que está nossa informação. Para isso vamos repetir o processo da condição simples, ou seja, o programa deve estar sendo executado e a work-area e o campo deve existir.
Lembre-se de colcoar um ponto de parada fixo próximo do START-OF-SELECTION, só para conseguirmos fazer nossa parada com condição complexa.
No Watchpoint precisamos informar o nome do tipo de dado e na condição livre temos que colocar nossa condição desejada, lembrando que a condição precisa ter espaços em branco entre o nome do tipo de dado o operador e o valor.
Depois é só executar com F8 e esperar a condição ser satisfeita, caso não seja, o sistema irá executar até terminar o processo, caso encontre ele para na linha imediatamente depois da condição satisfeita.
Debugar regras do log da folha
Agora que ja estamos “fera” em debugar programas vamos para nosso maior desafio, aprender a debugar a regra de folha de pagamento que para os analistas funcionais SAP HR é uma dica valiozissima.
Porque é necessário aprender debugar regra de folha ? As vezes olhamos para uma regra e não conseguimos identificar no help de onde vem a informação e as vezes existem condições internas que não estão explicitas. Para aprendermos a debugar a regra, vamos fazer um exemplo real.
Nosso objetivo será saber o valor que o sistema está atribuindo no campo
“NUM=F01T A” da regra ZBB1, porque ja tentamos ver pelo help e não conseguimos entender o que está sendo feito nessa linha.
Para isso precisamos abrir o programa RPCMAS09_FUPIT pela transação SE38 que faz acesso as regras de calculo das folhas de pagamentos.
Selecione Exibir e quando abrir o programa clique na linha 14 .
Quando clicar na linha indicada o sistema irá solicitar qual programa que fará referencia ao seu ponto de parada, isso acontece porque nosso programa RPCMAS09_FUPIT é usado por varios programas.
Pronto, agora vamos simular uma folha (pode ser qualquer folha) mas em uma nova janela.
No momento em que o sistema parar no ponto de parada fixo, devemos criar o watchpoint com condição como abaixo, informando o nome da regra na condição, no nosso exemplo famos debugar a regra ZBB1.
Depois de ter criado o watchpoint e salvo, retire o ponto de parada fixo, e pressione F8 até que a variavel ccycl seja = ZBB1, para facilitar coloque a variavel no panel ao lado para vermos o valor dela.
Assim que o debug parar na regra colocada no watchpoint, vamos entrar no LOOP AT, e ja vimos que o LOOP fica rodando uma tabela, no nosso caso é a tabela IT e vamos ter que chegar até a rubrica que precisamos, no nosso exemplo é a rubrica / 199.
Assim que chegarmos na rubrica, com F5 entre na PERFORM regel.
Agora, precisamos encontrar a PERFORM boper. (utilize CTRL+F e digite FORM boper) e coloque um ponto de parada fixo na chamada da PERFORM boper, e clique em F8 para chegar ao ponto de parada fixado.
Chegando no ponto, entre na PERFORM boper com F5.
Agora, precisamos encontrar a PERFORM process_oper. (utilize CTRL+F e digite FORM process) e coloque um ponto de parada fixo na chamada da PERFORM process_oper., e clique em F8 para chegar ao ponto de parada fixado.
Assim que chegar no ponto, coloque a variavel OP no painel de variavel.
Agora com o ponto de parada fixado na PERFORM process_oper. Com F8 debug até a variavel OP ficar com a linha que deseja saber o valor no nosso caso NUM=F01T A
Assim que o valor da variavel ficar igual a linha da regra que desejamos, vamos entrar com F5 dentro da PERFORM process_oper.
A partir deste ponto não existe mais um caminho fixo, pois pode variar para cada linha da regra, no nosso exemplo vamos entrar dentro de uma perform chamada vget, mas poderia ser outra, conforme a linha da regra.
E nesse ponto abaixo encontramos o momento do calculo que estamos procurando e o valor que nosso NUM vai receber. A variavel pfeld normalmente recebe o valor calculado e transfere para o NUM, RTE ou AMT.
BIBLIOGRAFIA E CRÉDITOS
• Ken Greenwood, ABAP Aprenda em 21 dias. • Shimene Gomes, Como Debugar regras de folha. • Lucas Nery, ABAP para funcionais.
• Amantino Freitas Soares, Comandos e Funções ABAP. • Trainning Education Service, ABAP Foundations. • Trainning Education Service, ABAP Advanced.
SOBRE O AUTOR
Meu nome é Wagner Jefferson Binoto, atualmente sou analista funcional SAP HR na Accenture de Curitiba, sou formado em Analise de Sistemas e pós-graduado em Gestão de Recursos Humanos pela UNIVEM-Universidade Euripedes de Marilia.
Cursei uma academia ABAP e trabalhei durante 15 anos como desenvolvimento de sistemas, isso justifica meus conhecimentos nos códigos ABAP, mas a alguns anos “pindurei” a chuteira de programador para se tornar um analista Funcional SAP HR, um sonho que persegui durante 3 anos, e graças a Deus e a Accenture pude realizar este sonho.
Caso alguém tenha alguma dúvida ou quiser acrescentar algo neste material, por gentileza, fique a vontade em entrar em contato: [email protected]. Abraços e espero que este material seja util de alguma maneira.