2010-12-13 63 views
2

Considérons une feuille de calcul contenant un certain nombre de formes, et un extrait (1):VBA Excel: collection de sélection en boucle références index plage incorrecte lorsqu'il est utilisé avec des formes

'(1) 
For i = 1 To Selection.Count 
    MsgBox Selection(i).Name 
Next 

Quelle que soit les formes sont sélectionnées (doit être plus que 1 bien sûr) les deux premières Formes semblent toujours être retournées.
faudrait envisager l'utilisation ShapeRange (2):

'(2) 
For i = 1 To Selection.Count 
    MsgBox Selection.ShapeRange(i).Name 
Next 

Ce (2) retourne en fait le nom de la forme sélectionnée, tout comme (3):

'(3) 
For i = 1 To Selection.ShapeRange.Count 
    MsgBox Selection.ShapeRange(i).Name 
Next 

Tout (1) produit une erreur Si moins de 1 Shape est sélectionné, (3) semble fonctionner correctement - à moins qu'un Chart soit la seule sélection, sur laquelle une erreur Automation est renvoyée: "L'objet invoqué a une déconnexion de ses clients."

Je ne comprends pas pourquoi le premier ne parvient pas à retourner la bonne forme en général - Je suppose que la collection de sélection est plus complexe que l'œil, et je ne comprends pas pourquoi Selection.ShapeRange.Count échoue quand un graphique est sélectionné, mais réussit quand une forme est.

vous serions reconnaissants de toute la lumière sur cette

Répondre

2

La sélection peut contenir des objets autres que des formes. Tous les objets de la sélection ne possèdent pas une propriété de nom. C'est probablement pourquoi vous obtenez des erreurs avec plus d'une forme sélectionnée - parce que vous sélectionnez plus que des formes. La bonne façon de scanner toutes les formes sélectionnées est # 3 comme discussed here. L'erreur "invoqué par l'objet" ressemble à un bogue Excel.

J'attraperais simplement l'erreur, la traiterais, et me tournerais vers la base de connaissances MS pour obtenir des conseils sur la façon de contourner ce problème et/ou de minimiser son occurrence.

2

J'ai un graphique et cinq rectangles sur une feuille et je suis en utilisant Excel 2003.

Si je sélectionne un rectangle, puis le graphique, le code (1) fonctionne pour moi sans erreur. Il renvoie les noms des deux formes que j'ai sélectionnées comme je m'y attendais.

Si je sélectionne d'abord le graphique, puis un rectangle, il renvoie le graphique deux fois comme si le graphique représentait les deux formes sélectionnées. Je peux seulement supposer que c'est un bug. Mais un bug étrange parce que si je réexécute le code sans changer la sélection, il revient comme si j'avais d'abord sélectionné le rectangle. Impair.

Si moins d'une forme est sélectionnée, cela signifie qu'une plage est sélectionnée. Quelque chose est toujours sélectionné dans Excel, donc si vous n'avez aucune forme sélectionnée, il est probable que votre objet Selection fasse référence à un objet Range. Vous pouvez utiliser

Typename(Selection) 

pour déterminer ce qui est sélectionné. Si vous avez sélectionné une plage et que cette plage n'a pas de nom défini, la propriété Name renvoie une erreur.

Il est très difficile (impossible?) De sélectionner une "forme de diagramme" dans Excel. Découvrez les points de sélection lorsque vous sélectionnez un graphique par lui-même - ce sont des carrés noirs. Maintenez maintenant la touche de contrôle enfoncée et sélectionnez une autre forme. Les points de sélection sur le graphique se transforment en cercles blancs. Lorsqu'il est sélectionné par lui-même, l'objet Selection est en fait un objet ChartArea. Excel "devine" que lorsque vous sélectionnez un graphique, vous voulez vraiment sélectionner un composant d'un graphique (le ChartArea par défaut).Parce que le ChartArea n'a pas une propriété ShapeRange, vous obtenez une erreur.

En ce qui concerne le premier bug supposé, voici un code qui le prouve. Notez dans la troisième section, je vérifie le Typename, mais ne fais rien avec. Cela semble pousser Excel à savoir ce qui est effectivement sélectionné

Sub testshapes() 

    Dim i As Long 
    Dim sType As String 

    Sheet1.Shapes.Range(Array("Rectangle 5", "Chart 6")).Select 

    For i = 1 To Selection.Count 
     Debug.Print Selection(i).Name 
    Next i 

    Sheet1.Shapes.Range(Array("Chart 6", "Rectangle 5")).Select 

    For i = 1 To Selection.Count 
     Debug.Print Selection(i).Name 
    Next i 

    Sheet1.Shapes.Range(Array("Chart 6", "Rectangle 5")).Select 

    sType = TypeName(Selection(1)) 'avoids chart selected first bug 
    For i = 1 To Selection.Count 
     Debug.Print Selection(i).Name 
    Next i 

End Sub 

Dans la première section, j'obtiens la bonne réponse. Dans la deuxième section, j'obtiens "Chart 6" pour les deux instructions debug.print. Dans la troisième section, j'obtiens la bonne réponse.

Je ne sais pas si cela répond totalement à votre question, mais j'espère que cela vous rapproche.