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 :

Intercepter des objets "vides".


Sujet :

Access

  1. #1
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 17
    Points : 17
    Points
    17
    Par défaut Intercepter des objets "vides".
    Bonjour à tous,

    J'ai déjà contourné (maladroitement) ce problème lors d'opérations à faire sur une section de formulaire ou d'état qui pouvait ne pas exister.
    Mais là je ne vois pas comment m'en sortir :
    Dans la section détail d'un état, j'ai un contrôle boîte de texte indépendant compteur de lignes qui est vide (parcequ'il n'y a rien dans la section détail de l'état).

    La variable objet n'est pas initialisée ?
    Peut-on "passer par dessus" ce cas de figure à l'aide d'un test qui serait du type :

    If MonOBJET Is Nothing Then
    ---instructions---

    Dans la procédure ci-après j'obtiens le message d'erreur 2427 :
    "Expression sans paramètre" lorsque la section détail est vide parce qu'on a saisi un numéro de bon de commande qui n'existe pas.

    Ce n'est pas un très bon exemple, vous me direz qu'on peut éviter cette erreur en travaillant en amont, mais l'autre exemple du même type serait vraiment plus long à expliquer.

    J'aimerais savoir s'il existe un moyen de tester un objet non initialisé.
    Et si c'est de cela qu'il s'agit.
    Sinon, il ne me reste plus qu'à utiliser le code d'erreur pour quitter la procédure.


    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
    '=======================================================================================================
    '--Détail_Format
    '=======================================================================================================
    '--Déf : Alterne la couleur de fond de chaque ligne de la section détail de l'état en fonction de la
    '        valeur paire ou impaire du numéro de la ligne (effet "listing").
    '-------------------------------------------------------------------------------------------------------
    '
    Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
    Stop
      'BtiCTL est un contrôle indépendant, Source = 1, Cumul =True.
       Dim BtiCTL As TextBox     
     
          Set BtiCTL = Me.Bti_LIGNEN°
     
    '''   'La section détail est vide (pas de numéro de ligne).
    '''      If BtiCTL = "Nothing" Then
    '''         Exit Sub
          'Lignes paires.
             ElseIf BtiCTL Mod 2 = 0 Then
                Me.Section(acDetail).BackColor = 16777215 'Blanc.
          'Lignes impaires.
             Else
                Me.Section(acDetail).BackColor = 15132390 'Gris pâle.
             End If
     
    Exit Sub
    End Sub
    NB Je n'ai pas mis la gestion d'erreur ni la libération de la variable objet pour ne pas faire trop long.

    Merci d'avance pour vos conseils.

    Cordialement.

    CRUSOE13

  2. #2
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Ciao,

    2 choses viennent à l'esprit :
    1- ta question : tu as essayé avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If IsNull(Bti_LIGNEN) Then...
    sachant qu'une boîte de texte vide renvoit la valeur Null ?

    2- sur le fond : si ta section détail est vide, l'état est vide.
    Normalement, ça se traite effectivement en amont, dans l'évènement 'NoData' (='Sur aucune donnée') qui affiche un message et referme l'état :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub Report_NoData(Cancel As Integer)
        MsgBox "Circulez, y a rien à voir...", vbCritical, "Préfecture de Police"
        Cancel = True
    End Sub

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    1
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2005
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Sinon, il y a aussi cette technique qui te permet de savoir si un champ retourne le type "null".

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    If VarType("NomDuChamp") <> vbNull Then
       ...
    End If
    Normalement ça marche bien.

    A+

  4. #4
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Salut, julien,

    Aïe, attention, quand même :
    Outre que c'est un peu compliqué d'aller chercher le VarType(),
    1- VarType ne fonctionne qu'avec des variables de type VARiant.
    Je n'ai pas cherché à l'utiliser avec un champ, et c'est possible qu'il n'y ait pas d'erreur, si le compilateur utilise la valeur par défaut de l'objet Champ, à savoir Champ.Value... (qui est de type Variant).
    2- ici, il ne s'agit pas d'un champ, mais d'un contrôle. Indépendant qui plus est : donc sans champ.

    Je sais, ta méthode peut marcher parce que VBA planque toutes les transformations/interprétations.
    Mais attention à ne pas confondre variable, champ et contrôle ! Ça entraîne de nombreuses cafouilles, et, du coup, beaucoup de questions sur le forum

  5. #5
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 17
    Points : 17
    Points
    17
    Par défaut Intercepter des objets "vides".
    Bonjour à tous !

    Ma réponse est en deux temps :
    D'abord à l'attention de Julien, post suivant à Papy Turbo.
    Avec lui c'est pas du jeu, il a tout bon !

    Donc voilà ce que les fonctions d'examen des variables retournent dans la fen. d'exécution :

    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
    '======================================================================
    '--Détail_Format
    '======================================================================
    '--Déf : Test sur section détail d'un état vide.
    '        Alternance de la couleur de fond de chaque ligne de la section
    '        détail de l'état en fonction de la valeur paire ou impaire du
    '        numéro de la ligne (effet "listing").
    '----------------------------------------------------------------------
    '
    Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
    'Stop
     
       Dim BtiCTL As TextBox
       Dim VarCTL As Variant
     
          Set BtiCTL = Me.[Bti_LIGNEN°]
          Set VarCTL = Me.[Bti_LIGNEN°]
     
             Debug.Print VarType(BtiCTL)   '-->  9 (= vbObject).
             Debug.Print TypeName(BtiCTL)  '-->  Textbox.
     
             Debug.Print VarType(VarCTL)   '-->  9 (= vbObject).
             Debug.Print TypeName(VarCTL)  '-->  Textbox.
     
    'Cond1    'La section détail est vide (pas de numéro de ligne).
                If IsNull(Me.[Bti_LIGNEN°]) Then
                'If IsNull(BtiCTL) Then
                'If IsEmpty(VarCTL) Then
                   Exit Sub
    'Cond2   'La ligne est paire.
                ElseIf BtiCTL Mod 2 = 0 Then
                   Me.Section(acDetail).BackColor = 16777215 'Blanc.
    'Cond3   'La ligne est impaire.
                Else
                   Me.Section(acDetail).BackColor = 15132390 'Gris pâle.
                End If
     
    Exit Sub
    End Sub
    Ce qui est bizarre c'est que la boucle passe la Cond1 quel que soit le cas testé (tous ceux que j'ai laissés écrits) et que le message d'erreur 2427 n'apparaît qu'à la Cond2.

    Encore plus bizarre, j'avais trouvé l'alternative de code ci-dessous qui ne provoque pas d'erreur et affiche l'en-tête d'état avec une ligne vide sauf pour la valeur de la Bti_LIGNEN° qui est à 1 !!!

    Il y avait donc bien une valeur dedans, ce qui semble cohérent avec le fait que l'on ait en quelque sorte initialisé sa propriété source avec = 1.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
     
    With Me.Section(acDetail)
     
        If .BackColor = 16777215 Then 'Si blanc.
           .BackColor = 15132390 'Gris pâle.
        Else
           .BackColor = 16777215 'Blanc.
        End If
     
    End With
     
    Exit Sub
    End Sub
    Voilà.
    Merci beaucoup.

    CRUSOE13

  6. #6
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 17
    Points : 17
    Points
    17
    Par défaut Intercepter des objets "vides".
    À Papy Turbo,

    Votre suggestion est la meilleure à mon sens :
    "HasData" que vous m'avez suggéré d'après "NoData" résoud le problème et me permet d'utiliser cet état comme sous-état.

    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
    Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
     
       Dim BtiCTL As TextBox
     
          If Me.HasData = False Then
             'Me.Visible = False
             Exit Sub
          Else
             'Me.Visible = True
             Set BtiCTL = Me.[Bti_LIGNEN°]
                'Si la ligne est paire, détail sur fond blanc.
                   If BtiCTL Mod 2 = 0 Then
                      Me.Section(acDetail).BackColor = 16777215
                'Si la ligne est impaire, détail sur fond gris pâle.
                   Else
                      Me.Section(acDetail).BackColor = 15132390
                   End If
          End If
     
    Exit Sub
    End Sub
    Dernière remarque : Je préfère ce code à l'alternative soumise plus haut (qui se contente de mettre un fond blanc si gris et l'inverse à la ligne suivante) parce que la numérotation des lignes peut être affectée à un regroupement.
    Quant à la différence de performance : Aucune idée !

    Je sais seulement que sans vous j'y serais encore !

    À défaut de pouvoir vous payer un 'ti punch j'en boirai un à votre santé !
    Cordialement.

    CRUSOE13

  7. #7
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    bois en 2 (un pour moi)
    Le pinailleur de service demande : à quoi sert le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set BtiCTL = Me.[Bti_LIGNEN°]
    :
    Pourquoi ne pas interroger directement le contrôle lui-même, dans les 2 lignes en dessous ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If ([Bti_LIGNEN°] Mod 2) = 0 Then
    Le pinailleur de service ajoute des parenthèses autour de l'opération Mod :
    - ça ne change rien aux performances ni à l'interprétation,
    - ça garantit à ceux qui relisent le code que l'opération Mod sera exécutée en premier, puis le résultat comparé à zéro, et non pas l'inverse :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If [Bti_LIGNEN°] Mod (2 = 0) Then
    qui serait très différent !!!

  8. #8
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 17
    Points : 17
    Points
    17
    Par défaut
    Bonjour !

    Le pinailleur de service demande : à quoi sert le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Set BtiCTL = Me.[Bti_LIGNEN°]
    :
    Pourquoi ne pas interroger directement le contrôle lui-même, dans les 2 lignes en dessous ?
    À rien, sauf à savoir si l'instruction d'affectation passait, pour trouver une manière d'accéder à ce contrôle sur lequel rien d'autre n'avait prise.
    La toute première version du code (avant le "bug") était directe, j'ai eu tort de ne pas corriger cela avant de poster la version retenue.

    Le pinailleur de service ajoute des parenthèses autour de l'opération Mod :
    - ça ne change rien aux performances ni à l'interprétation,
    - ça garantit à ceux qui relisent le code que l'opération Mod sera exécutée en premier,
    puis le résultat comparé à zéro, et non pas l'inverse :
    Code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    If [Bti_LIGNEN°] Mod (2 = 0) Then 
    qui serait très différent !!!
    Là, pas de chance !
    D'habitude je mets TOUJOURS DES PARENTHÈSES, POUR LES DEUX EXCELLENTES RAISONS QUE VOUS DONNEZ.
    Il suffit d'avoir affaire à Papy Turbo pour les oublier ! Diantre !

    Il ne me reste plus qu'à poster la version du code retenue ET corrigée que voici :

    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
     
    '=======================================================================================================
    '--Détail_Format
    '=======================================================================================================
    '--Déf : Alterne la couleur de fond de chaque ligne de la section détail de l'état (sous-état) en
    '        fonction de la valeur paire ou impaire du numéro de la ligne : effet "listing".
    '-------------------------------------------------------------------------------------------------------
    '--Rem : Le numéro de la ligne se trouve dans un contrôle ajouté à la section détail de l'état (sous-
    '        état).
    '        Ce contrôle est une boîte de texte indépendante dont les propriétés sont définies comme suit :
    '           "Nom" : Bti_LIGNEN°
    '           "Source contrôle" : = 1
    '           "Cumul" : En continu
    '-------------------------------------------------------------------------------------------------------
    '
    Private Sub Détail_Format(Cancel As Integer, FormatCount As Integer)
     
       'Si la ligne est paire, détail sur fond blanc.
          If (Me.[Bti_LIGNEN°] Mod 2) = 0 Then
             Me.Section(acDetail).BackColor = 16777215 '15132390
       'Si la ligne est impaire, détail sur fond gris pâle.
          Else
             Me.Section(acDetail).BackColor = 15132390 '16777215
          End If
     
     Exit Sub
     End Sub
    REMARQUES 1 :

    J'ai laissé tomber le "HasData" qui ne me semblait pas à sa place pour détecter un recordset vide.
    Je voulais le mettre dans l'état principal à l'événement formatage de la section "Détail".
    Ce faisant je me suis aperçu que l'état principal ne voit pas cet événement ("Stop" ignoré), comme il reste souverainement insensible au fait que le sous-état rapatrie des données ou pas.
    S'il est vide, il ne s'affiche pas, point barre !

    Pourquoi faire simple quand ...

    Je présente mes excuses mais j'ai repris cette appli. en cours de développement et je dois revalider tous les objets.
    C'est la raison pour laquelle je voulais dédouaner le sous-état AVANT de m'occuper de l'état principal !

    REMARQUES 2 :

    J'emploie la syntaxe "Me.Section(asDetail)" bien que moins rapide que "Me.Détail" parce que l'accent aigu de "Détail" me navre !
    Il faudrait demander à Microsoft d'arrêter le massacre !

    Je sais qu'on peut parfaitement omettre le mot clé "Me" avant [Nom de champ] et je l'emploie sans raison valable.
    Pensez-vous qu'il soit préférable de l'omettre systématiquement ?

    Encore merci !
    J'ai appris plein de choses, mais à ce point le rhum devient dangereux pour la santé !

    CRUSOE13

  9. #9
    Membre expérimenté
    Avatar de Papy Turbo
    Homme Profil pro
    Développeur Office/VBA
    Inscrit en
    Mars 2004
    Messages
    822
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Office/VBA
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2004
    Messages : 822
    Points : 1 709
    Points
    1 709
    Par défaut
    Mort de rire :
    À quoi sert le "Exit Sub", juste avant le "End Sub".
    Non, j'ai rien dit, là, c'est de la pure provok !

    Sinon, je ne sais pas s'il y a intérêt ou pas à utiliser Me. Je soupçonne le compilateur de n'en avoir rien à ficeler...
    Je l'aime bien dans les cas où ça améliore la lisibilité du code.

  10. #10
    Membre à l'essai
    Inscrit en
    Mai 2005
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Mai 2005
    Messages : 17
    Points : 17
    Points
    17
    Par défaut Intercepter des objets "vides".
    Bonjour !

    Ok pour l'utilisation de "Me".

    "Exit Sub" est un reliquat de la routine de gestion d'erreur "standard", sans intérêt dans ce cas, que j'ai enlevée pour alléger le code.

    Sincères remerciements.
    Je considère que ce sujet est clos, je tagge "Résolu".

    À bientôt sur les ondes.
    Cordialement.

    CRUSOE13

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/08/2006, 09h19

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