[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