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

VBA Access Discussion :

Formater champ en fonction de l'enregistrement précédent dans un formulaire continu


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur
    Inscrit en
    Mars 2002
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Mars 2002
    Messages : 34
    Par défaut Formater champ en fonction de l'enregistrement précédent dans un formulaire continu
    Bonjour,

    Après quelques recherches, je commence à penser que ce que je souhaite faire n'est pas possible, mais j'aimerais en avoir la confirmation.

    Dans un formulaire continu, par défaut Access alterne la couleur de fond à chaque enregistrement. Je voudrais que cette alternance ait lieu à chaque fois que la valeur d'un enregistrement est différente du précédent.

    J'ai fait une tentative avec l'évènement Détail_Paint(), mais ça fait comme un Refresh permanent qui semble utiliser beaucoup de ressources. En plus de ça, étonnamment, en mode debug je n'ai pas réussi à interrompre l'exécution du code en cours : quand je clique sur "Réinitialiser" (le petit carré bleu), le programme continue de tourner et s'arrête au prochain point d'arrêt.

    Pour info, voici le code essayé :
    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
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    Public lngCouleurPrec As Long
     
    Private Sub Détail_Paint()
     
    On Error GoTo Err_Previous
        Dim strPrecedent As String
        Dim rstClone As DAO.Recordset
        Dim strBookmark As String
        Dim lngCouleurPrec As Long
     
        With Me.Form
            Set rstClone = .RecordsetClone
            strBookmark = .Bookmark
            rstClone.Bookmark = .Bookmark
        End With
     
        ' Si premier enregistrement du recordSet
        If rstClone.BOF Then
            ' Obtient la couleur de fond
            lngCouleurPrec = Me.Section("Détail").BackColor
        ' Sinon se déplace au précédent
        Else
            rstClone.MovePrevious
            ' Lit valeur précédent
            strPrecedent = rstClone.Fields("Champ1")
            ' Re-synchronise bookmark
            Me.Form.Bookmark = strBookmark
        End If
     
        ' Si, dans l'enregistrement courant, le champ a la même valeur que le précédent
        If rstClone.Fields("Champ1") = strPrecedent Then
     
            With Me.Section("Détail")
                ' Applique la même couleur comme couleur de fond
                .BackColor = lngCouleurPrec
                ' Supprime l'alternance de couleur
                .AlternateBackColor = .BackColor
            End With
        Else
            With Me.Section("Détail")
                .BackColor = .AlternateBackColor
                lngCouleurPrec = .AlternateBackColor
            End With
        End If
     
    Exit_Previous:
          Exit Sub
     
    Err_Previous:
          If Err.Number <> 3021 Then    'Not at the 1st or New Record
            MsgBox Err.Description, vbExclamation, "Error in Previous()"
          End If
            Resume Exit_Previous
    End Sub
    Je suppose qu'initialiser puis fermer un recordset dans un évènement Paint() n'est pas une bonne idée. Est-ce que créer un Recordset public, initialisé par Form_Load() pourrait améliorer le résultat ? Je vais essayer, mais je n'y crois pas trop.

  2. #2
    Membre Expert Avatar de Zekraoui_Jakani
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    1 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 671
    Par défaut
    ça sonne la complexité et ça demande de l'ingéniosité; s'il faut absolument le faire, je jouerai sur le format conditionnel de l'enregistrement x en fonction de l'enregistrement (x-1); mais pour cela, il faudra mémoriser la valeur (n-1) de l'enregistrement (x-1) et la comparer à la valeur n de l'enregistrement x. En cas de différence, appliquer la format souhaité à x. (facile à dire et +/- fastidieux à programmer, mais faisable).

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur
    Inscrit en
    Mars 2002
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Mars 2002
    Messages : 34
    Par défaut
    S'il y a un moyen de faire référence à l'enregistrement (x-1) dans la mise en forme conditionnelle, je suis preneur.

  4. #4
    Membre Expert Avatar de Zekraoui_Jakani
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    1 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 671
    Par défaut
    La solution que je viens de trouver est beaucoup plus simple:

    Imaginons un formulaire affichant les fournisseurs d'une firme
    Ajoutons un champ numérique (nommé 'Compteur') dans la table-source, qui numérote les lignes (surtout pas un 'AutoNumber'): utilisons 0,1,2,3,4, .... ,n
    Ajoutons ce champ à notre formulaire, quitte à le rendre invisible

    Nommons ce formulaire "F_Fournisseurs", et mettons le code ci-dessous dans un module libre (pas dans les modules du formulaire).
    On peut, dès lors, faire appel à la procédure ci-dessous avant ouverture du dit formulaire:

    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
    Sub alternerCouleurs()
        Dim ctl As Control
        Dim myExpression As String
     
        DoCmd.Echo (False)
     
        DoCmd.OpenForm "F_Fournisseurs", acDesign
     
        For Each ctl In Forms("F_Fournisseurs").Section(acDetail).Controls
                ctl.FormatConditions.Delete
                myExpression = "[compteur] Mod 2 = 0"
                ctl.FormatConditions.Add acExpression, , myExpression
                ctl.FormatConditions.Item(0).BackColor = vbYellow
        Next ctl
     
        DoCmd.Save
        DoCmd.Restore
        DoCmd.Echo (True)
        DoCmd.OpenForm "F_Fournisseurs", acNormal
     
    End Sub
    Si votre table est volumineuse, utilisez ce code pour incrémenter le 'Compteur':
    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
    Sub Updt_Compteur()
        Dim rs As Recordset
        Dim j As Long: j = 0
     
        Set rs = CurrentDb.OpenRecordset("T_Fournisseurs", dbOpenDynaset)
     
        With rs
            .MoveFirst
            Do While Not .EOF
                .Edit
                !Compteur = j
                .Update
                j = j + 1
                .MoveNext
            Loop
        End With
     
        rs.Close: Set rs = Nothing
     
    End Sub

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur
    Inscrit en
    Mars 2002
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur

    Informations forums :
    Inscription : Mars 2002
    Messages : 34
    Par défaut
    Mais avec cette solution, comment peut on faire référence à la valeur de l'enregistrement ? Si j'interprète correctement, chaque ligne paire aura un fond jaune, indépendamment de la valeur des enregistrements ?

    Ce que je souhaite faire, c'est d'avoir un fond jaune pour :
    Fournisseur1
    Fournisseur1
    Fournisseur1
    puis blanc pour
    Fournisseur2
    Fournisseur2
    Fournisseur2
    Fournisseur2
    Fournisseur2
    puis jaune pour
    Fournisseur3
    puis blanc pour
    Fournisseur4
    Fournisseur4
    etc.
    avec un nombre variable de lignes de même couleur.

    Et bien sûr, je veux éviter de faire un test sur la valeur de l'enregistrement courant du type "Si valeur=Fournisseur1 alors fond jaune" puisque les valeurs peuvent varier et qu'elles peuvent être nombreuses.

  6. #6
    Membre Expert Avatar de Zekraoui_Jakani
    Homme Profil pro
    Inscrit en
    Novembre 2013
    Messages
    1 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 671
    Par défaut
    Dans ce cas, j'adapterai la valeur de mon "compteur" comme suit:
    Commencer par définir le contenu "Fournisseur" ainsi : "Fournisseur_xxxx", en supposant que j'ai un maximum de 9999 noms de fournisseurs (xxxx = 0 à 9999)
    Adapter le code de mise à jour du compteur ainsi:
    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
    Sub Updt_Compteur()
        Dim rs As Recordset
        Dim previousFournis
        Dim previousCompt
     
        Set rs = CurrentDb.OpenRecordset("T_Fournisseurs", dbOpenDynaset)
        'Ceci suppose que le contenu [Fournisseur] est sous la forme "Fournisseur_xxxx"
        'où xxxx = 0 à 9999, et que les noms du même fournissuer se suivent (trier données par fournisseur)
        'On peut utiliser SQL pour définir "rs" avec la clause 'OrderBy [Fournieeur]'
     
        With rs
            .MoveFirst
            previousFournis = ![Fournisseur]
            previousCompt = !Compteur
            .Edit
            !Compteur = CLng(Mid(![Fournisseur], InStr(![Fournisseur], "_") + 1))
            .Update
            .MoveNext
     
            Do While Not .EOF
                If previousFournis = ![Fournisseur] Then
                    .Edit
                    !Compteur = previousCompt
                    .Update
                Else
                    .Edit
                    !Compteur = CLng(Mid(![Fournisseur], InStr(![Fournisseur], "_") + 1))
                    .Update
                End If
                previousFournis = ![Fournisseur]
                previousCompt = !Compteur
                .MoveNext
            Loop
        End With
     
        rs.Close: Set rs = Nothing
     
    End Sub
    Enfin, appliquer le code pour la MFC (mise en forme conditionnelle)

    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
     
    Sub alternerCouleurs()
        Dim ctl As Control
        Dim myExpression As String
     
        DoCmd.Echo (False)
     
        DoCmd.OpenForm "F_Fournisseurs", acDesign
     
        For Each ctl In Forms("F_Fournisseurs").Section(acDetail).Controls
                ctl.FormatConditions.Delete
                myExpression = "[compteur] Mod 2 <> 0"   'jaune si n° impair, blanc sinon
                ctl.FormatConditions.Add acExpression, , myExpression
                ctl.FormatConditions.Item(0).BackColor = vbYellow
        Next ctl
     
        DoCmd.Save
        DoCmd.Restore
        DoCmd.Echo (True)
        DoCmd.OpenForm "F_Fournisseurs", acNormal
     
    End Sub

Discussions similaires

  1. Réponses: 4
    Dernier message: 18/06/2020, 02h28
  2. Réponses: 1
    Dernier message: 08/02/2013, 14h08
  3. Réponses: 7
    Dernier message: 31/01/2008, 12h42
  4. Réponses: 2
    Dernier message: 03/12/2007, 23h45
  5. Réponses: 4
    Dernier message: 10/08/2006, 17h58

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