0% found this document useful (0 votes)
74 views

Exploring Shape Group Hierarchy in VBA Excel

The document discusses exploring the shape group hierarchy in VBA Excel. It notes that while VBA can see top-level groups and shapes on a worksheet, it cannot see any lower grouping levels. The author wants to be able to discover the entire shape hierarchy to recreate the structure when reopening a file. However, subgroups are not accessible through the parent's groupitems collection or the worksheet shapes collection. Workarounds discussed include storing additional data in shape fields or using a separate hidden worksheet to persist object relationships between sessions.

Uploaded by

Maddy Sjiicro
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
74 views

Exploring Shape Group Hierarchy in VBA Excel

The document discusses exploring the shape group hierarchy in VBA Excel. It notes that while VBA can see top-level groups and shapes on a worksheet, it cannot see any lower grouping levels. The author wants to be able to discover the entire shape hierarchy to recreate the structure when reopening a file. However, subgroups are not accessible through the parent's groupitems collection or the worksheet shapes collection. Workarounds discussed include storing additional data in shape fields or using a separate hidden worksheet to persist object relationships between sessions.

Uploaded by

Maddy Sjiicro
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Exploring shape group hierarchy in VBA excel.

pdf
Saved to Dropbox • Dec 12, 2022 at 9:27 PM

r/excel Use App

x
r/excel
arcosapphire • 13 • 6y Join !

Exploring shape group hierarchy in VBA


unsolved

I have some interesting ideas for making it easier to


design interfaces. Part of this involves creating
shapes and assigning them to instance variables of
instantiated objects which handle the real work.

The thing is, if it takes more than one session to


design the interface, currently all of that information
is lost since you can't serialize the objects into the
saved file and reload from there. That's no good. So
I've come up with ideas for being able to recreate the
structure, by walking the tree of shapes on the
worksheet and pulling some information from the
name or alternativetext field or something.

There's a major roadblock. VBA can see any shapes


on the sheet, and it can see any top-level groups,
but it cannot see any other grouping level.

The groups themselves can be accessed if their


name is known beforehand, but they will not appear
in sh.shapes or the .groupitems of any shape it can
discover.

Is there any way to really cycle through ALL the


shapes to discover these?

I have no idea why Microsoft programmed it to


ignore full hierarchy and always report the top level
group as the parentgroup, and exclude subgroups
from the parent's groupitems, but it does.

11
Share16this Link x

u/americanairlines • Promoted !
SHARE LINK
When you fly, we know you want free
checked bags and seat upgrades. And "
with the American Airlines AAdvantage…
program, you c...
aa.com Learn More

16 Comments sorted by Top ˇ

Leave a comment

DankVapor 26 6y !
Why not just use a user form? You're talking
about a lot of code to do what a user form
does natively.

2 Reply

arcosapphire # 13 6y !
I'm talking about code to create forms, not
the form itself. User forms have a lot of
disadvantages, design-wise.

1 Reply

frescani 6y !
But it sounds like you're doing it within
the worksheet objects instead of using
actual form objects. Also, I hope you're
making use of class modules, b/c I can't
tell that either from your descriptions.

1 Reply

arcosapphire " 13 6y !
Yes and yes. I don't like working with
userforms because the presentation is
so limited.

1 Reply

xlViki 238 6y !
Here's an idea:

When you create groups, give the groups


names and store those name on a
xlVeryHidden sheet. Even after a session is
closed, the names would still be there within
the workbook and can be accessed the next
time.

With that said, I still don't fully comprehend


your ultimate goal, so this may or may not
solve all your problems. If you can share a
demo of what you're trying to create, I may be
of more help to you.
1 Reply

arcosapphire ! 13 6y "
Yeah, I could use an extra sheet like that,
but I really hate to do so. Especially as
there's the (incredibly unlikely) possibility of
name collision with an existing sheet, as the
interface items could be added to any
workbook...

Since a hierarchy tree can have any number


of levels of grouping, the next problem
becomes how to organize that data in a
sheet...solvable, but somewhat annoying to
manage since Excel isn't a relational
database.

I'll see what I can post when I'm at my


computer. I consider creating veryhidden
sheets to persist object information to be
the last resort. That sort of information
doesn't always translate well to a grid of
cells.

1 Reply

arcosapphire ! 13 6y "
Here is an example of a page of my UI. I've
made many of these things as "push
button" report generators, etc. However,
I've had to manually set them up each time I
create some sort of automated report. My
goal is to create an add-in that can more
easily set these up. So on a designated
worksheet, it can add panels (the large
containing blocks), buttons, progress bars,
indicator lights (which each have multiple
statuses with a different color and
message), and present these to the actual
report program in a convenient way.

Hierarchically, each panel is a group which


contains these different components. Some,
like the status light bar, contain multiple
subcomponents (a light) which themselves
contain multiple subcomponents (different
statuses).

The end result for the ones I've created


manually is really nice, functional, and
attractive. But it's something of a pain to set
them up, and reconfiguring them (e.g.,
create a bar with five lights now, or make
the panels wider) is a huge pain, as the
elements do not scale very sensibly.
Generally I just copy and paste chunks from
where I already did the work once, and then
make the easy changes (text, name, etc.).
But that's still not great.

So I'm writing an add-in that will make this


simpler: "add panel", "add lightbar", "add
light", "add status", etc.--it will
automatically size, place, and format
everything. And if I want to put something in
the middle, it will rearrange things as
necessary. This is a significant undertaking,
but it would make my work experience
better. The thing is, for the code to work in a
sensible way, I should have an object
hierarchy that parallels the UI. The
PanelController class oversees everything,
and contains Panel objects, which contain a
reference to the panel shape and
components like PanelLightBar, which in
turn contains references to some base
shapes plus PanelLights, which hold
references to numerous Light shapes, etc.
By taking the object-oriented approach,
each segment can effectively manage its
sub-segments very well, and the actual
amount of programming is pretty minimal.

The problem, as I've outlined, is that this


object hierarchy does not persist. I mean,
the main PanelController is attached to the
worksheet declaration area, so it persists
between various macros. However, if I close
and reopen the file, that built-up structure is
completely destroyed. It needs to be
recreated on load. And that's why I need to
be able to discover every object and every
group and sub-group--that would inform
the controller as to how to create child
objects and assign references within them
to groups, and those child objects can
explore the child shapes and groups that
they own, etc. Except...they can't. Because
Microsoft decided that anyone writing VBA
would surely only care about top-level
grouping. And although sub-groups can be
referenced by name and return a Shape,
those sub-groups cannot be discovered be
iterating through the Worksheet.Shapes
collection. Only top level shapes and groups
appear there. Lower-level shapes appear in
the GroupItems of a top-level group, but
GroupItems contains all lower-level shapes
and no sub-groups. The hierarchy gets
flattened to two levels.

My current idea for a workaround is to


embed "type" and "parent" identifiers in
child shapes (probably in the AlternateText
field) so this can be read by iterating
through top-level groups, and the hierarchy
can be reconstructed. This isn't really ideal,
and I keep hoping someone will show up
with "oh, here's a wonky way you can
actually discover all parent/child
relationships among Shapes in a worksheet"
instead, but it's what I'll go with if there
really is no solution.

1 Reply

ericblank01 1 6y !
I've done some work for a jet engine
manufacturer, which manages very
complex assemblies in the engine. The
bills of material, essentially a massive
hierarchy, are managed in just 1 table.
Each part is an entry in the table, and the
entry has an optional ParentID field. A
database query then rebuilds the
hierarchy. A lot like the workaround you
mentioned. Point is, your workaround is
used other places in industry if that helps
build your confidence in it.

I'm wondering if you can just assign a


name to each shape, and then reference
shapes by that name. I'm writing a tutorial
on creating visual dashboards found here.
In it, I create a clickable map of the US,
where each state is a shape. I assign the
shape's name according to what state it
is, and I can reference it in VBA that way.

Perhaps you could use a naming


convention like GroupName-Level-Item#,
or something like that. Just a
thought...probably not the "wonky way"
you were hoping for, but maybe this will
trigger some other ideas.

1 Reply

arcosapphire ! 13 6y "

your workaround is used other


places in industry if that helps
build your confidence in it.

It's not so much that I'm worried it


won't work, it's just that I was hoping a
"proper" solution existed that I just
didn't know about. It would make
everything a bit cleaner. The limitation I
ran into is just one of those "really
dumb" things Microsoft decided on for
no apparent reason. It's so absurd that
I thought, surely there's a right way to
do this...maybe not.

Perhaps you could use a naming


convention like GroupName-
Level-Item#, or something like
that. Just a thought...probably
not the "wonky way" you were
hoping for, but maybe this will
trigger some other ideas.

Well, something like that, but I don't


like relying on names too much. You
have to start being very careful that no
naming overlap can occur, you need to
sanitize strings to avoid use of
delimiters where unexpected, etc. It
can be done that way, but I think using
AlternativeText just to encode hierarchy
data is a bit more elegant. Still not as
good as being able to properly read the
hierarchy from GroupItems and
ParentGroup.

Note that the actual code would be


accessing my custom class objects to
call functions on these UI elements.
This whole construct-the hierarchy
thing is only necessary when the sheet
is opened, to properly construct the
object tree from the interface elements
itself.

1 Reply

pmo86 44 6y !
Can you post a book with a sampe UI on
it? I would like to play around with the
VBA when I get time. I have also done a
lot with HTML forms. You can use CSS,
etc.

1 Reply

arcosapphire " 13 6y !
Well, I have workbooks with an existing
manually-created interface, which
doesn't use any of these principles.

Or I have the very beginnings of my


add-in development, where I have
classes (barely) defined and no real
functionality yet...I've got the ability to
generate a new panel rectangle so far.

Which one are you talking about? Or if


you meant "a workbook with one of
these auto-created UIs, but there are
problems because of the described
roadblock", that will exist in a few days.
I was hoping to solve the problem
theoretically before I actually ran into
it, in case a solution requires some
redesign.

1 Reply

pmo86 44 6y !
Any that you are willing to share.
What do you want your hierarchy to
look like? I am thinking you will need
a class for each level along with one
for the various objects.

1 Reply

arcosapphire " 13 6y !
Okay, I'll be able to provide an
example UI, for the way I'm
currently doing it, in a few hours.
For confidentiality reasons, I'm
genericizing names and removed
my VBA, which is much more
about the report actions than the
UI stuff.

Yes, I'd need a class for each type


of component--controller (which
administers everything), panel,
different panel components,
subcomponents, etc. Although it's
annoying that these each require
separate modules (seriously, who
came up with this?), that's not a
big problem.

In my head right now I'm wrestling


with two different ideas.

keep this structure in an add-


in, populate it only when the
"panel designer" mode is
activated, ensure appropriate
helper methods are placed in
target workbook, don't use any
hierarchy for UI actions. That's
basically what I've been doing,
but everything is created by
hand instead of automatically.

put the actual class modules in


the target workbook, use them
to actually handle the UI
actions as well.

In the first case, my


discoverability problem is only a
problem if I don't create the whole
UI in one go. So, a moderate
problem.

In the second case, my UI


absolutely would not function
unless I solve the discoverability
problem. Major problem.

1 Reply

arcosapphire ! 13 6y "
Here is the example.

1 Reply

tjen 365 6y !
Edit: Derp, I got to a computer and looked at
my old file, I was specifically working with
SmartArt designs, so you can probably
safely ignore the below comment, lol, but
I'll leave it there.

You've obviously worked with this a lot more


than me lol and it's really interesting to read
your problem, so I'm sorry if this is a silly
comment but my memory is a bit fuzzy.
However, I seem to remember making an
organizational chart generator at some point
using the built-in shapes and
accessing/adding lower levels of the hierarchy
by referring to different nodes?

I'm not sure if that syntax carries over to your


shapes though, but iirc it was something like
shape.node(1).node(3).node(2) to get to the
second item of the third item of the first group.

I'll have to dig out my file when I get to my


computer, but like if I'm way off no worries lol

1 Reply

arcosapphire " 13 6y !
Thanks for looking into it; unfortunately not
quite the structure I need.

1 Reply
Top posts of March 22nd, 2016

Top posts of March, 2016

Top posts of 2016

You might also like