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 30/03/2007, 23h20   #21
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 772
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 40
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 772
Points : 4 337
Points : 4 337
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?
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2007, 08h45   #22
philben
Membre Expert
 
Inscription : avril 2006
Messages : 1 387
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 1 387
Points : 1 903
Points : 1 903
bonjour,

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

A) créer la requête suivante :
Code :
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 :
1
2
3
4
 
INSERT INTO TableN ( N2, N3 )
SELECT Identity.MAX, Identity.MAX
FROM X, [Identity];
Cordialement,

Philippe
philben est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/03/2007, 15h45   #23
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 772
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 40
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 772
Points : 4 337
Points : 4 337
J'ai une suggestion à faire sur le type d'incrémentation:

tofalou tu as posté:
Citation:
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...
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/04/2007, 20h23   #24
Tofalu
Rédacteur

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

Informations forums :
Inscription : octobre 2004
Messages : 8 633
Points : 24 307
Points : 24 307
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 ?
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/04/2007, 22h29   #25
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 772
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 40
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 772
Points : 4 337
Points : 4 337
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ù?
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/04/2007, 09h03   #26
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 817
Points : 3 817
GenUniqueId()
ou GetUniqueId() ?

pourrais tu commenter un peu et nous parler de SqlCacheDependency ?
je reste sur ma faim
__________________
Elle est pas belle la vie ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/04/2007, 14h58   #27
krina85
Candidat au titre de Membre du Club
 
Inscription : août 2006
Messages : 56
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 56
Points : 10
Points : 10
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
krina85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/04/2007, 18h16   #28
Tofalu
Rédacteur

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

Informations forums :
Inscription : octobre 2004
Messages : 8 633
Points : 24 307
Points : 24 307
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 ?
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 10h51   #29
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 817
Points : 3 817
bravo solution élégante et peu documentée !
__________________
Elle est pas belle la vie ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 11h34   #30
Tofalu
Rédacteur

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

Informations forums :
Inscription : octobre 2004
Messages : 8 633
Points : 24 307
Points : 24 307
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
Tofalu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 11h39   #31
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 817
Points : 3 817
à 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 ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 12h02   #32
krina85
Candidat au titre de Membre du Club
 
Inscription : août 2006
Messages : 56
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 56
Points : 10
Points : 10
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
krina85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 13h17   #33
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 772
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 40
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 772
Points : 4 337
Points : 4 337
juste en passant: bravo random! car il ne faut pas oublié effectivement que c'est toi qui as fourni la meilleurs réponse.
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 14h04   #34
random
Expert Confirmé
 
Inscription : mai 2005
Messages : 3 419
Détails du profil
Informations forums :
Inscription : mai 2005
Messages : 3 419
Points : 3 817
Points : 3 817
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 ?
random est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/04/2007, 15h56   #35
krina85
Candidat au titre de Membre du Club
 
Inscription : août 2006
Messages : 56
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 56
Points : 10
Points : 10
Bonjour,

J’ai trouvé ceci dans l’aide d’Access :
Citation:
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
Citation:
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
krina85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 02h22   #36
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 772
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 40
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 772
Points : 4 337
Points : 4 337
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.
vodiem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 09h23   #37
krina85
Candidat au titre de Membre du Club
 
Inscription : août 2006
Messages : 56
Détails du profil
Informations forums :
Inscription : août 2006
Messages : 56
Points : 10
Points : 10
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
krina85 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 12h07   #38
vodiem
Expert Confirmé Sénior
 
Avatar de vodiem
 
Homme Diem VO
Vivre
Inscription : avril 2006
Messages : 2 772
Détails du profil
Informations personnelles :
Nom : Homme Diem VO
Âge : 40
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 772
Points : 4 337
Points : 4 337
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 :
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.
vodiem 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 07h49.


 
 
 
 
Partenaires

Hébergement Web