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.
Olá Mauro. Você poderia também dar o loop na it_ekpo. No at new ebeln vc faz o read da it_ekko.
ResponderExcluirConcordo que o seu método é útil e em alguns casos, o mais recomendado.
Grande abraço e ótimo trabalho que você está fazendo.
Vagnão
Isso Mesmo Vagnão, eu vejo bastante isso, só não recomendo muito pra quem está começando senão pode perder referencia durante o processo do que é cabeçalho e do que é item.
ResponderExcluirMas é um comentário que caso for fazer manutenção iremos ver muito, Valeu a dica.
Outra maneira de fazer a mesma coisa é da seguinte forma (é oq costumo usar):
ResponderExcluirhttp://abap4kids.blogspot.com.br/2012/08/boas-praticas-para-loop-at-aninhados.html
Legal Mauricio, Seu metodo substitui meu 'DO' pelo seu novo 'LOOP'..... Resultado igual de formas diferentes... Dahora !!!! Valeo por compartilhar isso.
ResponderExcluir