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

Contribuez Discussion :

Pallier la limite de la méthode VBA/Excel Range.specialcells


Sujet :

Contribuez

  1. #1
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 422
    Points
    12 422
    Par défaut Pallier la limite de la méthode VBA/Excel Range.specialcells
    Bonjour,
    Je ne vois rien de prévu pour déposer ce que j'appellerais un simple "snippet".
    Je dépose donc ici sur ce site ce que je viens de déposer également ailleurs.

    La méthode VBA Specialcells applicable à un objet Range de Excel est utile et très pratique.
    Elle a cependant une limite gênante : elle ne peut recenser d'un seul coup plus d'un certain nombre d'aires (areas) résultant de son application. Ce nombre est égal à la moitié de la limite d'un type integer. Pourquoi la moitié ? Tout simplement parce-qu'il lui faut prévoir le pire des cas de fractionnement : une cellule sur deux correspondant au critère appliqué à la méthode.
    Comment pallier cet inconvénient ? En traitant par blocs de cellules dont le nombre n'excède pas la moitié de la limite d'un type integer.
    Ce qui veut clairement dire qu'il va falloir diviser encore par le nombre de colonnes de la plage. C'est ce que fait le petit code/snippet qui suit :
    1) la fonction :
    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
    Private Function plage_specialcells(p As Range, nature As Integer, typ As Byte) As Range
      Dim plage_bloc As Range, nb As Long, taille_bloc As Integer, nb_blocs As Integer, dep As Long, fin As Long, i As Long
      nb = p.Rows.Count
      taille_bloc = 16385 ' à votre gré entre 2 et 16385 maximum : taille de bloc à traiter en boucle
      taille_bloc = taille_bloc \ p.Columns.Count ' car le nb de cellules d'une ligne est celui de ses colonnes
      nb_blocs = nb \ taille_bloc
      If typ = 0 Then typ = 2
      For i = 0 To nb_blocs + 1
        dep = p.Offset(i * taille_bloc).Row '- 1
        fin = dep + taille_bloc - 1
        If fin > nb Then fin = nb
        On Error Resume Next ' pour le cas ou aucune cellule concernée
        Set plage_bloc = Range(p.Cells(dep, 1), p.Cells(fin, p.Columns.Count)).SpecialCells(nature, typ)
        On Error GoTo 0
        If Not plage_bloc Is Nothing Then
          If plage_specialcells Is Nothing Then
             Set plage_specialcells = plage_bloc
          Else
             Set plage_specialcells = Union(plage_specialcells, plage_bloc)
          End If
        End If
        If fin >= nb Then Exit Function
      Next
    End Function
    2) un exemple d'utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     Application.ScreenUpdating = False
      Dim nature As Integer, typ As Byte, plage_traitee As Range, plage_desti As Range
      Set plage_traitee = Range("A1:B50123") ' ===>> ici la plage à traiter
      nature = xlCellTypeBlanks ' par exemple (ou autre nature de votre choix)
      typ = 0 ' ===>> mettre 0 pour tous types ou 16 (xlErrors) ou 4 (xlLogical ou 1 (xlNumbers) ou 2 (xlTextValues)
      Set plage_desti = plage_specialcells(plage_traitee, nature, typ)
      Application.ScreenUpdating = True
      '============== le reste n'est là que pour visualiser le résultat, si on le souhaite
      If Not plage_desti Is Nothing Then plage_desti.Select Else MsgBox "aucune correspondance"
    Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
    Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .

    ****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...

    Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.

  2. #2
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 422
    Points
    12 422
    Par défaut
    Ah !
    Aucune réaction ...
    J'en attendais toutefois une !
    Et je vais donc vous y aider, à réagir :
    Si, de cette manière, nous avons passé un certain cap "liminaire" (aller au delà de ce que permet normalement l'application sans tremplins de la méthode Specialcells) nous n'avons pas réellement énormément avancé, même si l'avancée est déjà assez significative et suffisante dans la plupart des contextes.
    Pourquoi ? parce-que nous nous heurtons à une seconde limite : celle de la méthode Union qui, elle également, connaît des limites. Avec, pour corollaire, l'impossibilité d'utiliser en l'état cette méthode palliative au delà d'un SECOND nombre de "sous-plages" de la plage extraite. Il se trouve que cette seconde limite se situe autour de la cinquantaine de milliers d'aires (objets areas d'une plage).
    A quoi servirait-il, dans de telles conditions, de "dresser" une plage qui, elle-même limitée, en limiterait les actions (suppression, sélection ou autres) qui lui seraient appliquées au delà d'un certain nombres d'aires ? Et quelle est exactement cette nouvelle limite ?
    Que faudrait-il faire pour passer ce nouveau cap ?
    Je m'y mets de mon côté, mais aimerais beaucoup que d'autres tentent d'en faire autant.
    Amitiés
    Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
    Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .

    ****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...

    Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.

  3. #3
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut
    Salut Jacques !

    Pour ma part n'ayant pas le temps de chercher sur quel chemin de traverse tu veux nous embarquer
    et n'appréciant guère cette méthode SpecialCells, j'attendrais donc ta version définitive …

    _________________________________________________________________________________________________________
    Je suis Paris, Istanbul, Berlin, Nice, Bruxelles, Charlie, …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

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