Data

28 jan, 2014

Utilizando collections para criação de formulários tabulares no Oracle APEX – Parte 03

Publicidade

Olá, pessoal! Vou continuar o artigo de como criar formulários tabulares no Oracle APEX utilizando collections. Nesta última parte do artigo, vou demonstrar como efetuar o processamento dos dados das collections e como efetuar a carga das informações que estão nas tabelas para a collections equivalentes.

Criando processo de carga da collection

Para visualizar as informações no formulário tabular é necessário primeiro carregar as informações da tabela para a collection quando o usuário acessar a página.

Crie um processo do tipo PL/SQL para ser executado no momento de renderização da página:

art01

art02

Este processo deverá inicializar/limpar a collection. Para isso, utilize a API APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION e passe o nome da collection criada anteriormente, no caso TELEFONE.

Para carregar as informações, deve-se  ler os telefones da pessoa escolhida anteriormente na tela de listagem e utilizar a API APEX_COLLECTION.ADD_MEMBER, passando o nome da collection e os valores para os campos equivalentes. Lembre-se que deve ser seguido o mesmo mapeamento dos campos que foi determinado na query da região do formulário tabular.

declare
begin

   apex_collection.create_or_truncate_collection(p_collection_name  => 'TELEFONE');
   
    
    FOR dd in (SELECT *
                 FROM TB_TELEFONE P
                WHERE P.ID_PESSOA = :P2_ID_PESSOA) LOOP
                
             
        APEX_COLLECTION.add_member (p_collection_name      => 'TELEFONE',
                                  
                                    p_N001                 => dd.ID_TELEFONE,
                                    p_N002                 => dd.ID_PESSOA,
                                    p_C001                 => dd.DESCRICAO,
                                    p_N003                 => dd.DDI,
                                    p_N004                 => dd.DDD,
                                    p_N005                 => dd.NUMERO,        
                                    p_C002                 => dd.RAMAL,
                                    p_C003                 => dd.PRINCIPAL,        
                                    p_C004                 => dd.ATIVO,      
                                    p_D001                 => dd.DATA_INCLUSAO,
                                    p_C005                 => dd.USUARIO_INCLUSAO,
                                    p_D002                 => dd.DATA_ALTERACAO,
                                    p_C006                 => dd.USUARIO_ALTERACAO,                         
                                        
                                    p_generate_md5         => 'YES'
                                        
                                   );   
       
       
    END LOOP;                
   
end;

Atenção: O parâmetro p_generate_md5 é utilizado para gerar uma HASH do tipo MD5 baseado nos dados do registro, essa chave será utilizada posteriormente para identificar se o registro foi alterado. Logo deve-se optar por sim.

Importante: o processo criado acima deve ser executado após o processo de carga dos dados da pessoa.

Criando o botão de adição de linhas

Para adicionar novas linhas no formulário tabular é necessário adicionar um novo registro em branco na collection. Crie um botão do tipo “Region Button” para adicionar o novo registro:

art03

Determine a localização do botão na região:

art04

Determine a ação que será executada quando o botão for clicado. Neste caso, quando botão for clicado, deverá ser executado um conjunto de ações dinâmicas.

art05

Finalize a criação do botão e crie uma ação dinâmica para ele:

art06

Deverão ser executadas duas ações quando o botão for clicado.

1. Adicionar uma linha na collection

Deve executar a procedure APEX_COLLECTION.ADD_MEMBER, passando o nome da collection e os valores para seus campos. Lembre-se que deve ser seguido o mapeamento que está sendo utilizado na query da região que foi criada na segunda parte do artigo.

APEX_COLLECTION.add_member (p_collection_name      => 'TELEFONE',
                                  
                              p_N001                 => 0,              		--ID_TELEFONE
                              p_N002                 => :P2_ID_PESSOA,    	--ID_PESSOA
                              p_C001                 => null,           		--DESCRICAO,
                              p_N003                 => null,           		--DDI,
                              p_N004                 => null,           		--DDD,
                              p_N005                 => null,           		--NUMERO,        
                              p_C002                 => null,           		--RAMAL,
                              p_C003                 => null,           		--PRINCIPAL,        
                              p_C004                 => 'S',           		--ATIVO,      
                              p_D001                 => SYSDATE,        		--DATA_INCLUSAO,
                              p_C005                 => V('APP_USER'),  		--USUARIO_INCLUSAO,
                              p_D002                 => SYSDATE,        		--DATA_ALTERACAO,
                              p_C006                 => V('APP_USER'),  		--USUARIO_ALTERACAO,                         
                                        
                              p_generate_md5         => 'YES'
                                        
                             );

Atenção: o campo ID_TELEFONE (PK da Tabela) deve sempre ser inicializado com 0 – esse será o identificador para determinar se o registro é novo ou esta sendo alterado.

art07

 

No atributo “Page Items to Submit”, informe o campo equivalente ao ID da pessoa, neste caso P2_ID_PESSOA que foi passado pela tela de listagem de pessoas.

2. Efetuar um refresh na região de telefones

art08

 

O Refesh na região irá recarregar os dados da tabela APEX_COLLECTION para o formulário tabular com o novo registro adicionado.

Processando as informações

Por último, deve-se criar um “Process” para executar o bloco PL/SQL que atualizará a tabela de telefones quando clicar nos botões Salvar/Incluir.

art09

O código abaixo busca as informações contidas na collection e Atualiza/Insere na tabela de telefones.

DECLARE

numAlteradosTelefone number := 0;
numDeletadosTelefone number := 0;
numIncluidosTelefone number := 0;

numPessoa            number;

BEGIN


      ---Processa os TELEFONES 
      BEGIN
       FOR a IN (SELECT SEQ_ID,
                        ID_TELEFONE,
                        DESCRICAO,
                        DDI,
                        DDD,
                        NUMERO,        
                        RAMAL,
                        PRINCIPAL,        
                        ATIVO,      
                        DATA_INCLUSAO,
                        USUARIO_INCLUSAO,
                        DATA_ALTERACAO,
                        USUARIO_ALTERACAO,
                        CHECKSUM
                   FROM (  SELECT SEQ_ID            SEQ_ID,
                                  N001              ID_TELEFONE,
                                  N002              ID_PESSOA,
                                  C001              DESCRICAO,
                                  N003              DDI,
                                  N004              DDD,
                                  N005              NUMERO,        
                                  C002              RAMAL,
                                  C003              PRINCIPAL,        
                                  C004              ATIVO,      
                                  D001              DATA_INCLUSAO,
                                  C005              USUARIO_INCLUSAO,
                                  D002              DATA_ALTERACAO,
                                  C006              USUARIO_ALTERACAO,
                                  MD5_ORIGINAL      CHECKSUM
                             FROM APEX_COLLECTIONS A
                            WHERE A.COLLECTION_NAME = 'TELEFONE') TB_TELEFONE_V) LOOP
       
       
          --Se existir o ID_TELEFONE, identifica como registro alterado
          IF(a.ID_TELEFONE > 0)THEN
          
            ---verifica o checksum do registro para verificar se o dado foi alterado
            IF(A.CHECKSUM <> APEX_COLLECTION.GET_MEMBER_MD5('TELEFONE',a.SEQ_ID)) THEN
            
               UPDATE TB_TELEFONE
                  SET DESCRICAO            = a.DESCRICAO,
                      DDI                  = a.DDI,
                      DDD                  = a.DDD,
                      NUMERO               = a.NUMERO,        
                      RAMAL                = a.RAMAL,
                      PRINCIPAL            = a.PRINCIPAL,        
                      ATIVO                = a.ATIVO,
                      DATA_INCLUSAO        = SYSDATE,
                      USUARIO_INCLUSAO     = V('APP_USER'),      --Login do usuário corrente
                      DATA_ALTERACAO       = SYSDATE,
                      USUARIO_ALTERACAO    = V('APP_USER')         
                WHERE ID_TELEFONE          = a.ID_TELEFONE
                  AND ID_PESSOA            = V('P2_ID_PESSOA'); --Item com o id da pessoa
        
               if(sql%rowcount > 0)then
                   IF(A.ATIVO = 'N')THEN
                     numDeletadosTelefone := numDeletadosTelefone + 1;             
                   ELSE
                     numAlteradosTelefone := numAlteradosTelefone + 1;
                   END IF;
               end if;
       
             END IF;
       
          --Se o ID_TELEFONE for 0, então é inclusão
           ELSE
       
                       
              BEGIN
       
       
                    INSERT INTO TB_TELEFONE(DESCRICAO,
                                            DDI,
                                            DDD,
                                            NUMERO,        
                                            RAMAL,
                                            PRINCIPAL,        
                                            ATIVO,
                                            DATA_INCLUSAO,
                                            USUARIO_INCLUSAO,
                                            DATA_ALTERACAO,
                                            USUARIO_ALTERACAO,
                                            ID_PESSOA,
                                            ID_TELEFONE)
                                   VALUES(a.DESCRICAO,
                                          a.DDI,
                                          a.DDD,
                                          a.NUMERO,        
                                          a.RAMAL,
                                          a.PRINCIPAL,        
                                          a.ATIVO,
                                          SYSDATE,
                                          V('APP_USER'),           --Login do usuário corrente
                                          SYSDATE,
                                          V('APP_USER'),
                                          V('P2_ID_PESSOA'),      --Item com o id da pessoa
                                          TELEFONE_SEQ.NEXTVAL);
       
       
       
                       if(sql%rowcount > 0)then
                        IF(A.ATIVO = 'N')THEN
                           numDeletadosTelefone := numDeletadosTelefone + 1;             
                        ELSE
                           numIncluidosTelefone := numIncluidosTelefone + 1;
                        END IF;
                       end if;
                       
              EXCEPTION WHEN DUP_VAL_ON_INDEX THEN
                  NULL;
              END;
                
          END IF;
       
       
         END LOOP;
       
       
      END;


END;

Veja que para identificar se o registro é novo, utilize o ID_TELEFONE igual a zero e ele deverá ser inserido. Caso o ID_TELEFONE seja maior que zero, isso indica que o registro já existe. No caso de alteração, a coluna CHECKSUM da view APEX_COLLECTION (que guarda a HASH do registro quando esta foi lida) será comparada com a nova HASH do registro, se os conteúdos forem diferentes o registro esta alterado.

Importante: o novo processo deve ser criado após o processo de inclusão dos dados da tabela pessoa.

Conclusão

É possível criar quantos formulários tabulares forem necessários, basta repetir os passos citados no artigo. Faça isso para o formulário tabular de ENDEREÇOS.

Esta solução além de possibilitar criar vários formulários tabulares em uma mesma página, também permite inserir todos os registros de uma só vez de maneira prática para o usuário, sem a necessidade de efetuar várias paginações entre páginas.

Veja abaixo a página exemplo com o resultado final da solução:

art10

Para acessar o exemplo criado acesse a aplicação exemplo abaixo:

http://apex.oracle.com/pls/apex/f?p=30361

  • Usuário: DEMO
  • Senha: imasters