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:
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:
Determine a localização do botão na região:
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.
Finalize a criação do botão e crie uma ação dinâmica para ele:
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.
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
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.
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:
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