Se olhar direito, a pesqcontrole inicia a contagem com RecCount() + RecCount() / 4
Isso vai ser 50% a mais do que a quantidade de registros.
Se olhar direito também, não pode usar REPLACE direto, já que a rotina pode falhar e retornar valor zero, ou até esse número acima em determinada situação.
Tem que considerar que a rotina é exemplo, não é só colocar no seu programa e pronto.
Tem que ajustar pra suas rotinas de rede, pra considerar falhas no programa que usa a rotina, etc.
Até mesmo conflito de nome de variáveis usadas na rotina.
Tá aqui uma versão mais próxima do que eu uso:
Código: Selecionar todos
FUNCTION ProximoCodigo( cDbf, lSeek )
LOCAL nCodigo, nSelect, acStructure
nSelect := Select() // salva a área atual
lSeek := iif( lSeek == NIL, .T., lSeek )
IF Select( "CONTROLE" ) == 0
IF .NOT. File( "CONTROLE.DBF" )
acStructure := { { "DATABASE" , "C", 12, 0 } , { "CONTADOR" , "N", 10, 0 } } // pra que economizar. Deixa tamanho 10 e tá pronto pro futuro
SELECT 0 // só por garantia
dbCreate( "CONTROLE", acStructure )
ENDIF
SELECT 0
USE CONTROLE SHARED
ENDIF
SELECT ( Select( "CONTROLE" ) ) // SELECT é comando, e Select() é função
LOCATE FOR UPPER( controle->Database ) = UPPER( cDbf )
IF Eof()
APPEND BLANK
REPLACE controle->Database WITH cDBF, controle->Contador WITH 1
SKIP 0
UNLOCK
ENDIF
DO WHILE .NOT. RLock()
InKey(0.5) // aguarde, não vai querer travar o computador ou sobrecarregar a rede tentando bloquear o registro
ENDDO
SKIP 0 // depois que conseguiu bloquear o registro, atualiza informação pra ver se mudou
nCodigo := controle->Contador
IF lSeek // se é pra pesquisar se existe, então pesquisa
SELECT ( nSelect )
DO WHILE .T.
SEEK nCodigo
IF Eof()
EXIT // se não existe, então achou código disponível
ENDIF
nCodigo += 1
ENDDO
ENDIF
SELECT CONTROLE
REPLACE controle->Contador WITH nCodigo + 1 // deixa gravado como disponível o seguinte, e não o que vai usar agora
SKIP 0 // antes de liberar, deixa atualizado
UNLOCK // ok, atualizado libera, antes disto não, porque primeiro tem que achar o código e ter certeza de que ninguém mais vai usar
SELECT ( nSelect )
RETURN nCodigo // ok, aqui é o atual que não existe
Notas:
- Não usava COMMIT no Clipper, e continuo não usando no Harbour.
- Usando ou não o código retornado, ele vai ser desprezado, então pode acontecer de pular um número.
- Montei a rotina na hora de postar, apenas como exemplo, revise, só usei compilação -w3 -es2 pra não errar nomes de variáveis.
- Estou considerando que está usando Clipper 5.x
- Não se esqueça de passar .F., caso não queira confirmação de registro já existente
A idéia é: pega o próximo número, com a opção de verificar no arquivo original se já existe, mas o arquivo original precisa estar indexado por essa chave, e precisa ser numérica (a não ser que altere esta rotina).