<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Adriano Campanhola on Medium]]></title>
        <description><![CDATA[Stories by Adriano Campanhola on Medium]]></description>
        <link>https://medium.com/@adrianosc?source=rss-77e4cdae7abb------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*5NgweEfKDSFB8fLy.</url>
            <title>Stories by Adriano Campanhola on Medium</title>
            <link>https://medium.com/@adrianosc?source=rss-77e4cdae7abb------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 10:56:18 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@adrianosc/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[ABAP on Vim]]></title>
            <link>https://medium.com/bar8/abap-on-vim-14781dd1bbbd?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/14781dd1bbbd</guid>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[vim]]></category>
            <category><![CDATA[sap]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Thu, 15 Sep 2016 17:48:16 GMT</pubDate>
            <atom:updated>2019-01-11T14:06:16.173Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>VIM ROCKS — <a href="https://medium.com/u/48566ad29212">Antelio I. Abe</a></blockquote><p>E aiii gente bonita, tudo bem com vocês?</p><p>Hoje vou falar um pouco sobre um experimento que tenho feito nos últimos meses com esse treco chamado VIM e esse treco chamado ABAP.</p><p>Se vocês não moram debaixo de uma pedra, sabe que a SAP liberou faz um tempinho algo chamado ADT, ou ABAP on Eclipse, teve até post sobre isso aqui no blog por um escritor gatérrimo:</p><p><a href="https://bar8.com.br/abap-no-eclipse-efafd5aa873a">ABAP no Eclipse</a></p><p>Uma das grandes vantagens do Eclipse é o fato dele ser extensível por plugins, algo que sempre subutilizei (se conhecer plugins legais, por favor me fale). Porém num dia de inspiração eu me perguntei:</p><blockquote>Existe plugin de VIM?</blockquote><p>A resposta é sim, e é diversão garantida para toda a família!</p><p><strong>Aviso:</strong> Este post é sobre como utilizar com ABAP, não é um tutorial sobre Vim propriamente dito, para isso existem diversos materiais na internet, indicarei alguns que utilizei no fim do post.</p><h3>O que é VIM?</h3><p><a href="http://www.vim.org/about.php">Vim</a>(<strong>V</strong>i <strong>IM</strong>proved) é um clone do editor de texto Vi, um programa criado para editar textos em Unix, sendo que este é mais focado em edição de códigos e é feito para ser altamente configurável. Por ter que suportar o uso via terminal, seus comandos são, em geral, voltados para uso via texto, desde a navegação até a edição/gravação.</p><p>Uma busca rápida no Google sobre “Most popular text editor” vai lhe retornar alguns concorrentes, mas normalmente você encontrará VIM na lista e sempre um dos mais indicados.</p><h3>Qual a vantagem?</h3><p>Se você costuma utilizar atalhos de teclado, sabe que toda vez que tem que utilizar seu mouse, você perde um pouquiiiinho de produtividade. A idéia neste editor é sempre manter a mão no teclado, para editar, para se mover no código, tudo via comandos.</p><p>Já utilizamos alguns atalhos no nosso dia a dia, Ctrl F3, Ctrl F2, F3, etc etc, então não preciso argumentar muito para dizer que eles agilizam o seu desenvolvimento. A questão é que Vim vai além:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sjX0bQFpZiT80ili8KUzlA.png" /><figcaption>Ohhhh yea</figcaption></figure><p>Os comandos do vim acabam sendo “simples” depois de um tempo. Vim é um editor modal, então existe um modo em que você insere o texto diretamente enquanto digita e um modo de navegação. No modo de navegação, chamado de modo normal, os comandos normalmente são &lt;ação&gt;&lt;movimento&gt;, depois que você aprende as ações básicas e começa a usar os movimentos, consegue deduzir o que uma ação+movimento faz.</p><p>Por exemplo, <strong><em>d&lt;movimento&gt;</em></strong> deleta uma palavra na direção do movimento que você mandou, <strong><em>w</em></strong> navega para o início da próxima palavra, então <strong><em>dw</em></strong> deleta até o início da próxima palavra, então se <strong><em>y </em></strong>é copiar, <strong><em>yw</em></strong> copia até o início da próxima palavra. Combinando isso com macros e os outros atalhos, transforma Vim no editor de texto muito poderoso.</p><p>Abaixo você pode ver um pouco alguém programando usando este lindo editor de texto.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FQNAXa0W4OFg%3Fstart%3D19%26feature%3Doembed%26start%3D19&amp;url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DQNAXa0W4OFg&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FQNAXa0W4OFg%2Fhqdefault.jpg&amp;key=d04bfffea46d4aeda930ec88cc64b87c&amp;type=text%2Fhtml&amp;schema=youtube" width="640" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/224716842a0e25df063be45cd4a9c267/href">https://medium.com/media/224716842a0e25df063be45cd4a9c267/href</a></iframe><h3><strong>Ecomofaz?</strong></h3><p>Atualmente a única solução para programar fora do ambiente do seu querido SAP Gui é através do Eclipse+ADT, e dentro desse universo existem duas soluções para edição usando Vim: Vrapper e Eclim. Ambos têm objetivos diferentes, mas apenas um deles funciona com ABAP.</p><ul><li><a href="http://vrapper.sourceforge.net/home/">Vrapper</a> transforma o Eclipse num editor Vim.</li><li><a href="http://eclim.org/">Eclim</a> transforma o Eclipse num servidor e você consome ele no seu Vim.</li></ul><p>Como ainda temos a necessidade de utilização do SAP Gui(Edição de telas, dependendo do teu servidor, não tem criação de data elements no ADT, etc), a melhor solução acaba sendo o Vrapper. De qualquer maneira, o Eclim não entende a hierarquia de projetos ABAP e nem tem suporte :P.</p><p>Para instalar, tem duas maneiras, uma é buscar no Eclipse Market place pelo plugin Vrapper e instalar, simples assim.</p><p>A outra maneira é ir em HELP&gt;Install New Software. Na tela seguinte coloque as informações:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/445/1*xpAnn_FrE6WFZ2Ig3y_L7w.png" /><figcaption>http://vrapper.sourceforge.net/update-site/stable</figcaption></figure><p>Abaixo da tela, vai aparecer várias coisas para instalar:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/494/1*22DuCyXYFag2kppjM4FPGQ.png" /></figure><p>Na imagem acima, marquei dois plugins que utilizo, e também pra funcionar você precisar instalar o Vrapper.</p><p>Ao instalar, vai ganhar um botãozinho na tua barra do Eclipse que ativa e desativa:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/726/1*0wKzmC846dDoKdaTCQjbZA.png" /><figcaption>Sim, nós temos um servidor nosso, e ele é lindo;)</figcaption></figure><p>E pronto! já pode sair editando teu programa com Vim! :)</p><p><strong>Truquezinhos/Conflitos</strong></p><p>Como o próprio Vim, o Vrapper tem um arquivo .vimrc onde você pode colocar todas as suas configurações, para usuários de Linux e Mac, existe um arquivo .<strong>vrapperrc </strong>e para usuários de windows,<strong> _vrapperrc</strong>, você encontra este arquivo na pasta principal do usuário.</p><p>Neste arquivo você pode configurar seus atalhos e opções de editor, assim como também pode adicionar macros.</p><p>Algumas configurações que recomendo de início:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55335e2a10e386020d9640b8e651bd01/href">https://medium.com/media/55335e2a10e386020d9640b8e651bd01/href</a></iframe><p>O Vrapper nada mais é do que uma camada que captura comandos que o eclipse deixa de capturar, então caso tenha algum atalho direto no eclipse, ele sempre irá utilizar este atalho primeiro e caso realmente queira utilizar alguma funcionalidade nativa do Vim que está em conflito, ou você remapeia através do vrapperrc ou remove o atalho do Eclipse.</p><p>Um pequeno bug que eu me deparei foi que as sugestões do eclipse não funcionam completamente com este plugin, para isso deve habilitar o contentassistmode(no arquivo acima), porém o quickfix do eclipse não respeita a navegação padrão do Vim(Ctrl+N/P para a navegar entre as ocorrências). Porém isso funciona normalmente para o auto-complete(Ctrl+space)</p><p>Uma funcionalidade muito louca do Vrapper é a capacidade de mapear comandos do eclipse a atalhos do Vim, por exemplo, tenho as seguinte configurações no meu vrapperrc:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/92652babbc269edac5dc0a31bb5e6029/href">https://medium.com/media/92652babbc269edac5dc0a31bb5e6029/href</a></iframe><p>Posso então, digitar :a para ativar um programa ou quando o cursor estiver sobre uma variável, digitar gd para navegar para a definição(igual o duplo clique do abap).</p><p>Um tutorial de como encontrar os comandos acima pode ser visto <a href="https://github.com/vrapper/vrapper/wiki/Adding-key-bindings-to-commands">aqui</a>.</p><h4>It&#39;s not easy</h4><p>Caso decida entrar nessa brincadeira e nunca mexeu com Vim, gostaria de deixar um aviso de que a curva de aprendizado é devagar, não fique com medo de desligar o Vrapper para finalmente conseguir liberar aquela request. No começo não será tão produtivo quanto anteriormente e várias vezes vai ser frustrante.</p><p>A princípio, vários atalhos não serão intuitivos, como por exemplo, as setas terem sido trocadas por h(esquerda)j(baixo)k(cima)l(direita),o botão copiar é no y, etc etc mas se você largar o preconceito, vai acabar gostando!</p><p>Recomendo anotar dúvidas, eu quando fui estudando, todo dia decidia que iria me forçar a utilizar um comando novo: “Hoje vou utilizar :s e suas variações”, caso não saiba fazer algo no Vim ou achou algo que sente falta, anote e procure posteriormente.</p><p>Outra dica é que os comandos básicos são os mais importantes, quanto mais você praticar eles, mais rapidamente vão virar <em>muscle memory</em> e mais rapidamente irá programar.</p><h3>Material para estudo:</h3><p><a href="http://vrapper.sourceforge.net/documentation">Vrapper - Documentation - Introduction</a></p><p>Movimentos básicos do vim:</p><p><a href="http://vim-adventures.com/">VIM Adventures - Learn VIM while playing a game</a></p><p>Acho que o tutorial abaixo segura muito na mão mas…</p><p><a href="http://www.openvim.com/">Interactive Vim tutorial</a></p><p><strong>Mas o melhor que usei até agora é o vimtutor, precisa ter Vim instalado na máquina, ai basta digitar :vimtutor e correr pro abraço</strong></p><p>E é isso ai povo, caso você utilize eclipse, recomendo gastar um tempo com Vim. Se não utiliza eclipse e já brincou com Vim em outras linguagens, que tal utilizar essa oportunidade para começar ;)?</p><p>Não deixe de conferir as referências abaixo, e se curtiu o post não deixe de participar comentando, compartilhando ou simplesmente segurando esse botão de aplausos para mostrar que é esse tipo de conteúdo que você deseja ter por aqui. Muito obrigado e até mais!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=14781dd1bbbd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/abap-on-vim-14781dd1bbbd">ABAP on Vim</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[barLabs — Table Meshes — parte I]]></title>
            <link>https://medium.com/bar8/barlabs-table-meshes-parte-i-712e24d0ea70?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/712e24d0ea70</guid>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[barlabs]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Tue, 16 Aug 2016 18:02:05 GMT</pubDate>
            <atom:updated>2016-08-16T18:02:05.979Z</atom:updated>
            <content:encoded><![CDATA[<p>E aiiii povo lindo, tchudju em ordi?</p><p>Hoje vou falar sobre um assunto que é muito lindo, mas admito que é confuso, table meshes. Como é um assunto complicadinho, vou dividir em algumas partes(que ainda não sei quantas vão ser ;) )</p><h3>O que são?</h3><p>Já sentiu a necessidade de um inner join de tabelas internas? O mais próximo que temos disso é o comando <a href="https://help.sap.com/abapdocu_70/en/ABAPPROVIDE.htm">PROVIDE</a>, mas não chega lá.</p><p>Table Meshes são novos tipos de estruturas introduzidos no release<strong> 740 SP5 </strong>em que seus componentes(denominados <strong>nós</strong>) são tabelas ou refêrencias a tabelas, e os nós têm relações semelhantes a chaves estrangeiras entre eles.</p><h3>A sintaxe</h3><p>Primeiro, vamos declarar alguns tipos de tabela:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a40fca52914fd7a6e23b91fba10b25dd/href">https://medium.com/media/a40fca52914fd7a6e23b91fba10b25dd/href</a></iframe><p>E então, a declaração do mesh:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cfaefaa96c4d4f735f4e4e0415019e3d/href">https://medium.com/media/cfaefaa96c4d4f735f4e4e0415019e3d/href</a></iframe><p>O que fazemos de especial na declaração é nomear a ASSOCIAÇÃO entre as tabelas. Fazemos isso utilizando:</p><blockquote>ASSOCIATION assoc_name TO itab ON key</blockquote><p>Onde <strong><em>assoc_name</em></strong> é um nome qualquer (<em>pelamordedeususeumnomedecente</em>), <em>itab</em> é o nome de outra tabela dentro do mesh e <em>key</em> será a relação entre as duas tabelas.</p><p>No final, <strong>notas_fiscais</strong> acaba sendo uma estrutura, como pode ser visto no debugger:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/534/1*rZia_9NuQ9hRyEQb_vOT7Q.png" /></figure><p>Esta estrutura pode ser utilizada normalmente, com todos os comandos que você A-DO-RA, o MESH apenas acrescenta novas possibilidades.</p><h3>Mesh Paths</h3><p>Agora vem a parte legal, como utilizar as associações.</p><p>Utilizam-se esses comandos com uma sintaxe não tão ortodoxa:</p><blockquote>mesh-node\assoc[ source [cond] ]</blockquote><p>onde source é uma linha do nó raiz que está sendo utilizado.</p><p>Por exemplo:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/af1b7e7553a87bf047baa89f07b0d7dd/href">https://medium.com/media/af1b7e7553a87bf047baa89f07b0d7dd/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/380/1*u3SNiCTkZfwnZQmYJhsSxg.gif" /></figure><p>Pois é… vamos lá.</p><p>O comando <a href="https://help.sap.com/abapdocu_740/en/abenmesh_path_assoc.htm"><strong>\assoc</strong></a> é utilizado para indicar que queremos encontrar a associação para o sub-nó, e qual item do sub-nó será encontrado depende do que será passado nos colchetes. Repare que nele eu passei o retorno de um read table, ou seja, a linha inteira da NFDOC.</p><p>Aqui, pra mim fica mais fácil fazer uma analogia com <strong>SELECT.</strong></p><p>Apesar de termos vários itens na tabela NFITEM, o comando demonstrado retorna uma linha apenas, assim como num <strong>SELECT SINGLE.</strong></p><p>E se quisermos todos os itens relacionados à essa associação?</p><p>Vamos incrementar o exemplo acima, queremos todos os itens relacionados ao primeiro documento em que o valor do item seja maior que 1000:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/37174eefdc10b616d7323b5e66bada02/href">https://medium.com/media/37174eefdc10b616d7323b5e66bada02/href</a></iframe><p>Utilizei então, a adição <em>cond, </em>que pode ser colocado no código para restringir mais ainda o que será retornado na associação. Veja também que o mesh funciona no loop e nesse caso trará todos os itens que satisfazerem a condição e forem relacionados ao primeiro item.</p><p>E por hoje fica assim povo! Considero a sintaxe de table meshes algo complexo e não intuitivo, então trarei aos poucos. A título de curiosidade, fuçando a documentação da SAP encontrei o programa DEMO_MESH_PACK, recomendo MUITO dar uma olhada e ver onde que o ABAP tem chegado, caso você não tenha acesso a um ambiente que tem esse programa, da uma olhadinha na loucura:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/1*472501ss5huCdP-OdIE_hg.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=712e24d0ea70" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/barlabs-table-meshes-parte-i-712e24d0ea70">barLabs — Table Meshes — parte I</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Read The Fucking Documentaiton 03]]></title>
            <link>https://medium.com/bar8/read-the-fucking-documentaiton-03-5615bc02feb2?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/5615bc02feb2</guid>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[sap]]></category>
            <category><![CDATA[rtfd]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Tue, 02 Aug 2016 14:50:10 GMT</pubDate>
            <atom:updated>2016-08-02T14:50:10.258Z</atom:updated>
            <content:encoded><![CDATA[<h3>Read The Fucking Documentation 03</h3><p>O RTFD de hoje vai ser curtinho, mostrando um pequeno erro que pode acontecer ao trocar um <strong>READ TABLE</strong> por um <strong>LOOP WHERE</strong>. Encontrei este erro um dia quando fuçava a documentação da SAP e achei interessante compartilhar.</p><h4>A Motivação</h4><p>De vez em quando somos obrigados a trocar um READ TABLE por um LOOP WHERE. Provavelmente você precisa fazer alguma validação mais complexa em cada registro ou uma das chaves tem que ser comparada de maneira que o READ não é compatível.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/50a64eb0430a30ee9cc4ca155d605bcf/href">https://medium.com/media/50a64eb0430a30ee9cc4ca155d605bcf/href</a></iframe><p>E ai você altera para LOOP WHERE e teu programa não entra mais no IF:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/60358ba4915bb30ef33d32db25c4c4ac/href">https://medium.com/media/60358ba4915bb30ef33d32db25c4c4ac/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*jUJQKvOOxh_pGnWxK-gx8Q.gif" /></figure><h4>Causa e Teoria</h4><p>O que acontece aqui é que o READ TABLE <a href="https://help.sap.com/abapdocu_750/en/abenconversion_type_c.htm">converte</a> as variáveis para o tipo da coluna antes de comparar, nesse caso a conversão é de CHAR 04 para 03, e essa conversão no SAP é simples, ele trunca BAR8 para BAR e encontra na tabela.</p><p>E o LOOP WHERE? Bom, neste caso o SAP usa <a href="https://help.sap.com/abapdocu_750/en/abenlogexp_rules.htm">regras de comparação</a> para determinar se encontra ou não o registro, e para o tipo C, a regra é:</p><blockquote>Converta o menor campo para o tamanho do maior e adicione espaços para na direita</blockquote><p>Logo, ‘BAR’ vira ‘BAR ‘ que é diferente de BAR8!</p><p>O exemplo acima foi retirado <a href="https://help.sap.com/abapdocu_731/en/abaploop_at_itab_cond.htm#!ABAP_ADDITION_3@3@">daqui</a>(<em>sue me bitch</em>). Eu não me recordo de ter encontrado esse problema, mas é algo que já tive que fazer diversas vezes e portanto provavelmente ignorei este comportamento errante no calor do momento e fui atrás de outras alternativas.</p><p>E…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/236/1*406yo2jKxVg-MgE2_UthqA.jpeg" /></figure><p>até a próxima :*</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5615bc02feb2" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/read-the-fucking-documentaiton-03-5615bc02feb2">Read The Fucking Documentaiton 03</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[barLabs — CONV]]></title>
            <link>https://medium.com/bar8/barlabs-conv-9c85da327e77?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/9c85da327e77</guid>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[sap]]></category>
            <category><![CDATA[barlabs]]></category>
            <category><![CDATA[sap-training]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Tue, 19 Jul 2016 13:01:01 GMT</pubDate>
            <atom:updated>2016-07-19T17:33:31.738Z</atom:updated>
            <content:encoded><![CDATA[<h3>barLabs — CONV</h3><p>Bom diaaaaa povo, vamos a mais um barLabs!</p><p>Se você for igual a mim, fica puto da vida toda vez que tem que declarar uma variável auxiliar pra conseguir chamar um método ou uma função. Pois bem, parece que alguém na SAP também deve ter ficado de saco cheio de ter que ficar criando um monte de sujeirinha.</p><p>Vamos ao programa exemplo, ele vai ser meio idiota, mas serve. O que faremos é utilizar uma classe de calcular soma e subtração de números inteiros:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/049088cc9b38a65c77a55e0049d9d508/href">https://medium.com/media/049088cc9b38a65c77a55e0049d9d508/href</a></iframe><p>Só que por algum motivo de força maior, o desenvolvedor decidiu utilizar 3 parâmetros de INPUT que são caracteres:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e5970447708992772210682640cbb330/href">https://medium.com/media/e5970447708992772210682640cbb330/href</a></iframe><p>Se você copiar os dois códigos acima em um report, vai ver que não compila e gera os erros seguintes:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/478/1*Mcvf-Uofq3IrFmvL_5uSxA.png" /><figcaption>Se fosse uma função, você seria avisado quando desse o dump em PRD</figcaption></figure><p>Bom, pra resolver isso é simples, basta criar o que? O QUE? UMA VARIÁVEL AUXILIAR</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*RLQHqrwfxaHwujYEj8R83A.gif" /></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/22532a2cdf5ec7344965f2192d916cb1/href">https://medium.com/media/22532a2cdf5ec7344965f2192d916cb1/href</a></iframe><p>Começando na versão 7.40 SP 2, nós obtivemos acesso a uma série de comandos novos chamados de <a href="https://help.sap.com/abapdocu_740/en/abenconstructor_expressions.htm">constructor expressions</a>, este assunto por si só é extenso e não é a idéia deste barLabs. Tenha apenas em mente que essas expressões retornam valores.</p><p>Quatro das expressões novas são expressões de conversão: <strong>EXACT</strong>, <strong>CAST</strong>, <strong>REF </strong>e <strong>CONV</strong>.</p><ul><li><strong>EXACT</strong>— Faz uma conversão em que perda de dados é verificada, causando uma exceção caso aconteça</li><li><strong>CAST </strong>— Como o comando CONV abaixo, mas para refêrencias e objetos</li><li><strong>REF </strong>— Retorna a referência da variável em que é utilizada</li><li><strong>CONV </strong>— Realiza a conversão da variável seguindo as <a href="https://help.sap.com/abapdocu_740/en/abenconversion_rules.htm">regras de conversão da SAP</a></li></ul><p>Como o título do post indica, vou focar apenas no último, já vai dar pra ter uma ideia de como utilizar os outros com isso.</p><p>O operador CONV tem a seguinte sintaxe:</p><blockquote>… CONV type( [<a href="https://help.sap.com/abapdocu_740/en/abaplet.htm">let_exp</a>] dobj ) …</blockquote><p>Onde dobj é a variável que queremos converter, type é para qual tipo e let_exp pode ser utilizado para criar variáveis auxiliares durante a conversão.</p><p>Para o tipo, podemos declarar tipos do dicionário de dados, locais, elementares ou então, já que o compilador sabe qual é o tipo do parâmetro que estamos enviando o valor(afinal, ele tem que saber para dar aquele erro de sintaxe), podemos utilizar um # para identificar que queremos que a variável seja simplesmente convertida para a variável de destino, sendo que esse último só funciona se o parâmetro for “tipado”(nada de TYPE ANY).</p><p>Refatorando o código acima, ficamos com:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c10aca3332017e9d0b98749fdc207857/href">https://medium.com/media/c10aca3332017e9d0b98749fdc207857/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*QrgMP9wzi_C1cWs1YHKvkg.gif" /><figcaption>The tenth agrees</figcaption></figure><p>A quantidade de variáveis inúteis no teu código pode diminuir consideravelmente com essa belezinha, sem contar no tempo de desenvolvimento e aquele entra e sai de método/função pra ficar copiando o tipo da variável!</p><p>É interessante ressaltar a diferença para o comando <strong>EXACT</strong>. A diferença deste é que, se estivéssemos fazendo uma conversão de CHAR3 para CHAR2, o valor poderia ser truncado(ABC viraria AB )e nesse caso o comando EXACT nos retorna a exceção CX_SY_CONVERSION_DATA_LOSS, enquanto que o comando CONV simplesmente truncaria o valor.</p><p>E é isso povo, espero que gostem dessas utilidades que estamos colocando, até o próximo barLabs ;)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9c85da327e77" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/barlabs-conv-9c85da327e77">barLabs — CONV</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[barLabs — String Templates]]></title>
            <link>https://medium.com/bar8/barlabs-string-templates-9f9f926b0c8a?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/9f9f926b0c8a</guid>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[sap]]></category>
            <category><![CDATA[barlabs]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Thu, 07 Jul 2016 17:18:41 GMT</pubDate>
            <atom:updated>2016-07-07T17:20:00.027Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<p>Nos últimos anos, o ABAP vem mudando cada vez mais, acaba ficando difícil acompanhar as novas tecnologias que são integradas ou então a própria sintaxe do bichinho que vem sendo alterada.</p><p>Nesta série de posts, mostraremos rapidamente comandos novos que podem melhorar a qualidade do código e facilitar o seu trabalho. Então chega de blablabla, e…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*7ifZWj-WL4j7JU0XTJiNlQ.gif" /><figcaption>Time to ge this party starteeeeeeeeeed!!</figcaption></figure><p>No meu dia a dia, trabalho principalmente com desenvolvimento de produtos SAP e tenho que me preocupar principalmente com as versões mais antigas, tendo de usar uma sintaxe defasada. Portanto decidi começar com uma das coisas que realmente me incomoda, que é trabalhar com texto.</p><p>Seja para formatar um texto num Alv Tree ou num relatório, tenho que ficar chamando diversas funções de conversão em variáveis diferentes, jogando em textos temporários e concatenando parcialmente(e nem sempre o concatenate sai exatamente como quero), um exemplo simples é exibir número e série de Nota Fiscal:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/94f01ad8f5c37b3dcfab64dd07941fe4/href">https://medium.com/media/94f01ad8f5c37b3dcfab64dd07941fe4/href</a></iframe><p>Ou então utilizando o <strong>write to</strong>:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bcb4595fd39256e3cc72b97827bb14ca/href">https://medium.com/media/bcb4595fd39256e3cc72b97827bb14ca/href</a></iframe><p>De ambas maneiras, o desenvolvedor acaba gastando um tempo “desnecessário” neste trecho do código.</p><p>Bom, se você está num programando num ambiente AS ABAP 7.0 Ehp 2 ou superior, então de um sorriso :) poderá utilizar do <a href="http://help.sap.com/abapdocu_702/en/abenstring_templates.htm">string template</a>.</p><p>Falando de maneira boba, o string template é um texto que você fecha entre dois “|”.</p><blockquote>Mas Adriano, e qual a vantagem?</blockquote><p>A vantagem meu filho, é que além de escrever o texto da maneira como queremos que saia, também já podemos tratar as variáveis diretamente no texto.</p><p>O código anterior, ficaria muito mais simples:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ce7665a30873680b4bf99f5fa05394ca/href">https://medium.com/media/ce7665a30873680b4bf99f5fa05394ca/href</a></iframe><p>Pra quem já trabalhou com javascript, acaba notando que a sintaxe é semelhante:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a26a603540b7eb7b8e1ea8510299e446/href">https://medium.com/media/a26a603540b7eb7b8e1ea8510299e446/href</a></iframe><p>O único cuidado ai é que(e muito difícil que acabe acontecendo) é que esse comando só funciona em programas unicode.</p><p>Masss e o que podemos fazer? Dentro desses colchetes mágicos, podemos realizar contas, utilizar métodos funcionais, algumas funções predefinidas e <a href="http://help.sap.com/abapdocu_702/en/abenstring_templates_expressions.htm">muito mais</a>, deixando o código menor e mais legível.</p><p>Caso precise utilizar de mais de uma linha para o seu texto( como por exemplo ao montar um JSON ou HTML rapidamente ), foi criado também um novo concatenate(&amp;&amp;). Quebrando o código acima um pouco apenas para exemplo:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/00d47b7a6156546811689892c9a76c24/href">https://medium.com/media/00d47b7a6156546811689892c9a76c24/href</a></iframe><p>E é isso, espero que tenham gostado do primeiro barLabs! Em próximos posts vamos mostrar algumas conveniências que vem sendo feitas e que diminuem um tanto a quantidade de código que precisamos digitar :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9f9f926b0c8a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/barlabs-string-templates-9f9f926b0c8a">barLabs — String Templates</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Read the Fucking Documentation 02]]></title>
            <link>https://medium.com/bar8/read-the-fucking-documentation-02-41086eb0296b?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/41086eb0296b</guid>
            <category><![CDATA[objects]]></category>
            <category><![CDATA[access-modifier]]></category>
            <category><![CDATA[abap]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Fri, 24 Jun 2016 12:59:55 GMT</pubDate>
            <atom:updated>2019-01-11T14:10:36.638Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*k6iQsU2VkVVa6uXC-kPt5g.jpeg" /></figure><p>Quando comecei a estudar ABAP Objects fiquei curioso com o bloqueio do acesso a atributos e métodos privados. Pensava horas e horas em como alterar um atributo privado de fora da instância.</p><p>Neste post, apresentarei duas maneiras de se alterar um atributo privado de uma instância em outro ponto que não seja dentro dela.</p><h3>Usando GET REFERENCE</h3><p>A minha primeira tentativa foi utilizando Field-symbols:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5dbe1eca845156153c41252081204b13/href">https://medium.com/media/5dbe1eca845156153c41252081204b13/href</a></iframe><p>Lembro que na versão que testei, o código acima gerava um dump, porém no meu ambiente atual(SAP NW 7.40 SP 5), obtive apenas um sy-subrc = 4. De qualquer maneira, a tentativa é frustrada :(.</p><p>Após um tempo, aprendendo sobre a diferença entre parâmetros <a href="https://help.sap.com/abapdocu_731/en/abenpass_by_value_glosry.htm">pass-by-value</a> e <a href="https://help.sap.com/abapdocu_731/en/abenpass_by_reference_glosry.htm">pass-by-reference</a>, percebi que poderia utilizar o comando GET REFERENCE para burlar o encapsulamento.</p><p>Em resumo, a diferença entre os dos tipos de parâmetro é que o primeiro cria uma variável local e apenas passa o valor para o parâmetro na conclusão da rotina, enquanto que o segundo sempre altera a variável original.</p><p>Sabendo disso, podemos criar um método que retorna um ponteiro para o atributo do nosso objeto:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a7027e1324392d81e3f5fe468f3eeaf2/href">https://medium.com/media/a7027e1324392d81e3f5fe468f3eeaf2/href</a></iframe><p>Para testar:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4f660affbd27cb476b36cbdf706df1df/href">https://medium.com/media/4f660affbd27cb476b36cbdf706df1df/href</a></iframe><p>Copie a classe, rode o programa e teste. O que acontece faz sentido? Como que a SAP pode permite um backdoor desses?</p><h4>A documentação</h4><p>O problema no código acima está no comando <a href="https://help.sap.com/abapdocu_70/en/ABAPGET_REFERENCE.htm"><strong>GET REFERENCE OF</strong></a>, se olharmos na documentação, encontramos a seguinte afirmação:</p><blockquote>The context in which a data reference is acquired using <strong>GET REFERENCE</strong> determines whether or not the referenced data object can be changed. If the data object in the context of <strong>GET REFERENCE</strong> can be changed, it can be changed at any position also through the reference.</blockquote><p>O exemplo que a SAP acaba dando na documentação é exatamente o que acontece no código acima, ou seja, o que acaba importando é <strong>QUANDO </strong>utiliza-se o comando GET REFERENCE e não <strong>ONDE </strong>a variável é alterada.</p><p>E existe problema nisso?</p><p>Não, de fato não existe. O fato de criarmos um método que retorna a referência mostra que existe intenção de que se quebre o encapsulamento e no final de contas, não existe uma grande diferença entre criar o método ou alterar o atributo para público. Isso é uma escolha do desenvolvedor e ele está ciente de que está fazendo isso.</p><p>Dando um exemplo em outra linguagem(Python) do que quero dizer quando falo que existe a “intenção” de expor o atributo, não existe nada forte que proíba o desenvolvedor de acessar um atributo privado, na verdade é algo <a href="http://docs.python-guide.org/en/latest/writing/style/">cultural</a>: “Não altere variáveis iniciadas em _ ou __”, sendo que o segundo caso utiliza de <a href="https://en.wikipedia.org/wiki/Name_mangling">name mangling</a> para esconder a variável:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8b00ca74107742e4eb5b21dfed70bf8a/href">https://medium.com/media/8b00ca74107742e4eb5b21dfed70bf8a/href</a></iframe><h3>Utilizando conceitos de OOP</h3><p>A segunda solução surge mais de um erro comum de conceito de orientação a objeto e que varia de linguagem para linguagem:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5e3cd7565cc97907e3e8d71fc0c5476f/href">https://medium.com/media/5e3cd7565cc97907e3e8d71fc0c5476f/href</a></iframe><p>No código acima um objeto acessa o atributo privado num_of_kidneys de outro objeto e altera seu valor, aparentemente quebrando o encapsulamento, afinal de contas, quando colocamos o algo como privado, a intenção é que seja algo privado e pertinente apenas a esse objeto e nesse caso um objeto altera um atributo de outro!</p><p>Lendo a documentação sobre <a href="http://help.sap.com/abapdocu_702/en/abapprivate.htm">seção privada</a>, encontramos o seguinte:</p><blockquote>All components of the class defined in the section behind the <strong>PRIVATE SECTION</strong> statement can only be <strong>addressed in the class itself</strong>.</blockquote><p>A distinção é pequena mas clara: atributos e métodos privados podem sempre serem acessados quando dentro da CLASSE, nada se refere a instância na documentação.</p><p>E afinal, qual a utilidade disso/por que foi feito assim?</p><p>Beeeeeeem, caso você decida pesquisar na internet como é em outras linguagens, vai ver que existem várias pessoas com a mesma dúvida(<a href="https://stackoverflow.com/questions/16354728/why-have-class-level-access-modifiers-instead-of-object-level">C#</a>, <a href="https://stackoverflow.com/questions/17027139/access-private-field-of-another-object-in-same-class">JAVA</a>, <a href="https://stackoverflow.com/questions/7396846/with-a-private-modifier-why-can-the-member-in-other-objects-be-accessed-directl">C++</a>, etc ) e que isso não acontece apenas em ABAP . Porém existe uma “desculpa” teórica que embasa uma explicação técnica</p><h4>Explicação técnica</h4><p>É complicado/lento ficar verificando o acesso a atributos ou métodos por outros objetos, muito mais simples deixar isso para a verificação de sintaxe ao código ser compilado. A verificação a nível de instância só existe em casos em que não se sabe ao certo o objeto que teremos naquele ponto do código.</p><h4>“Desculpa” teórica</h4><p>O modificador de acesso privado serve para encapsularmos na nossa classe o que não é relevante para o mundo externo, não importa realmente o que estamos fazendo dentro do método pois o que importa é que, quem cuida das alterações e chamadas privadas seja a classe.</p><h4>Aplicação</h4><p>Encontraremos aplicações deste conceito mais em outras linguagens como JAVA ou C++. Nestas linguagens existem conceitos como o <a href="https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)#Copy_constructors">copy constructor</a>, onde cria-se uma instância de uma classe baseada em outra instância, ou então pode-se definir igualdade entre objetos e comparar os atributos que quiser, independentemente se eles são privados ou não.</p><p>Mas como podemos utilizar isso no ABAP?</p><p>Existem dois Design Patterns que podem ser implementados com isso</p><ol><li><a href="https://pt.wikipedia.org/wiki/Factory_Method">Factory</a></li><li><a href="https://pt.wikipedia.org/wiki/Prototype">Prototype</a></li></ol><p>Não vou entrar em detalhes sobre o Factory, pois o Prototype é mais interessante já que se assemelha um pouco ao copy_constructor, ou seja, serve basicamente para gerar uma cópia de uma instância da sua classe.</p><p>Fazendo um prototype beeeem simples(e idiota) com o exemplo anterior, podemos preencher os atributos privados do clone como quisermos(fazendo um monstrinho :)):</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/46779acd30010d23ba3bd7dbcbb80694/href">https://medium.com/media/46779acd30010d23ba3bd7dbcbb80694/href</a></iframe><p>Uma segunda aplicação que existe em ABAP é durante o desenvolvimento de seus testes unitários. Pode ser que você sinta a necessidade de verificar a igualdade entre dois objetos.</p><p>Para isso a SAP criou a interface IF_AUNIT_OBJECT, que tem o método EQUALS_TO. Durante a execução do seu Teste Unitário, ao utilizar CL_ABAP_UNIT_ASSERT=&gt;ASSERT_EQUALS, o programa verifica se você utiliza essa interface e realiza a comparação dos objetos que foi programada por você, um exemplo pode ser visto <a href="https://help.sap.com/saphelp_nw74/helpdata/en/54/07a7ed10b64f0588bab6882c4c9f5f/content.htm">aqui</a>(Porém esse método de comparação é obsoleto e foi substituído por isso <a href="https://help.sap.com/saphelp_nw70ehp2/helpdata/en/73/a417fb3e80462980dd4caf0a653041/content.htm">aqui</a>).</p><p>Então existem sim maneiras de acessar atributos privados em ABAP, porém são feitos de tal maneira que ou o trabalho é demais e é melhor mudar o atributo para público ou então não estamos quebrando encapsulamento, e isso pode ser uma ferramenta poderosa no nosso dia a dia!</p><p>E se curtiu o post não deixe de participar comentando, compartilhando ou simplesmente segurando esse botão de aplausos para mostrar que é esse tipo de conteúdo que você deseja ter por aqui. Muito obrigado e até mais!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=41086eb0296b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/read-the-fucking-documentation-02-41086eb0296b">Read the Fucking Documentation 02</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RTFD — 01]]></title>
            <link>https://medium.com/bar8/rtfd-01-f0f0c82ac6df?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/f0f0c82ac6df</guid>
            <category><![CDATA[bugs]]></category>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[sap]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Thu, 09 Jun 2016 12:57:24 GMT</pubDate>
            <atom:updated>2016-06-09T19:13:34.956Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nd/4.0/</cc:license>
            <content:encoded><![CDATA[<h3>RTFD — Read the Fucking Documentation 01</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZDGyck4UwH9ecilEeF0oXw.jpeg" /></figure><p>Nesta série de posts, apresentarei aparentes bugs que na verdade são erros de conceito e que estão bem documentados dentro do lindo botão F1 no código abap :)</p><p>Lidei com o problema que vou mostrar quando tive de utilizar as funções <strong>WS_DELIVERY_UPDATE </strong>e<strong> WS_REVERSE_GOODS_ISSUE. </strong>Essas funções são respectivamente utilizadas para lançar e estornar MIGOs baseadas em delivery, ambas são relativamente simples e não tem muitos parâmetros.</p><p>Quando utilizo uma seguida da outra, ou seja, na mesma transação o usuário quer lançar e depois estornar uma migo, o SAP acusa que a delivery relacionada a esta entrega não existe, mas se entrarmos novamente na transação, o estorno ocorre normalmente. Caso queira uma explicação mais detalhada, pode-se ler neste <a href="https://scn.sap.com/thread/3748326">post</a> da SCN que abri na época.</p><p>Pra se entender o porque deste comportamento, é legal começarmos pelos códigos. Leia, veja os resultados e caso não tenha entendido o que aconteceu, recomendo que crie um pacotinho ZBAR8 no seu ambiente do coração e replique estes códigos.</p><p>Vamos lá, anote a receita. Para replicar este cenário você vai precisar de:</p><ul><li>1 programa que será utilizado pelo usuário</li><li>1 programa que vai causar o bafafa todo</li><li>2 funções em grupos de funções <strong>diferentes</strong></li></ul><p>O primeiro programa é:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/12c61c1bca03d8703891b1f145fdcaa0/href">https://medium.com/media/12c61c1bca03d8703891b1f145fdcaa0/href</a></iframe><p>O Include top dos dois grupos de função e suas funções respectivamente</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fe66f381c4320fe4a8d0a9b378b8f6c5/href">https://medium.com/media/fe66f381c4320fe4a8d0a9b378b8f6c5/href</a></iframe><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f43b99fe7993d049a4a8fa829416b8cd/href">https://medium.com/media/f43b99fe7993d049a4a8fa829416b8cd/href</a></iframe><p>E finalmente, o programa que rodaremos nos nossos testes:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/92e9835b36d184196caf68b39845639b/href">https://medium.com/media/92e9835b36d184196caf68b39845639b/href</a></iframe><p>Agora, o que você espera que aconteça quando rodarmos o programa acima? Ninguém está alterando a variável <strong>t100-text</strong> no programa <strong>z_resposta_cor</strong>, a não ser ele mesmo no form <strong>load_program</strong> que é chamado dentro das funções, portanto a saída deveria ser <strong>Nenhuma cor</strong>, correto? Bom, vamos ver…</p><p>Executando com a primeira opção, obtemos:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/219/1*xPcQ1qUU23t0fEbJvj_ZiQ.png" /></figure><p>Executando a segunda opção, obtemos:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/185/1*0W3ss-WeaCk8A4jg8opoew.png" /></figure><p>E ai?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/493/1*Vb7idlKpe327SLBg3aKcPw.gif" /><figcaption>Wtf?</figcaption></figure><h4>Está tudo na documentação</h4><p>Para entender o que está acontecendo aqui, precisamos entender o conceito de <a href="http://help.sap.com/abapdocu_70/en/ABENPROGRAM_GROUP_GLOSRY.htm">Grupo de Programas</a>(PG).</p><p>Quando iniciamos uma <a href="http://help.sap.com/abapdocu_70/en/ABENINTERNAL_SESSION.htm">sessão interna</a> no SAP, o grupo de programas principal é iniciado e cada programa que é chamado que não seja um grupo de função(FG) ou um class-pool(CP, classe global, declarada na SE24), é adicionado ao grupo de programas <strong>atual</strong>. Cada FG e CP que é chamado posteriormente, cria um <a href="http://help.sap.com/abapdocu_70/en/ABENADDITIONAL_PROG_GROUP_GLOSRY.htm">grupo de programas adicional</a>, mas não pode utilizar programas já adicionados a grupos anteriores.</p><p>Os programas dentro de um grupo compartilham algo chamado <a href="http://help.sap.com/abapdocu_70/en/ABENINTERFACE_WORK_AREA_GLOSRY.htm">Interface Work Area</a>, um conjunto de variáveis que podem ser acessadas de qualquer programa nesse grupo. As variáveis que compõe esta área são declaradas utilizando <a href="http://help.sap.com/abapdocu_70/en/ABAPTABLES.htm">TABLES</a>, <a href="http://help.sap.com/abapdocu_70/en/ABAPNODES.htm">NODES</a>, ou <a href="http://help.sap.com/abapdocu_70/en/ABAPDATA_COMMON.htm">DATA BEGIN/END OF COMMON PART</a> . No exemplo, foquei na declaração TABLES que é mais comum do que Nodes e Common part.</p><p>No programa acima temos a declaração TABLES t100 que está sendo utilizado em ambos os grupos de função e em um programa. O primeiro grupo que é chamado cria um PG e ao inicializar o programa <strong>Z_RESPOSTA_COR</strong>, faz com que o programa seja adicionado no PG deste grupo de funções, a próxima função já não faz isso pois o programa já está adicionado em um PG.</p><p>Veja bem, isto não é um bug, é uma funcionalidade da SAP que acaba realizando alterações implícitas em variáveis em programas distintos, causando confusão em você, em mim e em todos que estão envolvidos.</p><h4>Para Finalizar</h4><p>Como eu me safei dessa? Bom, para resolver meu problema sem que o usuário perdesse em usabilidade eu teria que fazer o SAP criar uma nova sessão interna, logo tive que encapsular a chamada de uma das duas funções em uma minha e chamar esta em uma sessão diferente(CALL FUNC STARTING NEW TASK).</p><p>Teoricamente, a mesma coisa poderia ser feita em classes globais, só que a SAP espertinha decidiu que, as declarações TABLES, NODES e COMMON PART não podem ser utilizadas no contexto OO(Você sabe porque?).</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f0f0c82ac6df" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/rtfd-01-f0f0c82ac6df">RTFD — 01</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Diretriz de Programação]]></title>
            <link>https://medium.com/bar8/diretriz-de-programa%C3%A7%C3%A3o-e1993c3c99c?source=rss-77e4cdae7abb------2</link>
            <guid isPermaLink="false">https://medium.com/p/e1993c3c99c</guid>
            <category><![CDATA[abap]]></category>
            <category><![CDATA[workbook]]></category>
            <category><![CDATA[sap]]></category>
            <dc:creator><![CDATA[Adriano Campanhola]]></dc:creator>
            <pubDate>Thu, 26 May 2016 12:13:04 GMT</pubDate>
            <atom:updated>2016-05-26T13:18:28.818Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SxMvHbycirKpgoG0UBBIBQ.jpeg" /><figcaption>Capa do Livro — Clean Code — Uncle Bob</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/740/1*6u51C_pl-UH3X3CbggmCjA.png" /><figcaption>It’s like hell, but with no syntax errors</figcaption></figure><p>Qualquer um que trabalha com SAP há algum tempo já teve que ler um workbook de ABAP ou um documento de diretrizes de programação com as mais diversas regras de nomenclaturas de transações, programas, variáveis locais, elementos de dados, como fazer selects … enfim, a lista não termina.</p><p>A ideia por trás desses padrões é simples: facilitar a manutenção no código e evitar erros. Acontece que a maior parte dos padrões ou regras feitos nos documentos para SAP não fazem sentido nenhum e apenas estão lá pois quem fez aquele manual leu em outro manual a mesma coisa e pensou “Como já existe em algum manual, o meu só será bom se tiver também!”. Então nós somos obrigados a viver constantemente com :</p><blockquote>Para nomear o seu programa, utilizar Z+R/M+MODULO+SUBMODULO+SEQUENCIA NUMERICA</blockquote><p>ou então,</p><blockquote>Nomear com algo que faz sentido, pegue a primeira letra de cada parte da descrição da funcionalidade: zihbtpr — iventory held by third parties report</blockquote><p>Padrões de desenvolvimento são sim importantes, pois se aplicados corretamente, agilizam a leitura do código. Por exemplo, o que você prefere ler, o seguinte código:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b79fa00d53e510cc7fd5ae797d546711/href">https://medium.com/media/b79fa00d53e510cc7fd5ae797d546711/href</a></iframe><p>Ou:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/06bd62785ca1afb5635c2c50f27531d2/href">https://medium.com/media/06bd62785ca1afb5635c2c50f27531d2/href</a></iframe><p>Quando lemos um código, quem está fazendo o parse deles é o nosso cérebro, e quanto mais consistente for a sua sintaxe, mais rápido entenderemos o que está acontecendo e assim, passamos menos tempo tentando entender o que estamos lendo, e sim, mais tempo analisando o que aquele código faz fisicamente.</p><p>Em geral, penso que as documentações focam em coisas idiotas e não comentam sobre ter um padrão no código.</p><p>Ter uma indentação padronizada, por exemplo, é muito mais importante do que colocar “boas e más maneiras de se fazer select”. Um código indentado com consistência é MUITO mais fácil de ler.</p><p>Uma diretriz normalmente “forçada” é a Notação Húngara. Existem duas vertentes nessa notação, não sei como traduzir então vou me referir a seus nomes em inglês:</p><ul><li><strong>System Hungarian</strong> — Nomear variáveis em cima de seus tipos: t_bkpf (t_ indicando que é uma tabela);</li><li><strong>Apps Hungarian </strong>— Nomear variáveis em cima do que elas são e como são utilizadas no código: bkpf_fae(fae indicando que é uma variável utilizada para um for all entries, nada mais que isso).</li></ul><p>No mundo fora do SAP, System Hungarian é considerado uma má pratica: atrapalha o entendimento , a leitura do código e normalmente é redundante. Já Apps Hungarian pode ter benefícios se utilizada corretamente. Uma boa leitura da utilização é “<a href="http://www.joelonsoftware.com/articles/Wrong.html">Making Wrong Code Look Wrong</a>” de Joel Spolsky.</p><p>Nomear estruturas da SE11 começando com o que elas são (T para tabelas, por exemplo) é redundância numa linguagem onde a IDE é tão fortemente integrada como no ABAP, mas nomear variáveis em cima do que elas são pode te ajudar a notar possíveis erros e agilizar sua codificação. Concordo apenas com a necessidade de nomear variáveis globais para facilitar sua identificação, fora isso, se o programa está modularizado , as rotinas serão enxutas o suficiente para você ver a declaração na mesma tela que teu código. Um ótimo exemplo de uma linguagem em que se utiliza um tipo de notação Húngara é Python:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e6cc805a38a18ba10b8f486c3ffba848/href">https://medium.com/media/e6cc805a38a18ba10b8f486c3ffba848/href</a></iframe><p>Em Python somos <strong>obrigados </strong>a prefixar variáveis e métodos privados com _ e __ para que o próprio compilador consiga entender o que deve fazer com esses objetos. Outro ponto que eu considero bacana é que a indentação é obrigatória para que o compilador possa entender o que está dentro de uma rotina ou não, fazendo com que esses dois aspectos sejam universais entre os programadores dessa linguagem.</p><p>Uma diretriz meio “natural” no mundo SAP que já ouvi reclamações (inclusive minha) é o padrão de utilizar os nomes das tabelas e estruturas da SE11 na declaração de variáveis, é algo que é muito confuso no início, mas ao longo do tempo aprendemos do que se trata cada tabela e como existe uma integração muito forte no SAP com o dicionário de dados, é fácil saber do que se trata a variável que estamos lidando.</p><p>No final de contas, o que deve ser feito é utilizar a cabeça, essa sim é uma boa diretriz de programação. Não é preciso ser informado por um manual que é uma má pratica utilizar header line ou que ficar alterando variáveis globais dentro de suas classes é algo problemático, afinal de contas, todos nós somos adultos responsáveis aqui!</p><p>Leituras interessantes:</p><ul><li><a href="http://scn.sap.com/community/abap/blog/2013/06/17/are-you-writing-dirty-filthy-abap-code">Are you writing Dirty Filthy ABAP Code?</a></li><li><a href="https://www.amazon.com.br/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Clean Code: A Handbook of Agile Software Craftsmanship - Livros importados na Amazon.com.br</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e1993c3c99c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/bar8/diretriz-de-programa%C3%A7%C3%A3o-e1993c3c99c">Diretriz de Programação</a> was originally published in <a href="https://medium.com/bar8">Bar8</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>