Clipper On Line • Ver Tópico - Função de Autonumeração( Uso Geral )

Função de Autonumeração( Uso Geral )

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

 

Função de Autonumeração( Uso Geral )

Mensagempor rochinha » 24 Fev 2005 23:10

Amiguinhos

A função que apresento é muito boa para se controlar os vários contadores que usamos em nossos sistemas e vale a pena investir em seu uso, já que a velha técnica de pegar o RECNO() sempre falha após um exclusão fisica via PACK.

Exemplo:

Eu tinha um cadastro de clientes com 20 registros e eliminei 5 aleatóriamente ficando com 15. Ao usar um PACK o meu RECNO()+1 devolveria 16 e se usasse este numero eu poderia ter registros duplicados.

A função possui um cálculo que retorna um valor baseado na regra:

nControle := ... recco()+(recco()/2) ...

Ou seja numero de registros é igual ao seu total mais sua metade, ou seja, meu proximo contador poderia ser 22 ou 23.

Ela não é a prova de falhas, pois depende de um cálculo FIXO baseado em valores FLUTUANTES.

Seu código é:

FUNCTION PsqControle( database )
   // Inicializa controle com um numero diferente do total de registros
   nControle := iif( recco()=0, 1, recco()+(recco()/2) )
   // Guarda a área atual do .DBf a ser controlado
   OldArea := Select()
   If !File("CONTROLE.DBF")
      // Cria a estrutura do controlador caso ainda não exista
      ESTRU_DBF := { ;
           { "DATABASE"  , "C",12, 0 } , ;  // Guarda o nome do DBF/ALIAS
           { "CONTADOR"  , "N", 7, 0 } }    // Armazena o contador
            DBCREATE( "CONTROLE", ESTRU_DBF )
   EndIf
   If Select("CONTROLE") == 0 // Se ainda não estiver aberto, abre...
      USE controle NEW
   Else
      DbSelectar("CONTROLE")  // Se ja estiver aberto SELEciona
   EndIf
   // Verifica a existencia da chave( que pode ser também uma palavra )
   LOCATE FOR UPPER(controle->database) = UPPER(database)
   if found()
      // Encontrando incrementa o contador
      nControle := controle->contador + 1
      RLOCK() // Usado no caso de rede
      controle->contador := nControle
      COMMIT
   else
      // Caso a chave ainda não exista será criada
      APPEND BLANK
      controle->database := database
      controle->contador := nControle
      COMMIT
   endif
   // Volta a área antiga
   SELE (OldArea)
   // Retorna o numero de controle
   RETURN nControle


O seu uso é muito simples:

...
CLIENTES->IDCLIENTE := PsqControle( DBF() )
APPEND BLANK
...
COMMIT
...

O registro de cliente será salvo com um numero atualizado e o controle também será atualizado.

A manutenção do arquivo de controle poderá ser feita também via dBase, DBU ,Fox ou um browse interno chamado pelos menos de sua aplicação .

@braços :xau
Editado pela última vez por rochinha em 29 Set 2006 10:56, num total de 1 vezes
Avatar de usuário

rochinha
Membro Master

Membro Master
 
Mensagens: 4538
Data de registro: 18 Ago 2003 20:43
Cidade/Estado: São Paulo - Brasil
Curtiu: 800 vezes
Mens.Curtidas: 242 vezes

Contador

Mensagempor gavel » 07 Mai 2005 12:52

Eu uso o contador do MIRO. é muito interessante, quando em rede, pois ele evita um cadastro duplo do mesmo código para clientes diferentes.
Mesmo assim ele comete falha. Por isso eu implementei um pouco.

Ex.: 2 computadores abrem um cadastro de cliente e buscam o ultimo registro. O contador do banco de dados não sabe se outro terminal está cadastrando um novo código.
O que fiz? criei um contador temporário de cada código criado num intervalo de milésimos de segundo, para cada terminal. Assim nunca nenhum deles irá repetir o mesmo número. seria algo como dois carros de fórmula 1 passar na linha de chegada no mesmo milésimo.

hehehe :))
Abraços.
Gavel
gavel
Usuário Nível 1

Usuário Nível 1
 
Mensagens: 39
Data de registro: 16 Mar 2005 07:30
Curtiu: 0 vez
Mens.Curtidas: 0 vez

Mensagempor rochinha » 09 Mai 2005 02:20

Amiguinho

Isto pode ser resolvido com a seguinte modificação:

Antes:

FUNCTION PsqControle( database )
...
LOCATE FOR UPPER(controle->database) = UPPER(database)
if found()
// Encontrando incrementa o contador
nControle := controle->contador + 1
RLOCK() // Usado no caso de rede

controle->contador := nControle
COMMIT
...
RETURN nControle

Depois:

FUNCTION PsqControle( database )
...
LOCATE FOR UPPER(controle->database) = UPPER(database)
if found()
// Encontrando incrementa o contador
RLOCK() // Usado no caso de rede
nControle := controle->contador + 1

controle->contador := nControle
COMMIT
...
RETURN nControle

Desta forma o numero de cadastro será retornado a primeira estação e liberado após o destravamento sendo impossivel antes do travamento que duas estações possuam o mesmo código.

O motivo da criação desta função é que quando usamos numeradores baseados no numero de registro de um .dBF, ou recco() os mesmos falhas quando executamos PACKs. Portanto existe a necessidade de uso de arquivos externos.

Visite o post: http://www.pctoledo.com.br/forum/viewtopic.php?t=1362

@braços :?)
Avatar de usuário

rochinha
Membro Master

Membro Master
 
Mensagens: 4538
Data de registro: 18 Ago 2003 20:43
Cidade/Estado: São Paulo - Brasil
Curtiu: 800 vezes
Mens.Curtidas: 242 vezes




Retornar para Contribuições, Dicas e Tutoriais

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 19 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro