Précédent   Forum des professionnels en informatique > Logiciels > Microsoft Office > Access > VBA Access
VBA Access Le forum pour les questions relatives au code VBA sous Access, et à son environnement de développement VBE.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/03/2011, 14h49   #1
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Par défaut Problème avec une clef primaire

Bonjour,

Dans une table Access qui comporte une clef primaire qui me permet de donner un numéro d’inventaire à mes films, il arrive que certains numéros « sautent » : Mon numéro d’inventaire passe par exemple de 1 à 3.

Je suppose qu’il s’agit d’une erreur liée à des suppressions d’enregistrements, mais je n’arrive, ni en compactant la base, ni par programmation à supprimer ou modifier ces enregistrements fantômes :

Code :
1
2
3
4
While Not rst.EOF
MsgBox (rst.Fields("Inventaire") & " " & rst.Fields("Titre"))
rst.MoveNext
Wend
Passe de la fiche 1 à la fiche 3, sans s’arrêter au 2 qui reste un enregistrement que je n’arrive pas à atteindre.

Cela me gène car mon numéro d’inventaire, qui devait me servir à numéroter mes films n’est pas fiable.

Quelqu’un sait-il comment faire pour atteindre et modifier ces enregistrements inutiles ?

Merci à tous ceux qui me liront.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 15h01   #2
Rédacteur/Modérateur
 
Avatar de jpcheck
 
Jean-Philippe ANDRÉ
Inscription : juillet 2007
Messages : 7 863
Détails du profil
Informations personnelles :
Nom : Jean-Philippe ANDRÉ
Âge : 28
Localisation : France

Informations forums :
Inscription : juillet 2007
Messages : 7 863
Points : 10 742
Points : 10 742
Envoyer un message via MSN à jpcheck
Salut,

une proposition d'approche est disponible dans la pour ce sujet
http://access.developpez.com/faq/?pa...elNumAutoHoles
__________________
Pas de question technique par MP, je ne réponds pas

Mon perso ? Une vraie brute

Tutos Access, Tâches planifiées et Batch,Tables de Paramètres sous Access, Excel et Batch, Tâches planifiées et Access
jpcheck est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 15h12   #3
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Un grand merci pour votre réponse si rapide.

Je vais essayer de mettre en place la solution que vous me proposez.
Aussi vite que possible, je vous donne des nouvelles.

Encore merci.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 15h42   #4
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonsoir,

Modifié pour pouvoir fonctionner avec les noms de ma table et du champ que je cherche à compléter, le code dont j’ai pu profiter grâce à vous devient :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Dim sSQL    As String
    Dim rs      As DAO.Recordset
    Dim n       As Long
 
    'Chaîne SQL en fonction de Inventaire et de Films, retournant NULL ou le numéro du trou
    sSQL = "Select Min([" & Inventaire & "]-1) As NextID From " & Films & " As T1 "
    sSQL = sSQL & "Where ((([" & Inventaire & "]-1)>0) And (((Select [" & Inventaire & "] "
    sSQL = sSQL & "From " & Films & " T2 "
    sSQL = sSQL & "Where T2.[" & Inventaire & "]=T1.[" & Inventaire & "]-1)) Is Null));"
    Set rs = CurrentDb.OpenRecordset(sSQL, dbOpenSnapshot)
    'Nbre d'enregistrements dans Films
    n = DCount("[" & Inventaire & "]", "[" & Films & "]")
    If n = 0 Then               'S'il n'y a pas d'enregistrements, mettre 1
        NextID = 1
    ElseIf IsNull(rs(0)) Then   'Si la requête ne renvoie rien, incrémenter de 1 le maximum
        NextID = DMax("[" & Inventaire & "]", "[" & Films & "]") + 1
    Else
        NextID = rs(0)          'Sinon, il y a un trou. Renvoyer la valeur du trou
    End If
Il bloque à la ligne :

Set rs = CurrentDb.OpenRecordset(sSQL, dbOpenSnapshot)

Et indique :

Erreur d’exécution ‘3131’ :
Erreur de syntaxe dans la clause FROM

Je cherche la solution, si quelqu’un pouvait m’aider, je l’en remercie, si je trouve une solution, je la poste sur le forum en espérant qu'elle pourra être utile à un autre.

Merci.
Bien cordialement.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 17h02   #5
Rédacteur/Modérateur
 
Avatar de jpcheck
 
Jean-Philippe ANDRÉ
Inscription : juillet 2007
Messages : 7 863
Détails du profil
Informations personnelles :
Nom : Jean-Philippe ANDRÉ
Âge : 28
Localisation : France

Informations forums :
Inscription : juillet 2007
Messages : 7 863
Points : 10 742
Points : 10 742
Envoyer un message via MSN à jpcheck
En fait ici tu dis a Access de prendre les valeurs de variables, au lieu de prendre les noms de champs et tables,

essaie avec

Code :
1
2
3
4
sSQL = "Select Min([" & "Inventaire" & "]-1) As NextID From " & "Films" & " As T1 "
    sSQL = sSQL & "Where ((([" & "Inventaire" & "]-1)>0) And (((Select [" & "Inventaire" & "] "
    sSQL = sSQL & "From " & "Films" & " T2 "
    sSQL = sSQL & "Where T2.[" & "Inventaire" & "]=T1.[" & "Inventaire" & "]-1)) Is Null));"
__________________
Pas de question technique par MP, je ne réponds pas

Mon perso ? Une vraie brute

Tutos Access, Tâches planifiées et Batch,Tables de Paramètres sous Access, Excel et Batch, Tâches planifiées et Access
jpcheck est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 17h57   #6
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonsoir,

Il me semble avoir compris ce que tu disais, mais je n’en suis pas certain.

J’ai tenté le code :

Code :
1
2
3
4
5
6
7
8
Dim requete As String
DoCmd.SetWarnings False
requete = sSQL = "Select Min([" & "Inventaire" & "]-1) As NextID From " & "Films" & " As T1 "
    sSQL = sSQL & "Where ((([" & "Inventaire" & "]-1)>0) And (((Select [" & "Inventaire" & "] "
    sSQL = sSQL & "From " & "Films" & " T2 "
    sSQL = sSQL & "Where T2.[" & "Inventaire" & "]=T1.[" & "Inventaire" & "]-1)) Is Null));"
 
DoCmd.RunsSQL requete
Mais il plante au moment de l’exécution de la requête :

Erreur de compilation :

Membre de méthode ou de données introuvable

Il y a certainement au moins un truc que je n’ai pas compris.
Merci de ce que tu as déjà fait pour m’aider.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/03/2011, 18h24   #7
Rédacteur/Modérateur
 
Avatar de jpcheck
 
Jean-Philippe ANDRÉ
Inscription : juillet 2007
Messages : 7 863
Détails du profil
Informations personnelles :
Nom : Jean-Philippe ANDRÉ
Âge : 28
Localisation : France

Informations forums :
Inscription : juillet 2007
Messages : 7 863
Points : 10 742
Points : 10 742
Envoyer un message via MSN à jpcheck
Attention a ne pas t'egarer entre les variables

ici tu utilises mal requete et sQSL

de plus, il y a un s de trop dans
Docmd.RunSQL

Enfin, ne s'agissant pas d'une requete Action, mais d'une requete selection, RunSQL n'est pas la bonne fonction.
essaie avec

Code :
1
2
3
4
5
 sSQL = "Select Min([" & "Inventaire" & "]-1) As NextID From " & "Films" & " As T1 "
    sSQL = sSQL & "Where ((([" & "Inventaire" & "]-1)>0) And (((Select [" & "Inventaire" & "] "
    sSQL = sSQL & "From " & "Films" & " T2 "
    sSQL = sSQL & "Where T2.[" & "Inventaire" & "]=T1.[" & "Inventaire" & "]-1)) Is Null));"
requete = sSQL
en gardant la syntaxe de depart (en corrigeant les erreurs deja evoquees), la suite de ton code a utiliser sera :
Code :
1
2
3
4
5
6
7
8
9
10
Set rs = CurrentDb.OpenRecordset(requete, dbOpenSnapshot)
    'Nbre d'enregistrements dans Films
    n = DCount("[Inventaire]", "[Films]")
    If n = 0 Then               'S'il n'y a pas d'enregistrements, mettre 1
        NextID = 1
    ElseIf IsNull(rs(0)) Then   'Si la requête ne renvoie rien, incrémenter de 1 le maximum
        NextID = DMax("[Inventaire]", "[Films]") + 1
    Else
        NextID = rs(0)          'Sinon, il y a un trou. Renvoyer la valeur du trou
    End If
__________________
Pas de question technique par MP, je ne réponds pas

Mon perso ? Une vraie brute

Tutos Access, Tâches planifiées et Batch,Tables de Paramètres sous Access, Excel et Batch, Tâches planifiées et Access
jpcheck est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/03/2011, 13h46   #8
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonjour,

Le code que tu as rédigé et que j’ai repris ainsi :

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
Code :
1234567891011121314151617
Dim requete As String
sSQL = "Select Min([" & "Inventaire" & "]-1) As NextID From " & "Films" & " As T1 "
    sSQL = sSQL & "Where ((([" & "Inventaire" & "]-1)>0) And (((Select [" & "Inventaire" & "] "
    sSQL = sSQL & "From " & "Films" & " T2 "
    sSQL = sSQL & "Where T2.[" & "Inventaire" & "]=T1.[" & "Inventaire" & "]-1)) Is Null));"
requete = sSQL
Set rs = CurrentDb.OpenRecordset(requete, dbOpenSnapshot)
    'Nbre d'enregistrements dans Films
    n = DCount("[Inventaire]", "[Films]")
    If n = 0 Then               'S'il n'y a pas d'enregistrements, mettre 1
        NextID = 1
    ElseIf IsNull(rs(0)) Then   'Si la requête ne renvoie rien, incrémenter de 1 le maximum
        NextID = DMax("[Inventaire]", "[Films]") + 1
    Else
        NextID = rs(0)          'Sinon, il y a un trou. Renvoyer la valeur du trou
        MsgBox (NextID)
    End If
Fonctionne, il me donne l’index du premier trou.
Grand merci pour cette aide, mais je ne parviens toujours pas à modifier l’enregistrement en question :

Code :
1
2
3
DoCmd.SetWarnings False
requete = "select * from Films Where INDEX = " & NextID
DoCmd.RunSQL requete
Ne fonctione pas (Erreur d’exécution ‘2342’ :
Une action ExécuterSQL nécessite un argument consistant en une instruction SQL.)

Quelqu’un a-t-il une idée pour pouvoir modifier l’enregistrement « fantôme » ?

Merci et bonne journée à tous.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2011, 10h43   #9
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonjour et bonne semaine à tous.

Il y a une autre solution pour trouver les numéros automatiques manquants.
Elle est certainement moins pure que celle proposée plus haut, mais elle fonctionne aussi :


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
'Chercher le nombre de fiches manquantes
 
While Not rst.EOF
Compteur_enregistrements = Compteur_enregistrements + 1
If (rst.Fields("Inventaire")) > Compteur_enregistrements Then
    numabs = numabs + 1
    Compteur_enregistrements = Compteur_enregistrements + 1
End If
rst.MoveNext
Wend
rst.Close
ReDim numfiches(numabs)
 
' Mettre le numéro des fiches manquantes dans un tableau
 
rst.Open ("Films")
While Not rst.EOF
Compteur_enregistrements = Compteur_enregistrements + 1
If (rst.Fields("Inventaire")) > Compteur_enregistrements Then
    Nombreamodifier = Nombreamodifier + 1
    numfiches(Nombreamodifier) = Compteur_enregistrements
    Compteur_enregistrements = Compteur_enregistrements + 1
End If
rst.MoveNext
Wend
Elle a le petit avantage de récupérer tous les trous en une seule passe.

Ce n’est pas là que se situe le cœur de mon problème : Ce que j’aimerai savoir c’est si il est possible de se servir des numéros récupérés pour créer des fiches qui s’intercaleraient aux numéros trouvés (J’ai tenté sans succès de passer par UPDATE).

En clair, si mon premier enregistrement trouvé comme manquant est le numéro 2 comment établir ou rétablir une fiche numéro 2 sachant que ce numéro est un numéro automatique, clef primaire de la table Films.


Merci à jpcheck pour l’aide qu’il m’a apportée et à tous ceux qui me liront.
Cordialement.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2011, 11h14   #10
Membre Expert
 
Homme Pierre ANTOINE
Inscription : février 2008
Messages : 650
Détails du profil
Informations personnelles :
Nom : Homme Pierre ANTOINE
Âge : 43
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Secteur : Enseignement

Informations forums :
Inscription : février 2008
Messages : 650
Points : 1 302
Points : 1 302
Bonjour

Selon toute vraisemblance, s'il y a eu des "trous" c'est que le champ "numéro" est au format "Numéro auto" dans la table.

Dans ce cas, il n'y a pas de possibilité de créer un enregistrement avec le numéro disponible.

Il faut d'abord supprimer le format "numéro auto", et ensuite, au moment de créer un enregistrement, récupérer le premier "emplacement" vide (le "2" entre le "1" et le "3"), qui peut se situer après le dernier enregistrement.

Pierre
pier.antoine est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/03/2011, 15h31   #11
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonjour,

Tout à fait, le champ "numéro" est au format "Numéro auto" dans la table.

Est-il possible, en VBA, de supprimer l'attribution clé primaire au champ "numéro", transformer ce champ en champ numérique simple pour pouvoir ensuite modifier les fiches.

Puis, ensuite de redonner au champ sa valeur de clé primaire et de le remettre au format "Numéro auto" ?

Merci à tous ceux qui se pencheront sur mon problème.
Bon week-end à tous.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/03/2011, 10h31   #12
Rédacteur/Modérateur
 
Avatar de jpcheck
 
Jean-Philippe ANDRÉ
Inscription : juillet 2007
Messages : 7 863
Détails du profil
Informations personnelles :
Nom : Jean-Philippe ANDRÉ
Âge : 28
Localisation : France

Informations forums :
Inscription : juillet 2007
Messages : 7 863
Points : 10 742
Points : 10 742
Envoyer un message via MSN à jpcheck
Citation:
Envoyé par marcbo Voir le message
Grand merci pour cette aide, mais je ne parviens toujours pas à modifier l’enregistrement en question :

Code :
1
2
3
DoCmd.SetWarnings False
requete = "select * from Films Where INDEX = " & NextID
DoCmd.RunSQL requete
Ne fonctione pas (Erreur d’exécution ‘2342’ :
Une action ExécuterSQL nécessite un argument consistant en une instruction SQL.)
SAlut,
attention, une requete SELECT * FROM n'est pas une requete action, elle se "contente" de retourner une serie d'enregistrements.

Si tu veux utiliser RunSQL, il faut une requete action, type INSERT, UPDATE, DELETE, SELECT INTO...
__________________
Pas de question technique par MP, je ne réponds pas

Mon perso ? Une vraie brute

Tutos Access, Tâches planifiées et Batch,Tables de Paramètres sous Access, Excel et Batch, Tâches planifiées et Access
jpcheck est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 22/03/2011, 19h13   #13
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonsoir,

Toutes mes excuses à jpcheck, je n'avais pas vu qu'il avait, encore, répondu à ma demande.
Je le remercie pour sa patience, sa disponibilité et sa rapidité.

Je comprends bien que l'utilisation de "select" est une erreur, ( c'est même, à mon avis, une connerie, je le remercie de ne pas me l'avoir fait remarquer), mais je n'arrive pas non plus à utiliser INSERT, UPDATE, DELETE, SELECT INTO... sur les enregistrements qui correspondent à des numéros d'index supprimés.

pier.antoine a sans doute raison lorsqu'il dit: "Dans ce cas, il n'y a pas de possibilité de créer un enregistrement avec le numéro disponible."


S'il n'a pas de solution à mon problème, Il faut clore cette discussion même si elle m'a appris bien des choses.

Je ne veux pas le faire avant de remercier tous ceux qui m'ont aidé.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 05h22   #14
Membre Expert
 
Homme Pierre ANTOINE
Inscription : février 2008
Messages : 650
Détails du profil
Informations personnelles :
Nom : Homme Pierre ANTOINE
Âge : 43
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Secteur : Enseignement

Informations forums :
Inscription : février 2008
Messages : 650
Points : 1 302
Points : 1 302
Bonjour

Si vraiment c'est important pour vous que l'identifiant soit continu (sans trou de numérotation), alors, il faut sérieusement envisager de modifier votre table
- en ajoutant dans un premier temps un nouveau champ "IDnormal" (numérique)
- en recopiant le contenu du champ "ID auto" dans ce champ.
- de modifier toutes les références à ID auto pour qu'elles se réfèrent à "ID Normal", et non plus à "ID auto"

C'est ce que je ferais.

Bonne journée

Pierre
pier.antoine est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/03/2011, 11h16   #15
Invité de passage
 
Inscription : août 2010
Messages : 14
Détails du profil
Informations forums :
Inscription : août 2010
Messages : 14
Points : 2
Points : 2
Bonjour,

C'est ce que je vais faire.

Un grand merci à tous ceux qui m'ont aidé.
Bonne journée à tous.
marcbo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 15h53.


 
 
 
 
Partenaires

Hébergement Web