Página 1 de 2
Condigo Sequencial
Enviado: 24 Set 2014 17:58
por Josmar dos Santos
Boa tarde amigos, o código sequencial abaixo esta gerando um problema. O registro estava em torno de 7324, derre pente o mesmo saltou para 9094. Isso também ocorreu em mais três arquivos. Eu já reorganizei os arquivos umas mil vezes, mas ele não volta novamente no registro inicial de 7324. Desde que ele saltou para o registro 9094, ele só segue essa sequencia acima do mesmo. A minha pergunta é o seguinte: Como voltar a partir desse código fonte via programação a iniciar os registros novamente no número "7324"? Nos últimos anos, eu andei me desligando um pouco da programação, porém, um cliente meu antigo me pediu para rever esse sistema para ele. Talvez seja uma boa oportunidade de voltar novamente. Peço a paciência de vocês....Um abraço.
Josmar
Código: Selecionar todos
FUNCTION SALVAR02(TIPO_ACAO)
LOCAL IRetorno := .F.
IF TIPO_ACAO = INCLUSAO
CLIENTES->(Dbappend())
cCODIGO := alltrim( STRZERO( PSQCONTROLE( "clientes" ), 5 ))
if cCODIGO="00000"
ALERT("Ocorreu um erro na efetiva‡Æo do CODIGO SEQUENCIAL")
RETURN .F.
ENDIF
CLIENTES->CODIGO := cCODIGO
ALERT("Numero gerado no arquivo: " +cCODIGO)
ELSE
CLIENTES->(RLOCK() )
ENDIF
IF .NOT. NETERR()
CLIENTES->NOME1 := M->NOME1
CLIENTES->DATA := M->DATA
CLIENTES->ENDERECO := M->ENDERECO
CLIENTES->BAIRRO := M->BAIRRO
CLIENTES->UF := M->UF
CLIENTES->NOME2 := M->NOME2
CLIENTES->FONE := M->FONE
CLIENTES->CIDADE := M->CIDADE
CLIENTES->CGC := M->CGC
CLIENTES->INSC := M->INSC
CLIENTES->CPF := M->CPF
CLIENTES->RG := M->RG
CLIENTES->CEP := M->CEP
CLIENTES->OBS := M->OBS
CLIENTES->VEICULO := M->VEICULO
CLIENTES->ANO := M->ANO
CLIENTES->PLACA := M->PLACA
CLIENTES->COR := M->COR
CLIENTES->MODELO := M->MODELO
CLIENTES->FONE2 := M->FONE2
CLIENTES->SEGU_DORA := M->SEGU_DORA
CLIENTES->SEGURADO := M->SEGURADO
CLIENTES->TERCEIRO := M->TERCEIRO
CLIENTES->FONE_SEG := M->FONE_SEG
CLIENTES->CORRETORA := M->CORRETORA
CLIENTES->FONE_CORR := M->FONE_CORR
CLIENTES->SINISTRO := M->SINISTRO
CLIENTES->CONTATO := M->CONTATO
clientes->aniversar := M->aniversar
clientes->ASSINAT := M->ASSINAT
clientes->arq_dia := M->arq_dia
clientes->fone_2 := M->fone_2
clientes->fone_3 := M->fone_3
clientes->e_mail := M->e_mail
CLIENTES->SALDO := M->SALDO
CLIENTES->( DBCOMMIT() )
CLIENTES->( DBUNLOCK() )
ELSE
ALERT("Falha ao incluir novo cliente")
endif
return .t.
Condigo Sequencial
Enviado: 24 Set 2014 18:14
por ANDRIL
Melhor criar um arquivo DBF onde se colocam todos os numeradores do seu sistema. Exemplo:
DESCRICAO | NUMERADOR
CLIENTE | 1
PRODUTO | 1000
Quando for adicionar um novo cliente, va neste arquivo, posicione no primeiro registro e faça NUMERADOR+1, para obter o sequencial, logo apos atualize o campo NUMERADOR com o novo valor.
Para ficar melhor, crie uma função para checar se o novo numero ja existe, se sim, vá acrescentando +1 até um que não exista.
Acho esta a melhor forma, sem usar indexação e etc.
Bom retorno à programação!
Condigo Sequencial
Enviado: 24 Set 2014 18:43
por Jairo Maia
Olá Josmar,
Outra opção também é você controlar isso na função PSQCONTROLE(). Cheque nela se o ultimo código é o código 9094, e se for, faça um SKIP -1. Então verifique se o anterior é menor que 9093, quando chegar a 9093, então tudo resolvido, basta retornar 9095. A partir dai fica tudo normal, e se desejar pode até remover o código. Caso queira, poste o código dela que dou uma sugestão.
PS: Vou também sugerir que você mude a posição desta linha: CLIENTES->(Dbappend()), para antes dessa: CLIENTES->CODIGO := cCODIGO. Isso evita que se houver um erro na geração do codigo, você deixa um registro vazio no DBF.
Condigo Sequencial
Enviado: 24 Set 2014 19:32
por Maligno
Acho que uma solução muito melhor é simplesmente esquecer os números em sequência para identificações (chaves primárias). Eu só utilizo calculados. Em cada cadastro some as strings com os dados que normalmente são únicos. Por garantia adicione data/hora da inclusão e, se quiser uma segurança extra, até mesmo um número aleatório. Gere o CRC32 desta soma e grave como código de identificação. A taxa de colisão do CRC32 é baixíssima. É garantido que os números nunca se repetirão.
A principal vantagem é não ter que se preocupar em pesquisar seu BD para garantir a unicidade do código.
Evidentemente, há casos de números que precisam ser sequenciais. Para esses casos a técnica deve ser outra.
Condigo Sequencial
Enviado: 24 Set 2014 22:48
por rochinha
Amiguinhos,
Maligno, faz tempo que não te vejo aqui meu querido, ou tô frequentando somente algumas dependências, he he he, @braços.
Josmar dos Santos
A função
Função de Autonumeração - PSQControle() é muito útil para o controle de muitas sequencias ao mesmo tempo.
Se você analisar o código verá que a mesma recebe o nome da tabela que voce quer controlar e a partir dai é criada uma variável e o numero de sequencia vai sendo manipulado.
O fato da tabela sendo controlada inflar ou perder registros não influi na contagem e a diferença de sequência é minima.
Você pode criar um browse para visualizar e manipular as sequências.
Condigo Sequencial
Enviado: 25 Set 2014 01:48
por alxsts
Olá!
É uma pena que você ainda usa Clipper. Se fosse Harbour com DBF, poderia utilizar o novo tipo de dados que ele suporta: autoincrement.
Condigo Sequencial
Enviado: 25 Set 2014 17:16
por Maligno
Apesar de que também disponho de auto-incremento no Firebird, não utilizo quando preciso apenas de uma identificação única. Acho que em cada caso deve-se utilizar o método mais apropriado, sem criar processos desnecessários, mesmo que sejam muito simples e fáceis de usar. Nesses casos, o caminho mais curto é sempre melhor.
No caso do colega, pelo que entendi, o importante é conseguir obter uma identificação garantidamente única. Se for isso, gerar essa identificação diretamente no código evita trabalho extra. Ainda mais pra quem não dispõe de auto-incremento.
<Rochinha>
Pois é, meu amigo. Também fico mais "observando" o fórum. Mas normalmente entro no vapt-vupt. Nem dá tempo de ver tudo.

[]'s
Condigo Sequencial
Enviado: 03 Out 2014 18:25
por Josmar dos Santos
Jairo, desculpe a demora para responder, muito enrolado esses dias...eis a função PsqControle que você pediu..Essa Função achei ela no fórum.
Amanhã se Deus quiser vou tentar resolver essa situação. Agora, os caras estão reclamando que a Nota Fiscal Também está dando Problemas. Aí o bicho pega! Mas vou tentar fazer tudo que os colegas me disseram para fazer.
Um abraço
[FUNCTION PsqControle( database )
nControle := iif( recco()=0, 1, recco()+(recco()/4) )
OldArea := Select()
if !file( "CONTROLE.DBF" )
ESTRU_DBF := { { "DATABASE" , "C",12, 0 } , ;
{ "CONTADOR" , "N", 5, 0 } } // Controle de FINANCEIRO
DBCREATE( "CONTROLE", ESTRU_DBF )
endif
If Select("CONTROLE") == 0
// USE controle Shared NEW
if !userede("CONTROLE",.f.,30,.t.) // adicionado por Pablo C‚sar
TONE( 250, 4 )
MENSAGEM( "Nao foi possivel abrir arquivo CONTROLE", 5 )
MENSAGEM( "tente novamente", 5 )
RETURN 0
endif
Else
DbSelectar("CONTROLE")
EndIf
LOCATE FOR UPPER(controle->database) = UPPER(database)
if found()
nControle := controle->contador + 1
if reglock(30) // adicionado por Pablo C‚sar
controle->contador := nControle
UNLOCK
COMMIT
else
TONE( 250, 4 )
MENSAGEM( "Nao foi possivel bloquear registro no arquivo CONTROLE", 5 )
MENSAGEM( "tente novamente", 5 )
SELE (OldArea)
RETURN 0
endif
else
// APPEND BLANK
if adireg(30) // adicionado por Pablo C‚sar
controle->database := database
controle->contador := nControle
COMMIT
else
TONE( 250, 4 )
MENSAGEM( "Nao foi possivel adicionar registro no arquivo CONTROLE", 5 )
MENSAGEM( "tente novamente", 5 )
SELE (OldArea)
RETURN 0
endif
endif
SELE (OldArea)
RETURN nControle
/quote]
Condigo Sequencial
Enviado: 04 Out 2014 11:23
por Jairo Maia
Olá Josmar,
Eu particularmente não usaria essa função para controle de sequências, até mesmo porque analisando o código original postado pelo Rochinha, não há garantia que os códigos sejam sequenciais, e na minha opinião (salvo se eu estiver muito enganado) também pode ocorrer duplicação. Mas enfim, veja em anexo uma sugestão para você testar e ver se funciona.
Nota: Não tenho como testar, por favor veja se vai funcionar:
Condigo Sequencial
Enviado: 04 Out 2014 13:03
por Josmar dos Santos
Jairo, houve uma evolução com a Função que você alterou, ou seja, ele travou no registro 9096. Vou explicar melhor: ao registrar os registros, ele começa no número 9096. Se eu continuar, ele dará sequência, 9097, 9098, 9099, etc. Ao deletar esses três últimos registros, ele volta novamente no número 9096 que antes não voltava. Antes da alteração, ele dava sequência 9100, 9101, etc. Mas o meu principal objetivo é voltar na numeração 7324 que é o último registro para assim eu continuar dando sequência na numeração. Esse sistema funcionou durante 4 anos sem dar problemas. De uma para a outra começou a dar esses rolinhos. Enquanto isso continuo tentando..
Um abraço..
Josmar
Condigo Sequencial
Enviado: 04 Out 2014 14:02
por Josmar dos Santos
Jairo, consegui voltar novamente ao código sequencial, vamos agora ver se vai dar continuidade e não pular mais..
Condigo Sequencial
Enviado: 11 Mai 2015 18:17
por Josmar dos Santos
Boa tarde pessoal, no ano passado criei esse tópico para resolver alguns problemas que infelizmente ainda tenho. Como já
havia explicado, o sistema deu uma pane em seus números sequenciais. Venho tentando resolver, mas não obtive sucesso até
o momento. Mas anotei umas ocorrências interessantes. Tenho 17 arquivos. Desses arquivos, três deles foram apagados os registros
de anos anteriores, pois bem, são exatamente esses que estão dando problemas. Quando deu a pane no ano passado eu entrei
na tabela CONTROLE.DBF da PsqControle e fiz as alterações dando sequência na numeração. Os arquivos que estavam
intactos, ou seja, sem apagar os registros de anos anteriores estão normais, mas os três que foram apagados estão
fazendo subtrações. Por exemplo: No arquivo Orçamento.dbf(Com problema), hoje ele está na numeração 33.000(Na tabela
ele também está com esse valor), ao registrar um novo registro, o programa registra 15.300(Ele também insire esse
valor na tabela de controle). Ao entrar na DBU e apagar alguns registros, ele subtrai o valor de 15.300 para um certo
valor. Eu já fiz de tudo que podia para inserir os valores sequenciais exatos, mas ele não aceita, sempre volta a
registrar esses valores tanto nos arquivos como também na tabela.
Obs-> Ao dar um zap no arquivo ele volta na sequência normal.
Vale lembrar que o programa já está migrado para harbour, mas usei esse mesmo tópico para não dar duplicidade..
O que eu quero é que volte a dar sequencia na numeração conforme inserido na tabela sem fazer essas subtrações.
Se alguem tive alguma ideia de como resolver isso eu agradeceria.
Um abraço a todos
Josmar
Condigo Sequencial
Enviado: 11 Mai 2015 21:22
por rochinha
Amiguinhos,
Vejamos então a novissima versão 2.0(ka, ka, ka) da função PsqControle():
Código: Selecionar todos
FUNCTION PsqControle( database, _altera_, _ComValor_ )
DEFAULT _altera_:= .t., _ComValor_ := 0
nControle := iif( recco()=0, 1, recco()+(recco()/4) )
OldArea := Select()
if !file("CONTROLE.DBF")
ESTRU_DBF := { { "DATABASE" , "C",12, 0 } , ;
{ "CONTADOR" , "N", 7, 0 } }
DBCREATE( "CONTROLE", ESTRU_DBF )
endIf
If Select("controle") == 0
USE controle NEW SHARED
Else
DbSelectArea("controle")
EndIf
LOCATE FOR UPPER(controle->database) = UPPER(database)
if found()
nControle := controle->contador
if _altera_ = .t. // NIL
if _ComValor_ # 0 // NIL
nControle := _ComValor_
else
nControle := controle->contador + 1
endif
//else
// nControle := controle->contador + 1
controle->( rLock() )
controle->contador := nControle
controle->( dbUnLock() )
controle->( dbCommit() )
endif
else
if _altera_ = .t. // NIL
if _ComValor_ # 0 // NIL
nControle := _ComValor_
endif
endif
controle->( dbAppend() )
controle->database := database
controle->contador := nControle
controle->( dbUnLock() )
controle->( dbCommit() )
endif
SELE (OldArea)
RETURN nControle
Neste caso o segundo parametro sempre será verdadeiro, ou seja, sempre altera a contagem, mas em casos especificos que não se queira que seja alterado o contador automaticamente mas mantenha momentaneamente o ultimo valor, exemplo: estou tentando enviar a NF-e 3000 e tento por 5 vezes, este valor 3000 não se alterará automáticamente até que eu deseje.
No caso do terceiro parametro, coloco o valor provável na nova sequencia, ou seja, estou forçando a contagem à partir do novo numero que coloquei.
Quando acontece um pau e os registros são zerados ou perdidos o cálculo,
nControle := iif( recco()=0, 1, recco()+(recco()/4) ), traz a contagem baseada no número de registros na tabela, ocasionando um numero mais baixo, então
_ComValor_ entraria em ação trazendo o último contador obtido na tabela CONTROLE conforme o indice registrado até o referido PAU.
Exemplo:
Código: Selecionar todos
M->NF := PsqControle( "NF", .f. ) // Somente carrega numero de nota
cSeekCodigo := M->NF // Variavel temporaria
// Dialogo para configurar o numero da nota
SET _3DLOOK ON
DEFINE DIALOG oNFDlg RESOURCE "dlgPrintNF" TITLE "Imprimindo nota fiscal"
REDEFINE GET oGet101 VAR cSeekCodigo PICTURE "999999" ID 101 OF oNFDlg ;
SPINNER ON UP (cSeekCodigo:=cSeekCodigo+iif(cSeekCodigo>99999,0,1),oGet101:Refresh()) ;
ON DOWN (cSeekCodigo:=cSeekCodigo-iif(cSeekCodigo<00001,0,1),oGet101:Refresh())
REDEFINE BUTTON ID 2 OF oNFDlg ACTION ( lSave := .t. , oNFDlg:End() ) DEFAULT
REDEFINE BUTTON ID 3 OF oNFDlg ACTION ( lSave := .f. , oNFDlg:End() )
ACTIVATE DIALOG oNFDlg CENTERED
if !lSave // Se CANCELei o dialogo volta sem processar mais nada
return .t.
endif
// Se o SEQUENCIAL for o mesmo que o usuário digitou...
if cSeekCodigo = M->NF
// Atualiza o contador
M->NF := PsqControle( "NF" )
endif
// Guarda o numero digitado pelo usuario, seja qual for.
M->NF := cSeekCodigo
Caso eu queira sempre salvar meu último numero digitado manualmente:
Código: Selecionar todos
// Se o SEQUENCIAL for o mesmo que o usuário digitou...
if cSeekCodigo = M->NF
// Atualiza o contador com o novo numero digitado manualmente
M->NF := PsqControle( "NF", .t., cSeekCodigo )
endif
// Guarda o numero digitado pelo usuario, seja qual for.
M->NF := cSeekCodigo
Condigo Sequencial
Enviado: 12 Mai 2015 19:03
por JoséQuintas
Uma solução simples:
A rotina pega como número inicial o campo CONTADOR que está no arquivo CONTROLE.
É só alterar o conteúdo desse campo.
Condigo Sequencial
Enviado: 13 Mai 2015 17:33
por Josmar dos Santos
Boa tarde Rochinha vou testar essa sua nova função hoje, depois eu retorno..
Quintas, sobre a sua sugestão eu já havia tentado fazer essas alterações no Controle.DBF várias vezes e não obtive sucesso. Por esse motivo acionar novamente esse tópico. Eu altero o campo contador colocando o valor correto para dar continuidade, mas ao tentar fazer os registros novamente ele registra outro valor (sempre valor a menos) e insere esse valor tanto no contador do controle.dbf. como também nos arquivos.
Mas to aberto a outras idéias para meu aprendizado...
Um abraço
Josmar