Fonction MATCH() capricieuse (parfois marche, parfois bugge !)

Sebast

XLDnaute Impliqué
Bonjour à toutes et à tous,


J’ai un souci avec la fonction MATCH() qui parfois renvoie le bon résultat, parfois plante.
Pour faire simple, le code doit réaliser ce qui suit (adaptation d’un fil précédent) :

Dans feuille ORIGINE, j’ai des données que je dois (ultérieurement) coller dans la feuille DESTINATION.
Pour éviter les doublons, je dois d’abord effacer dans DESTINATION les lignes inscrites dans l’intervalle figurant en ORIGINE.

J’utilise la fonction MATCH (equiv en français). Lors de la mise au point, hier, j’ai testé des cas de figure « limite » et ai dû gérer le tout avec un select case.
J’ai placé aux bons endroits des témoins (msgbox) pour savoir si je remonte les valeurs attendues, ce qui me permet de dire que normalement, tout est OK …
Hier encore, tout marchait parfaitement pour les cas évoqués dans la feuille Contrôles
Ce matin, je refais le test (avec le même périmètre) et ça bugge … ou alternativement bug et pas bug !

Incrédule, je vérifie d’une feuille à l’autre, trie à nouveau ORIGINE et/ou DESTINATION et ça remarche, ou parfois ça remarche après que j’ai enregistré le fichier puis réouvert …
Parfois, le message de contrôle annonce les bonnes lignes à supprimer mais ça plante quand ça sélectionne la zone (ici en remplacement de l’effacement : select plutôt que delete, car sinon je passerai mon temps à reconstituer la table …)

D’autres fois, ça échoue et quand je vais dans le code surligné en jaune, j’ai l’impression que l’erreur est due au fait que la zone à sélectionner n’est pas « croissante » (ex : de ligne 917 à 2).


Je suis perplexe car le bon fonctionnement/le bug semble ne pas répondre à une règle …
D’avance, merci beaucoup à celles ou ceux qui voudront me donner leur avis



Code:
Sub Supprimer_intervalle()

Dim DateDepuis_Origine As Long     ' dans feuille Origine, la plus ancienne date
Dim DateJusquà_Origine As Long     ' dans feuille Origine, la plus récente date
Dim DateMini_Destination As Long   ' plus ancienne date de la feuille "Destination"
Dim DateMaxi_Destination As Long  ' plus récente date de la feuille "Destination"
Dim LigneDepuis As Long                ' n° de ligne dans feuille Destination correspondant à date minimale de feuille Origine
Dim LigneJusquà As Long                ' n° de ligne dans feuille Destination correspondant à date maximale de feuille Origine


'--- Rechercher la date mini et la date maxi présentes dans la feuille "Origine"
With Sheets("Origine").UsedRange

.Sort key1:=.Cells(1, 1), order1:=xlAscending, Header:=xlYes ' pas nécessaire mais permet contrôle visuel

    DateDepuis_Origine = WorksheetFunction.Min(.Columns(1))    ' colonne 1 contient la date
    DateJusquà_Origine = WorksheetFunction.Max(.Columns(1))
End With

MsgBox "Dans Origine, la date la plus ancienne est le " & CDate(DateDepuis_Origine) & " et la date la plus récente est le " & CDate(DateJusquà_Origine)
' juste pour contrôle



' --- Extraire plus petite et plus grande date de la feuille "Destination"
With Sheets("Destination").UsedRange

    .Sort key1:=.Cells(1, 1), order1:=xlAscending, Header:=xlYes   ' on trie par date car les les lignes doivent être en ordre croissant pour fonction Match
    
     DateMini_Destination = WorksheetFunction.Min(.Columns(1))
     DateMaxi_Destination = WorksheetFunction.Max(.Columns(1))
     
    MsgBox "Dans Destination, la date la plus ancienne est le " & CDate(DateMini_Destination) & " et la date la plus récente est le " & CDate(DateMaxi_Destination)
          
    
    
    ' Le test suivant permet de contrer les erreurs
    ' Problème si date minimum de feuille "Origine" <= date minimum de feuille "Destination"
    ' Problème purement calculatoire car pour connaître le rang de la ligne correspondante, on se postionne sur la valeur directement inférieure (puis on saute d'un rang)
    ' mais dans le cas où date minimum de feuille "Origine" <= date minimum de feuille "Destination", erreur système car la DateDepuis_Origine existe, certes, mais
    ' pas [DateDepuis_Origine -1], c'est à dire la date directement inférieure (dont on se sert quand il y a plusieurs occurrences)
    
     Select Case DateDepuis_Origine
    
                Case Is = DateMini_Destination
                    MsgBox " Cas de figure où la date minimum de la feuille Origine est égale à date minimum de la feuille Destination"
                    LigneDepuis = WorksheetFunction.Match(DateDepuis_Origine, .Columns(1), 0) ' ici paramètre 0 car on se positionne sur la valeur exacte puisqu'il y a égalité
                    LigneJusquà = WorksheetFunction.Match(DateJusquà_Origine, Columns(1), 1)
                    MsgBox "Je supprime donc de ligne n° " & LigneDepuis & " à ligne n° " & LigneJusquà
                    .Range(.Rows(LigneDepuis), .Rows(LigneJusquà)).Select       ' ici, select et non delete car encore en phase de test, permet un meilleur contrôle ...
                                       
                Case Is < DateMini_Destination
                    MsgBox " Cas de figure où la date minimum de la feuille Origine est strictement inférieure à date minimum de la feuille Destination"
                    LigneDepuis = 2  ' 2 car première ligne comportant des enregistrements (la 1ère comporte les en-têtes)
                    LigneJusquà = WorksheetFunction.Match(DateJusquà_Origine, Columns(1), 1)
                    MsgBox "Je supprime donc de ligne n° " & LigneDepuis & " à ligne n° " & LigneJusquà
                    .Range(.Rows(LigneDepuis), .Rows(LigneJusquà)).Select
                    
                Case Is > DateMini_Destination
                    MsgBox " Cas de figure où la date minimum de la feuille Origine est strictement supérieure à date minimum de la feuille Destination"
                    LigneDepuis = WorksheetFunction.Match(DateDepuis_Origine - 1, .Columns(1), 1) + 1
                    LigneJusquà = WorksheetFunction.Match(DateJusquà_Origine, Columns(1), 1)
                    MsgBox "Je supprime donc de ligne n° " & LigneDepuis & " à ligne n° " & LigneJusquà
                    .Range(.Rows(LigneDepuis), .Rows(LigneJusquà)).Select
                    
                    ' Rappels de la fonction Match() avec 3ème paramètre = 1
                    ' si le terme cherché n'existe pas, alors Excel prend la valeur immédiatement suivante
                    ' si le terme cherché existe plusieurs fois, alors Excel retient la dernière occurrence)
                    ' donc dans le cas de LigneDepuis, on se positionne sur le terme recherché directement inférieur (en ayant écrit [DateDepuis_Origine-1])
                    ' ici la veille du dernier jour présent, alors Excel renvoie le rang de la ligne de la dernière occurrence et on ajoute + 1 pour se positionner
                    ' sur la bonne ligne
                    
                    
                                        
    End Select
    
End With

End Sub
 

Pièces jointes

  • Bloc_suppression.xlsm
    49.6 KB · Affichages: 52
G

Guest

Guest
Re : Fonction MATCH() capricieuse (parfois marche, parfois bugge !)

Bonjour,

Juste deux choses.

1 - Avant de sélectionner quoique ce soit sur une feuille, cette dernière doit être active. Donc en dessous de ton With sheets("Destination") mets un .Activate.

2 - Les variables résultats des fonctions de feuille de calcul utilisée en VBA (Match vs Equiv) doivent être de type Variant. Elles peuvent recevoir soit un résultat soit une valeur d'erreur XlCVError. Elle peuvent être testée par If IsError(LaVariableResulTat) then.....

Ses corrections faite, je n'ai pas pu reproduire ton problème.

A+
 

Sebast

XLDnaute Impliqué
Re : Fonction MATCH() capricieuse (parfois marche, parfois bugge !)

Bonjour Hasco,

merci pour ton aide.
Dois-je écrire

Code:
With Sheets("Destination").UsedRange.activate ?

(je ne connais pas cette syntaxe)

et dans ce cas-là, dois-je le faire pour la feuille "Origine" ?


à +
 
G

Guest

Guest
Re : Fonction MATCH() capricieuse (parfois marche, parfois bugge !)

Re,

Il faut BIEN lire les réponse, je disais EN DESSOUS pas à la suite:

Code:
With Sheets("Destination")
.Activate

'....suite du code
End With

Le activate n'est là que parceque plus loin tu as des .Select et que cela plante si la feuille concernée n'est pas la feuille active.
Et puis tu as l'aide excel pour t'aider à comprendre.
Si tu ne fais pas de .select sur la feuille ORigine, tu n'en a pas besoin pour cette dernière.

Lorsque tu auras finalisé ta macro et que tu supprimeras tes lignes sans les sélectionnées au préalable tu pourras enlever le .Activate.


A+
 

Sebast

XLDnaute Impliqué
Re : Fonction MATCH() capricieuse (parfois marche, parfois bugge !)

Hasco,

Merci beaucoup pour tes explications : elles m’ont mis la puce à l’oreille et c’est effectivement un problème de feuille active. Je disais dans mon premier post que parfois ça marchait, parfois pas quand je passais d’une feuille à l’autre … c'était donc bien ça !
Si je lance la macro en étant positionné sur « Destination », pas de problème …

Je m'étais permis de te demander où placer le .activate car en l'état (comme je l'avais compris mais testé avec un bug pour résultat), je remontais une erreur si la macro n'était pas lancée depuis la feuille "Destination".

En effet, après quelques essais, je me suis rendu compte qu’il vaut mieux utiliser :

Code:
Sheets("Destination").Activate

With Sheets("Destination").UsedRange


Plutôt que


Code:
With Sheets("Destination")
.Activate

Car si on ne lance pas la macro depuis la feuille « Destination », le problème reste entier.


Encore merci de m'avoir aidé à résoudre le problème
 
G

Guest

Guest
Re : Fonction MATCH() capricieuse (parfois marche, parfois bugge !)

Re

Si tu utilises Sheets("Destination").usedRange tu peux Faire:

Code:
With sheets("Destination").UsedRange
            .Parent.Activate
                                          '.......suite du code
 End With

Ou imbriquer les With pourvu qu'ils respectent la hierarchie objet parent et objets enfants
Code:
With Sheets("Destination") 'Travil sur feuille
      .Activate
      With .UsedRange
             'TRavail sur UsedRange
      End With
      'Suite travail sur feuille
       msgbox .name
end with

A+
 

Discussions similaires

Réponses
17
Affichages
747
Réponses
5
Affichages
169
Réponses
7
Affichages
327

Statistiques des forums

Discussions
312 107
Messages
2 085 354
Membres
102 873
dernier inscrit
yayo