VBA - Using .onAction on SmartArtNodes - vba

I am new to VBA and trying to use smartArt.Nodes to dynamically generate an organizational chart based on some cell data. I am able to generate the chart with no problems. Now, I would like to be able to display more details of specific nodes of the chart by clicking on them. I am aware that we can convert smartArts into Shapes with the Drawing Tools in Excel and then use .onAction on them like:
ActiveSheet.Shapes(name1).OnAction = "detail"
However, is there a way to achieve the same thing with smartArt.nodes using VBA? Say I have a node called "nodes1" I have tried:
nodes1.Shapes.OnAction = "detail"
or
Dim objShape As Shape
Dim SmartArtNod As SmartArtNode
Set objShape = ActiveSheet.Shapes(1)
Set SmartArtNod = objShape.SmartArt.AllNodes(1)
SmartArtNod.Shapes(1).OnAction = "detail"
and other combinations, but none of them seem to work...
Thank you for your help!

Hard to prove a negative, but I believe this is not possible. Testing with Excel 2013, I can confirm the following do not work:
Trying to trap the Selection of the SmartArt using
Worksheet_SelectionChanged does not fire. If you change the
selection from a cell to the SmartArt object, you will not get an
event. You will get an event however when you lose focus on the
SmartArt and go back to the cell.
You can select a SmartArt object and then debug to check what is selected. The object is of type
Object/Shape and the watch window indicates that it exposes an
OnAction property, but attempting to set this property will throw
an error.
I take the two issues above to mean that is will be very difficult (if not impossible) to get an OnAction event to fire from the SmartArt.

Related

PowerPoint VBA add shape event/ add shape with tag value

i'am currently trying to add a small function to PowerPoint using VBA, my goal is to create a gadget that works kind of like Photoshop graphics layer.
My plan is to add a layer name Tag on each shape that is drawn by user, so later I can parse through every item by loop and preform lock/unlock, show/hide shapes based on it's tag value, such as:
Sub add_shape_with_layer_tag()
Set islide = ActivePresentation.Slides(1)
Set ishape = islide.Shapes.AddShape(msoShapeRectangle, 5, 5, 80, 60)
ishape.Tags.Add "Layer", "1"
End Sub
Sub show_hide_layer_one_shapes()
Dim active_slide As Slide
Set active_slide = ActiveWindow.View.Slide
For Each ishape In active_slide.Shapes
If ishape.Tags("Layer") = "1" Then
ishape.Visible = Not (ishape.Visible)
End If
Next ishape
End Sub
However, I couldn't found a way to achieve this, so I would like to ask whether there's a method that provides following functions?
override add shape function so I can sneak tag value in to shape every time user drawn a shape
catch add shape event (if this thing did exist) so i can add tag to the last added item
a way to set a default tag value to shape, just like setting default shape color/line width
or is there any better options that is also viable?
thanks.
20200728
To John, thanks for the advice, I did found some interesting event that might be helpful for some of my other projects, however I couldn't found events that able to trigger after custom function while shape is added.
To Steve, my plan is to add a modeless userform with list UI that manage layers, the shape tag and shape fill texture/color will be determined based on what list item that currently selected.
As to saving settings, I'll use VBComponents.CodeModule to dump existing settings in userforms to a VBA module and store as text, so in theory I should able to make this function self contained in one file.
Not totally an answer, sorry SO, but comments don't allow enough scope for this. So ...
To Steve, my plan is to add a modeless userform with list UI that manage layers, the shape tag and shape fill texture/color will be determined based on what list item that currently selected.
Ah, so you're creating your own "pseudo-layers". That wasn't clear. Thanks for the add'l info. As it happens, I have a selection manager add-in that works very similarly to what you're proposing.
To John, thanks for the advice, I did found some interesting event that might be helpful for some of my other projects, however I couldn't found events that able to trigger after custom function while shape is added.
The SelectionChange event should get you there. When it fires, you'll need to check first to see if the current selection is a shape or something else. If a shape, check to see if its .Index = current slide's .Shapes.Count and also to see if you've already tagged it. If no tag AND if it's the correct index, it'll be a newly added shape. If you're tagging ALL shapes, you may only need to check to see if the .Tag(name) is blank.
As to saving settings, I'll use VBComponents.CodeModule to dump existing settings in userforms to a VBA module and store as text, so in theory I should able to make this function self contained in one file.
Why not save any needed slide or presentation level info as further slide- or presentation-level tags? PPT can absorb quite a lot of info as tags w/o getting cranky.

VBA ungroup Shape (SmartArt)

Does anyone know how to ungroup SmartArt element via VBA?
Sub UngroupSmartArt()
Dim shapeWithSmartArt As Shape
Set shapeWithSmartArt = ActivePresentation.Slides(2).Shapes(2)
shapeWithSmartArt.Ungroup
End Sub
I get an error for this code:
"This member can only be accessed for a group."
It doesn't make any sense to me, because it's easily possible to do it in powerpoint itself (Right click on SmartArt -> Group -> Ungroup). It's driving me nuts :)
Can anyone help me with ungrouping SmartArt element/shape?
I also took a look on similar question, but it doesn't work properly, because ungrouped result is different in comparison to the one made via powerpoint itself.
Please help me out. I would really appreciate any help!
It is simply impossible to do it via VB code. That is also statement from Microsoft. Disadvantage of using SmartArt is also that user cannot record any actions with macro (using Excel) which are performed on this type of object/element.
It is also impossible to change width or height property of SmartArt nodes via VB, this was actually the reason why I wanted to change SmartArt element to shapes, because you can easily change width and height property of the shape via code.
Microsoft and their developers should really consider to make SmarArt element more developer-friendly, because I noticed I'm not the only one with these issues.
EDIT: Solution found! There is a way to execute commands from the powerpoint ribbon. You need to select your shape first, afterwards execute CommandBars.ExecuteMso with the action: SmartArtConvertToShapes.
Sub UngroupSmartArt()
Dim shapeWithSmartArt As Shape
Set shapeWithSmartArt = ActivePresentation.Slides(2).Shapes(2)
shapeWithSmartArt.Select
CommandBars.ExecuteMso("SmartArtConvertToShapes")
End Sub
This still doesn't change the fact and my point of view: Microsoft should really consider to make SmartArt element more friendly to developers!

Running a VBA script from a button after selecting a chart

I’m running Excel 2010 on Windows 7.
I have four charts on a worksheet. What I want to do is select one of the charts and then click a button to open the ‘Format Axis’ dialogue box. I found the following code online to open the dialogue box. If I select a chart and then run the code from the toolbar (Developer tab, Macros, select macro, press ‘Run’), it works well.
Sub formatXAxis1()
ActiveChart.Axes(xlCategory).Select
Application.CommandBars.ExecuteMso "ChartFormatSelection"
End Sub
The trouble I have is when the VBA script is assigned to a button. If I use a shape as the button, I get “Run-time error ‘91’: Object variable or With block variable not set”. I get the same error if I use an ActiveX Command Button. However, with a Form Control button it works as expected. The only problem with this solution is that it is not possible to change the background colour of the button so it looks out of place against the other macro calling buttons on the worksheet.
I'm guessing that in the first two cases (shape and ActiveX buttons), VBA drops or loses the chart selection when I press the button – even though the chart still appears selected on screen. Is there a fix for this, or am I doing something wrong?
For an ActiveX button, in the Properties set the property
TakeFocusOnClick
to False. That will cause Selection to keep on the chart rather than switch to the button and your code should work. The color can also be changed from the properties box, though you probably already know that.
You need to reference the chart by name. So either have 4 buttons (one for each chart), or ask the user to input the name of the chart, then:
Dim co as ChartObject
Dim c as Chart
Dim NameOfChart as String
NameOfChart = Inputbox("Enter name of chart")
Set co = ActiveSheet.ChartObjects(NameOfChart)
Set c = co.chart
c.Axes(xlCategory).Select
Application.CommandBars.ExecuteMso "ChartFormatSelection"

Custom Design of an Excel Textbox VBA

Well I was wondering whether we can somehow create custom looking text boxes that act as an input box and is linked to VBA.
As far as I am aware the standard procedure would entail adding an ActiveX Textbox Control and then using the TextBox1_Change event to add the code as to what needs to happen when the user enters something in to.
Sadly the look of the default textbox isn't matching the way I want by spreadsheet to look. So is there any way to change how it looks or have something replace it while serving the same purpose?
One thing I could think of and have tried is inserting a shape (blue):
Shape http://im52.gulfup.com/qD2F0B.png
I can get the text that is in the shape using VBA by:
InputText = Shapes("Rounded Rectangle 1").TextFrame.Characters.Text
But I don't suppose there is a way to detect a change of shape text event?
Suggestions / Workarounds are welcome!
Thanks
There are limitations on what you can change on an ActiveX TextBox, such as Font/Color/Border/SpecialEffects, but the basic rectangle shape cannot be changed.
However you can make the TextBox transparent by BackStyle property and group it to a shape (bring the TB forward) and still use the TextBox1_Change method for changes.
If you need to access the value in the TextBox somewhere else, a quick way is to use TextBox1.LinkedCell and below to set the value to a cell, or a Named Range.
Private Sub TextBox1_Change()
' Same Sheet as TextBox1
ActiveSheet.Range(TextBox1.LinkedCell).Value = TextBox1.Value
' Or Below for Named Range
ThisWorkbook.Names(TextBox1.LinkedCell).RefersToRange.Value = TextBox1.Value
End Sub

How to manipulate the selected objects on screen in AUTOCAD using VBA?

In autocad 2008, I want to learn how to operate the screen selected objects. There is a VBA object named ThisDrawing.SelectionSets, but it is a sets of selections, not the selected objects which are selected by user. Which VBA object represents the user selected objects?
There is also a "built-in" selection set you can use that represents the currently selected objects.
Public Sub test()
Dim ss As AcadSelectionSet
Set ss = ThisDrawing.ActiveSelectionSet
MsgBox ss.Count
End Sub
You actually need to create your own Selection Set and add it to ThisDrawing.SelectionSets.
Then when the user clicks on an entity you need to add it to the Selection Set you created.
Finally, you can then step through every entity in the Selection Set to perform some manipulation on it.
I'm sorry I can't offer VBA code as I use C# but this is the process that you need to follow. You can however get help from within AutoCAD itself by hitting F1 and then looking under:
ActiveX and VBA Developer's Guide -> Create and Edit AutoCAD Entities -> Work with Selection Sets