Merci de ta réponse.
J'ai testé mais le problème ne change pas.
Il y a toujours les enregistrements fantômes... Qu'est-ce qui provoque ça?
Merci de ta réponse.
J'ai testé mais le problème ne change pas.
Il y a toujours les enregistrements fantômes... Qu'est-ce qui provoque ça?
As-tu commencé par "nettoyer" la table T_Prevision en effaçant les lignes fantômes ?
Les fantômes apparaissent parce que le moteur de base de données Jet est très serviable (trop serviable ?) mais n'a pas les moyens de rendre un service correct.
Jet détecte que la requête sous-jacente est une requête basée sur des jointures externes, sans enregistrement du côté de la table T_Prevision.
Quand tu veux modifier une ligne du formulaire (donc du jeu de données de la requête sous-jacente), "automatiquement" Jet essaye alors d'ajouter des enregistrements du côté T_Prevision.
Mais comme la requête ne ramène pas le champ T_Prevision.ID_Article, alors Jet ne peut pas le renseigner, donc le laisse vide, d'où le fantôme.
En espérant avoir été clair...
Il ne faut plus utiliser les procédure événementielles Form_BeforeUpdate et Form_AfterUpdate.
Veille à les supprimer pour éviter des erreurs.
J'ai supprimé systématiquement les enregistrements fantômes, mis la procédure sur FormCurrent et supprimé les autres procédures.
Le problème persiste.
Y a-t-il un moyen de gérer les nouveaux enregistrements que fait Access?
De cette façon on pourrait vérifier que la clé est bonne sinon lui interdire de faire l'enregistrement?
Est-ce la bonne façon de voir les choses?
J'ai aussi penser à supprimer par VBA les enregistrements où l'ID_Article est null mais cela implique que je supprime au préalable ma clé primaire pour permettre les enregistrements avec ID_Article null.
Le problème c'est que je perds du même coup l'intégrité de ma base.
Donc si je n'arrive pas à créer ces enregistrements fantômes (c'est dommage j'aime bien le principe, ça semble "propre"), je vais devoir peut-être regarder les contrôles inrépendants (mais je ne sais pas faire...)
Bonjour,
Effectivement, pour que tout fonctionne correctement, il faudrait que dans le Form_Current() on utilise un Me.Requery au lieu de Me.Refresh.
Mais cela repositionne le formulaire sur le premier enregistrement. Voilà encore un autre problème...
Alors aux grands maux les grands remèdes !
Comme tu le suggères, on peut agir au moment de la modification des données.
Voilà ce que je te propose, pièce jointe à l'appui.
(1) Créer une requête qui récupère tous les champs qui doivent être renseignés pour éviter les soucis de fantômes:
ID_Article, ID_Enseigne, Mois en plus de Quantite.
Code VBA : 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
38
39
40 Public Sub CréerReqPrévisions() Dim oDB As DAO.Database, oQD As DAO.QueryDef Dim i As Integer Dim sChamps As String, sFrom As String Dim sGauche As String, sDroite As String Dim SQL As String Set oDB = CurrentDb On Error Resume Next oDB.QueryDefs.Delete "R_Prev" On Error GoTo 0 sChamps = "T_Article.ID_Article, T_Article.Prix" sFrom = "T_Article" sGauche = "" sDroite = "" For i = 1 To 12 sChamps = sChamps & _ ", T_Prevision_" & i & ".ID_Article" & _ ", T_Prevision_" & i & ".ID_Enseigne" & _ ", T_Prevision_" & i & ".Mois" & _ ", T_Prevision_" & i & ".Quantite AS Qte_" & i sFrom = sGauche & sFrom & sDroite & _ " LEFT JOIN (SELECT * FROM T_Prevision WHERE Mois=" & i & ") AS T_Prevision_" & i & _ " ON T_Article.ID_Article = T_Prevision_" & i & ".ID_Article" sGauche = "(" sDroite = ") " Next i SQL = "SELECT " & sChamps & " FROM " & sFrom Set oQD = oDB.CreateQueryDef("R_Prev", SQL) Application.RefreshDatabaseWindow End Sub
(2) Dans le formulaire, réagir à l'événement Si modification pour renseigner correctement toutes les données clés du Recordset sous-jacent au formulaire.
Code VBA : 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 Private Sub Form_Dirty(Cancel As Integer) Dim i As Integer Dim oRS As DAO.Recordset If DCount("*", "T_Prevision", "ID_Article='" & Me.ID_Article & "'") < 12 Then Set oRS = Me.Recordset For i = 1 To 12 oRS.Edit oRS.Fields("T_Prevision_" & i & ".ID_Article") = Me.ID_Article ' /!\ à compléter ' oRS.Fields("T_Prevision_" & i & ".ID_Enseigne") = < ??? > oRS.Fields("T_Prevision_" & i & ".Mois") = i oRS.Update Next i End If End Sub
ça marche impeccable.
J'ai adapté le code à ma base de donnée et tout fonctionne (j'avais une erreur qui m'a pris pas mal de temps avant de la solutionner).
Maintenant, je vais essayer de gérer mes articles en fonction de l'enseigne (liste déroulante dans l'en-tête du formulaire).
Merci!
Bonjour,
La solution marche très bien.
J'ai donc tenté d'aller plus loin et j'ai donc un complément de question.
Maintenant, j'ai aussi des quantités promotionnelles qui sont calculées dans la requête R_Promo.
J'aimerai les afficher pour chacun des mois.
J'étais passé, dans un premier temps, par des formules DSUM mais le temps d'exécution a explosé à cause du nombre.
Donc comment puis-je les relier cette requête à la requête R_Prev créé précédemment.
Les champs de la requête R_Promo sont :
- ID_Article
- ID_Enseigne
- Mois
- QtePromo
Peut-on intégrer le champ QtePromo dans les "petites tables temporaires" créées (donc par mois) ? Au fait comment appelle-t-on ces tables temporaires?
QtePromo ne dois pas pouvoir être modifié (je verrouille donc sur le formulaire).
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager