Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Zones de plages

8 réponses
Avatar
GL
Bonjour,

Avec la souris, il est possible de sélectionner une plage
en deux morceaux :
par exemple dans A1:B2 :
je sélectionne A1:B1
puis A2:B2 (en maintenant appuyé la touche CTRL)

En VBA la plage contient deux zones :
R.Areas.item(1).Address donne A1:B1
.item(2).Address A2:B2

Est-il possible de construire en VBA une telle plage ?

Autrement dit est-il possible en VBA de sélectionner
A1:B1 et A2:B2 en deux zones différentes ?

Merci d'avance.

8 réponses

Avatar
DanielCo
Bonjour,
Set R = Range("A1:B1,A2:B2")
Daniel


Bonjour,

Avec la souris, il est possible de sélectionner une plage
en deux morceaux :
par exemple dans A1:B2 :
je sélectionne A1:B1
puis A2:B2 (en maintenant appuyé la touche CTRL)

En VBA la plage contient deux zones :
R.Areas.item(1).Address donne A1:B1
.item(2).Address A2:B2

Est-il possible de construire en VBA une telle plage ?

Autrement dit est-il possible en VBA de sélectionner
A1:B1 et A2:B2 en deux zones différentes ?

Merci d'avance.
Avatar
isabelle
bonjour GL,

Set R = Union(Range("$A$1:$A$6"), Range("$B$10:$B$16"), Range("$C$20:$B$26"))
g = R.Address
x = Split(g, ",")
For i = LBound(x) To UBound(x)
Rng = x(i)
Next

isabelle

Le 2014-05-29 11:26, GL a écrit :
Bonjour,

Avec la souris, il est possible de sélectionner une plage
en deux morceaux :
par exemple dans A1:B2 :
je sélectionne A1:B1
puis A2:B2 (en maintenant appuyé la touche CTRL)

En VBA la plage contient deux zones :
R.Areas.item(1).Address donne A1:B1
.item(2).Address A2:B2

Est-il possible de construire en VBA une telle plage ?

Autrement dit est-il possible en VBA de sélectionner
A1:B1 et A2:B2 en deux zones différentes ?

Merci d'avance.
Avatar
GL
Le 29/05/2014 17:33, DanielCo a écrit :
Bonjour,
Set R = Range("A1:B1,A2:B2")
Daniel



Oui. Effectivement il suffisait de regarder R.Address
et de faire l'inverse : R=Range(<Adresse>).

Mais j'aimerais le faire à partir de 2 plages :
R1 = Range("A1:B1"): R2 = Range("A2:B2")

puis R = Une sorte d'Union de R1 et R2 de telle sorte
que R1 et R2 soient des zones différentes.

Mais apparemment, la propriété Areas est en lecture seule
et donc cette possibilité est fermée.

Je peux donc :
- faire un tableau : Dim R() as Range
=> inconvénient : utiliser UBound au lieu de .Areas.count
- faire une collection : Dim R as new Collection
=> inconvénient : R(1) n'est pas typé (range)

Merci.
Avatar
GL
Le 29/05/2014 17:43, isabelle a écrit :
bonjour GL,

Set R = Union(Range("$A$1:$A$6"), Range("$B$10:$B$16"),
Range("$C$20:$B$26"))
g = R.Address
x = Split(g, ",")
For i = LBound(x) To UBound(x)
Rng = x(i)
Next



Oui enfin dans ce cas précis :

For i=1 to R.Areas.count: Rng = R.Areas.Item(i):Next i

C'est parce que Union est instable :
Union(Range("A1:A6"),Range("B1:B6")) renvoie Range("A1:B6")
Union(Range("A1:A6"),Range("B2:B5")) renvoie A1:A6 , B1:B5
Union(Range("A1:B5"),Range("A6")) renvoie A1:A5 , A6
qui pourtant est le même que le précédent

Union fusionne les zones contiguës qui ont le même nombre de lignes
et les zones contiguës qui ont le même nombre de colonnes.

En bref: on ne peut pas ajouter d'élément à la collection Areas.


Pour pousser un peu plus loin:
C'est comme .Resize qui est une méthode illogique et donc inadaptée :
.Resize plante sur une plage de plusieurs zones, même si la plage
totale est carrée.

Alors que la méthode logique serait un truc du type .Offset
(qui fonctionne quelque soit la plage/le nombre de zones, pourvu
qu'on reste dans les limites de la feuille) mais qui sélectionne
au lieu de décaler (ça s'écrit facilement en VBA mais ça n'existe
pas en natif : ce qui existe en natif, c'est un truc illogique et
inadapté à la définition des objets Range...)

Cdt.
Avatar
GL
Le 29/05/2014 18:15, GL a écrit :
Le 29/05/2014 17:43, isabelle a écrit :
bonjour GL,



C'est parce que Union est instable :
Union(Range("A1:A6"),Range("B1:B6")) renvoie Range("A1:B6")
Union(Range("A1:A6"),Range("B2:B5")) renvoie A1:A6 , B1:B5
Union(Range("A1:B5"),Range("A6")) renvoie A1:A5 , A6
qui pourtant est le même que le précédent

Union fusionne les zones contiguës qui ont le même nombre de lignes
et les zones contiguës qui ont le même nombre de colonnes.

En bref: on ne peut pas ajouter d'élément à la collection Areas.



Ce qui signifie que si j'ai sélectionné la plage : "A1:B1 , B2:B2"
(en deux zones) je ne peux pas en VBA sélectionner
la plage agrandie : "A1:C1 , B2:C2"
en deux zones... sauf à passer par les adresses.

Bon ben voilà : on ne m'aurait pas dit que c'était du Microsoft,
j'aurais trouvé en 3 secondes...
Avatar
MichD
Bonjour,

Il manque un petit quelque chose à ta question...

Quel traitement veux-tu faire avec ces 2 plages de cellules A1:B1 et A2:B2

lorsque les plages sont adjacentes comme dans ton exemple, il y a aussi ceci :

'-------------------------------------
Dim Rg As Range, R As Range, C As Range

Set Rg = Range("A1:B2")

For each R in Rg.Rows 'boucle sur chaque ligne de la plage
For each C in R.Cells 'Boucle sur chaque cellule de chaque ligne

Next
Next
'-------------------------------------





"GL" a écrit dans le message de groupe de discussion : 5387519e$0$2029$

Bonjour,

Avec la souris, il est possible de sélectionner une plage
en deux morceaux :
par exemple dans A1:B2 :
je sélectionne A1:B1
puis A2:B2 (en maintenant appuyé la touche CTRL)

En VBA la plage contient deux zones :
R.Areas.item(1).Address donne A1:B1
.item(2).Address A2:B2

Est-il possible de construire en VBA une telle plage ?

Autrement dit est-il possible en VBA de sélectionner
A1:B1 et A2:B2 en deux zones différentes ?

Merci d'avance.
Avatar
GL
Le 29/05/2014 19:04, MichD a écrit :
Bonjour,

Il manque un petit quelque chose à ta question...

Quel traitement veux-tu faire avec ces 2 plages de cellules A1:B1 et A2:B2



Oui tout à fait: commençons par là. On donc accès :
- aux zones (collection .Areas)
- aux lignes (collection .Rows)
- aux colonnes (collection .Columns)

Tant qu'on ne fait pas dans les formules matricielles, c'est suffisant.

Par contre, si on veut traiter en boucle les formules matricielles,
on a en toute généralité une collection de zones (rectangulaires donc)
qui ne sont ni des lignes ni des colonnes.

J'aurais aimé construire un Range qui regroupe ces zones (chaque zone
correspondant une formule matricielle, ie telle que
<< zone.CurrentArray = zone >> )

L'application première c'est que j'ai une macro
CTRL+SHIFT+D / CTRL+SHIFT+B qui recopie vers le bas/la droite,
mais seulement les formules et les formats des nombres, et les
VerticalAlignment/HorizontalAlignment (avec cas particulier en
cas de cellule fusionnée pour ces deux dernières propriétés).

Parce que le FillRight/FillDown, c'est une daube qui oblige sans
arrêt à modifier à la main les bordures... Bref : j'ai ma config.

Mais il peut y avoir d'autres applications pour lesquelles il serait
pratique d'avoir la liste des zones des formules matricielles qui
intersectent une plage donnée... Pour dire que ce n'est pas de la
programmation "ad hoc" : je fais le boulot que Kro$oft n'a pas fait !

Or cette macro de recopie ne me donne pas satisfaction en cas de
FormulaArray qui s'étend sur plusieurs cellules (je voudrais que tout
le FormulaArray soit recopié notamment, quitte à annuler et émettre un
Beep si les cellules devant accueillir la copie sont à la fois non
sélectionnées et non vides - ce qui peut se produire avec des
vecteurs...).

Voilà le décors.

Donc j'ai déjà le :

TypeDef RangeCollection
Empty as Range
Constants As Range
Formulas As Range ' Pas les formules matricielles
FormulaArray() As Range ' Série des zones de formules matricielles
End Type

Et la Property Get GetRangeCollection(R as Range) qui classifie les
cellules de R dans les cases de mon type RangeCollection.

A partir de là, je peux bosser: traitement différencié des
Empty/Constants/Formulas/FormulaArray()


Voilà, et j'ai aussi besoin pour ce FillRight/Down perso de pouvoir,
à partir d'une plage *quelconque* (plusieurs zones etc...) de
sélectionner la plage identique mais :
- agrandie (ou rétrécie) à droite de <Right> colonnes
- agrandie (ou rétrécie) à gauche de <Left> colonnes
- agrandie (ou rétrécie) en haut de <Top> colonnes
- agrandie (ou rétrécie) en bas de <Bottom> colonnes

C'est à dire un truc du type :
<Range>.SpreadOffset(<Left>,<Right>,<Top>,<Bottom>)

Or Kro$oft ne fournir que .Offset (et cette bidouille de .Resize)
Donc là aussi, je suis obligé de faire leur boulot.

Heureusement que j'ai une version illégale !
Il n'auront pas 1 franc de ma poche !


Voilà. Ces fonctions très générales peuvent être ensuite utilisées
dans différents contextes.

Cordialement.
Avatar
MichD
Excuse-moi, je n'ai pas lu ta réponse...

Lorsque je veux lire de la prose, je choisis autre chose qu'Excel ou VBA comme sujet!