Arquivo da categoria ‘Abap’

Na maioria das vezes é útil utilizar componentes de listas conhecidos como Combobox ou Dropdown para mostrar relacionamentos de dados entre tabelas e de uma forma amigável exibir a descrição dos itens de dados e manipular seu identificador único. Para isto o Web Dynpro nos disponibiliza componentes e classes no qual nos permite manipular dados através de objetos e persisti-los em um banco de dados relacional usando o Open SQL ou SAP Persistence Service. Um relacionamento de dados mais simples é criado através de duas tabelas, sendo uma tabela pai que contem os dados mestres e uma filho que contem um ou mais identificadores relacionados ao pai. Um modo de fácil de identificar e tradicional de utilizar relacionamentos em um banco de dados é através de chaves estrangeiras, uma chave estrangeira é um campo, que aponta para a chave primária de outra tabela ou da mesma tabela. Ou seja, passa a existir uma relação entre duas tabelas ou de uma única tabela. A finalidade da chave estrangeira é garantir a integridade dos dados referenciais, pois apenas serão permitidos valores que supostamente vão aparecer na base de dados e estão ligados ao registro mestre.

Foreign Key: Chaves Estrangeiras

Exibindo Relacionamentos

1 – Crie uma nova tabela transparente para os tipos de cargos e a ative, use a imagem abaixo para referencia:

Tabela Transparente - ZTCargo

Tabela Transparente – ZTCargo

2 – Crie uma nova tabela transparente para os participantes e inclua o campo para referencia chamado CARGOID da tabela cargos criada logo acima. Após ativar a tabela clique no campo de referencia para o CARGOID e clique no ícone (chave amarela) Foreign Key localizado na barra de ferramenta da sua tabela para criar um relacionamento entre as tabelas:

ZParticipante - Referencias

ZParticipante – Referencias

3 – Relacione os campos identificadores das duas tabelas:

Foreign Key - Chave Estrangeira

Foreign Key – Chave Estrangeira

4 – Assim que salvar e ativar sua tabela, clique na aba Entry Help/Check para ver a ligação entre as tabelas:

FK - Check

FK – Check

5 – Abra a transação SE16 e crie novos registros para a tabela de cargo:

Cargos - Registros

Cargos – Registros

6 – Caso queira pode criar um modelo de dados no Data Modeler para seus relacionamentos:

Data Modeler - Modelo de Dados

Data Modeler – Modelo de Dados

7 – Crie um componente Web Dynpro e no contexto do Controller crie um node para a tabela de participante e um node para a tabela de cargo e os importe para o contexto da sua View. No node para o cargo escolha a propriedade Cardinality como o valor 0..n. Use os elementos web adequados para cada tipo de campo de sua tabela, para o relacionamento use o elemento DropDownByIndex. Use a figura abaixo como referencia:

Node - Cardinality

Node – Cardinality

8 – Use os códigos abaixo para os respectivos métodos, salve, ative seu componente e crie sua aplicação:

Web Dynpro - Métodos

Web Dynpro – Métodos

9 – Digite os valores para cada tipo de campo e clique no botão de enviar:

Web Dynpro - Aplicação

Web Dynpro – Aplicação

10 – Você pode conferir os valores dos dados e o conteúdo do identificador do relacionamento entre as tabelas:

Data Browser = SE16

Data Browser  –  SE16

Exemplo:

Neste exemplo criamos duas tabelas no banco de dados SAP MAxDB através do dicionário de dados ABAP e as relacionamos através da chave primaria e uma chave estrangeira. Usamos um elemento Web Dynpro para tornar este relacionamento amigável, exibindo assim a descrição do relacionamento mas manipulando seu identificador e os persistindo através do SAP Persistence Service.

ABAP

ONACTIONACAO_BOTAO_ENVIAR

method ONACTIONACAO_BOTAO_ENVIAR .

* // Gravar dados
wd_this->ONGRAVAR( ).

endmethod.

WDDOINIT

method WDDOINIT .

* // Recupera dados do contexto
  Data: context_node type ref to if_wd_context_node.

* // Cria tabela interna do tipo da tabela do node
  Data: it_cargo type STANDARD TABLE OF if_main=>element_ZTCARGO,
        wa_cargos like line of it_cargo.

* // Seleciona dados da tabela Pai
  select * from ztcargo
    into table it_cargo.

* // Recupera node do contexto
  context_node = wd_context->get_child_node( name = 'ZTCARGO').

* // liga tabela interna a tabela do node
  context_node->BIND_TABLE( it_cargo ).

endmethod.

ONGRAVAR

method ONGRAVAR .

* // Recupera dados do controlador
  DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

  DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
  DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
  DATA lv_usuario_login TYPE wd_this->Element_usuario_controler-usuario_login.

  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

*   // Recupera Nome
  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `USUARIO_LOGIN`
    IMPORTING
      value = lv_usuario_login ).

* // Recupera Sobrenome
  DATA lv_sobrenome TYPE wd_this->Element_usuario_controler-sobrenome.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `SOBRENOME`
    IMPORTING
      value = lv_sobrenome ).

* // Recupera Salario
  DATA lv_salario TYPE wd_this->Element_usuario_controler-salario.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `SALARIO`
    IMPORTING
      value = lv_salario ).

* // Recupera Data
  DATA lv_data TYPE wd_this->Element_usuario_controler-data.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `DATA`
    IMPORTING
      value = lv_data ).

* // Recupera Genero
  DATA lv_genero TYPE wd_this->Element_usuario_controler-genero.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `GENERO`
    IMPORTING
      value = lv_genero ).

* // Recupera Ativo
  DATA lv_ativo TYPE wd_this->Element_usuario_controler-ativo.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `ATIVO`
    IMPORTING
      value = lv_ativo ).

* // Recupera Observacao

  DATA lv_observacao TYPE wd_this->Element_usuario_controler-observacao.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `OBSERVACAO`
    IMPORTING
      value = lv_observacao ).

* // Retorna valores do dropdown by index

* // Retorna conexto do node
  DATA: context_node type ref to if_wd_context_node.

* // Cria tabela baseado no tipo do node
  DATA: it_cargo type STANDARD TABLE OF if_main=>element_ZTCARGO,
        wa_cargo like line of it_cargo,
        index type i.

* // chama o node requerido
  context_node = wd_context->get_child_node( name = 'ZTCARGO').

* // Recupera o indice selecionado
  index =  context_node->GET_LEAD_SELECTION_INDEX( ).

* // Recupera os valores atraves do indice
  context_node->GET_STATIC_ATTRIBUTES(
     exporting index = index
     importing STATIC_ATTRIBUTES = wa_cargo ).

* // Declara variáveis
  DATA : guid         TYPE zGuid,
         nome         TYPE ZNome,
         sobrenome    TYPE ZSobrenome,
         cargo        TYPE ZCARGOID,
         salario      TYPE Zsal,
         data_adm     TYPE Zdata,
         genero       TYPE ZGenero,
         ativo        TYPE Zativo,
         observacao   TYPE ZObservacao.

* // Alimenta dados.

  nome       = LV_USUARIO_LOGIN.
  sobrenome  = LV_SOBRENOME.
  cargo      = WA_CARGO-CARGOID.
  salario    = LV_SALARIO.
  data_adm   = LV_DATA.
  genero     = LV_GENERO.
  ativo      = LV_ATIVO.
  observacao = LV_OBSERVACAO.

* // Gera GUID

  CALL FUNCTION 'GUID_CREATE'
    IMPORTING
      ev_guid_16 = guid.

* // Cria persistencia
* // Declara classe Actor e Persistencia
  DATA:  agente       TYPE REF TO ZCA_PARTICIPANTE,
         participante TYPE REF TO ZCL_PARTICIPANTE.

* // Cria agente da classe actor
  AGENTE = ZCA_PARTICIPANTE=>AGENT.

* // cria persistencia
  try.
      participante = AGENTE->CREATE_PERSISTENT( guid ).
    catch CX_OS_OBJECT_EXISTING.
  ENDTRY.

* // Alimenta objeto de persistencia
  PARTICIPANTE->SET_NOME( NOME ).
  PARTICIPANTE->SET_SOBRENOME( SOBRENOME ).
  PARTICIPANTE->SET_CARGOID( CARGO ).
  PARTICIPANTE->SET_DATA( DATA_ADM ).
  PARTICIPANTE->SET_SALARIO( SALARIO ).
  PARTICIPANTE->SET_GENERO( GENERO ).
  PARTICIPANTE->SET_ATIVO( ATIVO ).
  PARTICIPANTE->SET_OBSERVACAO( OBSERVACAO ).

* // Grava e finaliza persistencia
  TRY.
    COMMIT WORK.

* // Exibe mensagem
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

* // Chama método de menssagem
    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* // Exibe mensagem
    CALL METHOD lo_message_manager->REPORT_SUCCESS
      EXPORTING
        MESSAGE_TEXT = 'Dados Inseridos com Sucesso'.

  ENDTRY.

endmethod.
Publicidade

Em princípio, os programas ABAP trabalham com dados de programas locais, que residem na sessão interna dos programas, os dados vivem somente enquanto seu contexto existe, estes tipos de dados são chamados de Transient e existem dentro de objetos de dados do ABAP. Os dados que podem ser preservados além do tempo de execução do programa é conhecido como persistente.

Em uma aplicação orientada a objeto ideal, os dados ocorrem apenas como os atributos de objetos, objetos são uma agregação de funções, nos métodos e de dados nos atributos. A descrição de um objeto, ou seja, a classe, ocorre persistentemente como um pedaço de código-fonte. Isto significa que linguagens orientadas a objeto persistem dados contidos nos atributos dos objetos, que podem ser manipulados através de seus métodos. Tecnicamente falando em uma linguagem orientada a objetos, os objetos contem dados Transients e através de serviços como o SAP Persistence Service podemos utilizar o recurso de mapeamento para preenche a lacuna entre a visão do banco de dados relacional e da visão orientada a objeto, ou seja podemos mapear um atributo que contem dados e liga-lo a um campo em uma tabela transparente.

Podemos identificar cada instancia do objeto utilizando um identificador único global ou GUID (Globally Unique IDentifier) que é um tipo especial de identificador utilizado em aplicações de software para providenciar um número de referência que será único em qualquer contexto (por isso é “Universal”) como, por exemplo, em uma definição de referência interna para um tipo de ponto de acesso em uma aplicação de software ou para a criação de chaves únicas em um banco de dados.

O serviço de persistência permite que o programador ABAP trabalhe com dados de bancos de dados relacionais de forma orientada a objetos, este serviço pode ser comparado a vários outros tipos  de frameworks conhecidos como ORM (Object-relational mapping) é uma técnica de desenvolvimento utilizada para reduzir a impedância da programação orientada aos objetos utilizando bancos de dados relacionais. As tabelas do banco de dados são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes.

SAP Persistence Service: Serviço de Persistência

Usando o Serviço de Persistência com Web Dynpro

1 – Crie uma tabela transparente chamada ZPARTICIPANTE, utilize a imagem abaixo para os tipos de campos:

Tabela Transparente - ZParticipante

Tabela Transparente – ZParticipante

2 – No Class Builder, na transação SE24 crie uma nova classe do tipo persistente chamada ZCL_PARTICIPANTE:

Classe - ZCL_PARTICIPANTE

Classe – ZCL_PARTICIPANTE

3 – Note que temos uma classe com algumas interfaces implementadas. No menu Goto escolha Persistence Representant:

Class Builder

Class Builder

4 – Escolha a tabela transparente criada acima para o mapeamento do objeto:

Tabela Transparente - Mapeamento

Tabela Transparente – Mapeamento

5 – Selecione os campos do dicionário de dados na parte inferior e os insira na parte superior, no qual definirá o mapeamento relacional para o objeto:

Mapeamento - Relacional

Mapeamento – Relacional

6 – Com o mapeamento finalizado salve e volte para a edição da classe:

ORM - Mapeamento Objeto Relacional

ORM – Mapeamento Objeto Relacional

7 – Como você pode notar os atributos e métodos necessários para o mapeamento objeto relacional foram criados automaticamente, salve e ative a classe:

Classe Persistente - Implementada e Ativada

Classe Persistente – Implementada e Ativada

8 – Crie um novo componente Web Dynpro e utilize os elementos de acordo a cada campo na tela, crie um método para o botão e um método de persistência de acordo com os códigos abaixo:

Web Dynpro - MVC - View - ABAP

Web Dynpro – MVC – View – ABAP

9 – Salve, ative, crie e teste sua aplicação. Preencha os dados na pagina web e os envie, eles serão automaticamente persistidos no banco de dados utilizado pelo sistema:

Web Dynpro - Aplicação

Web Dynpro – Aplicação

10 – Você pode conferir os dados persistidos no bando através do Data Browser na transação SE16:

Persistência - Data Browser

Persistência – Data Browser

Exemplo:

Neste exemplo persistimos dados através do serviço de persistência SAP que utiliza um mapeamento objeto relacional, que pode ser considerado equivalente aos frameworks ORM de outras linguagens de programação como o Rails (Ruby),  Hibernate (Java), EF (C#) e ORM Django (Python) entre vários outros.

ABAP

Evento – ONACTIONACAO_BOTAO_ENVIAR

method ONACTIONACAO_BOTAO_ENVIAR .

* // Retorna campos do contexto da View
  DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

  DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
  DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
  DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.

* // Recupera node controller
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).

* // Recupera elemento via lead selection
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

* // Recupera atributo
  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `CARGO`
    IMPORTING
      value = lv_cargo ).

* // Define objetos Regex
  DATA:  regex   TYPE REF TO cl_abap_regex,
         matcher TYPE REF TO cl_abap_matcher.

* Cria objeto Regex e define Pattern
  CREATE OBJECT regex
    EXPORTING
      pattern     = '[a-zA-Z]+'.

* // Verifica valot do elemento contra o Pattern
  matcher = regex->create_matcher( text =  lv_cargo ).

* // Verifca Pattern
IF matcher->match( ) NE 'X'.

* // Define menssagem
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

* // Chama método de menssagem
    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* // Exibe mensagem
    CALL METHOD lo_message_manager->REPORT_MESSAGE
      EXPORTING
        MESSAGE_TEXT      = 'Cargo é exclusivamente um campo alphanumérico'
        CANCEL_NAVIGATION = ABAP_TRUE.
  ENDIF.

* // Gravar dados
wd_this->ONGRAVAR( ).

endmethod.

Método – ONGRAVAR

method ONGRAVAR .

* // Recupera dados do controlador
  DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

  DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
  DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
  DATA lv_usuario_login TYPE wd_this->Element_usuario_controler-usuario_login.

  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

*   // Recupera Nome
  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `USUARIO_LOGIN`
    IMPORTING
      value = lv_usuario_login ).

* // Recupera Sobrenome
  DATA lv_sobrenome TYPE wd_this->Element_usuario_controler-sobrenome.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `SOBRENOME`
    IMPORTING
      value = lv_sobrenome ).

* // Recupera Cargo

  DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `CARGO`
    IMPORTING
      value = lv_cargo ).

* // Recupera Salario
  DATA lv_salario TYPE wd_this->Element_usuario_controler-salario.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `SALARIO`
    IMPORTING
      value = lv_salario ).

* // Recupera Data
  DATA lv_data TYPE wd_this->Element_usuario_controler-data.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `DATA`
    IMPORTING
      value = lv_data ).

* // Recupera Genero
  DATA lv_genero TYPE wd_this->Element_usuario_controler-genero.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `GENERO`
    IMPORTING
      value = lv_genero ).

* // Recupera Ativo
  DATA lv_ativo TYPE wd_this->Element_usuario_controler-ativo.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `ATIVO`
    IMPORTING
      value = lv_ativo ).

* // Recupera Observacao

  DATA lv_observacao TYPE wd_this->Element_usuario_controler-observacao.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `OBSERVACAO`
    IMPORTING
      value = lv_observacao ).

* // Declara variáveis
  DATA : guid         TYPE zGuid,
         nome         TYPE ZNome,
         sobrenome    TYPE ZSobrenome,
         cargo        TYPE ZCargo,
         salario      TYPE Zsal,
         data_adm     TYPE Zdata,
         genero       TYPE ZGenero,
         ativo        TYPE Zativo,
         observacao   TYPE ZObservacao.

* // Alimenta dados.

  nome       = LV_USUARIO_LOGIN.
  sobrenome  = LV_SOBRENOME.
  cargo      = LV_CARGO.
  salario    = LV_SALARIO.
  data_adm   = LV_DATA.
  genero     = LV_GENERO.
  ativo      = LV_ATIVO.
  observacao = LV_OBSERVACAO.

* // Gera GUID

  CALL FUNCTION 'GUID_CREATE'
    IMPORTING
      ev_guid_16 = guid.

* // Cria persistencia
* // Declara classe Actor e Persistencia
  DATA:  agente       TYPE REF TO ZCA_PARTICIPANTE,
         participante TYPE REF TO ZCL_PARTICIPANTE.

* // Cria agente da classe actor
  AGENTE = ZCA_PARTICIPANTE=>AGENT.

* // cria persistencia
  try.
      participante = AGENTE->CREATE_PERSISTENT( guid ).
    catch CX_OS_OBJECT_EXISTING.
  ENDTRY.

* // Alimenta objeto de persistencia
  PARTICIPANTE->SET_NOME( NOME ).
  PARTICIPANTE->SET_SOBRENOME( SOBRENOME ).
  PARTICIPANTE->SET_CARGO( CARGO ).
  PARTICIPANTE->SET_DATA( DATA_ADM ).
  PARTICIPANTE->SET_SALARIO( SALARIO ).
  PARTICIPANTE->SET_GENERO( GENERO ).
  PARTICIPANTE->SET_ATIVO( ATIVO ).
  PARTICIPANTE->SET_OBSERVACAO( OBSERVACAO ).

* // Grava e finaliza persistencia
  TRY.
    COMMIT WORK.

* // Exibe mensagem
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

* // Chama método de menssagem
    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* // Exibe mensagem
    CALL METHOD lo_message_manager->REPORT_SUCCESS
      EXPORTING
        MESSAGE_TEXT = 'Dados Inseridos com Sucesso'.

  ENDTRY.

endmethod.

 

Web Dynpro – Persistência – SAP – Abap

Publicado: 15 de fevereiro de 2015 em Abap

O Open SQL consiste em um conjunto de instruções ABAP que executam operações no banco de dados central no SAP Web AS ABAP. Os resultados das operações e as mensagens de erro são independentes do sistema de base de dados em uso. Open SQL proporciona assim uma sintaxe e a semântica uniforme para todos os sistemas de base de dados suportadas pela SAP. Programas ABAP que usam apenas instruções Open SQL iram funcionar em qualquer sistema SAP, independentemente do sistema de banco de dados em uso.

O Open SQL fornece uma solução moderna e inteligente para persistir dados nos sistemas SAP, no entanto Open SQL é baseado no paradigma de programação declarativa da linguagem SQL e utiliza os tipos de dados e os Data Objects que definem os tipos de campos do sistema SAP, além de também utilizar o dicionário de dados ABAP para manipular dados. Este modelo apesar de ser eficiente e rápido, se utilizado dentro das melhores praticas, não tratam os dados como objetos assim como os frameworks ORM mais modernos usados atualmente nas linguagens orientadas a objeto como o HibernateRails , Entity Framework e vários outros.

A desvantagem é que o ABAP com o Open SQL não proporciona um modo simples a manipulação dos dados completamente orientados a objetos, não podemos manipular objetos e persisti-los do mesmo modo que os frameworks ORM nos proporcionam e nem utilizar recursos de identificadores automáticos que manipulam objetos do banco de dados como tipos de auto incrementos ou sequencias,  mas podemos utilizar alguns Design Patterns para adaptar esta funcionalidade, o único inconveniente é que este tipo de programação pode gerar margem há uma mistura de paradigmas que pode ocasionar um código de baixa qualidade caso não utilizado conforme seus padrões. Por outro lado os sistemas SAP rodam em um ambiente pré estabelecido e já possuem todos os recursos necessários para que você possa manipular e persistir dados facilmente e você só sentirá falta dos recursos dos modernos dos frameworks ORM apenas se você já os utiliza em outras linguagens de programação.

ABAP: Open SQL

Obs: A SAP nos proporciona um framework de persistência ORM para trabalhar sobre o OpenSQL, veremos sobre estas classes mais adiante.

Persistence: Conceitos de Persistência

Persistindo Dados Com Web Dynpro e Open SQL

Os códigos a seguir utilizam os métodos da View de um modo simples para que seja de fácil entendimento,  a manipulação de dados não estão escritos sob nenhum Design Pattern especifico além do MVC proporcionado pelo Web Dynpro.

1 – Crie uma nova tabela transparente chama ZPARTICIPANTE, crie seus tipos, utilize a figura abaixo para detalhes:

Tabela - Tipos de Campos

Tabela – Tipos de Campos

2 – Defina o tipo de tabela e a quantidade de registros previstos para a tabela:

Maintain Technical Settings

Maintain Technical Settings

3 – Quando finalizar ative sua tabela:

ZPARTICIPANTE - Tabela Transparente

ZPARTICIPANTE – Tabela Transparente

4 – O dicionário de dados e o Open SQL não nos proporcionam nenhum tipo de recurso para manipulação de IDs automáticos, ou objetos do banco de dados, já que não possuímos acesso diretamente a ele. No entanto utilizaremos um objeto chamado NUMBER RANGE.

Numer Range: Number Range Object Types

Entre na transação SNRO e crie um novo objeto chamado ZID_PAR:

Number Range Object

Number Range Object

5 – Em Number Length Domain use, NUM10 e em Warning % use o valor 5 ou o valor de porcentagem que deseja receber avisos quando a faixa estiver chegando ao seu limite. Salve.

Define Parâmetros

Define Parâmetros

6 – Clique em Intervals e crie um novo intervalo:

Intervalos

Intervalos

7 – Adicione a faixa de valores desejados que serão utilizados para criar seus identificadores:

Faixa de valores

Faixa de valores

8 – Crie um novo componente Web Dynpro para os dados da tabela, crie seus atributos no controlador e os use na View. Crie um evento para o botão e um método para gravar dos dados na tabela transparente:

Web Dynpro - Métodos

Web Dynpro – Métodos

9 – Ative seu componente Web Dynpro, e teste sua aplicação:

Web Dynpro - Persistência

Web Dynpro – Persistência

10 – Abra a transação SE16 para acessar o navegador de dados do Netweaver e verifique os dados gravados com sucesso:

Mostra Tabela

Mostra Tabela

Exemplo:

Neste exemplo criamos uma tabela transparente e persistimos dados no banco de dados corrente através do Open SQL.

ABAP

Método Botão – ONACTIONACAO_BOTAO_ENVIAR

method ONACTIONACAO_BOTAO_ENVIAR .

* // Retorna campos do contexto da View
  DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

  DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
  DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
  DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.

* // Recupera node controller
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).

* // Recupera elemento via lead selection
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

* // Recupera atributo
  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `CARGO`
    IMPORTING
      value = lv_cargo ).

* // Define objetos Regex
  DATA:  regex   TYPE REF TO cl_abap_regex,
         matcher TYPE REF TO cl_abap_matcher.

* Cria objeto Regex e define Pattern
  CREATE OBJECT regex
    EXPORTING
      pattern     = '[a-zA-Z]+'.

* // Verifica valot do elemento contra o Pattern
  matcher = regex->create_matcher( text =  lv_cargo ).

* // Verifca Pattern
IF matcher->match( ) NE 'X'.

* // Define menssagem
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

* // Chama método de menssagem
    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* // Exibe mensagem
    CALL METHOD lo_message_manager->REPORT_MESSAGE
      EXPORTING
        MESSAGE_TEXT      = 'Cargo é exclusivamente um campo alphanumérico'
        CANCEL_NAVIGATION = ABAP_TRUE.
  ENDIF.

* // Gravar dados
wd_this->ONGRAVAR( ).

endmethod.

Método Gravação – ONGRAVAR

method ONGRAVAR .

* // Recupera dados do controlador
  DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

  DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
  DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
  DATA lv_usuario_login TYPE wd_this->Element_usuario_controler-usuario_login.

  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

*   // Recupera Nome
  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `USUARIO_LOGIN`
    IMPORTING
      value = lv_usuario_login ).

* // Recupera Sobrenome
  DATA lv_sobrenome TYPE wd_this->Element_usuario_controler-sobrenome.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `SOBRENOME`
    IMPORTING
      value = lv_sobrenome ).

* // Recupera Cargo

  DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `CARGO`
    IMPORTING
      value = lv_cargo ).

* // Recupera Salario
  DATA lv_salario TYPE wd_this->Element_usuario_controler-salario.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `SALARIO`
    IMPORTING
      value = lv_salario ).

* // Recupera Data
  DATA lv_data TYPE wd_this->Element_usuario_controler-data.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `DATA`
    IMPORTING
      value = lv_data ).

* // Recupera Genero
  DATA lv_genero TYPE wd_this->Element_usuario_controler-genero.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `GENERO`
    IMPORTING
      value = lv_genero ).

* // Recupera Ativo
  DATA lv_ativo TYPE wd_this->Element_usuario_controler-ativo.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `ATIVO`
    IMPORTING
      value = lv_ativo ).

* // Recupera Observacao

  DATA lv_observacao TYPE wd_this->Element_usuario_controler-observacao.
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  `OBSERVACAO`
    IMPORTING
      value = lv_observacao ).

* // Declara variáveis
  DATA : nome         TYPE ZNome,
         sobrenome    TYPE ZSobrenome,
         cargo        TYPE ZCargo,
         salario      TYPE Zsal,
         data_adm     TYPE Zdata,
         genero       TYPE ZGenero,
         ativo        TYPE Zativo,
         observacao   TYPE ZObservacao.

* // Alimenta dados.

  nome       = LV_USUARIO_LOGIN.
  sobrenome  = LV_SOBRENOME.
  cargo      = LV_CARGO.
  salario    = LV_SALARIO.
  data_adm   = LV_DATA.
  genero     = LV_GENERO.
  ativo      = LV_ATIVO.
  observacao = LV_OBSERVACAO.

* // Recupera numero auto-incremento para o ID
  DATA id_participante TYPE I.

  CALL FUNCTION 'NUMBER_GET_NEXT'
    EXPORTING
      nr_range_nr             = '1'
      object                  = 'ZID_PAR'
    IMPORTING
      NUMBER                  = ID_PARTICIPANTE
    EXCEPTIONS
      INTERVAL_NOT_FOUND      = 1
      NUMBER_RANGE_NOT_INTERN = 2
      OBJECT_NOT_FOUND        = 3
      QUANTITY_IS_0           = 4
      QUANTITY_IS_NOT_1       = 5
      INTERVAL_OVERFLOW       = 6
      BUFFER_OVERFLOW         = 7
      OTHERS                  = 8.

* // Cria Set de dados
  DATA participante TYPE ZPARTICIPANTE.

  PARTICIPANTE-ID_PART = ID_PARTICIPANTE.
  PARTICIPANTE-NOME = NOME.
  PARTICIPANTE-SOBRENOME = SOBRENOME.
  PARTICIPANTE-CARGO = CARGO.
  PARTICIPANTE-DATA = DATA_ADM.
  PARTICIPANTE-GENERO = GENERO.
  PARTICIPANTE-ATIVO = ATIVO.
  PARTICIPANTE-OBSERVACAO = OBSERVACAO.

* // Insere dados na tabela
  INSERT INTO ZPARTICIPANTE VALUES PARTICIPANTE.
  IF SY-SUBRC = 0.
* Define menssagem
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

* Chama método de menssagem
    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* Exibe mensagem
    CALL METHOD lo_message_manager->REPORT_SUCCESS
      EXPORTING
        MESSAGE_TEXT = 'Dados Inseridos com Sucesso'.
  ENDIF.

endmethod.

Web Dynpro – UI Elements – SAP – Abap

Publicado: 7 de fevereiro de 2015 em Abap

O Web Dynpro fornece várias categorias com elementos de interface de usuário e estes elementos estão disponíveis no explorador Web Dynpro através de sua caixa de ferramentas em uma interface RAD para que você possa criar seu layout de um modo simples e fácil. Estes elementos da interface padrão incluem botões, etiquetas, campos de entrada e vários outros elementos.

Como sabemos podemos facilmente utilizar os dados entrados por qualquer interface e grava-los em uma tabela do banco de dados utilizando o dicionário ABAP e o Open SQL. Entretanto a linguagem de programação ABAP não possui Arrays no sentido clássico da palavra, então para que possamos popular as propriedades dos elementos que exigem um índice e valores simples criados manualmente como os ComboBox, Radio Buttons ou outros elementos da interface gráfica como normalmente é utilizado em qualquer outra linguagem de programação, precisamos recorrer a um recurso que os domínios do dicionário ABAP nos disponibilizam chamados de Fixed Values.

Os Fixed Values são faixas de valores de um domínio que especificam uma faixa de valores e podem ser ainda mais restritas, definindo apenas valores fixos. Dos valores fixos definidos para um domínio, estes são utilizados na verificação de entrada de dados em modelos de triagem nos elementos de tela. Você pode criar os valores fixos diretamente na criação de um domínio ou dinamicamente através de código ABAP.

Fixed Values: Valores fixos dos Atributos.

Utilizando os Elementos da UI Web Dynpro

1 – Primeiro precisamos criar um domínio para os elementos de valores fixos que serão utilizados como as tradicionais Arrays para popular os elementos da UI. Entre na transação SE11 e crie um Domain para campo de caixa de escolha no qual utilizaremos na pagina web, este elemento na UI será do tipo DropDownByKey:

Domain - DropDownByKey

Domain – DropDownByKey

2 – Na aba Value Range você pode alimentar os valores fixos ou cria-los manualmente através de código dinâmico:

Value Range - DropDownByKey

Value Range – DropDownByKey

3 – Após criar e ativar o domínio, crie um novo Data Type para a caixa de seleção utilizando o domínio criado, neste caso você pode utilizar o mesmo nome para o Domain e Data Type:

Data Type - DropDownByKey

Data Type – DropDownByKey

OBS: Repita os passos 1 ao 3 para o de botão de radio onde utilizaremos o elemento da UI chamado RadioButtonGroupByKey:

4 – Crie um novo componente Web Dynpro e para o seu controlador crie um node e os atributos para os campos da interface de usuário, você pode utilizar os tipos do ABAP e os Data Types criados acima para manipular os seus atributos. Neste exemplo utilizamos String para os campos Nome, Sobrenome, Salário e Observação. Os Data Types criados acima para os campos Cargo e Gênero, o tipo d para a Data de Admissão e Abap_bool para o campo Ativo:

Controller - Atributos

Controller – Atributos

5 – Crie um layout baseado na figura abaixo, link os atributos do controlador nos atributos de sua View e os ligue aos seus respectivos elementos através de suas propriedades:

View - Layout

View – Layout

6 – Salve e ative seu componente Web Dynpro, crie uma aplicação e a teste. Você pode utilizar uma nova View para exibir os valores dos atributos ou grava-los em uma tabela Z transparente que você também pode criar. Utilize o evento clique do botão para exibir a visão de resultado ou gravar os dados no banco de dados.

Web Dynpro - Aplicação

Web Dynpro – Aplicação

Exemplo:

Neste exemplo utilizamos o paradigma declarativo da interface do Web Dynpro para criar uma pagina web com os elementos básicos de entrada disponíveis pela UI do Web Dynpro. Você encontra os detalhes de como realizar cada procedimento utilizado acima para criar o layout e os elementos básicos da UI nos exemplos anteriores.

 

Em ciência da computação teórica e teoria da linguagem formal, uma expressão regular abreviada de Regex ou Regexp e, por vezes chamado de uma expressão racional é uma sequência de caracteres que forma um padrão de pesquisa, principalmente para uso na correspondência de padrões com Strings, ou sequência correspondente, ou seja, como operações de localizar e substituir. O conceito surgiu na década de 1950, quando o matemático americano Stephen Kleene formalizava a descrição de uma linguagem regular, e entrou em uso comum com os utilitários Unix de processamento de texto.

Cada caractere em uma expressão regular ou é entendido como um MetaCharacter com seu significado especial, ou um caractere regular com o seu significado literal. Em conjunto, eles podem ser usados para identificar material textual de um determinado padrão, ou processar um número de instâncias do mesmo que podem variar de uma igualdade exata para uma semelhança muito geral do padrão.

O Regex pode ser usado para analisar rapidamente grandes quantidades de texto para encontrar padrões de caracteres específicos; para extrair, editar, substituir ou excluir substrings de texto, também é comum serem utilizadas para validar campos.

Regular Expression

Existe muito material sobre expressões regulares, inclusive o ABAP Objects contempla as classes CL_ABAP_REGEX e CL_ABAP_MATCHER para combinar sequências de caracteres contra padrões especificados por expressões regulares. O ABAP também utiliza expressões regulares nas funções FIND e REPLACE através da instrução REGEX.

Regex: Regular Expressions in Routines.

Por outro lado existem alguns sites que proporcionam ótimos materiais sobre Regex e permitem que você crie e teste sua própria expressão regular antes de a utilizar.

RegExr: http://regexr.com/

Expressão regular que contempla caracteres maiúsculos e minúsculos: Pattern [a-zA-Z]+

Regex - [a-zA-Z]+

Regex – [a-zA-Z]+

Expressão regular que contempla números inteiros e flutuantes: Pattern (?:\d*\.)?\d+

Regex - (?:\d*\.)?\d+

Regex – (?:\d*\.)?\d+

Usando Expressões Regulares

1 – Crie um componente Web Dynpro utilizando os elementos básicos como rótulos, campos de texto e um botão. Use a figura abaixo para referencia:

Web Dynpro - Layout

Web Dynpro – Layout

2 – Crie uma Action para o botão e no seu método de evento ONACTIONACAO_BOTAO_ENVIAR utilize o código abaixo:

Web Dynpro - Action - Método

Web Dynpro – Action – Método

3 – Ative seu componente, crie sua aplicação e teste. Insira caracteres no campo Cargo que não correspondem aos caracteres do Pattern escolhido:

Web Dynpro - Validação Regex

Web Dynpro – Validação Regex

Exemplo:

Neste exemplo utilizamos expressões regulares para validar o conteúdo dos campos de uma aplicação Web Dynpro. Na aplicação se um campo de texto conter caracteres que não correspondem a expressão serão automaticamente invalidados.

Abap

Método – ONACTIONACAO_BOTAO_ENVIAR

method ONACTIONACAO_BOTAO_ENVIAR .

* // Retorna campos do contexto da View
  DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

  DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
  DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
  DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.

* // Recupera node controller
  lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).

* // Recupera elemento via lead selection
  lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).

* //  @TODO handle not set lead selection
  IF lo_el_usuario_controler IS INITIAL.
  ENDIF.

* // Recupera atributo
  lo_el_usuario_controler->get_attribute(
    EXPORTING
      name =  'CARGO'
    IMPORTING
      value = lv_cargo ).

* // Define objetos Regex
  DATA:  regex   TYPE REF TO cl_abap_regex,
         matcher TYPE REF TO cl_abap_matcher.

* // Cria objeto Regex e define Pattern
  CREATE OBJECT regex
    EXPORTING
      pattern     = '[a-zA-Z]+'.

* // Verifica valot do elemento contra o Pattern
  matcher = regex->create_matcher( text =  lv_cargo ).

IF matcher->match( ) NE 'X'.

* // Define menssagem
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

* // Chama método de menssagem
    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* // Exibe mensagem
    CALL METHOD lo_message_manager->REPORT_MESSAGE
      EXPORTING
        MESSAGE_TEXT      = 'Cargo é exclusivamente um campo alphanumérico'
        CANCEL_NAVIGATION = ABAP_TRUE.

  ENDIF.

* // Dispara botão
  wd_this->fire_ir_saudacao_plg(
  ).
endmethod.

Web Dynpro – Usando Javascript – SAP- Abap

Publicado: 25 de janeiro de 2015 em Abap, JavaScript

A tecnologia Web Dynpro até a sua versão 7.2 não permite que você utilize Javascript para manipular elementos de sua UI, no entanto o ABAP Objects nos presenteia com a classe CL_JAVA_SCRIPT para que possamos utilizar scripts externos para chamar nossas funções Javascript em aplicações Web Dynpro. As versões mais recentes do Web Dynpro como a 7.3 ou superiores já inclui elementos de integração HTML chamados HTMLIsland e HTMLContainer que possibilita integrar Javascript e CSS aos elementos de sua UI.

Você pode usar a classe CL_JAVA_SCRIPT para executar programas em JavaScript que, por exemplo, são carregados de recursos externos ou programados em um editor e escrito por você mesmo. Você também pode criar um arquivo Javascript dinamicamente de um código ABAP.

CL_JAVA_SCRIPT: Objetos Javascript

HTML Integration: Integração HTML

Usando uma Biblioteca Externa

1 – Crie um novo componente Web Dynpro e crie seu layout como na figura abaixo, usando os elementos básicos, como labels, caixa de texto, botões e containers transparentes para espaçar os elementos:

Web Dynpro - Layout

Web Dynpro – Layout

2 – Crie dois atributos no contexto da View Main, um para o Input_field e outro para exibir a mensagem no TextView:

Web Dynpro - Contexto - Atributos

Web Dynpro – Contexto – Atributos

3 – Crie um evento de clique para o botão e utilize o código abaixo para criar seu recurso javascript dinamicamente:

Web Dynpro - Botão - Evento

Web Dynpro – Botão – Evento

4 – Ative e teste sua aplicação, entre com um valor e a função Javascript do recurso criado dinamicamente chamado script.js será executada e seu resultado retornado em uma variável javascript chamada resultado que será recuperada e exibida na página Web.

Web Dynpro - Aplicação

Web Dynpro – Aplicação

Exemplo:

Neste exemplo utilizamos a classe CL_JAVA_SCRIPT para criar um arquivo Javascript que contem uma função e uma variável que retorna o resultado da função, utilizamos o evento de clique do botão para criar, compilar e executar a função Javascript e manipula-la através de código ABAP.

Abap

method ONACTIONONCLIQUEBOTAO .

* //Declara objetos javascript e scripts
  DATA: MSG       TYPE string,
        Get_valor TYPE string,
        JS_Objeto TYPE REF TO CL_JAVA_SCRIPT,
        MeuScript TYPE String.

* //Os códigos utilizando a instrução WRITE
* //Não tem efeito no Web Dynpro
* //você pode utilizar os trechos em um programa comum
* //para testar o seu javascript dinâmico.

* //Cria Script
  CONCATENATE
  ' function quadrado(x) { return x * x}; '
  ' var resultado = quadrado(mapa) '
  INTO MEUSCRIPT SEPARATED BY  CL_ABAP_CHAR_UTILITIES=>CR_LF.

* //Cria objeto javascript
  JS_OBJETO = CL_JAVA_SCRIPT=>CREATE( ).

* //Compila objeto javascript
  JS_OBJETO->COMPILE(
    exporting
      SCRIPT_NAME = 'script.js'
      SCRIPT      = MEUSCRIPT ).

* //Verifica compilação
  if JS_OBJETO->LAST_CONDITION_CODE <> 0.
    write: / 'Erro de compilação de script',
             JS_OBJETO->LAST_ERROR_MESSAGE.
  else.
    write / 'foi compilado com sucesso'.
  endif.

* //Recupera valor do usuário
  DATA lo_el_context TYPE REF TO if_wd_context_element.
  DATA ls_context TYPE wd_this->Element_context.
  DATA lv_valor TYPE wd_this->Element_context-valor.

* //Recupera elemento via lead selection
  lo_el_context = wd_context->get_element( ).

* // @TODO Caso queira validar o elemento vazio
  IF lo_el_context IS INITIAL.
  ENDIF.

* //Recupera o atributo
  lo_el_context->get_attribute(
    EXPORTING
      name =  `VALOR`
    IMPORTING
      value = lv_valor ).

* //Define um valor de variavel atravez do ABAP
  JS_OBJETO->SET( NAME = 'mapa' VALUE = lv_valor  ).

* //Executa Javascript
  JS_Objeto->EXECUTE(
                exporting SCRIPT_NAME = 'script.js' ).

* //Verifica se script foi executado
  if JS_OBJETO->LAST_CONDITION_CODE <> 0.
    write: / 'Erro na execução de script',
             JS_OBJETO->LAST_ERROR_MESSAGE.
  else.
    write / 'JavaScript foi executado com sucesso'.
  endif.

  skip.

* //Retorna valor de script
  GET_VALOR = JS_OBJETO->GET( NAME = 'resultado' ).

* //Define uma menssagem para o usuario
  DATA lv_msg TYPE wd_this->Element_context-msg.

* //Recupera o elemento via lead selection
  lo_el_context = wd_context->get_element( ).

* // @TODO - caso queira validar
  IF lo_el_context IS INITIAL.
  ENDIF.

* //Cria mensagem de retorno para o usuário
  CONCATENATE lv_valor ' * ' lv_valor ' = ' GET_VALOR INTO MSG.
  lv_msg = MSG.

* //Define valor do atributo
  lo_el_context->set_attribute(
    name =  `MSG`
    value = lv_msg ).

* //Verifica se o objeto retornou um valor
  if JS_OBJETO->LAST_CONDITION_CODE <> 0.
    write: / 'Erro em recuperar objeto javascript',
             JS_OBJETO->LAST_ERROR_MESSAGE.
  else.
    write: / 'Valor do objeto :', GET_VALOR.
  endif.

endmethod.

SAP – Web Dynpro – Validations – Abap

Publicado: 16 de janeiro de 2015 em Abap

Web Dynpro possui algumas funcionalidades que visam facilitar a validação de campos e economizar tempo do desenvolvedor na criação da interface com o usuário. Uma verificação dos campos de entrada requeridos automáticos ainda não estão implementados no Web Dynpro e também não é planejado para o futuro, no entanto existem alguns métodos para executar esta ação. Para validação você pode executar a classe CL_WD_DYNAMIC_TOOL no seu evento ou no evento DoBeforeAction.

Isto significa que a propriedade State com o valor Required no elemento InputField somente exibirá um caractere asterisco na cor vermelha no seu elemento Label Associado, para que ocorra uma validação você precisa escrever códigos que valide o valor do atributo e exiba uma mensagem de acordo com o resultado.

Web Dynpro: Input Fields

Validando Campos Obrigatórios

Neste walkthrough utilizamos um componente e uma aplicação Web Dynpro básica com duas Views. Lembre-se que o Web Dynpro utiliza a arquitetura MVC e você deve criar a rota para suas Views utilizando corretamente os plugs InBound e OutBound na árvore Windows. Caso queira lembrar como configurar uma aplicação básica Web Dynpro clique aqui.

1 – Crie sua View principal (Main) utilizando os componentes básicos como PageHeader, Labels, InputFields, TransparentContainer e Button. Modifique suas propriedades e utilize o layout chamado GridLayout, use a figura abaixo para referencia.

No InputField para o valor cargo, mude sua propriedade state para required:

Web Dynpro - View - Main

Web Dynpro – View – Main

2 – No controlador, crie os atributos para cada campo no contexto:

Web Dynpro - Controlador - Atributos

Web Dynpro – Controlador – Atributos

 

3 – Adicione os atributos no contexto da View principal:

Web Dynpro - View - Contexto

Web Dynpro – View – Contexto

4 – Volte para a View e associe os atributos as campos de entrada:

Web Dynpro - Associar Atributos

Web Dynpro – Associar Atributos

5 – Na segunda View, adicione os atributos para o contexto e arraste para a página os elementos de texto e associe os atributos a seus valores:

Web Dynpro - View- Associar Atributos

Web Dynpro – View- Associar Atributos

6 – Na View Main, na barra de ferramentas escolha Web Dynpro Code Wizard, e na aba atributos escolha o atributo Cargo. Preencha o método WDDOBEFOREACTION para fique igual ao código abaixo:

Web Dynpro - Code Wizard

Web Dynpro – Code Wizard

7 – Ative o componente e teste sua aplicação, entre com o seu usuário e senha e preencha os campos menos o campo com o sinal de asterisco (campo obrigatório):

Web Dynpro - Campo Obrigatório

Web Dynpro – Campo Obrigatório

8 – Assim que você enviar a requisição o campo será validado no evento DoBeforeAction e se o campo tiver com seus valores iniciais, ou seja em branco uma mensagem será exibida e a navegação cancelada:

Web Dynpro - Validação

Web Dynpro – Validação – Mensagem

9 – Quando o campo requerido for satisfeito e a requisição reenviada, o processo será executado com sucesso:

Web Dynpro - Validação - OK

Web Dynpro – Validação – OK

Exemplo:

Neste exemplo utilizamos o evento WDDoBeforeAction para validar o atributo e exibir uma mensagem para que o usuário preencha o campo corretamente:

Abap

method WDDOBEFOREACTION .

   DATA lo_nd_usuario_controler TYPE REF TO if_wd_context_node.

   DATA lo_el_usuario_controler TYPE REF TO if_wd_context_element.
   DATA ls_usuario_controler TYPE wd_this->Element_usuario_controler.
   DATA lv_cargo TYPE wd_this->Element_usuario_controler-cargo.

*  navigate from <CONTEXT> to <USUARIO_CONTROLER> via lead selection
   lo_nd_usuario_controler = wd_context->get_child_node( name = wd_this->wdctx_usuario_controler ).

*  @TODO handle non existant child
*  IF lo_nd_usuario_controler IS INITIAL.
*  ENDIF.

*  get element via lead selection
   lo_el_usuario_controler = lo_nd_usuario_controler->get_element( ).
*  @TODO handle not set lead selection
   IF lo_el_usuario_controler IS INITIAL.
   ENDIF.

*  get single attribute
   lo_el_usuario_controler->get_attribute(
     EXPORTING
       name =  `CARGO`
     IMPORTING
       value = lv_cargo ).

if lv_cargo is initial.

* get message manager
    data lo_api_controller     type ref to if_wd_controller.
    data lo_message_manager    type ref to if_wd_message_manager.

    lo_api_controller ?= wd_This->Wd_Get_Api( ).

    CALL METHOD lo_api_controller->GET_MESSAGE_MANAGER
      RECEIVING
        MESSAGE_MANAGER = lo_message_manager.

* report message
    CALL METHOD lo_message_manager->REPORT_MESSAGE
      EXPORTING
        MESSAGE_TEXT = 'Cargo é um campo obrigatório'
        CANCEL_NAVIGATION = ABAP_TRUE.

ENDIF.

endmethod.

A interface gráfica das ferramentas do Web Dynpro nos proporciona um modo de criar aplicações web usando um ambiente RAD que em português significa, desenvolvimento rápido de aplicações. Além do ambiente RAD, o Web Dynpro nos proporciona o paradigma da programação declarativa, que significa que vamos desenvolver uma aplicação escrevendo o mínimo de código fonte possível. Vamos fazer isto utilizando o Pattern mais difundido para aplicações para web na atualidade, o MVC, que nos permite maior controle sobre os elementos e objetos da aplicação em relação aos modelos e visões.

Criando um Aplicação Web Dynpro

1 – Crie um novo componente Web Dynpro e arraste para a tela um elemento Header, um TransparentContainer, um Label, um Input_Field e um Button. Preencha os campos textos e para o elemento Header e ligue a propriedade Label For no elemento Input_Field. Para o elemento TransparentContainer mude a propriedade Height para 10 px:

View - Main - Layout

View – Main – Layout

2 – Clique em Views e com o botão direito crie uma nova View chamada Saudação:

Nova - View - Saudacao

Nova – View – Saudação

3 – Abra a nova View e insira em seu Layout os elementos Header, TransparentContainer e 2 TextView. Mude as propriedades Text dos elementos TextViews para “Bem-vindo:” e “usuário” e a propriedade Height do TransparentContainer para 10px:

View - Saudação - Layout

View – Saudação – Layout

4 – Agora vamos utilizar atributos para guardar o valor do campo de entrada de texto, vamos fazer isto no contexto do controlador. No seu componente Dynpro, clique em COMPONENTCONTROLLER e selecione Context e com o botão direito Create->Node:

Controller - Contexto

Controller – Contexto

5 – Crie um Node para o controlador chamado Usuario_Controller, este node será onde guardaremos nosso atributo, ele está localizado no contexto do controlador, isto significa que todas as visões podem vê-lo:

Node - Controle Usuário

Node – Controle Usuário

6 – No novo Node crie um atributo chamado usuario_login do tipo string, este atributo será usado para guardar o valor digitado no campo de texto:

Atributo - Usuário - String

Atributo – Usuário – String

7 – ATENÇÃO – Neste momento vamos ligar os componentes para que obtenhamos a funcionalidade desejada para a aplicação. Clique na View Main e na aba Context, arraste o Node criado no controlador para o contexto da View:

Main - Contexto - Atributos

Main – Contexto – Atributos

8 – Agora podemos enxergar o atributo do controlador em nossa View, clique em Layout e clique no elemento Input_Field, vamos ligar o atributo no valor da propriedade Value do elemento:

Ligação - Atributo - Valor

Ligação – Atributo – Valor

9 – Abra a View Saudacao e na aba Context faça a mesma coisa, arraste o Node do controlador para o contexto da View para que possamos enxergar o atributo:

View - Saudação - Contexto - Atributo

View – Saudação – Contexto – Atributo

10 – Abra a aba Layout e clique no segundo elemento TextView no qual está reservado para exibir o nome digitado pelo usuário e ligue a propriedade Text do elemento ao atributo da View:

View - Atributo - Text

View – Atributo – Text

11 – IMPORTANTE – Agora vamos criar a regra para uma ação, ou seja vamos criar plugs dizendo que queremos que a View Main abra a View Saudação. Para isto abra a aba OutBound Plugs e crie um Plug de saída chamado ir_saudação:

Plugs - OutBound - Saida

Plugs – OutBound – Saida

12 – Abra a View Saudação e na aba InBound Plugs vamos criar um plug de entrada chamado vir_main:

Plugs - InBound - Entrada

Plugs – InBound – Entrada

13 – No seu componente Dynpro abra o item Windows e arraste a View Saudação para a estrutura do objeto Window:

Window - Estrutura das Views

Window – Estrutura das Views

14 – Agora vamos plugar os plugs criados anteriormente arraste o plug Out (vermelho) IR_SAUDACAO para o plug In VIR_MAIN:

Ligação - Plugar Out -> In

Ligação – Plugar Out -> In

15 – Volte para a View Main e clique no elemento Button, em sua propriedade onAction vamos criar uma ação para o evento de clique do botão, preencha os dados para o evento e escolha o plug de saída IR_SAUDACAO:

Eventos - Botão - Ação

Eventos – Botão – Ação

16 -Salve, ative o componente e teste sua aplicação. Alimente o usuário e senha para login, com o navegador aberto entre seu nome no campo de texto e clique no botão enviar:

Aplicação - View - Main

Aplicação – View – Main

17 – O controlador processará a ação alimentando o valor ligado ao atributo ao dado inserido na propriedade de texto do campo de entrada e o enviará para a visão de saudação alimentando a propriedade de texto do elemento de texto, criando assim a funcionalidade da aplicação:

View - Saudação

View – Saudação

Como utilizamos o paradigma de programação declarativa não escrevemos uma única linha de código sequer, mas isto não significa que não haja código fonte.  Para ver o código da aplicação, clique na View Main e na aba Action e dê um duplo clique na ação criada, você será levado ao método criado para executar o evento de clique do botão.

Abap

method ONACTIONACAO_BOTAO_ENVIAR .
  wd_this->fire_ir_saudacao_plg(
  ).
endmethod.

SAP – Web Dynpro – Hello World – Abap

Publicado: 2 de janeiro de 2015 em Abap

O Web Dynpro é a tecnologia padrão SAP para o desenvolvimento de aplicações Web no ambiente ABAP. Ela consiste de um ambiente de tempo de execução e um ambiente gráfico de desenvolvimento com ferramentas Dynpro especiais para web que estão integradas no ABAP Workbench. O modelo de programação Web Dynpro é baseado no Design Pattern Model View Controller (MVC) entretanto sua UI utiliza o paradigma de programação declarativa.

O Web Dynpro possui ferramentas gráficas para o desenvolvimento que de certo modo são similares a outras soluções para web que utilizam programação declarativa como por exemplo, o Oracle Application Express que também utiliza o paradigma declarativo, no entanto diferente do Web Dynpro o APEX possui uma IDE RAD que é executada inteiramente no navegador web e é parte integrante do Oracle Database. A principal característica deste paradigma de programação é a pouca necessidade de escrever código fonte para criar aplicações robustas.

Criando Sua Primeira Aplicação Web Dynpro

Para criar um aplicação Web Dynpro você precisa criar um componente Dynpro que é nada mais que um tipo de projeto MVC.

1- Abra ABAP Development Workbench com a transação SE80, escolha “Web Dynpro Comp./ Inf.” e preencha o campo de busca como ZMeuDynpro.

SE80 - Web Dynpro - Componente

SE80 – Web Dynpro – Componente

2- Clique em pesquisar, quando indagado escolha criar um componente Web Dynpro:

Dynpro - Criar Componente

Dynpro – Criar Componente

3 – Expanda Views e clique em Main. Na aba Layout clique com o botão direito em ROOTUIELEMENT e escolha Insert Element:

Dynpro - View

Dynpro – View

4 – Escolha um ID para o elemento e escolha o tipo Page Header:

Tipo de Elemento

Tipo de Elemento

5 – Com o elemento criado, o selecione e em sua propriedade title, escolha um titulo:

Modifica Elemento

Modifica Elemento

6 – ATENÇÃO – Clique no botão Show/Hide Layout Preview. O Preview irá lhe mostrar o design da pagina, entretanto todos os serviços necessários para que o Web Dynpro funcione precisam estar ativados, caso lhe mostre algum erro nesta tela, saia, ative os serviços requisitados e volte.

O Preview lhe permite utilizar uma caixa de ferramentas para que você arraste os elementos na pagina e monte seu design mais rapidamente. Adicione na tela um elemento TransparentContainer e um Label, mude a propriedade text do Label e associe sua propriedade Label For no TransparentContainer. A propriedade Label For é obrigatória e geralmente é associada a uma caixa de texto:

Layout Preview

Layout Preview

7 – Clique no seu componente com o botão direito e o ative:

Ativar - Dynpro

Ativar – Dynpro

8 – Agora precisamos criar uma aplicação Web Dynpro, com o botão direito escolha Create e Web Dynpro Application:

Criar Aplicação

Criar Aplicação

9 – Defina uma descrição para sua aplicação:

Descrição da Aplicação

Descrição da Aplicação

10 – Em sua aplicação, clique com o botão direito e escolha Test:

Testar Aplicação

Testar Aplicação

11 – O seu navegador padrão será aberto, no entanto ainda não definimos um protocolo seguro para aplicação e uma pagina lhe questionará sobre a autenticação, clique em Log On:

Web Dynpro - Log On

Web Dynpro – Log On

12 – Digite o seu usuário e senha:

Log On

Log On

13 – Pronto sua aplicação foi executada com sucesso:

Web Dynpro App

Web Dynpro App

Não se esqueça que todos os serviços básicos ICM e ICF precisam estar ativados para que você possa desenvolver e rodar aplicações Web Dynpro. A Aplicação é criada como um serviço ICF no seguinte local, Virtual Host: sap/bc/webdynpro/sap/SuaApp.

Para saber como configurar um ambiente básico para criar e rodar aplicações Web Dynpro clique aqui.

 

 

O Web Dynpro é uma tecnologia de aplicação web proprietária desenvolvida pela SAP AG que se concentra no desenvolvimento de aplicações de negócio  para web, do lado do servidor. Uma de suas principais características de seu projeto é que a interface do usuário é definida de uma forma totalmente declarativa. Aplicações Web Dynpro podem ser desenvolvidas usando um Java (Web Dynpro para Java) ou ABAP (Web Dynpro ABAP).

Por motivos de segurança os serviços necessários para que uma aplicação Web Dynpro seja executada ou escrita utilizando o Netweaver, por padrão estão desabilitados, deste modo é necessário uma serie de configurações adicionais para que possamos rodar um aplicação Web Dynpro. Podemos dizer então que basicamente o Web Dynpro utiliza os componentes ICM (Internet Communication Manager) e ICF (Internet Communication Framework).

SAP Oficial: Web Dynpro

Configuração Inicial Web Dynpro

1 – Abra a transação SMICM para acessar o ICM Monitor:

ICM Monitor

ICM Monitor

2- No menu GOTO escolha Parameters->Display. Procure pelo item icm/host_name_full, você verá que ele esta com o nome do seu computador que é o nome do servidor de aplicação do Netweaver.

ICM Parâmetros

ICM Parâmetros

3 – O ICM requer que tenhamos um DNS valido chamado de Fully Qualified Domain Names (FQDN) e não o nome do servidor de aplicação do Netweaver.

FQDN: Fully Qualified Domain Names 

Para realizar esta tarefa podemos efetuar uma configuração no perfil do Default do Netweaver, entre na transação RZ10 e selecione o perfil Default, clique em Extended Maintance e clique em Change:

Netweaver - Profile

Netweaver – Profile

4 – Adicione um novo parâmetro para o icm/host_name_full de valor devabertosap.com, este será o nosso FQDN, salve o parâmetro, volte a tela e ative o perfil:

Netweaver - ICM - FDQN Parâmetro

Netweaver – ICM – FQDN Parâmetro

Sabemos que estas configurações no mundo real precisam ser efetuadas por um consultor BASIS, por este motivo caso você tenha algum problema par importar, modificar, salvar e ativar seu perfil no qual depende de outras configurações, você pode utilizar diretamente o arquivo de configuração de perfil do Netweaver, com isso você corta os dois passos acima. Seu arquivo Default.PFL é encontrado no diretório: C:\usr\sap\NSP\SYS\profile.

Default.PFL (Utilizamos o cliente de desenvolvimento 200 nesta configuração)

SAPDBHOST = Estacao01
j2ee/dbtype = sap
j2ee/dbname = NSP
j2ee/dbhost = Estacao01
SAPSYSTEMNAME = NSP
SAPGLOBALHOST = Estacao01
system/type = ABAP
#-----------------------------------------------------------------------
# SAP Message Server for ABAP
#-----------------------------------------------------------------------
rdisp/mshost = Estacao01
rdisp/msserv = 0
rdisp/msserv_internal = 3900
login/system_client = 200
login/no_automatic_user_sapstar = 0
icm/host_name_full = devabertosap.com

5 – ATENÇÃO – Entre na transação SICF e clique no botão Execute. Neste passo você precisa ativar os serviços básicos para que possamos criar e rodar aplicações Web Dynpro:

ICF - Services

ICF – Services

Procure com cuidado e ative clicando com o botão direito em cima do serviço selecionado e escolhendo a opção Activate Service:

/default_host/sap/public/bc/ur
/default_host/sap/public/bc/icons
/default_host/sap/public/bc/icons_rtl
/default_host/sap/public/bc/webicons
/default_host/sap/public/bc/pictograms
/default_host/sap/public/bc/webdynpro/* (ssr, mimes, etc.)
/default_host/sap/public/myssocntl

/default host/sap/bc/webdynpro
/default host/sap/bc/wdvd

ICF: ICF services

6 – Após as configurações no Netweaver precisamos configurar o arquivo de host do Windows para utilizar o FQDN configurado no sistema SAP. Entre no prompt de comando e digite ipconfig, verifique o IP da sua placa de rede virtual (MS Loopback) ou qualquer outra que você utilize.

Nesta instalação não utilizamos o MS Loopback (recomendado pela SAP) e o substituímos pelo Oracle VirtualBox Host:

Servidor de Aplicação SAP - Placa Virtual

Servidor de Aplicação SAP – Placa Virtual

7 – Abra seu arquivo de hosts com direitos de administrador e insira o IP e o seu FQDN, vide imagem para referencia:

O arquivo hosts é encontrado no diretório: C:\Windows\System32\Drivers\etc

Hosts - IP - FQDN

Hosts – IP – FQDN

8 – Após todas estas configurações reinicie o servidor SAP e você estará apto a criar sua primeira aplicação Web Dynpro. Veja nosso post Hello World – Web Dynpro para saber como utilizar o Web Dynpro pela primeira vez:

Servidor SAP

Servidor SAP

Para criar sua primeira aplicação Web Dynpro clique aqui.