Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
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');
Excelente.
Vai me ajudar bastante, não só a mim como a todos da comunidade.
Obrigado e parabéns, aderlanrm.
Muito boa idéia Aderlan. Show.
Valeu Alessandro, obrigado pela classificação!
Valeu aderlanrm!!! Parabéns!!!
Preciso de uma ajuda com a formatação.
A rotina para formatação de números, criada pelo ADERLAN, funciona perfeitamente quando eu tenho os valores de CPF e de CNPJ separados por campos.
A minha dúvida é quando os valores de CPF e de CNPJ estão no mesmo campo e de que forma eu posso criar uma função CALL para formatar o numero com 11 dígitos como CPF e número com 14 dígitos como CNPJ?
Grato desde já!
Olá Edson, tudo bem?
Até pensei em fazer isso na função, mas por boa prática, é melhor separar os campos mesmo, ficando separados no modelo.
Pensando no usuário final, na aplicação, facilita para criar análises com CPF e com CNPJ, também sendo útil nas buscas, melhorando o entendimento do modelo.
Sendo assim, recomendo fazer a carga dos campos e a formatação em campos separados ou fazer adaptação na função para formatar corretamente dependendo da quantidade de caracteres.
Abraço.
Grato pela resposta Aderlan!
conforme a sua exposição, eu terei que fazer uma adaptação porque os registros de CPF e de CNPJ estão no mesmo campo.
Abraço Edson
Se separar os campos, não precisa adaptar.
No LOAD faça algo assim:
Load RazaoSocial,
If(Len(Doc)<=11,Doc) as CPF,
If(Len(Doc)>11,Doc) as CNPJ,
...
Assim você terá os dois campos na memória, podendo inclusive usa-los como indicadores.
Count(CPF)
Count(CNPJ)
Abraço.
Muito bom cara!!! Será de muita valia essas informações... Parabéns!!!
Abs,