IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Défis Discussion :

[Exercice] Numérotation automatique d'enregistrements


Sujet :

Défis

  1. #21
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Maxcence, je plaisantais, c'est l'idée qui compte dans mes exemples:
    pour ne plus avoir à faire de vérification de redondance les nombres générés devaient prendre des valeurs que ne pouvaient prendre les autres.

    j'ai d'ailleurs un doute sur le code de "LedZeppII", "helas" a raison il ne fait pas de controle sur les autres champs et dans le cas ou il le ferait pourrait-il avoir un résultat correct puisque:
    il appel la fonction une première fois pour obtenir N1
    et lorsqu'il appellera une deuxieme fois pour obtenir N2,
    l'enregistrement n'est pas encore sauvegardé dans la table donc N2 ne prendrais pas en compte le nouveau N1, non?

  2. #22
    Membre chevronné

    Profil pro
    Inscrit en
    avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    une possiblité de laboratoire, non testée en prod

    A) créer la requête suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT Max(TableN.N1) AS MAX1, @@IDENTITY AS MAX2, IIf([MAX2]>0,[MAX2],NZ([MAX1])) AS [MAX]
    FROM TableN;
    B) Pour l'insertion d'enr dans TableN:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    INSERT INTO TableN ( N2, N3 )
    SELECT Identity.MAX, Identity.MAX
    FROM X, [Identity];
    Cordialement,

    Philippe

  3. #23
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 895
    Points : 4 325
    Points
    4 325
    Par défaut
    J'ai une suggestion à faire sur le type d'incrémentation:

    tofalou tu as posté:
    Peut être serait-il possible de la transformer en fonction qui accepterait comme argument :

    Le nom du champ,
    Celui de la table
    Le type d'incrémenation
    donc si je raisonne qu'il faille faire une procedure ou une fonction celle ci devrait faire: (je ne traite pas le cas négatif)

    si on demande l'incrémentation d'abord par N1:
    Etape1:le nouveau N1 sera le Dernier N1 +1 sauf si N2 ou N3 on déjà pris cette valeur auquel cas je recherche la plus proche suivante non prise
    Etape2:je recherche des valeurs aléatoires pour N2 et N3 non prise

    si on demande l'incrémentation d'abord par N2 ou N3:
    Etape1:je recherche des valeurs aléatoires pour N2 et N3 non prise
    Etape2:le nouveau N1 sera le Dernier N1 +1 sauf si N2 ou N3 on déjà pris cette valeur auquel cas je recherche la plus proche suivante non prise

    (autre remarque:Les nouvelles valeurs ne pourront jamais prendre les valeurs en dessous du dernier N1=> ca facilitera la recherche des nombres aléatoires)

    =>Conclusion: que l'on fasse l'étape1 ou l'étape2 en premier ne change pas grand chose au traitement si ce n'est de garantir que le (Dernier N1 +1 valide) sera réservé à N1 au cas où l'incrémentation par N2 ou N3 prendrait cette valeur, chose peu probable: seulement en limite d'incrémentation.

    Alors? Es ce bien utile de donner le type d'incrémentation surtout que N1 n'est pas exploitatable en tant qu'insertion chronologique?
    Donc:Si dans le cas où on n'utilise pas le type d'incrémentation on garanti à N1 l'exclusivité du Dernier N1 +1 valide ainsi on limite encore la recherche des nombres aléatoires valide.

    Tofalu> l'insertion par formulaire ne pose pas de problème, y a tellement de chose qui peuvent se passer lors d'un formulaire... mais directement dans la table aïe, aïe... ca limite drolement...
    Philben> Interessant...

  4. #24
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2004
    Messages : 9 501
    Points : 32 298
    Points
    32 298
    Par défaut
    Bof, ça ne colle pas du tout au problème.

    Que pensez vous de :


    N1 :

    Champ numéro auto, incrémentation standard

    N2 :

    Numérique Long, valeur par défaut : =GenUniqueId()


    N3 :

    Numérique Long, valeur par défaut : =GenUniqueId()

    Je peux ainsi insérer directement dans la table, les numéros aléatoires sont respectés et aucun doublon n'est généré. Non ?

  5. #25
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 895
    Points : 4 325
    Points
    4 325
    Par défaut
    c'est cette fonction qu'on essaie tous de faire... GenUniqueId
    visiblement je suis pas le seul a avoir cette lacune.

    il y en a beaucoup des comme ca qui n'apparaisse pas dans la liste des fonctions intégrées (il n'y a même pas l'aide dessus)? on peut les trouver où?

  6. #26
    Expert confirmé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 3 419
    Points : 4 227
    Points
    4 227
    Par défaut
    GenUniqueId()
    ou GetUniqueId() ?

    pourrais tu commenter un peu et nous parler de SqlCacheDependency ?
    je reste sur ma faim
    Elle est pas belle la vie ?

  7. #27
    Nouveau membre du Club
    Profil pro
    Inscrit en
    août 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2006
    Messages : 56
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    J’ai suivi de près le contenu de ce post et j’aimerai savoir si cette fonction s’utilise comme Aléat() (dans le générateur d’expression) ? Si c’est le cas, est-il possible de générer sans doublons et de manière certaine un numéro aléatoire compris en 10 000 et 99 000 ?
    Sur le site de MS (ici), j'ai vu que la solution proposée était valable pour Aceess 2002 et 2003. Je travaille avec Access 2000. Cela pose-t-il un problème ?

    Merci pour vos conseils

  8. #28
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2004
    Messages : 9 501
    Points : 32 298
    Points
    32 298
    Par défaut
    GenUniqueId est une fonction fourni par le moteur de base de données Jet retournant un nombre aléatoire unique pour le champ. Elle ne peut être utilisée uniquement comme valeur par défaut d'un champ numérique Long.

    SqlCacheDependency
    >> Connais pas. C'est du dotnet ?

  9. #29
    Expert confirmé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 3 419
    Points : 4 227
    Points
    4 227
    Par défaut
    bravo solution élégante et peu documentée !
    Elle est pas belle la vie ?

  10. #30
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : octobre 2004
    Messages : 9 501
    Points : 32 298
    Points
    32 298
    Par défaut
    Citation Envoyé par random
    bravo solution élégante et peu documentée !

    Sans cette fonction, c'est bien entendu la solution que tu as proposée qui est la meilleure

  11. #31
    Expert confirmé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 3 419
    Points : 4 227
    Points
    4 227
    Par défaut
    à l'attention de krina85 tu peux foncer sur cette solution après test sur 1200000 enregistrements pas de doublon
    Elle est pas belle la vie ?

  12. #32
    Nouveau membre du Club
    Profil pro
    Inscrit en
    août 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2006
    Messages : 56
    Points : 28
    Points
    28
    Par défaut
    Bonjour Random,

    Je veux bien foncer mais sur quelle solution ? La tienne (post #14) ou celle de Tofalu avec la fonction GenUniqueId() ? Parce que dans les 2 cas, j'ai pas bien comment parvenir à mon objectif (pas de doublons pour des nombres aléatoires compris entre 10 000 et 99 999, ou plus généralement si j'ai besoin d'une plus grande fourchette plus tard, entre 2 valeurs) ?

    Merci pour vos conseils

  13. #33
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 895
    Points : 4 325
    Points
    4 325
    Par défaut
    juste en passant: bravo random! car il ne faut pas oublié effectivement que c'est toi qui as fourni la meilleurs réponse.

  14. #34
    Expert confirmé

    Profil pro
    Inscrit en
    mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2005
    Messages : 3 419
    Points : 4 227
    Points
    4 227
    Par défaut
    celle de tofalu est blindée et prise en charge par le système
    (il serait bien que cela soit documenté pour plus de sécurité)
    Elle est pas belle la vie ?

  15. #35
    Nouveau membre du Club
    Profil pro
    Inscrit en
    août 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2006
    Messages : 56
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    J’ai trouvé ceci dans l’aide d’Access :
    Pour générer des entiers aléatoires dans une plage donnée, utilisez la formule ci-dessous :

    Int((upperbound - lowerbound + 1) * Rnd + lowerbound)

    Dans cette formule, upperbound désigne la limite supérieure de la plage et lowerbound la limite inférieure.
    et ceci
    Cet exemple utilise la fonction Rnd pour générer une valeur entière aléatoire comprise entre 1 et 6.
    Dim MyValue
    ' Renvoie une valeur aléatoire comprise entre 1 et 6.
    MyValue = Int((6 * Rnd) + 1)
    Je ne vois pas comment utiliser GenUniqueId() parmi ces 2 exemples pour :
    1. éviter à coup sûr d'avoir des doublons
    2. obtenir un nombre aléatoire compris entre mes 2 valeurs


    Merci pour votre aide

  16. #36
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 895
    Points : 4 325
    Points
    4 325
    Par défaut
    krina85> comme a dit Tofalu: GenUniqueId ne peut être utilisé autrement, donc pas exploitable dans ton cas.

    la solution de random pourrait te convenir, encore faudrait que tu utilise plusieur index et revoir les clefs sur ta plage (si j'ai bien suivi).

    si tu n'utilise qu'un index alors oriente toi sur la solus de helas ou LedZeppII sinon si cela t'intéresse j'ai une fonction comme eux mais qui a l'avantage de ne pas boucler inutilement jusqu'à obtention d'une valeur non utilisé.
    je pense que c'est globalement plus rapide.

  17. #37
    Nouveau membre du Club
    Profil pro
    Inscrit en
    août 2006
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2006
    Messages : 56
    Points : 28
    Points
    28
    Par défaut
    Bonjour à vous tous,

    Vodiem, je suis intéressée par ta fonction, et toutes solutions qui peuvent me faire avancer parce que j’ai de gros problèmes de sécurité.
    Je cherche à créer une série de nombres qui est en fait une concaténation de plusieurs NumAuto de plusieurs tables. La dernière série doit correspondre à un nombre parfaitement aléatoire compris entre 2 valeurs. Un peu à la façon d’un numéro de sécurité sociale.
    Le problème est que sur cette dernière série, avec Aléat en valeur par défaut d'un des champs de la table, je me retrouvais avec des doublons. D’où mon grand intérêt pour cette discussion et vos éclairages techniques.

    Merci pour vos conseils

  18. #38
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    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 895
    Points : 4 325
    Points
    4 325
    Par défaut
    puisque visiblement tu n'as pas besoin que ce dernier chiffre aléatoire ne fasse pas partie des autres numéros la structure de la function suivante te conviendrait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 AléatUnique(maTable, monChamp As String, De, a As Long) As Variant
    Dim liste() As Variant
    ReDim liste(a) ' j'ai préfèré crée au dim sup et non de De->a
     
    requete = "SELECT " + monChamp + " AS idx FROM " + maTable + " WHERE " + monChamp + ">=" + Str(De) + " AND " + monChamp + "<=" + Str(a) + ";"
    Set maRq = CurrentDb.OpenRecordset(requete)
     
    debut = De
    fin = a
     
    If maRq.EOF Then GoTo suite 'il n'y a pas encore d'enregistrement
    maRq.MoveFirst
    While (Not maRq.EOF)
    liste(maRq.idx) = maRq.idx
    maRq.MoveNext
    Wend
    If maRq.RecordCount = (a - De + 1) Then Exit Function 'il n'y a plus de numéro dispo
    maRq.Close
     
    Do
        While (Not IsEmpty(liste(debut))) And (debut <= fin): debut = debut + 1: Wend 'première place vide trouvé
        While (IsEmpty(liste(fin))) And (debut <= fin): fin = fin - 1: Wend 'dernière valeur prise
     
        If debut < fin Then
            liste(debut) = liste(fin)
            liste(fin) = debut 'permutation des places occupés avec ceux libre
            fin = fin - 1
        debut = debut + 1
        End If
    Loop Until debut >= fin
    If debut = fin Then debut = debut + 1 'cas chevauchement
     
    suite:
    nalea = Int((a - debut + 1) * Rnd) + debut 'prend une valeur aléatoire sur la plage restante
    If Not IsEmpty(liste(nalea)) Then nalea = liste(nalea) 'la valeur à déjà été prise donc on prend celle libre
    AléatUnique = nalea
    End Function
    il faut noté:
    1.qu'il n'y a aucune gestion d'erreur:
    .pb d'existance de la table ou du champ
    .gestion d'une erreur en plus de Exit Function lorsque la limite est atteinte
    .gestion d'erreur sur Redim (pb de mq de mémoire)
    2.qu'il n'y a pas d'optimisation d'occupation de la zone mémoire: liste() est Variant donc "gourmand" et peut occuper une plage > celle utilisée.
    3.Elle s'utilise dans un Evenement 'Avant insertion' d'un form ou dans une requete.
    4.Une adaptation est possible s'il ne dois pas avoir de doublon dans d'autre index: en rajoutant dans liste() les valeurs des autres champs (cas de cette exercice, encore qu'il ne traite pas le cas négatif => les index doivent avoir les mêmes plages de valeurs).
    5.Les valeurs 'De', 'a': inclus ces nombres.

    ex d'utilisation, sur événement 'Avant insetion' du form:
    Id = AléatUnique("Table1", "Id", 7, 15)
    Table1: la table contenant l'index aléatoire
    Id: le champ aléatoire
    7,15: limites de 7 inclus à 15 inclus.

    krina85> pour la plage que tu veux occuper: 10000 à 99999 cela ne devrait pas poser de problème.

Discussions similaires

  1. Numérotation automatique d'enregistrement dans une requête
    Par Mobydisk21 dans le forum Requêtes et SQL.
    Réponses: 12
    Dernier message: 05/12/2018, 12h58
  2. Fichier avec numérotation automatique et enregistrement
    Par ilankolins dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 29/11/2012, 20h55
  3. Réponses: 3
    Dernier message: 30/09/2010, 13h06
  4. Numérotation automatique selon les utilisateurs
    Par Safaritn dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 12/08/2005, 14h11
  5. suppression automatique des enregistrements
    Par abdou.sahraoui dans le forum Langage SQL
    Réponses: 4
    Dernier message: 02/08/2005, 13h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo