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
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