1

I have written some code for a custom ribbon button that inserts groups of shapes, and then groups the groups.

To be able to do this more than once on the same slide, the shape names need to be renamed (or else a subsequent press of the button gets confused and tries to group up with the old shapes). So part of the code includes going back through the shapes to rename them once grouped.

Referencing the slide's Shapes collection allows you to get the top-level group. Referencing the top-level group's GroupItems takes you all the way to the bottom. There doesn't seem to be any way to access the middle level.

In the image below, the top-level group is the "Key" shape, which is accessible directly Application.ActiveWindow.View.Slide.Shapes("Key")...

The GroupItems of that shape are the shapes that already have an underscore at the end Application.ActiveWindow.View.Slide.Shapes("Key").GroupItems.Count returns 8 i.e. all the shapes with the underscore at the end of the name

How do I refer to the intermediate level group names which are in the orange boxes?

This setup is required because the number of SeriesKeys is unknown when clicking the button, and choices are available for the format of the overall shape. Functionality also allows for adding into the main "Key" group later on.

So, grouping up each component seems to be the best approach.

enter image description here

JakeyG
  • 100
  • 11

3 Answers3

1

you can try this

Dim topGroup as shape, item as Shape
Dim subGroups as ShapeRange
Set topGrop = Application.ActiveWindow.View.Slide.Shapes("Key")
Set subGroups = topGroup.Ungroup

For Each item in subGroups("SeriesKey3")
    debug.print(item.Name)
next item

set topGroup = subGroups.Group
topGorup.name = "Key"

This leaves the top grouping as it was originally, but with the sub groups accesible in the subGroups ShapeRange by name.

wrbp
  • 870
  • 1
  • 3
  • 9
  • This isn't efficient as you have to group, ungroup, regroup. But it did give me enough of a clue to work out the best way to do it, so happy to award the bounty! – JakeyG Feb 28 '23 at 16:34
0

Unfortunately I do not think the intermediate groups can be accesed by name.

However, you could access multiple items like this:

Dim sr As ShapeRange
Set sr = Application.ActiveWindow.View.Slide.Shapes.Range(Array("SeriesLabel3_", "SeriesSwab3_"))

sr.Visible = msoFalse
Cristian Buse
  • 4,020
  • 1
  • 13
  • 34
  • 1
    That is the basic approach of the current code and leads to the issue - I can't reference the shapes that I need to. Think I will need to find another way to deal with the shapes... – JakeyG Feb 27 '23 at 13:50
  • @JakeyG You probably already tried and saw that you can't even select the intermediate groups in the task pane (Alt+F10). I tried doing the same in Excel, and macro recorded what happens when you select an intermediate group, and the code was something like ```Application.ActiveWindow.View.Slide.Shapes.Range(Array("SeriesKey3")).Visible = msoFalse```. But when I then tried to run that code outside the macro recorder, I was surprised to see that it does not work. This suggests to me that the intermediate groups are either built on-the-fly or they are simply not exposed to the Object Model. – Cristian Buse Feb 28 '23 at 09:48
  • Yeah it's strange. Feels like a bug/oversight but far be it from me to hypothesise the mindset of Microsoft devs! – JakeyG Feb 28 '23 at 16:38
0

The answer basically is to avoid using names in the first place and use a ShapeRange object. Once the shapes are stored in a variable of ShapeRange type, they can be freely renamed and then the Group method applied to the object instead of an array of the shape names. Thanks to wrbp for sending me down this path!

JakeyG
  • 100
  • 11