[firebase-br] UDF para validação de CNPJ / Calculo do DV
//---- Kelsie.Z.Marshall ----//
kelsie.z.marshall em gmail.com
Ter Set 8 17:23:31 -03 2009
Ae Pessoal
Aprendi como fazer UDF com o C++Builder e posto o resultado aqui, se
gostaram ou se ela for util para vocês me mande um e-mail que mando o código
e mais detalhes.
Meu e-mail:
kelsie.z.marshall em gmail.com
1º) Abra um novo projeto no CodeGear C++ Builder 2009 e escolha Dynamic Link
Library.
Dê o nome do projeto f_myfunctions.cbproj depois a DDL gerada será
f_myfunctions.dll
Abaixo o código que melhorei que faz a validação de CNPJ.
Se o CNPJ não for composto somente por números e o tamanho for diferente de
14 bytes a função retorna -1, caso contrário o DV (digito verificador) é
calculado com os 12 primeiro números e comparado com o DV informado ou seja
os dois últimos números da string.
//---------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use
MEMMGR.LIB
// if any other projects which use the DLL will be performing new or
delete
// operations on any non-TObject-derived classes which are exported from
the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its
calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
//---- Protótipo da função muito importante
extern int __declspec(dllexport) cnpj_valido(char *str);
//---------------------------------------------------------------------------
//---- Função
int cnpj_valido(char *str)
{
int d1,d4,xx,nCount,fator,resto,digito1,digito2,nro_1,nro_2;
int DV_Calculado_int=-1;
int DV_Informado_int=-1;
char CNPJ[14], DV_Calculado[3], DV_Informado[3], nrochar_1[2],
nrochar_2[2];
if(strlen(str)!=14)
return -1;
for(nCount = 0; nCount < strlen(str)-1; nCount++)
if(str[nCount] < '0' || str[nCount] > '9')
return -1;
strcpy(CNPJ, str);
d1=0; d4=0; xx=1;
for(nCount = 0; nCount < strlen(CNPJ)-3; nCount++)
{
if( xx < 5)
fator = 6 - xx;
else
fator = 14 - xx;
nrochar_1[0] = CNPJ[nCount];
nrochar_1[1] = '\0';
nro_1 = atoi(nrochar_1);
d1 = d1 + nro_1 * fator;
if(xx < 6)
fator = 7 - xx;
else
fator = 15 - xx;
nrochar_2[0] = CNPJ[nCount];
nrochar_2[1] = '\0';
nro_2 = atoi(nrochar_2);
d4 = d4 + nro_2 * fator;
xx = xx+1;
}
resto = (d1 % 11);
if (resto < 2)
digito1 = 0;
else
digito1 = 11 - resto;
d4 = d4 + 2 * digito1;
resto = (d4 % 11);
if(resto < 2)
digito2 = 0;
else
digito2 = 11 - resto;
sprintf(DV_Calculado,"%d%d\0",digito1,digito2);
DV_Informado[0] = CNPJ[12];
DV_Informado[1] = CNPJ[13];
DV_Informado[2] = '\0';
DV_Calculado_int = atoi(DV_Calculado);
DV_Informado_int = atoi(DV_Informado);
if(DV_Calculado_int==DV_Informado_int)
return 1;
else
return 0;
}
//---------------------------------------------------------------------------
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*
lpReserved)
{
return 1;
}
//------
2º) Depois basta compílar em mode RELEASE.
3º) Copie a DLL( f_myfunctions.dll ) gerada para o sub-diretório \UDF de seu
firebird o meu é 'C:\Program Files (x86)\Firebird\Firebird_2_1\UDF'
Atenção tentei fazer com o firebird 64 bits e não funcionou quebrei a cabeça
até descobrir isto, se não fosse a ajuda da galera aqui da lista estaria até
agora remando.
4º) Preferencialmente usando o IBExpert você deve fazer a [declaração da
função], não esqueça de apertar F5 em cima da funções para dar o refresh no
banco após cria-la.
declare external function VALIDA_CNPJ
cstring(14)
returns int by value
entry_point 'cnpj_valido'
module_name 'f_myfunctions';
Aqui para facilitar a vida, adoro quando postam isto.
CREATE TABLE A_TAB
(
CNPJ VARCHAR( 14)
);
INSERT INTO A_TAB (CNPJ) VALUES ('06947284000104'); /* CNPJ VÁLIDO google
brasil*/
INSERT INTO A_TAB (CNPJ) VALUES ('83583745923244'); /*CNPJ INVÁLIDO*/
select CNPJ from A_TAB where VALIDA_CNPJ(CNPJ)=1
ou
select VALIDA_CNPJ(CNPJ) from A_TAB
ou
select ('06947284000104') from A_TAB
a consulta acima dever retornar 1 dizendo que é válido
select ('83583745923244') from A_TAB
a consulta acima dever retornar 0 dizendo que é inválido
[]s,
Kelsie
kelsie.z.marshall em gmail.com
Mais detalhes sobre a lista de discussão lista