Partage
  • Partager sur Facebook
  • Partager sur Twitter

Aide VBA (macro + tableau croisé dynamique)

incomparabilité de type qui n'a aucun sens

    9 janvier 2020 à 12:33:45

    Bonjour, 

    Je débute le VBA depuis quelques jours en temps que stagiaire dans une PME. Mais voila j'avance lentement car je rencontre énormément de bug mais le problème viens du fait que je n'arrive pas à comprendre certains. Il me suffit de recommencer les tableaux du début en ne changeant rien pour que la macro remarche. C'est très étrange et rageant car étant le seul maîtrisant ce langage, on m'a demandé de faire des macros relativement accessible et stable

    Le tableau et graphique correspondant

    Sub ChangerFiltreDate()
        Dim result As VbMsgBoxResult
        result = MsgBox(Prompt:="Appliquer à toute la page?", Buttons:=vbYesNoCancel, Title:="Choix") 'On affiche un message avec un choix OUI/NON/ANNULER
        
        Dim counttables As Integer
        counttables = ActiveSheet.PivotTables.Count 'Le nombre de tables sur la feuille
        
        Dim tables() As Boolean, curtable As PivotTable
        ReDim tables(counttables)
        Dim j As Integer, i As Integer
        For j = 0 To counttables
            tables(j) = True 'Ce tableau permettra de savoir ce qu'a choisit de faire l'utilisateur pour chaque tableau (initialisation ici)
        Next j
        
        
        If (result = vbNo) Then 'S'il choisit de ne pas appliquer à tout
            For i = 1 To counttables
                Set curtable = ActiveSheet.PivotTables(i)
                result = MsgBox(Prompt:=("Appliquer à " & curtable.Name & "?"), Buttons:=vbYesNo) 'On demande à l'utilisateur de choisir si on applique la date à tous les tableaux
                tables(i) = result = vbYes
            Next i
        ElseIf (result = vbCancel) Then 'Annuler -> sort du programme
            Exit Sub
        End If
        Dim datestart As Date
        Dim dateend As Date
        datestart = CDate(Range("A5").Value) '/!\ Sujet à bug : Pour les deux dates il faut bien mettre les bonnes cases
        dateend = CDate(Range("B5").Value)
        MsgBox datestart & " to " & dateend
        
        Dim k As Integer, nbfalse As Integer, nbtrue As Integer
        nbfalse = 0
        nbtrue = 0
        For k = 1 To counttables 'Pour chacun des tableaux
                If tables(k) = True Then 'Si l'utilisateur a choisi d'appliquer à toutes les tables ou bien si la table a été acceptée précedemment
                    
                    Dim pt As PivotTable
                    Set pt = ActiveSheet.PivotTables(k) 'On met chaque tableau dans la variable pt
                    
                    Dim field As PivotField, item As Variant, filter As PivotFilter
                    For Each field In pt.PivotFields 'Pour chaque field
                        If field.Name Like "*date*" Then 'On ne garde que les champs comportant "date" dans le nom (attention il faut qu'il fasse partie des filtres du tableau)
                            For Each item In field.PivotItems '/!\ Pour une raison inconnue cette ligne est sujet à des bugs si le tableau change d'une cetaine façon (aussi inconue) : Pour chaque valeur dans le champ (field) de dates
                                If IsDate(item.Value) Then '/!\ S'il ne se passe rien ou si ne s'applique pas à tout peut venir de là (pas de chargement): On s'assure qu'on manipule bien des dates (si le programme ne fait rien peut-être que les données sont sous une mauvaise forme)
                                If CDate(item.Value) < datestart Or CDate(item.Value) > dateend Then '/!\ sujet à erreurs : Si la date ne remplit pas la condition on l'enlève
                                    field.PivotItems(item.Name).Visible = False 'On cache la date qui ne rentre pas dans les critères
                                    nbfalse = nbfalse + 1
                                Else
                                    field.PivotItems(item.Name).Visible = True 'Si la date remplit la condition on la montre
                                    nbtrue = nbtrue + 1
                                End If
                                End If
                            Next item
                            MsgBox field.PivotItems.Count
                        End If
                    Next field
                    MsgBox nbfalse & " and true : " & nbtrue
                    nbfalse = 0
                    nbtrue = 0
                    pt.RefreshTable
                End If
            Next k
        End Sub
    

    Voila tout le code mais la partie qui m’intéresse est celle-ci :

    For Each item In field.PivotItems '/!\ Pour une raison inconnue cette ligne est sujet à des bugs si le tableau change d'une cetaine façon (aussi inconue) : Pour chaque valeur dans le champ (field) de dates
                                If IsDate(item.Value) Then '/!\ S'il ne se passe rien ou si ne s'applique pas à tout peut venir de là (pas de chargement): On s'assure qu'on manipule bien des dates (si le programme ne fait rien peut-être que les données sont sous une mauvaise forme)
                                If CDate(item.Value) < datestart Or CDate(item.Value) > dateend Then '/!\ sujet à erreurs : Si la date ne remplit pas la condition on l'enlève
                                    field.PivotItems(item.Name).Visible = False 'On cache la date qui ne rentre pas dans les critères
                                    nbfalse = nbfalse + 1
                                Else
                                    field.PivotItems(item.Name).Visible = True 'Si la date remplit la condition on la montre
                                    nbtrue = nbtrue + 1
                                End If
                                End If
                            Next item
                            MsgBox field.PivotItems.Count

    Alors que tout fonctionnait très bien (même si un peu lent), tout d'un coup il s'est mit à ne plus reconnaître certaines dates en temps que date (les considérant comme String) et pour les autres il les traite comme toujours en dehors de dateend et datestart donc False

    Je sais que si je recommence le tableau le problème sera réglé mais si je suis incapable de comprendre l'erreur elle risque de réapparaitre dans le futur.

    Merci d'avance pour votre aide !



    • Partager sur Facebook
    • Partager sur Twitter
      9 janvier 2020 à 19:40:44

      Salut,

      La macro est censée faire quoi ? J'ai jamais travaillé avec des TCD en VBA mais si j'ai bien compris tu veux appliquer un filtre pour ne garder que les éléments dont la date de commande est entre les deux dates Start et End ?

      Tu as regardé avec le débogueur pour voir ce qu'il y a de différent entre une date reconnue et une date non reconnue ?

      Dans la doc de IsDate les exemples utilisent la notation américaine (mm/dd/yyyy), est-ce que la notation française (dd/mm/yyyy) est bien comprise ?

      • Partager sur Facebook
      • Partager sur Twitter
        15 janvier 2020 à 11:14:07

        Au final j'ai recommencé les TCD et graphs et j'ai plus le problème, le truc marche très bien alors que j'ai l'impression qu'il n'y a aucune différence.
        • Partager sur Facebook
        • Partager sur Twitter

        Aide VBA (macro + tableau croisé dynamique)

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown