Erreur 438 lors 'une déclaration de plage
Bonsoir à tous,
j'ai un problème avec une décalration de plage dans le code suivant:
Sub ComparerPlages()
Dim Plage As Range
Dim Plage1 As Range
Dim Plage2 As Range
Set Plage = Range("B5:C8")
Set Plage1 = ActiveWorkbook.Worksheets("Feuil1").Plage
Set Plage2 = ActiveWorkbook.Worksheets("Feuil2").Plage
For Each Cell In Plage
If Plage1.Cell.Value = Plage2.Cell.Value Then
Else: MsgBox ("Problème en " & Cell.Address)
End If
Exit For
Next Cell
End SubL'erreur 438 apparaît au niveau de la ligne surlignée. Je n'arrive pas à comprendre pourquoi. De l'aide please ?
SkillzZ
Bonsoir,
Ça te crève pas les yeux ?
Plage est une variable.
De surcroît :
Set Plage = Range("B5:C8")Le terme à droite du signe = est une expression non qualifiée.
Pour autant, elle représente bien une plage précise sur une feuille précise, celle qui était active au moment de l'exécution de cette ligne.
Imprécision du code pouvant toujours donner lieu à des surprises ultérieures...
Ceci étant, initialisée ou non, cela reste une variable objet, en aucun cas une propriété d'un objet Worksheet...
En tant que la variable représente un objet Range tu peux faire appel à ses propriétés : Plage.Value, Plage.Address... mais là tu es hors toute syntaxe... !
Et tu auras le même problème avec la ligne qui suit.
Et également 2 lignes ensuite plus loin : Cell est une variable, et par initialisation une cellule appartenant à Plage. Ton utilisation va déclencher la même erreur, mais en fait il y a au moins une double erreur !
Cordialement.
Bonjour,
Hello MFerrand
Il est possible d'en faire une propriété (ça n'a aucun intérêt mais c'est possible) !
On déclare une variable "Public" dans le module de la feuille :
Public Plage As Rangeon y accède comme une propriété mais pas visible dans l'Intellisense :
Set Worksheets("Feuil1").Plage = Worksheets("Feuil1").Range("B5:C8")Qu'il est ensuite possible de passer à un autre objet Range :
Sub ComparerPlages()
Dim AutrePlage As Range
Set Worksheets("Feuil1").Plage = Worksheets("Feuil1").Range("B5:C8")
Set AutrePlage = Worksheets("Feuil1").Plage
MsgBox AutrePlage(1, 1).Value
End Subça ne sert à rien mais c'est possible
Passez une bonne journée !
Bonjour à vous deux et à tous !
MFerrand, j'ai lu ton post mais je ne comprends toujours pas quel est le problème. Oui Plage est une variable mais en quoi cela m'empêche de la définir en faisant Set Plage = Range ("...") ? Ce n'est pas évident pour moi, même si ça l'est sûrement pour n'importe quel programmeur.
Par ailleurs, tu me dis que ce qui est écrit à droite de mon signe égal est une expression non qualifiée, je ne comprends pas ce que ça signifie.. Oui je suis novice en VBA comme je te l'ai déjà dit sur d'autres posts
Et pour la boucle qui suit je ne vois pas non plus ce qui cloche. Peut-être que j'aurais du utiliser "Cells" et pas "Cell" ? J'aimerais que chaque cellule de la collection Plage soit parcourue en fait. L'objectif général de ma macro étant de comparer deux plages, en comparant le contenu de chacune des cellules: La cellule(1,1) de la plage 1 avec la cellule (1,1) de la plage 2, la cellule (1,2) de la plage 1 avec ... Etc
Peux-tu m'éclairer sur la situation ?
Je te remercie. Theze je ne t'ai pas oublié, je vais me pencher sur ton post après avoir compris celui de MFerrand puisque tu y fais référence !
Bonne journée !
SkillzZ
Bonjour à tous,
Theze: Intéressant, je prendrai le temps de faire quelques tests
SkillzZ: Maîtrise d'abord les éléments de base avant de te lancer dans les spéculations induites par Theze...
Tu déclares Plage en tant que variable Range.
Quand tu l'initialises ainsi :
Set Plage = Range("B5:C8")une référence d'objet est affectée à Plage, et chaque fois que tu invoqueras Plage, ce sera l'objet affecté qui sera renvoyé.
Mais écrivant Range("B5:C8"), cette expression n'est pas qualifiée, c'est à dire que tu fais appel à la propriété Range sans indiquer l'objet auquel tu veux faire référer Range afin que la propriété renvoie un objet Range (j'espère que tu suis...
VBA ne pouvant se passer de cette référence d'un côté (pour trouver l'objet recherché à renvoyer) mais admettant certaines omissions dans le code va considérer que tu as écrit :
Application.ActiveSheet.Range("B5:C8")
Ainsi selon que la feuille active au moment de l'exécution sera Feuil1 ou Feuil2, Plage sera la plage B5:C8 de Feuil1 ou de Feuil2. Mais sera une plage bien précise d'une feuille bien précise (l'imprécision ne provient que de ton écriture...)
Pour préciser ce que je te demandais de suivre plus haut : Pour renvoyer un objet tu remontes toujours (le plus souvent implicitement) à l'objet Application, qui représente l'instance d'Excel en cours d'exécution, utilisant une propriété ou méthode de l'objet Application, renvoyant soit un seul objet, soit une collection (le plus fréquent) à partir de laquelle la propriété Item (quasiment toujours implicite) renvoie un seul élément : le modèle d'objet Excel te fournissant la hiérarchie des objets (parents-enfants) te permet de cheminer dans cette hérarchie pour atteindre précisément l'objet que tu cherches...
L'affectation d'un objet à une variable objet te dispense de refaire à chaque fois tout le chemin de l'Application vers l'objet voulu.
En écrivant ensuite Plage, cela renvoie directement la plage B5:C8 de la feuille (?) où elle se trouve.
Quand tu écris ensuite : ActiveWorkbook.Worksheets("Feuil1"), tu renvoies les feuilles de calcul du classeur actif, parmi lesquelles tu renvoies l'Item nommé Feuil1. A ce stade si tu veux renvoyer un objet dont le parent est Feuil1, une plage de cellules de Feuil1 par exemple, tu dois utiliser pour ce faire une propriété de l'objet Worksheet pouvant renvoyer une plage : Range, Cells, Rows, Columns...
Tu lui flaques Plage, en plage déjà définie, concurrente en quelque sorte, il y a contradiction, et VBA va te dire Stop, ça ce n'est pas une propriété ou méthode de Worksheet...
On se retrouvera dans la même situation avec Cell plus bas, Cell variable d'énumération des éléments de Plage sera successivement les cellules : B5, C5, B6, C6... B8, C8.
Plage1.Cell (si tant est que Plage1 soit définie) te fais accoler 2 variables objets en dépendance l'une de l'autre alors qu'il s'agit de deux objets définis chacun de leur côté, intrinsèquement distincts...
Ce que tu sembles avoir voulu faire :
Sub ComparerPlages()
Dim Plage As String
Dim Plage1 As Range
Dim Plage2 As Range
Dim i As Integer
Plage = "B5:C8"
Set Plage1 = ActiveWorkbook.Worksheets("Feuil1").Range(Plage)
Set Plage2 = ActiveWorkbook.Worksheets("Feuil2").Range(Plage)
For i = 1 To Plage1.Cells.Count
If Plage1.Cells(i) <> Plage2.Cells(i) Then
MsgBox "Problème en " & Plage1.Cells(i).Address
End If
Next i
End SubCordialement.
Hmmm.. J'ai peut-être un peu mieux compris. Veux-tu dire que l'un de mes principaux problèmes était de déclarer Plage comme une variable Range et ensuite de répéter ce "Range" dans la définition de Plage ? Plage attendait un objet de la classe Range et moi j'ai répété le Range ?
Ou alors il était problématique de définir Plage de cette manière car le Range était perdu au milieu de nulle part et qu'il n'était pas précédé d'un "chemin" ?
Finalement le problème me semble être la déclaration du Plage initial. Si j'avais tout écrit "en dur" et oublier la variable Plage, j'aurais écris correctement ce qu'il y avant la boucle non ?
Pour la boucle Plage1.Cell ne fonctionne pas car il y a confusion d'objet mais Plage1.Cells fonctionne. Peux tu m'expliquer la différence de type qu'il y entre Cell et Cells ?
Cell était juste une variable propre à ma macro tandis que Cells est référencé par excel comme quoi ?
Voilà pas mal de questions, en tout cas merci pour toutes les réponses que tu m'as déjà fourni ! Merci beaucoup.
SkillzZ
Toujours pareil. Cell est une variable. Cells est une propriété d'un objet Worksheet ou d'un objet Range.
Plage1.Cells renvoie toutes les cellules de l'objet Range Plage1.
Pas de contre-indication alors.