FUNCTION PARA GERAR CODIGO

RCMRO 11/09/2009 09:37:17
#322589
ABDON,

Essa filosofia de aproveitamento de código tende a gerar problemas de tempo no futuro pois o único modo de você saber se um número está livre é carregando toda a tabela e varrendo ela SEMPRE do 1º registro até encontrar um livre. Com poucos registros, vai fácil mas, imagina em poucos anos com milhares de registros???

Será que não vale a pena acrescentar 1 ao último (ou usar um AUTOINCREMENT) e esquecer os que já saíram?

Se for TOTALMENTE OBRIGATÓRIO o reaproveitamento de códigos, sugiro que crie uma tabela com um único campo, o ID, para cadastrar os código disponíveis para uso....
Mais ou menos assim:
1. Excluiu na tabela principal, grava na tabela de código disponíveis.
2. Usou um código disponível na tabela principal, exclui da tebela de disponíveis.
3. Não tem nenhum na tabela de disponíveis, usa o MAX + 1.

Enfim, volto a chamar a sua atenção na necessidade de reutilização de códigos... Não é uma boa prática, exceto se for COMPLETAMENTE E IRRESTRITAMENTE NECESSÁRIA, SEM A POSSIBILIDADE DE EXISTIR OUTRA OPÇÃO...

Boa sorte
ABDON 11/09/2009 13:33:53
#322617
Isso estou usando o Data Control.
o modo que gero o registro está correto, mas quero fazer este código de gerar código em uma função.
DANIKULL 11/09/2009 21:35:25
#322680
Citação:

ABDON escreveu:
Altem alguma idéia de como se faz!?!!??????????????????



Boa noite, tudo bem???

Deixa eu te dar uma dica.
Antes de eu mudar a forma de criação dos códigos para os cadastros eu fazia da seguinte forma:
Em uma sub roitina:


Public Sub AutoCod()
Dim UltCod, NewCod As Long

With tbCliente
If .BOF = True And .EOF = True Then
UltCod = 1
Else
.MoveLast
UltCod = !Cliente_Id + 1
End If
NewCod = UltCod
txt_cod.Text = Format(NewCod, [Ô]000000[Ô])
End With

End Sub


Utilizo coneão ADO modo desvinculado e para abri o tbCliente da seguinte forma


Set tbCliente = New ADODB.Recordset
tbCliente.Open [Ô]Clientes[Ô], Banco, adOpenKeyset, adLockOptimistic


Tena ai e veja se você vai conseguir, qualquer coisa posta ai novamente, ok????


EMERSONTADEU 12/09/2009 02:05:35
#322683
Poxa irmão, vc pode até criar templates no VS98 mas se está a ponto de querer esta agilidade pode ter certeza de que em 10 anos o VBNet evoluiu muito e parece que terminaram de mapear os nomes dos tipos de dados da framework e agora está bem tranquilo encontrar as coisas.

Dataset nada mais é do que acréscimo de algumas funcionalidades dos famigerados recorsets hierárquicos que ninguém quase usava (shape etc) ....
Hoje por exemplo vc não precisa codificar a consistencia de dados e se matar nos loops num form Master-Details ... da pra fazer isto com controles drag-drop meeeeeesmo sem meeeedo ... jamais pensei que diria isto mas se vc codifica é bem provável que vai ou ficar mais lento ou dar mais erro pq o código deles o mundo inteiro testa desde 2001 e o seu nem saiu da sua mente ainda!

Não, não é propaganda, é uma constatação que a linguagem e as ferramentas evoluiram muito e em 2 meses eu já me considero tão ruim quanto era no VB6. Só que mais rapido, claro.

Procure saber sobre templates, mztools no VS6 e sobre Code Snipped, Project Templates VS Net ... creio que é uma boa hora para vc avaliar o que é melhor estudar para o futuro, cada caso é um caso.

Mas fui obrigado a concordar que ficou boa a idéia dos caras. Gostaria até de que alguém que se opusesse a esta opinião se manifestasse ... não vamos abrir um off dentro do tópico, mas se existem problemas no futuro eu prefiro lidar com a realidade.
MARCELO.TREZE 12/09/2009 11:18:36
#322696
Resposta escolhida
Estou entendendo o que deseja veja esta função para ser usada em um módulo

Public Function AutoCod(DC as Data) As Integer
if DC.Recordset.RecordCount = 0 Then
AutoCod= 1
Else
DC.RecordSource = [Ô]SELECT MAX(Codigo) as XCodigo FROM Turmas ORDER BY Codigo[Ô]
DC.Refresh

AutoCod = DC.Recordset.Fields([Ô]XCodigo[Ô]) + 1
End If
End Function


'agora para usa-lo nos forms seria desta forma, veja

txtCodigo.Text = AutoCod(TTurmas)



ou para ficar mais genérica ainda, poderia fazer assim

Public Function AutoCod(DC as Data, CampoCod As String, Tabela As String) As Integer
if DC.Recordset.RecordCount = 0 Then
AutoCod= 1
Else
DC.RecordSource = [Ô]SELECT MAX([Ô] & CampoCod & [Ô]) as XCodigo FROM [Ô] & Tabela & [Ô] ORDER BY [Ô] & CampoCod
DC.Refresh

AutoCod = DC.Recordset.Fields([Ô]XCodigo[Ô]) + 1
End If
End Function


'agora para usa-lo nos forms seria desta forma, veja

txtCodigo.Text = AutoCod(TTurmas,Codigo,NomeDaTabela)


é pronto, basta você colocar o nome que deu ao objeto data control que será referenciado, seria esta sua necessidade?

MOISES.ARAUJO 13/09/2009 19:53:49
#322781
Tenho esta função em meus programas que estão rodando a mais de 10 anos e nunca deu problema.

Function GeraCodigo(TABELA As String) As String
On Error GoTo er
Set tb = New ADODB.Recordset
tb.Open [Ô]select Max(codigo) as cod from [Ô] & TABELA & [Ô] [Ô], DB, adOpenDynamic, adLockBatchOptimistic
[ô] gera codigo
intCont = [Ô]0[Ô] & tb(0)

intCont = tb.Fields([Ô]cod[Ô]) + 1
GeraCodigo = intCont

If intCont <> [Ô]0[Ô] Then
intCont = intCont - [Ô]0[Ô] [ô]Primeiro registro
GeraCodigo1 = intCont
Else
intCont = 1
GeraCodigo = intCont
End If
retorno:

Exit Function
er:
If Err.Number = 94 Then
GeraCodigo = 1
Resume retorno
End If
End Function
ICEMAN 13/09/2009 22:02:40
#322788
Citação:

ABDON escreveu:
mas com SELECT MAX e com o RECORDCOUNT + 1 vai dar erro tava analisando aqui, por exemplo tenho os seguintes registro:

Código | Nome
1 A
2 B
3 C

deleto o segundo registro,

Código | Nome
1 A
3 C

quando for add mais um vai dar duplicidade de código, o geito que fasso é mais correto

Código | Nome
1 A
3 C quantidade de resgistros = 2 + 1 = 3 , código é chave primaria, não funciona.
3 D











vc viu o fonte

o tecla conta para ver se há registreos se nao tem entao é 1, se tiver ele pega o valor maior e soma 1 entao nao gera-ra duplicidade

Citação:

TECLA escreveu:
Dessa forma não é totalmente eficas à duplicidade de código, uso esse código porque
permito o usuário decidir se vai reaproveitar código ou não.

Partindo deste princípio, tente assim:

Public Function GerarCod() As Double
if TTurmas.Recordset.RecordCount = 0 Then
GerarCod = 1
Else
TTurmas.RecordSource = [Ô]SELECT MAX(Codigo) as XCodigo FROM Turmas ORDER BY Codigo[Ô]
TTurmas.Refresh
GerarCod = CDbl(TTurmas.Recordset([Ô]XCodigo[Ô])) + 1
End If
End Function


Para chamar...
Text1 = GerarCod


Funciona desde que o RECORDSET esteja acessível no escopo da função.




esse ja te ajudará bastante, agora vc pode gerara um autonumeração no dbn tambem, qual o db?
RCMRO 14/09/2009 08:04:22
#322799
Pessoal,

O cara não quer o (MAX+1), ele quer aproveitar brexas nos números e, caso não existam, ai sim ser (MAX+1).
é isso que faeli ser um grande gerador de atrazo com o tempo. Claro e óbvio que uma tabela que tiver o indice num campo e você usar MAX+1 nela pouco DELAY vai gerar, mesmo daqui a 10 anos mas, não é isso que ele quer.....

Bem, seja como for, a decisão está com ele. Se ficar com a idéia de [Ô]procurar um código livre[Ô], é a pior e mais lenta mas... Depois disso, tanto o (MAX+1) quanto ou AUTOCONTADOR são uma solução muito pareceida, exceto pela integridade de código, que precisa ser feita no VB ao invez de ser gerida pelo BD.
Página 2 de 2 [19 registro(s)]
Tópico encerrado , respostas não são mais permitidas