November 24, 2024

ABAPZombie Guide to ABAP – Parte 28 – COLLECT

E cá estou eu, continuando essa saga que não tem um post novo desde Agosto. Eu não desisti, e não desistirei jamais! 😈

Enfim, hoje vou explicar um comando que deixa ABAPers Jrs maravilhados pelo mundo todo, o COLLECT!

Eu resumo o funcionamento desse comando da seguinte forma: se é valor, soma essa parada. Fim do post de hoje galera!

🙄

Mas a idéia é essa mesma: se você utilizar um COLLECT na hora de adicionar valores de uma work area para a sua tabela interna, o sistema vai verificar se existe alguma outra entrada com a mesma chave primária na tabela. Se tiver, ele vai somar todos os campos com valores, ao invés de duplicar a linha. Se não tiver, ele cria uma nova entrada.

Vamos ver isso funcionando na prática:

REPORT  zombie_collect.

TYPES: BEGIN OF ty_val,
         nome TYPE char10,
         sal  TYPE i,
       END OF ty_val.

DATA: t_val  TYPE SORTED TABLE OF ty_val WITH UNIQUE KEY nome,
      wa_val LIKE LINE OF t_val.

wa_val-nome = 'Zombie1'.
wa_val-sal  = 123.
COLLECT wa_val INTO t_val.

wa_val-nome = 'Zombie2'.
wa_val-sal  = 321.
COLLECT wa_val INTO t_val.

wa_val-nome = 'Zombie1'.
wa_val-sal  = 321.
COLLECT wa_val INTO t_val.

Esse é o funcionamento básico. Mas como toda boa operação com tabelas internas no ABAP, o COLLECT funciona de maneira diferente para cada tipo de tabela. No caso acima, se tentarmos adicionar um campo não numérico fora da chave primária, o código não compila por conta do COLLECT. Vejam:

REPORT  zombie_collect.

TYPES: BEGIN OF ty_val,
         nome  TYPE char10,
         cargo TYPE char10,
         sal   TYPE i,
       END OF ty_val.

DATA: t_val  TYPE SORTED TABLE OF ty_val WITH UNIQUE KEY nome,
      wa_val LIKE LINE OF t_val.

wa_val-nome  = 'Zombie1'.
wa_val-cargo = 'Gerente'.
wa_val-sal   = 123.
COLLECT wa_val INTO t_val. "Não Compila!!!

A busca pela linha feita pelo COLLECT para tabelas SORTED é sempre feita com um algoritmo de busca binária. Ah, e o COLLECT também não destrói a ordenação da tabela, caso o registro não exista e ele tenha que criar uma nova entrada. Divertido, não? 🙂

O funcionamento do COLLECT para SORTED e HASHED tables é praticamente o mesmo, a única diferença é que o sistema utiliza o algoritmo hash para fazer a busca na tabela interna, ao invés de fazer a busca binária.

Maaaas, e se não for tabela SORTED nem HASHED?

REPORT  zombie_collect.

TYPES: BEGIN OF ty_val,
         nome  TYPE char10,
         cargo TYPE char10,
         sal   TYPE i,
       END OF ty_val.

* Lembrando que quando existe só o "TABLE", o sistema
* assume que a tabela é uma STANDARD TABLE automaticamente
DATA: t_val  TYPE TABLE OF ty_val,
      wa_val LIKE LINE OF t_val.

wa_val-nome  = 'Zombie1'.
wa_val-cargo = 'Gerente'.
wa_val-sal   = 123.
COLLECT wa_val INTO t_val.

wa_val-nome = 'Zombie2'.
wa_val-cargo = 'Diretor'.
wa_val-sal  = 321.
COLLECT wa_val INTO t_val.

wa_val-nome = 'Zombie1'.
wa_val-cargo = 'Func'.
wa_val-sal  = 321.
COLLECT wa_val INTO t_val.

Notem que esse é o mesmo exemplo do COLLECT com tabela SORTED que não compila. Mas no caso acima, o sistema vai criar 3 linhas! Sim, porque para tabelas STANDARDs sem chave declarada, o COLLECT vai comparar TODOS os campos não numéricos para saber se pode ou não somar. No exemplo acima, troque todos os cargos para “Diretor” e teste novamente 🙂

Se a entrada não existir, o COLLECT vai ter o mesmo efeito do APPEND em STANDARD TABLES.

Uma curiosidade legal sobre o COLLECT em STANDARD TABLES: o sistema monta um “cache” da tabela em memória organizada por um algoritmo hash, sempre que ela é preenchida com o COLLECT. Isso faz o acesso posterior pelo COLLECT ficar bem rápido. Porém, se qualquer outro comando como INSERT ou APPEND alterarem a tabela, esse “cache” vai para o espaço, e o sistema faz a busca de forma linear caso algum COLLECT seja novamente utilizado.

Meio enrolado né? 😛 Eu vou fazer um post explicando somente Hash Tables em breve!

Divirta-se utilizando o COLLECT, e sofra quando você descobrir uma diferença no valor em um campo de uma tabela com 34 campos de valores ocasionada aparentemente pelo COLLECT. Lembre-se que a culpa nunca é do comando 😀

Abraços!

Mauricio Cruz

Pasteleiro há 15+ anos e criou o ABAPZombie junto com o Mauro em 2010. Gosta de filosofar sobre fundamentos básicos da programação e assuntos polêmicos. Não trabalha mais com SAP, mas ainda escreve sobre programação e faz vídeos de vez em quando.

View all posts by Mauricio Cruz →

3 thoughts on “ABAPZombie Guide to ABAP – Parte 28 – COLLECT

Leave a Reply

Your email address will not be published. Required fields are marked *