Précédent   Forum du club des développeurs et IT Pro > Logiciels > Microsoft Office > Défis
Défis Ce forum est celui des défis et challenges Office. Prêts à relever le gant ? C'est parti !
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 24/03/2007, 22h51   #1
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Par défaut [Exercice] Numérotation automatique d'enregistrements

Bonjour,

Je vous propose un petit exercice :

Comment procederiez vous pour avoir une table offrant 3 identifiants par enregistrement ?
  • Le champ 1 serait un numéro auto croissant
  • Le champ 2 serait un numéro aléatoire
  • Le champ 3 serait un autre numéro aléatoire

Code :
1
2
3
4
N1	N2	N3	Libelle
1	-858043924	-436861315	Chien
2	1683190266	-1215191821	Chat
3	-594784072	1798275161	Baleine
Notez que des valeurs de N1 peuvent se trouver dans N2 ou N3 et vice versa. Par contre, une valeur de N2 ne peut se répeter dans N2 et idem pour les deux autres colonnes.

Des idées ?

Si possible, j'aimerais que la solution que vous proposiez puisse s'adapter facilement à d'autres champs, genre une dizaine
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 08h12   #2
helas
Membre Expert
 
Inscription : août 2006
Messages : 1 455
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 1 455
Points : 1 783
Points : 1 783
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
Sub NouvelEnregistrement(animal As String)
 Dim n As Long, i As Integer, j As Integer, max As Long,NbChamp As Integer
 Dim db As DAO.Database, t As DAO.Recordset, t2 As DAO.Recordset
 Set db = CurrentDb
 
 NbChamp = 5                                      'Nombre de champs N
 max = DMax("[N1]", "tbAnimaux") + 1       'recherche N1 suivant
 Set t = db.OpenRecordset("tbAnimaux")
 t.AddNew
 t!N1 = max         'champ auto croissant
 
 For j = 2 To NbChamp      'pour chacun des champs N
 
  Do    '##################
 
   If Rnd(1) > 0.5 Then     'sélection du signe
    n = Rnd(1) * 2147483647
   Else
    n = Rnd(1) * -2147483647
   End If
 
   For i = 2 To NbChamp    'recherche presence du nombre n
    Set t2 = db.OpenRecordset("SELECT tbAnimaux.N" & CStr(i) & " FROM tbAnimaux WHERE (((tbAnimaux.N" & CStr(i) & ")=" & n & "));")
    If Not t2.EOF Then t2.Close: Exit For
    t2.Close
   Next i
    If i = 6 Then Exit Do    'nombre n'existe pas
 
  Loop  '####################
 
  t("N" & CStr(j)) = n         'enregistrement du nombre n dans champ N
 Next j
 
 t!texte = animal 
 t.Update
 
 t.Close
 Set t = Nothing
 Set db = Nothing
End Sub
helas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 13h37   #3
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Bonjour,

Cette solution ne me satisfait qu'à moitié car peu réutilisable.

Peut être serait t'il possible de la transformer en fonction qui accepteraient comme argument :

Le nom du champ,
Celui de la table
Le type d'incrémenation


Genre

DIncrement("N1","MaTable",0) renverrai un numéro autoincrémenté valide
DIncrement("N2","MaTable",1) renverrai un numéro aléatoire valide

Reste à voir comment utiliser cette fonction facilement dans un formulaire, et aussi lister les avantages et ses inconvénients pour les données

En tout cas, merci de ta participation
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 15h53   #4
helas
Membre Expert
 
Inscription : août 2006
Messages : 1 455
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 1 455
Points : 1 783
Points : 1 783
Avec dans le formulaire pour les champs la valeur par defaut =Dincrement("tbTest";0) pour l'increment simple et =Dincrement("tbTest";1) pour le nombre aleatoire

Les champs testés pour le nombre aleatoire sont les champs dont le nom se terminent par un nombre à partir du 2ème caractère
N12 est valide, B13 aussi, as12 ou n15d ne le sont pas
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 
Function DIncrement(NomTable As String, TypeIncrement As Integer) As Long
 
 Select Case TypeIncrement
 Case 0
  DIncrement = DMax("N1", NomTable) + 1
 
 Case 1
  Dim i As Integer, NbChamps As Long
  Dim db As DAO.Database, t As DAO.Recordset
 
  Set db = CurrentDb
  Set t = db.OpenRecordset(NomTable)
  NbChamps = 0
 
  For i = 0 To t.Fields.Count - 1
   If IsNumeric(Mid$(t.Fields(i).Name, 2)) Then NbChamps = NbChamps + 1
  Next i
 
  Randomize
  Do    '##################
 
   DIncrement = (Rnd(1) * 2147483647) * IIf(Rnd(1) > 0.5, 1, -1) 'genere le nombre aleatoire
 
   For i = 2 To NbChamps   'recherche presence du nombre
    Set t = db.OpenRecordset("SELECT [" & NomTable & "].N" & CStr(i) & " FROM [" & NomTable & "] WHERE (([" & NomTable & "].N" & CStr(i) & ")=" & DIncrement & ");")
    If Not t.EOF Then t.Close: Exit For
    t.Close
   Next i
   If i = NbChamps + 1 Then Exit Do  'nombre n'existe pas
 
  Loop  '####################
 
  Set t = Nothing
  Set db = Nothing
 End Select
End Function
helas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 17h00   #5
LedZeppII
Rédacteur
 
Avatar de LedZeppII
 
Homme
Maintenance données produits
Inscription : décembre 2005
Messages : 4 198
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Maintenance données produits
Secteur : Distribution

Informations forums :
Inscription : décembre 2005
Messages : 4 198
Points : 7 150
Points : 7 150
Bonjour,

voila ma proposition.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Function NouvId(Table, Champ, Optional Incr = 1) As Long
Dim s As Single, vMax As Variant
If Incr = 1 Then
    Randomize
    Do
       s = Rnd() * 4294967294#
       If s > 2147483647 Then s = -s
       NouvId = CLng(s / 2)
    Loop Until IsNull(DLookup(Champ, Table, Champ & "=" & NouvId))
Else
    vMax = DMax(Champ, Table)
    NouvId = IIf(IsNull(vMax), 0, vMax) + 1
End If
End Function
A+
LedZeppII est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 17h12   #6
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Helas, ta solution ne tiens pas compte du nom du champ à passer en paramètre. De ce fait, la solution de LedZeppII me parait meilleure, toutefois, reste une question, comment allez vous l'utiliser ?
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 19h07   #7
helas
Membre Expert
 
Inscription : août 2006
Messages : 1 455
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 1 455
Points : 1 783
Points : 1 783
Je pensais que le nombre aleatoire devait être unique dans toute la table, c'est pourquoi je testais aussi les autres champs Nn

La version de LedZeppII est effectivement meilleur

Pour l'utilisation dans un formulaire, Valeur par defaut = DIncrement(....)
helas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/03/2007, 20h14   #8
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Citation:
Pour l'utilisation dans un formulaire, Valeur par defaut = DIncrement(....)
Arf, et si je ne veux pas passer par un formulaire ?
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/03/2007, 08h59   #9
helas
Membre Expert
 
Inscription : août 2006
Messages : 1 455
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 1 455
Points : 1 783
Points : 1 783
Passer par quoi ?
Du code ?
helas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/03/2007, 09h34   #10
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 819
Points : 3 819
champ1 numéro auto incrément
champ2 double valeur par défaut rnd() indexé sans doublon
champ3 double valeur par défaut rnd() indexé sans doublon

reste à gérer les improbables conflits
__________________
Elle est pas belle la vie ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/03/2007, 12h37   #11
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Citation:
Envoyé par random
champ1 numéro auto incrément
champ2 double valeur par défaut rnd() indexé sans doublon
champ3 double valeur par défaut rnd() indexé sans doublon

reste à gérer les improbables conflits

Ah ben là c'est clairement déjà mieux puisque d'une part il est possible d'ajouter les données directement dans la table et d'autre part l'index permet de garantir l'intégrité des données.

Seul bémol effectivement il faut gérer les conflits très improbable. Ce n'est pas vraiment à cette solution que je pensais mais celle ci n'est pas mal du tout
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/03/2007, 14h36   #12
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 819
Points : 3 819
Après test et 510 0000 enregistrements ajoutés en plusieurs passes pas de conflit.

Comme disent les statisticiens « un évènement improbable ne se produit jamais »
__________________
Elle est pas belle la vie ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/03/2007, 20h52   #13
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Peut être existe t'il une solution qui permettrait d'être sûr qu'aucun doublon ne sera généré
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/03/2007, 11h11   #14
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 819
Points : 3 819
en testant ceci pour champ1=1 à 3000000

champ2=rnd(-champ1)
champ3=rnd(-champ2)

on trouve 3556 doublons sur champ2

ceci provient de la piètre qualité du générateur de nombres aléatoires de microsoft
en examinant les résultats on s'aperçoit que les doublons sont de la forme
x, (x*2^y)-1
genre
valeur valeur doublon
8....... 2097151
17..... 1114111
18...... 1179647
19.... 1245183
.....
11718 2999807

le plus grand nombre ayant un doublon qui lui est supérieur est donc
11718 sur l'intervalle choisi
conclusion
si je définis
champ2=rnd(-champ1-11718)
champ3=rnd(rnd(-champ1-11718))
je dispose de deux clefs pseudo aléatoires et d'un compteur

auqel cas mettre ces clefs dans la base serait inutile
Code :
1
2
3
 
SELECT champ1, Rnd(-[champ1]-11718) AS champ2, Rnd(Rnd(-[champ1]-11718)) AS champ3
FROM matable;
permettant de retrouver à tous moments les clefs

nb à ne pas utiliser en sécurité ni en cryptographie sans bien bien réfléchir
__________________
Elle est pas belle la vie ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/03/2007, 20h51   #15
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
C'est pas mal, mais je pense qu'on devrait pouvoir arriver à quelque chose garantissant encore plus le non doublonnage
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/03/2007, 01h00   #16
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 774
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 41
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Vivre
Secteur : Conseil

Informations forums :
Inscription : avril 2006
Messages : 2 774
Points : 4 340
Points : 4 340
une table avec
un champ N1, un champ N2, un champ N3, un champ Libelle

tous Indexé sans doublons

Libelle: (taille du champ:texte)
N1: taille du champ:NuméroAuto
N2: taille du champ:réel simple / valeur defaut:Aléat()
N3: taille du champ:réel simple / valeur defaut:-Aléat() / valide si:<>0

N1 sera toujours >=1
N2 n'atteindra jamais la valeur 1 et >=0
N3 sera toujours négatif et <>0

c pas dis le type du nombre aléatoire...
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/03/2007, 21h20   #17
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Oui mais rien n'empêche d'avoir deux fois le même N2 avec cette solution
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/03/2007, 02h08   #18
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 774
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 41
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Vivre
Secteur : Conseil

Informations forums :
Inscription : avril 2006
Messages : 2 774
Points : 4 340
Points : 4 340
et un truc comme ca:

Code :
DoCmd.RunSQL "INSERT INTO TABLE2(N2,N3) VALUES(" + Str(DMax("N1", "TABLE2") + 0.5 + (Rnd() / 2)) & "," & Str(DMax("N1", "TABLE2") + 0.49999999 - (Rnd() / 2)) + ")"
a rajouter le labelle dans les valeurs bien sur...
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2007, 20h41   #19
Tofalu
Rédacteur

 
Avatar de Tofalu
 
Christophe Warin
Inscription : octobre 2004
Messages : 8 632
Détails du profil
Informations personnelles :
Nom : Christophe Warin
Âge : 29

Informations forums :
Inscription : octobre 2004
Messages : 8 632
Points : 24 436
Points : 24 436
Citation:
Envoyé par vodiem
et un truc comme ca:

Code :
DoCmd.RunSQL "INSERT INTO TABLE2(N2,N3) VALUES(" + Str(DMax("N1", "TABLE2") + 0.5 + (Rnd() / 2)) & "," & Str(DMax("N1", "TABLE2") + 0.49999999 - (Rnd() / 2)) + ")"
a rajouter le labelle dans les valeurs bien sur...

Oui mais il n'y a rien d'automatique dans cette solution. Que se passe t'il si l'utilisateur veut saisir les données dans un formulaire ou dans la table directement ?
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/03/2007, 21h02   #20
Maxence HUBICHE
Rédacteur

 
Avatar de Maxence HUBICHE
 
Homme Maxence HUBICHE
Développeur SQLServer/Access
Inscription : juin 2002
Messages : 3 771
Détails du profil
Informations personnelles :
Nom : Homme Maxence HUBICHE
Âge : 43
Localisation : France, Val d'Oise (Île de France)

Informations professionnelles :
Activité : Développeur SQLServer/Access

Informations forums :
Inscription : juin 2002
Messages : 3 771
Points : 8 784
Points : 8 784
Envoyer un message via MSN à Maxence HUBICHE Envoyer un message via Skype™ à Maxence HUBICHE
Citation:
Envoyé par Tofalu
Comment procederiez vous pour avoir une table offrant 3 identifiants par enregistrement ?
C'est pas normatif !
Je ne fais pas !

__________________
Mes tutoriels et vidéos :
Tableaux croisés dynamiques, Access les Bases, et les autres !
Maxence HUBICHE est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 17h52.


 
 
 
 
Partenaires

Hébergement Web