Pour ceux qui souhaite participer au projet MELA c'est par ici :
https://crud4msaccess.codeplex.com/
Pour ceux qui souhaite participer au projet MELA c'est par ici :
https://crud4msaccess.codeplex.com/
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
Bonjour,
Merci beaucoup pour partager ce magnifique travail. Même plusieurs années après, ça fonctionne toujours très bien.
J'en ai profité pour y ajouter du code afin de masquer le bouton btnPrecedent lorsque l'on est sur le premier enregistrement, et le bouton btnSuivant lorsque l'on est sur le dernier enregistrement.
Ca peut être pratique.
Pour qui en a besoin, à ajouter à ActiverControleDetail() :
A la fin du point VI-A du tuto, il est indiqué
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 ' Désactivation du bouton "Précédent" lorsque l'on est sur le premier enregistrement If oForm.CurrentRecord > 1 Then oForm.btnPrecedent.Visible = True Else oForm.btnPrecedent.Visible = False End If ' Désactivation du bouton "Suivant" lorsque l'on est sur le dernier enregistrement ' Source : http://www.fontstuff.com/mailbag/qaccess04.htm Dim rst As Object Set rst = oForm.RecordsetClone ' Fournit une copie de l'enregistrement, qui peut être manipulée sans modification de l'enregistrement d'origine. Evite de naviguer jusqu'au dernier enregistrement. On Error Resume Next rst.MoveLast ' La propriété RecordCount affiche une valeur pour les enregistrements lus. Aller sur le dernier enregistrement permet d'afficher le nombre exact d'enregistrements On Error GoTo 0 If oForm.CurrentRecord < rst.RecordCount Then oForm.btnSuivant.Visible = True Else oForm.btnSuivant.Visible = False End If
De quoi s'agit-il, et où peut-on le mettre ?On continue le verrouillage/déverrouillage tout au long des actions qui le nécessitent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part Docmd.OpenForm "fAdherent",,,,acAdd
Et pourquoi placer les boutons de commande forcément dans l'en-tête ?
C'est pour donner un exemple d'une commande qui va déclencher le mode Ajout et de mettre ceci en pratique :A la fin du point VI-A du tuto, il est indiqué
Et pourquoi placer les boutons de commande forcément dans l'en-tête ?On continue le verrouillage/déverrouillage tout au long des actions qui le nécessitent. De quoi s'agit-il, et où peut-on le mettre ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part Docmd.OpenForm "fAdherent",,,,acAdd
Ici le choix de l'activation ou non des contrôles est conditionné par la valeur renvoyée par la propriété NewRecord du formulaire. Ceci permet d'être immédiatement en situation de saisie si l'ouverture du formulaire est réglée sur Ajout de données.Donc il n'y a rien à faire ! Du moment que tu ouvres un formulaire en mode acAdd (nouvel enregistrement).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 ' verrouille l'enregistrement dés son affichage sauf si c'est un nouvel enregistrement. ActiverControleDetail oForm.NewRecord ' Capte l'id de l'enregistrement If Not oForm.NewRecord Then Me.IdCurrentRecord = vIdCurrentRecord End If
Cordialement,
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
Concernant ton code :
Pense à libérer les objets que tu ouvres surtout dans des classes.
Il vaut mieux créer une fonction private qui renvoi le recordcount.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Dim rst As Object Set rst = oForm.RecordsetClone ... set rst = Nothing
Que se passe-t-il si le recordset est vide ?
Cordialement,
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
Exact, merci de me l'avoir rappelé
Pour quelle raison ?
S'il n'y a pas d'enregistrement dans ma table, les boutons ne sont pas visibles. C'est l'intérêt de la gestion des erreurs que j'ai inclus justement : sans enregistrement, RecordCount retourne la valeur 0.
Juste pour bien séparer les traitements et pour éviter d'avoir des On Error qui se ballade dans le code.Il vaut mieux créer une fonction private qui renvoi le recordcount.
Pour quelle raison ?
Cordialement,
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
OK, ça donne ça dans ce cas :
Bien entendu, des variantes sont possibles, comme changer Visible par Enabled par exemple, ou encore pour n'afficher les boutons suivant et précédant que s'il y a plus d'1 enregistrement.
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 Private Sub ActiverControleDetail(Optional Activer As Variant = True) ' Activation/désactivation des contrôles (...) ' Désactivation du bouton "Précédent" lorsque l'on est sur le premier enregistrement If oForm.CurrentRecord > 1 Then oForm.btnPrecedent.Visible = True Else oForm.btnPrecedent.Visible = False End If ' Désactivation du bouton "Suivant" lorsque l'on est sur le dernier enregistrement If oForm.CurrentRecord < NbRecord(oForm) Then oForm.btnSuivant.Visible = True Else oForm.btnSuivant.Visible = False End If End Sub Private Function NbRecord(objForm As Form) ' Nombre d'enregistrements d'un formulaire (Source : http://www.fontstuff.com/mailbag/qaccess04.htm) Dim rst As Object Set rst = objForm.RecordsetClone ' Fournit une copie de l'enregistrement, qui peut être manipulée sans modification de l'enregistrement d'origine. Evite de naviguer jusqu'au dernier enregistrement. On Error Resume Next rst.MoveLast ' La propriété RecordCount affiche une valeur pour les enregistrements lus. Aller sur le dernier enregistrement permet d'afficher le nombre exact d'enregistrements On Error GoTo 0 NbRecord = rst.RecordCount Set rst = Nothing End Function
Bonjour,
J'ai dû commettre une erreur dans mon code ci-dessus. En écrivant la fonction NbRecord() comme je l'ai fait, le bouton Copier copie uniquement le dernier enregistrement, et non pas l'enregistrement actif. Les autres boutons semblent tous fonctionner correctement.
J'ai remarqué que mettre le code de la fonction dans ActiverControleDetail() rétablit le bon fonctionnement du bouton.
D'où peut venir l'erreur ?
Vous utilisez tout 2 le recordsetclone.
Il faut que tu remettes le clone sur l'enregistrement de départ.
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
Zut, je ne vois pas du tout quoi modifier.
J'ai essayé de créer une procédure clone, qui produirait à la fois un clone et fournirai le nombre d'enregistrements, mais sans succès jusque là
J'essayerai ceci :
Inutile d'instancier le formulaire il l'est déjà dans oForm.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 Dim rst As recordset Set rst = oForm.RecordsetClone ' Fournit une copie de l'enregistrement, qui peut être manipulée sans modification de l'enregistrement d'origine. Evite de naviguer jusqu'au dernier enregistrement. On Error Resume Next rst.MoveLast ' La propriété RecordCount affiche une valeur pour les enregistrements lus. Aller sur le dernier enregistrement permet d'afficher le nombre exact d'enregistrements On Error GoTo 0 NbRecord = rst.RecordCount rst.bookmark = oform.recordset.bookmark Set rst = Nothing
Cordialement,
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
En remplaçant également ma fonction NbRecord(objForm As Form) par une procédure CalculNbRecords() qui calcule NbRecord, ça fonctionne mieux à présent.
Merci
J'essaie également d'ajouter un dernier effet : n'activer le bouton Annuler que lorsque l'utilisateur fait une modification sur le formulaire.
Il faudrait donc ajouter un code du style :
Où peut-on insérer ce code ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 If oForm.Dirty Then oForm.btnAnnuler.Enabled = True Else oForm.btnAnnuler.Enabled = False End If
Ce cas ne peut être fait via un simple test. En effet les mécanismes des formulaires (expliqué dans mon tuto sur les évènements de formulaires) nécessitent d'utiliser les événements adéquats pour le mettre en oeuvre. Les 2 évènements sont Si modification et Après_Maj.
Il faut surcharger l'évènement Form_Dirty() du formulaire, comme je l'ai fais pour Form_Current() pour y placer l'activation.
La désactivation doit être faite sur la sauvegarde, donc Form_AfterUpdate().
Le bouton doit être désactivé par défaut.
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
Si j'écris :
je reçois l'erreur L'expression Sur ouverture entrée comme paramètre de la propriété de type événement est à l'origine d'une erreur. La déclaration de la procédure ne correspond pas à la description de l'événement ou de la procédure de même nom.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Private Sub oForm_Dirty() ' En cas de modification du formulaire, activation du bouton Annuler. oForm.btnAnnuler.Enabled = True End Sub
Bonjour,
J'ai changé Private Sub oForm_Dirty() en Private Sub oForm_Dirty(Cancel As Integer), ce qui me permet d'enlever le message d'erreur.
Par contre, le bouton Annuler ne veut pas s'activer lorsque je modifie une donnée.
Vous avez une idée pour faire en sorte que ça fonctionne ?
Tu as oublié d'activer les événements avec "[Event Procedure]" dans la méthode/propriété Form.
Tu n'as pas lu le tuto... tout ça y est expliqué.
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
C'est bien ça, merci . Et si, j'avais bien lu tout le tuto, mais j'aurai dû le relire après avoir fait mes modif.
Ca fonctionne bien. J'en ai profité pour modifier le comportement du bouton Supprimer. En effet, j'ai remarqué que le bouton Supprimer se dirige sur l'enregistrement suivant après la suppression, y compris pour le dernier enregistrement. Dans ce cas, le formulaire cible un enregistrement vide (celui pour créer un nouvel enregistrement) et bascule en mode édition. Il faut donc tout d'abord enregistrer cet enregistrement en le laissant vierge, et revenir sur l'enregistrement précédent. Rien de grave, mais ça peut être automatisé.
J'ai continué l'analyse du code, pour le mettre à ma sauce.
Dans la procédure ActiverControleDetail(Optional Activer As Variant = True), comme Activer est mis à True par défaut, à quoi sert la ligne
N'y a-t-il pas double emploi avec l'option par défaut ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part If IsMissing(Activer) Then Activer = oForm.Controls(Me.DefaultControlName).Locked
Concernant la partie gestion des boutons Enregistrer et Modifier dans cette procédure, je pense qu'il est important de signaler que l'ordre d'affichage est important. J'ai notamment souhaité masquer les boutons Enregistrer et Annuler en mode sélection, et les boutons Créer, Modifier, Copier, Supprimer, Précédent et Suivant en mode édition, et si on ne place pas les Visible = True au début, puis le SetFocus, et enfin les Visible = False, l'affichage des boutons nous joue des tours.
Autre question : pourquoi conserver la définition de la propriété Get Form, puisque il est précisé "Nous pourrions nous passer de cette propriété et y accéder en utilisant l'objet oForm", ce qui semble être le cas dans le reste du programme ?
Cette classe de démonstration, bien que fonctionnelle, est perfectible.
Concernant le isMissing il est effectivement obsolète.
En effet la propriété Visible ne peut être manipulée sur un contrôle qui a le focus. Ce n'est pas lié à la classe mais un comportement logique d' ACCESS.
Le getteur permet de faire appel au formulaire depuis l'extérieur et ainsi de respecter les éventuelles contraintes (non présente dans cette version de démo) qui pourrait y être.
Cordialement,
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
Bonjour,
L'intégration de cette classe dans un sous-formulaire est-elle possible ?
Je viens d'essayer. Dans le sous-formulaire directement, nommé SsFrmStructure_Adresse, pas de problème. Mais dans le formulaire père, Access me retourne "2489 -- L'objet "SsFrmStructure_Adresse" n'est pas ouvert."
Normalement oui.
Par contre pas si le formulaire lui même à déjà cette classe en action.
Détecter les modifications formulaire Cloud storage et ACCESS
Classe MELA(CRUD) Opérateur IN et zone de liste Opérateur LIKE
Visitez mon Blog
Les questions techniques par MP ne sont pas lues et je ne pratique pas la bactériomancie
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