sexta-feira, 27 de janeiro de 2012

Consulta utilizando SQL dinâmico

Nesse post vou mostar como fazer para criar um tabela interna, selecionar dados e escrevê-los na tela dinamicamente a partir de uma string com o nome da tabela, outra com os campos a serem selecionados e outra com as condições de seleção. O programa exemplo abaixo foi criado a partir desse post.

A primeira coisa a fazer é montar um fieldcat com a estrutura da tabela dinámica, nesse exemplo eu utilizei a função LVC_FIELDCATALOG_MERGE para obter o fieldcat a partir do nome da tabela, em seguida a tabela interna é criada a partir desse fieldcat.


O próximo passo é selecionar os dados preenchendo a tabela interna. Primeiro as linhas com os campos a serem selecionados são montadas e armazenada na tabela lt_fields, em seguida as condições são montadas e armazenada na tabela lt_where em seguida é feita a seleção com todas as informações dinâmicas, inclusive o nome da tabela.


O último passo é escrever as informações na tela. A tabela é dinâmica, então a workarea também é dinâmica, assim como seus campos, então o loop é feito usando assigning e para os valores do campos é utilizada a intrução ASSIGN COMPONENT. Nesse outro post você pode ver um exemplo interessante em que é utilizado DO e SY-INDEX para obter e escrever os campos da workarea.


Exemplo Completo:

quarta-feira, 25 de janeiro de 2012

Executando comandos externos no servidor

Nesse post vou mostrar como executar um comando dos no servidor SAP utilizando a função RFC_REMOTE_PIPE e ler o resultado. Atenção não execute comandos externos no servidor se não tiver certeza do que está fazendo.

Primeiro declare as seguintes variáveis:


Agora monte a string de comando e execute a função RFC_REMOTE_PIPE:


Pronto, em lt_result vai estar o resultado do comando, nesse caso DIR.

Resultado da execução comando DIR no servidor

Agora é só substituir "dir c:" pelo comando que deseja executar e seus respectivos parâmetros.

Criando uma field-exit

A criação de uma field-exit é uma tarefa básica para um desenvolvedor ABAP, mas se você não ainda não sabe fazer isso não se preocupe, nesse post vou ensinar como criar e ativar uma field-exit para verificação do CEP na transação XD02, o procedimento é o mesmo para outras telas. 

Primeiro visualize a tela onde está o campo para o qual a field-exit será criada, nesse exemplo XD02, dados de endereço: 

Transação XD02
Endereço do cliente

Visualize as informações técnicas do campo, basta clicar no campo, pressionar F1 e clicar em Informação Técnica. Anote o nome do programa, número da tela e nome do elemento de dados.

Informações técnicas
Abap F1 - Informações técnicas do campo

Execute o report RSMODPRF e informe o elemento de dados do passo anterior. Na próxima tela clique em criar, informe o grupo de funções, uma descrição e confirme.

Report  RSMODPRF

Módulo de função da field-exit
Código do módulo de função da field exit

O parâmetro input traz o que está sendo informado no campo da tela e output permite passar um valor para o campo. 
 Volte a tela do report RSMODPRF, não informe nenhum parâmetro, então você irá visualizar todas as exits criadas no sistema.

Field-exit criada
Field exits do sistema (RSMODPRF)

Localize o elemento de dados da sua exit, marque-o e clique em atribuir programa ou tela, informe o programa e o número da tela do passo 1 e confirme. 

Atribuir programa e tela
Tela para atribuir a exit a um programa e tela

Agora clique no menu exit de campo em seguida ativar, informe a uma request e confirme. 

Ativar field-exit
Menu para ataivação da field exit

Pronto agora ao entrar novamente na XD02 você verá que sua validação está ativa. 

XD02 com field-exit ativa
Cadastro do cliente com a field exit ativada

segunda-feira, 23 de janeiro de 2012

Assinando o RPS da NFS-e de São Paulo

Há algum tempo atrás eu tive de implementar uma interface para emissão de NFS-e na prefeitura de São Paulo, e na época pesquisando em alguns forums vi que bastante gente tinha problema para gerar a assinatura do RPS que vai dentro da tag assinatura.
Após algumas pesquisas na internet e no manual da prefeitura eu consegui gerar essa assinatura, abaixo vou mostrar como fazer isso em java utilizando um certificado A1. O que veremos nesse post é como gerar o hash de assinatura de RPS (conteúdo da tag assinatura) e não como assinar o XML para envio.
Antes de mais nada você precisa ter a sequencia de caracateres ASCII a ser assinada, se não sabe como gerá-la consulte o manual NFe-Web-Service-v2-2 da prefeitura da página 23 a 25, pois lá explica detalhadamente como montar essa sequencia.

Primeiro importe as classes  Signature e BASE64Encoder


Agora inclua o método que faz a assinatura da sequencia ASCII


Primeiro é obtida uma instância do algorítimo RSA-SHA1, em seguida é informada a chave privada do certificado, a sequencia é convertida para bytes e finalmente o HASH é gerado.
O método getPrivateKey pode ser substituido pelo seu próprio método que obtem a chave privada do certificado, ou se preferir pode utilizar o exemplo abaixo:

Espero que isso ajude vocês em seus projetos de NFS-e para São Paulo. Valeu!!!

domingo, 22 de janeiro de 2012

Obtendo dados de uma base Oracle externa com Native SQL

Algumas vezes precisamos obter dados de bases de dados externas, principalmente se você trabalha com interfaces entre o SAP e outros sistemas. É possível fazer isso utilizando Native SQL
O Native SQL permite que você utilize comandos SQL do próprio banco de dados ao invés do OPEN SQL, mas você deve usá-lo somente para acessar tabelas que não estão declaradas no dicionário.
Nesse post vou ensinar como se conectar a uma base de dados Oracle. Vamos Lá.

A primeira coisa a fazer é configurar a conexão com o banco de dados. Solicite ao Basis para incluir os dados de conexão da base Oracle externa no tnsnames do do servidor SAP.


MY_DATABASE é um ID que vamos atribuir a base que vamos conectar, DOMAIN é o domínio configurado no servidor, 0.0.0.0 e 1111 devem ser substituidos pelo IP e porta do servidor Oracle e DBSID deve ser substituido pelo SID do banco de dados.

Acesse a transação DBCO e inclua uma nova entrada conforme abaixo:




Conexão BD: o ID que será passado para o comando CONNECT.
SABD: O tipo de bando de dados, nesse caso Oracle.
Nome usuário: O usuário registrado no Oracle.
Senha-BD: A senha do usuário Oracle.
Info lig: O ID atribuido a conexão no tnsnames do servidor SAP.

Agora que a conexão está configurada, vamos ao código ABAP. O programa abaixo é bastante simples, ele se conecta a base externa, obtem o conteudo do campo xml_field a partir do documento da NF e escreve o conteudo XML na tela.

Exemplo completo

Instanciando uma classe pelo nome


Se você tiver várias classes implementando uma mesma interface e deseja instancia-las a partir de uma string com o nome da classe, então você pode utilizar o trecho de código abaixo.

Validando expressões regulares em ABAP com javascript

As expressões regulares são a melhor forma de validar strings, aos invés de substrings e instruções IF. Infelizmente as versões anteriores ao Netweaver não dispoem de rotinas validação de expressões regulares, mas podemos contornar isso utilizando javascript.
O SAP contém uma classe chamada cl_java_script que permite executar códigos javascript dentro ABAP, mais do que isso, permite trocar dados entre o ABAP e o javascript.
Dentre os métodos dessa classe podemos destacar dois principais, o BIND que permite associar variavés ABAP a variáveis JS e o EVALUATE que permite executar o código JS.
Nesse post vou mostrar como utilizar o processador javascript do SAP para validar um CEP através de expressão regular.

Primeiro inclua a chamada da rotina que faz a validação do CEP dentro do local apropriado do seu programa:


Onde P_CEP deve ser substituido pelo campo que contém o CEP a ser validado.
Após a execução da rotina lv_match vai estar com o valor true se o CEP for válido ou false se for inválido.


Agora inclua o form para validação de CEP.

O código javascript utiliza o método match da classe RegExp para fazer a validação, se ocorrer algum erro durante a execução do código javascript, a mensagem de erro vai estar em l_return.
Agora você pode adaptar o código para outros tipos de vlidações como CPF, CNPJ, etc.

Abrindo uma URL no navegador padrão

Para abrir uma url no navegador padrão do usuário, basta utilizar o método execute da classe cl_gui_frontend_services passando a url no parâmetro document. Veja um exemplo prático abaixo.

Imagine que seu relatório tem um campo com o número de um objeto dos Correios (Sedex, PAC, etc) e você gostaria que quando o usuário desse um duplo clique sobre esse objeto fosse a aberto a página de rastreamento de objetos dos Correios.

Dentro do sua rotina de duplo clique inclua a seguinte chamada:

Obviamente lv_num_objeto pode ser substituida pelo campo do seu relatório que contém o número do objeto dos Correios.

Agora inclua o seguinte form no seu programa.


Pronto, agora quanto o usuário der um duplo clique no campo com o número do objeto dos Correios abrir uma janela do navegador com a tela de rastreamento do objeto no site dos correios.

Tela de tracking dos Correios





Criando um ALV OO Fullscreen

 Um problema que já deparei desenvolvendo um ALV OO, foi o tamanho da tela, ora ficava muito grande e usuário tinha que rolar a tela, ora ficava muito pequeno ocupando apenas metade da tela, eu até usei o docking_container, mas o problema dele é que o usuário consegue redimensioná-lo.
Eu encontrei esse post que ensina como fazer isso utilizando o custom_container mesmo. Basicamente para fazer um ALV OO Fullscreen basta você deixar o seu container bem grande e marcá-lo como redimensionável.
Abra a tela do seu relatório no screen painter, então redimensione a tela e o custom control. De um duplo clique no custom control e marque as opções redimensionamento vertical e horizontal, informe o número linhas e colunas mínimas que seu ALV deve ter e ative sua tela. Pronto, agora na próxima vez que seu relatório for executado o ALV vai se ajustar ao tamanho da tela do usuário.


Lendo um arquivo Excel

Nesse post vou mostrar como fazer a leitura de um arquivo excel (*.xls ou *.xlsx) diretamente, sem a necessidade  de convertê-lo para CSV ou qualquer outro formato de arquivo texto. É possível fazer isso através da função  ALSM_EXCEL_TO_INTERNAL_TABLE.
Nosso programa exemplo faz a leitura de um arquivo excel com três colunas, material, unidade de medida e quantidade, em seguida imprime os dados na tela.

A primeira coisa a fazer é ler o arquivo excel para a tabela t_excel_tmp, cada linha corresponde a uma célula da planilha excel.

No parâmetro i_begin_row deve ser informada a linha onde começam os dados.

Agora é preciso ordenar a tabela por linha e coluna, em seguida percorrê-la dando um append a cada mudança de linha.

O loop está ciurcandado com try catch para evitar um dump devido a possíveis incompatibilidades entre o formato dos dados no excel e as colunas da tabela interna.

Exemplo completo: