Icône de la ressource

VBA - Range Exclusion - Exclure un Range d'un autre Range V5

Le fichier à télécharger contient:
  1. Le Module_RangeFunctions
  2. Le Module_RangeExclusionByRanges (accessoirement pour information)
  3. Le Module_Test et le UserForm1 pour mettre en évidence le résultat des fonctions d'exclusion de Ranges
Ce fichier traite spécifiquement de la méthode Exclusion() et l'illustre avec des sélections colorées (voir le GIF animé ci-dessous).
Pour bénéficier du code correspondant, ainsi que d'autres fonctions de Ranges, voir la ressource:

Commentaires préliminaires:
  • VBA a prévu 2 fonctions de manipulation de Ranges:
    - Intersect()
    - Union()
    qui méritent d'ailleurs d'être "enveloppées" car elles plantent lorsqu'un Range en argument est Nothing ou que les .Parent des Ranges sont différents.

  • Dans les fonctionnalités liées à des ensembles, VBA n'a pas prévu d'intégrer la fonction importante:
    - Exclusion()

  • Il y a une méthode simple pour gérer l'exclusion d'un Range d'un autre Range qui consiste à parcourir les cellules du Range source (ou Range Réservoir) et d'unir par la fonction Union() toutes celles qui n'ont pas d'intersection détectée par la fonction Intersect() avec le Range à exclure (ou Range Exclusion).

    C'est la fonction ExclusionByRanges() fournie accessoirement dans le Module_RangeExclusionByRanges.
    Toutes les ressources Internet que j'ai pu examiner utilisent cette méthode basique qui n'est pas sans inconvénients.

    1685215849851.gif
    Inconvénient majeur
    : si le Range Réservoir est très grand, le parcours de ses cellules et l'union des cellules candidates peut devenir très long, voire même rédhibitoire (5 secondes CPU / million de cellules).

    1685268929927.gifInconvénient mineur: si le Range Réservoir contient des chevauchements d'Areas, le Range résultat a toutes chances d'en comporter aussi (voir les remarques).

  • 1685216061754.gif
    Il a donc fallu imaginer une méthode alternative
    pour contourner ce problème de temps de traitement.
La principale caractéristique:
  • La fonction Exclusion() du Module_RangeFunctions permet de trouver le Range résultat de l'exclusion d'un Range Réservoir d'un autre Range Exclusion sans parcours de cellules.
Mise en œuvre très simple:
Remarques:
  • Pour des Ranges complexes avec des Areas nombreuses qui se chevauchent (c'est à dire des Areas qui comportent des cellules communes), l'agrégation des cellules ou des Areas avec la fonction VBA Union() peut potentiellement conserver des chevauchements d'Areas. C'est le cas de la méthode ExclusionByRanges().

    Lorsqu'il y a des chevauchements d'Areas, le Range.Cells.CountLarge qui somme le nombre de cellules des Areas sera alors supérieur au nombre réel de cellules dans le Range.

  • La méthode Exclusion() propose une option pour supprimer les chevauchements d'Areas du Range résultat.
Versions:
  • V1 - Initiale.
  • V2 - Correction Exclusion() pour les cas ou Not ReservoirRange.Parent Is ExclusionRange.Parent.
  • V3 - Unions temporaires de travail par adresses pour limiter le nombre d'appels à la fonction Union() qui sont très pénalisants.
  • V4 - Changement de méthode pour Exclusion() et RemoveAreaOverlaps() en utilisant un tableau.
  • V5 - Intégration de la V6 du Module_RangeFunctions.
Le fichier fourni:
  • Il permet de visualiser et de tester (voir image GIF ci-dessous).

Exclusion.gif