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

Access Discussion :

[VBA]Retrouver le contrôle à l'origine d'une erreur


Sujet :

Access

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut [VBA]Retrouver le contrôle à l'origine d'une erreur
    Bonjour,

    Dans la fonction Form_Error, existe-t-il un moyen de retrouver le contrôle ou le champ à l'origine d'une erreur? Je pense notamment à une erreur de type 3314 qui est lancée lorsqu'un champ obligatoire a été omis lors de la sauvegarde d'un enregistrement...

    Merci

  2. #2
    Expert éminent
    Avatar de Lou Pitchoun
    Profil pro
    Inscrit en
    Février 2005
    Messages
    5 038
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Février 2005
    Messages : 5 038
    Points : 8 268
    Points
    8 268
    Par défaut
    Salut,

    Dans la table, sur la propriété 'Null interdit' du champ tu mets à oui.
    Une valeur sera requise.
    Au moins : plus d'oublis

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Ben en fait c'est déjà fait et Access me renvoie bien l'erreur 3314 comme je le souhaite. Le problème c'est que j'aimerais personnaliser le message d'erreur dans Form_Error en fonction du champ qui a été omis. Pour ça il faut que je puisse retrouver le champ responsable de l'erreur... Je me dis que ça doit être possible étant donné qu'Access indique le champ dans son message à lui.

    Une idée?

  4. #4
    Expert éminent sénior
    Avatar de Domi2
    Homme Profil pro
    Gestionnaire
    Inscrit en
    Juin 2006
    Messages
    7 194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Suisse

    Informations professionnelles :
    Activité : Gestionnaire
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 194
    Points : 16 044
    Points
    16 044
    Par défaut
    Bonjour,

    suis pas sûr d'avoir tout compris, mais le nom du champ doit être renvoyé dans la chaîne Err.Description, non ?

    De là, il doit être possible de l'extaire.

    Domi2

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Effectivement Domi2, ça a l'air d'être une très bonne idée J'y avais même pas pensé J'essaie ça tout de suite!

    Merci

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    En fait le problème c'est que selon l'aide Access, la procédure Form_Error ne traîte que les erreurs Microsoft Jet et pas les erreurs VB. Du coup, impossible d'utiliser Err.Description pour retrouver le message d'erreur (j'ai essayé, c'est une chaîne vide...).

    Y a-t-il vraiment aucun moyen de retrouver la description d'une erreur Microsoft Jet?


  7. #7
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour,
    Citation Envoyé par vcattin
    En fait le problème c'est que selon l'aide Access, la procédure Form_Error ne traîte que les erreurs Microsoft Jet et pas les erreurs VB. Du coup, impossible d'utiliser Err.Description pour retrouver le message d'erreur (j'ai essayé, c'est une chaîne vide...).

    Y a-t-il vraiment aucun moyen de retrouver la description d'une erreur Microsoft Jet?
    Il y a bien une possibilité avec DAO.

    L'objet DBEngine possède une collection Errors qui conserve toutes les erreurs qui ont pu se produire au cours d'une opération (une erreur de bas niveau pouvant en entraîner une autre au niveau au-dessus, etc.).
    D'après l'aide en ligne, la dernière erreur devrait être celle présentée dans le message d'erreur d'Access.

    En résumé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Application.DBEngine.Errors
    MAIS j'ai quand même un doute car je crains qu'Access n'utilise un DBEngine privé pour les opérations qu'il gère intégralement, différente de Application.DBEngine.
    A toi de nous dire...

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Merci =JBO=, je voir ce que je peux faire avec ton idée!

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    =JBO= Je crois que ton doute était justifié: j'ai mis la ligne suivante au beau milieu de la procédure Form_Error:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MsgBox Application.DBEngine.Errors.Count
    Et ça me retourne 0, donc pas d'erreur stockée...

    Je pense effectivement que les erreurs DAO et Jet ne sont pas stockées dans le même DBEngine...

    Une autre idée?

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Je viens de réaliser grâce à l'aide Access qu'il est possible de retourner le message d'erreur en utilisant la fonction Error avec en argument le numéro de l'erreur (donné par DataErr dans mon cas).

    J'ai essayé mais malheureusement pour l'erreur 3314, le message retourné est "Erreur définie par l'application ou par l'objet".

    J'espère que ça inspirera quelqu'un...


  11. #11
    Invité
    Invité(e)
    Par défaut
    Bonjour

    Pourquoi ne fais tu pas un contrôle sur chaque contrôle de ton formulaire avant l'enregistrement (contrôler s'il y'a une valeur) ?

    Ainsi s'il y'a une erreur sur un contrôle, tu lances une msgbox avec le nom de ton contrôle.

    Starec

  12. #12
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour,

    Après vérification, la piste DBEngine.Errors s'avère infructueuse.

    MAIS.......

    J'ai planché sur le sujet car la problématique m'intéresse et je te propose une solution, un peu compliquée d'accord, mais opérationnelle.

    Le principe consiste à détourner l'opération de mise à jour des données, au niveau de la procédure événementielle Form_BeforeUpdate, pour capturer l'erreur et empêcher qu'elle ne soit traitée dans la procédure événementielle Form_Error.

    Le GROS avantage de cette solution est qu'elle peut s'appliquer quelles que soient les règles d'intégrité mise en oeuvre sur le jeu de données sous-jacent. Cette technique prend en charge l'ajout et la modification des données.

    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
    38
    39
    40
    41
    42
    43
     
    Dim bTimerUpdate As Boolean
     
    Private Sub Form_BeforeUpdate(Cancel As Integer)
        ' En cas de premier appel à cette procédure,
        ' l'opération est momentanément repoussée (annulée)
        ' afin de contrôler une éventuelle erreur dans Form_Timer.
     
        ' En cas d'appel ré-entrant demandé par Form_Timer,
        ' on laisse faire la tentative de mise à jour de données.
        ' Si une erreur survient, elle est traitée dans Form_Timer.
     
        If bTimerUpdate = False Then
            Cancel = True
            bTimerUpdate = True
            Me.TimerInterval = 50
        Else
            bTimerUpdate = False
        End If
    End Sub
     
    Private Sub Form_Timer()
        Me.TimerInterval = 0
     
        If bTimerUpdate And Me.Dirty Then
            On Error Resume Next
     
            Me.Dirty = False
     
            ' à ce point, l'exécution est automatiquement re-transférée
            ' vers la procédure événementielle Form_BeforeUpdate (2ème appel)
            ' qui peut échouer, en cas de violation des règles d'intégrité
            ' mais sans déclencher l'exécution de la procédure événementielle
            ' Form_Error()
     
            If Err.Number <> 0 Then
                ' >> ICI, on peut récupérer et traiter
                ' >> le message d'erreur d'Access
     
                MsgBox Err.Number & " " & Err.Description, vbExclamation, "Erreur"
            End If
        End If
    End Sub

  13. #13
    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 : 52
    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
    dans l'idée que tu gère l'erreur suite à une saisie, il n'est pas possible de sortir du control av maj de l'enregistrement donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Form_Error(DataErr As Integer, Response As Integer)
    MsgBox Screen.ActiveControl.Name
    End Sub
    autrement je ne vois pas comment en code tu pourrais avoir ce type d'erreur, a moins que c'est volontaire mais là je pense que tu s'auras gérer.

  14. #14
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    À =JBO=:

    Entre temps, j'ai choisi la solution fastidieuse mais simple qui teste chaque champ obligatoire pour savoir lequel/lesquels est/sont vide(s) au moment de l'erreur.

    Néanmoins, ta solution m'intéresse et j'ai essayé de la comprendre seulement je manque un peu d'expérience: j'ai pas très bien compris comment la mise à False de Me.Dirty réenclanche l'événement AvantMJ, pourrais-tu m'expliquer?

    Merci

  15. #15
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour vcattin,
    Citation Envoyé par vcattin
    Entre temps, j'ai choisi la solution fastidieuse mais simple qui teste chaque champ obligatoire pour savoir lequel/lesquels est/sont vide(s) au moment de l'erreur.
    C'est un choixsûr .

    Citation Envoyé par vcattin
    Néanmoins, ta solution m'intéresse et j'ai essayé de la comprendre seulement je manque un peu d'expérience: j'ai pas très bien compris comment la mise à False de Me.Dirty réenclanche l'événement AvantMJ, pourrais-tu m'expliquer?
    Citation Envoyé par Aide en ligne VBA Access
    La propriété Brouillé (Dirty) permet de déterminer si l'enregistrement en cours a subi des modifications depuis sa dernière sauvegarde.
    Valeurs possibles de la propriété Dirty:
    True indique une modification en cours.
    False pas de modification.

    Il est aussi possible d'assigner une valeur à la propriété Dirty, en la passant de True à False.
    Dans ce cas, les modifications en cours sont "entérinées" et Access tente d'enregistrer les modifications et déclenche les événements du formulaire:
    >> BeforeUpdate (annulable),
    >> AfterUpdate.

    En résumé:
    L'assignation Me.Dirty = True revient à commander l'enregistrer des données en cours de modification.

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Le prolème c'est que d'après ce que je comprends, la mise à False de Me.Dirty signifie: "Pas de modification", donc je vois pas pourquoi il y a déclanchement de l'événement AvantMAJ juste après... Ne faudrait-il pas que Me.Dirty soit à True pour que l'événement se déclanche?

  17. #17
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par vcattin
    Le prolème c'est que d'après ce que je comprends, la mise à False de Me.Dirty signifie: "Pas de modification", donc je vois pas pourquoi il y a déclanchement de l'événement AvantMAJ juste après... Ne faudrait-il pas que Me.Dirty soit à True pour que l'événement se déclanche?
    Tu lis la valeur de Dirty pour savoir si l'enregistrement courant est "Brouillé" (modification en cours).

    Mais tu peux aussi forcer l'enregistrement en cours pour qu'il ne soit plus "Brouillé".

    Pour ce faire tu spécifies: << je ne veux plus que "Brouillé" soit Vrai >>.
    Ce qui revient à dire: << je veux que "Brouillé" devienne Faux >>
    Ou encore, en VBA Me.Dirty = False.
    A ce moment là, Access tente d'enregistrer les données...

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    67
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2005
    Messages : 67
    Points : 37
    Points
    37
    Par défaut
    Ah ben tu me tires une belle épine du pied là =JBO=, parce que j'avais tout compris à l'envers: je pensais qu'il fallait mettre Me.Dirty à True pour que le formulaire "se considère" comme étant brouillé et qu'il déclanche une mise à jour, mais apparemment c'est l'inverse, il faut le mettre à False.
    Autrement dit, je pensais qu'on pouvait utiliser cette propriété pour "faire croire" au formulaire qu'il avait été modifié, mais visiblement c'est pas le cas.

    Merci pour ces explications, je vois les choses autrement maintenant

  19. #19
    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 : 52
    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
    Une petite explication sur le déclenchement de l'événement après le changement de valeur:

    depuis la programmation orienté objet, les propriétés des objets comme dirty qui sont normalement que des variables ne sont plus mis à jour "directement" on passe systématiquement par une méthode qui va la changer (et faire répercuter le changement), la simplification de l'écriture ces dernières années a conduit à ne plus appeller la méthode (puisque cela dois être systématique) mais à effecter comme une variable classique.

    donc en conclusion: ne pas confondre un variable avec une propriété.

    ps: si tu controle chaque champ obligatoire tu pourrais centraliser la gestion d'erreur comme je te t'avais proposé au post 07/04/2007 23h26

    =JBO= > si l'événement est bien intercepté av la maj puisque c'est celui du form tu ne sais pas plus quel est le control qui la provoqué, non?

  20. #20
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par vodiem
    =JBO= > si l'événement est bien intercepté av la maj puisque c'est celui du form tu ne sais pas plus quel est le control qui la provoqué, non?
    Effectivement !

    J'ai pris la discussion en cours de route, à un moment où vcattin cherchait une solution pour récupérer le message d'erreur d'Access, au niveau de la procédure événementielle Form_Error.
    J'ai donc cherché à l'aider sur cet aspect seulement.

    Pour mémoire, ce message d'erreur peut contenir le nom du champ incriminé.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Comment trapper le code SQL à l'origine d'une erreur
    Par tibal dans le forum Adaptive Server Enterprise
    Réponses: 2
    Dernier message: 17/06/2009, 15h55
  2. Réponses: 2
    Dernier message: 26/05/2008, 08h54
  3. [E-03][VBA]Worksheet.Cells.Range(x, y) déclenche une erreur
    Par DonkeyMaster dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 02/04/2008, 16h18
  4. [SimpleXML] je sèche sur l'origine d'une erreur
    Par fastmanu dans le forum Bibliothèques et frameworks
    Réponses: 3
    Dernier message: 24/05/2007, 15h22
  5. [VBA-E]For each Cel in Plage, une erreur franchement bête...
    Par ouskel'n'or dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 09/02/2007, 12h16

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