Skip to main content
Announcements
Qlik Connect 2024! Seize endless possibilities! LEARN MORE
cancel
Showing results for 
Search instead for 
Did you mean: 
aderlanrm
Partner - Specialist
Partner - Specialist

Formatar Números (CPF, CNPJ, CEP, Telefone e Celular 9 digitos)

Olá pessoal,

 

<< versão nova 12/01/17 >>

 

Há muitas dúvidas na comunidade sobre formatação de números.

 

Realmente é algo que nos faz falta, entre tantas centenas de funções, ter uma que nos permita definir uma máscara personalizada e o número ser formatado adequadamente, então, inspirado pelo documento que fiz a um tempo atrás (Exportar para TXT (Sem Rótulos - No Labels)), resolvi criar uma outra rotina para formatação de números.

 

Para quem usa Personal Edition, segue script:

///$tab SUB

SUB FormataNumero(Tabela,Campo,Máscara)

 

             //**************************************************************\\

            //                 Curitiba, 11 de janeiro de 2017                  \\

           //                Desenvolvido por Aderlan Rodrigues                    \\

          //                                                                    \\

         //                                VERSÃO 1.2                                  \\

        //                                                                          \\

       // Permitido "Números", ".", "-", "/", "(", ")" e "+" na primeira posição,  \\

      //  outros caracteres devem ser evitados ou tratados adequadamente na rotina. \\

     //      O campo ID é ncessário para evitar multiplicação da linha no JOIN             \\

    //********************************************************************************\\

 

    TRACE ## Aplicar máscara "$(Máscara)" no campo [$(Campo)] da tabela [$(Tabela)];

 

    If Mid('$(Máscara)',1,1) = '0' THEN

        LET vDigito = 1; // Começa em 1 (um) para uso na correta posição dos números

        LET vMids = 'Mid([$(Campo) Preenchido],1,1)'; // Inicializa o primeiro dígito quando numérico, para montagem dos comando que será usado no LOAD

    ELSE

        LET vDigito = 0; // Começa em 0 (zero) para uso na correta posição dos números

        LET vMids = 'Mid('&Chr(39)&'$(Máscara)'&Chr(39)&',1,1)'; // Inicializa o primeiro dígito quando textual, para montagem dos comando que será usado no LOAD

    ENDIF

 

    FOR vPosição = 2 to Len('$(Máscara)') // Percorre os caracteres da máscara para fazer a distribuição dos números abaixo

 

        SWITCH Mid('$(Máscara)',$(vPosição),1)

            CASE '0'

                 LET vDigito = $(vDigito)+1;

                LET vMids = '$(vMids)&'&Chr(13)&

                     'Mid([$(Campo) Preenchido],'&$(vDigito)&',1)';

            CASE '.'

                LET vMids = '$(vMids)&'&

                    Chr(39)&'.'&Chr(39);

            CASE '-'

                LET vMids = '$(vMids)&'&

                    Chr(39)&'-'&Chr(39);

            CASE '/'

                LET vMids = '$(vMids)&'&

                    Chr(39)&'/'&Chr(39);

            CASE '(' // O primeiro é tratado do IF, os demais são tratados aqui, caso a máscara inicie com "+", por exemplo

                LET vMids = '$(vMids)&'&

                    Chr(39)&'('&Chr(39);

            CASE ')'

                LET vMids = '$(vMids)&'&

                    Chr(39)&')'&Chr(39);

            CASE ' '

                LET vMids = '$(vMids)&'&

                    Chr(39)&' '&Chr(39);

        ENDSWITCH

 

    NEXT

 

    Left Join ([$(Tabela)]) // Inclui o campo formatado a tabela de origem

    LOAD Distinct [$(Campo)],

        Dual($(vMids),[$(Campo)]) as [$(Campo) Formatado]; // Usada a função DUAL para manter a ordenação numérica após a máscara

    LOAD Distinct [$(Campo)],

        Repeat(0,SubStringCount('$(Máscara)','0')-Len([$(Campo)]))&[$(Campo)] as [$(Campo) Preenchido] // Preenche com zeros pela definição da máscara

    Resident [$(Tabela)]

    //Where IsNull([$(Campo)]);

    Where Len([$(Campo)])>0; // Na versão que foi desenvolvido a função IsNull não estava funcionando, alternativamente, foi feito dessa forma

 

    DROP Field [$(Campo)];

    RENAME Field [$(Campo) Formatado] to [$(Campo)];

 

    LET vPosição = ;

    LET vDigito = ;

    LET vMids = ;

 

END SUB

///$tab Exemplo de Uso

// Dados aleatórios para demonstração

Pessoas:

LOAD Num(Right(PurgeChar(Rand(),'.,'),11)) as CPF,

    'Fulano '&RecNo() as Nome,

    Num(Right(PurgeChar(Rand(),'.,'),11)) as Celular,

    KeepChar('() 9875-3200','0123456789') as Texto // O campo deve ser tratado, para manter apenas os número, antes da chamada da função

AutoGenerate Ceil(Rand()*1000);

 

Empresas:

LOAD Num(Right(PurgeChar(Rand(),'.,'),14)) as CNPJ,

    'Empresa '&RecNo() as [Razão Social],

    Num(Right(PurgeChar(Rand(),'.,'),8)) as CEP,

    Num(Right(PurgeChar(Rand(),'.,'),8)) as Telefone

AutoGenerate Ceil(Rand()*100);

 

Concatenate (Pessoas) // Simulação de valores nulos

LOAD * Inline [

    Código, CPF, Nome, Celular, Texto

    99, , Nulo 1, ,

    98, , Nulo 2, ,

    97, , Nulo 3, ,

];

 

CALL FormataNumero('Pessoas','CPF','000.000.000-00');

CALL FormataNumero('Pessoas','Celular','(00) 0 0000-0000');

CALL FormataNumero('Pessoas','Texto','(00) 0 0000-0000');

 

CALL FormataNumero('Empresas','CNPJ','00.000.000/0000-00');

CALL FormataNumero('Empresas','CEP','00.000-000');

CALL FormataNumero('Empresas','Telefone','+00 (00) 0000-0000');

Aderlan Rodrigues
Analista, Arquiteto de Dados e Piloto Amador Drone FPV
 (41) 9 9917-0869  www.BIdeAZ.com.br  Youtube.com/bideaz  Instagram.com/bideaz.in

"Nada é tão inútil quanto fazer eficientemente o que não deveria ser feito." (Peter Drucker)
14 Replies
jonas_lomiler
Contributor II
Contributor II

Muito bom, cara!
Quebrou uma floresta!

Anonymous
Not applicable

Valeu mestre pela sugestão!

Realmente, não precisou alterar o código da rotina ou criar uma condição IF..THEN para a chamada CALL.

O QV cria os dois campos CPF e CNPJ derivados do campo original "contas_cpf_cnpj" da minha base de dados.

Outro esclarecimento : Caso eu queira criar um campo único para usar como dimensão com os campos CPF e CNPJ?

Grato mais uma vez

Edson Costa

aderlanrm
Partner - Specialist
Partner - Specialist
Author

Que bom que deu certo Edson.

Tem que entender melhor a situação, vou imaginar e escrever aqui, você avalia o caso.

1. Se na origem dos dados está junto, dependendo o volume, não separe, altere a rotina para fazer a formatação dependendo do tipo de dados, CPF uma coisa CNPJ outra. Com isso, no layout, já terá o dado no mesmo campo único, mas... para o usuário fazer pesquisa, não precisa está no mesmo campo, ele usa o objeto pesquisa e o próprio Qlik já resolve o problema. Só é necessário ter as duas informações no mesmo campo, se for fazer um gráfico, tabela... sei lá! Não faz sentido ter duas informações diferente no mesmo campo.

2. Se na origem está separado, faz a formatação antes de concatenar esses dois campos em um só, no entanto, vale o aviso anterior, não consigo imaginar uma análise onde ter essas duas informações sejam úteis.

Cada caso é um caso, você entende do teu negócio e deve ter algum detalhe para que isso seja útil.

Abraço.

Aderlan Rodrigues
Analista, Arquiteto de Dados e Piloto Amador Drone FPV
 (41) 9 9917-0869  www.BIdeAZ.com.br  Youtube.com/bideaz  Instagram.com/bideaz.in

"Nada é tão inútil quanto fazer eficientemente o que não deveria ser feito." (Peter Drucker)
Anonymous
Not applicable

Bom dia Aderlan e demais camaradas!

De fato a base de dados que eu possuo trás as informações de CPF e de CNPJ no mesmo campo (cerca de 17.000 registros). Os registros de CPF e de CNPJ vem no mesmo campo por que são utilizados como ID de pessoas (físicas e jurídicas) de contas bancárias.

Por isso que as duas informações estão no mesmo campo, porque estão sendo utilizadas como ID de titulares de contas bancárias (independente se forem pessoas físicas ou jurídicas).
Eu consegui criar dois campos, utilizando objeto LISTA, com as informações por CPF e CNPJ, porém ,o meu objetivo é apresentar os valores de CPF e de CNPJ formatados no mesmo campo.

Grato mais uma vez!

Edson Costa

caioczm
Contributor
Contributor

Bom dia

Este script funciona perfeitamente para uma tabela. No meu caso, eu tenho diversas tabelas de diversas fontes ontem tem o campo CPF onde há tabelas que já vem com a mascara da fonte e outras que vem sem mascara. 

Ao chamar o formata numero na primeira tabela, ele funciona perfeitamente, porem quando vou chamar pela segunda vez o pelo script do formata numero ela dropava o campo CPF de todas tabelas carregadas anteriormente. Resolvi isso colocando no script assim: DROP Field [$(Campo)] from [$(Tabela)];

Só que agora esta dando um segundo erro, pois a função RENAME não pode ser usada duas vezes para o mesmo campo, pois no script considera que ja foi renomeado uma vez (ao chamar o formata numero pela primeira vez) o campo CPF Formatado para CPF.

Alguma sugestão de como corrigir isso?

Precisava que esse Formata Numero fosse utilizado para cada tabela individualmente

caioczm_0-1667249990856.png