Changing Shape Color in Visio - shapes

Need some help!
I'm relatively knowledgeable when it comes to macros, VBA, scripts, etc., but Visio coding is an all new monster to me.
In short, I have a warehouse map layout with simple square shapes marking product locations, and I want to color-code the squares based on their Prop._VisDM_F2 data element. My code so far seems to work, but only for the 1st shape in the group of squares, but sometimes the master shape consists of 1 square, sometimes 6, and everything in between.
I've learned that the # in "Shapes(#)" selects which square gets changed, but I want them ALL to change. I've tried to get a count of how many individual shapes are in each master shape to use a variable integer as the #, but it didn't work.
Surely such a simple task can't really this complicated so I'm probably just missing something a step. Any help would be greatly appreciated!
'''
Dim selectObj As Visio.Shape
For Each selectObj In ActiveWindow.Selection
If selectObj.CellExistsU("Prop._VisDM_F2", Visio.VisExistsFlags.visExistsAnywhere) Then
selectObj.Shapes(1).Cells("Fillforegnd").FormulaU = visWhite
End If
Next
End Sub
'''

Shapes can have sub-shapes which are accessed through the Shapes property as per your code (note that most Visio collections are 1 rather than 0 based).
You can address the sub-shapes collection either by index or with a further for each. So given that you may or may not know the depth of your sub-shapes you can recurse through them something like this:
Sub ApplyFillToAll()
Dim shp As Visio.Shape
For Each shp In ActiveWindow.Selection
If shp.CellExistsU("Prop._VisDM_F2", Visio.VisExistsFlags.visExistsAnywhere) Then
SetFill shp, "RGB(255,0,0)"
End If
Next
End Sub
Public Sub SetFill(ByRef shpIn As Visio.Shape, fillFormula As String)
Dim shp As Visio.Shape
For Each shp In shpIn.Shapes
shp.Cells("FillForegnd").FormulaU = fillFormula
SetFill shp, fillFormula
Next
End Sub
Note that the formula that you're setting is a string and so is wrapped in double quotes, and the above will set all of the sub-shapes to red with the SetFill method calling itself to navigate down through the tree.
I'll add a link to a very old post that you might also find useful:
https://visualsignals.typepad.co.uk/vislog/2007/11/looping-through.html

Related

How can I select all in Powerpoint VBA?

I have been struggling for a while to find a VBA code to select all the slides and all the shapes of a presentation (for some reason this seems to be of no one's interest). I have tried to set up a range with all the slides and then select all the shapes of the range, but that does not work. I also try looping slide by slide and accumulate the selection (msoFalse), but for that you also need to activate each slide and I was unable to do that.
I think selecting all the slides and shapes at once is useful to manipulate the fonts or run a full spell check. Your help would be really appreciated!!
Selecting objects in VBA is generally to be avoided. It's unreliable and slow. Instead, loop through every shape on every slide and perform whatever operation you need:
Sub DoStuffToShapes()
Dim oSlide as Slide
Dim oShape as Shape
For each oSlide in ActivePresentation.Slides
For each oShape in oSlide.Shapes
'Do stuff to the shape
Next oShape
Next oSlide
End Sub
If you've created a font theme and applied it to the Slide Master and Layouts, it's usually easier and faster to change fonts by modifying the theme and/or master rather than using VBA. VBA isn't needed for a spellcheck either.

Is it possible to update only a selected linked object in PPT?

I'm trying to build a macro which will update only the selected linked object within a PowerPoint, but I cannot figure out how to do it.
The first part below is what I've used to update all linked objects, but I am currently dealing with massive Excel files, and presentations with 200+ linked objects, so one-at-a-time updating is the only way to go unfortunately.
The second part is what I was hoping would work.
First part:
Dim sld As Slide
Dim sh As Shape
For Each sld In ActivePresentation.Slides
For Each sh In sld.Shapes
If sh.Type = msoLinkedOLEObject Then
sh.LinkFormat.Update
End If
Next
Next
Second part:
With ActiveWindow.Selection
.LinkFormat.Update
EndWith
I'm pretty inexperienced with PPT VBA, so please bear with me. Is it possible to build something like this? (It's going to be part of a more complicated macro, so it ultimately will be more convenient than just Right Click + Update Link)
Give this a try:
Sub UpdateOLELink()
ActiveWindow.Selection.ShapeRange.LinkFormat.Update
End Sub

Word macro to set image layout and size

I'm trying to record a macro that will set the size of a pasted image to 6.5 x 4 cms and the image layout 'in front of text'. I usually set this by right clicking on the image and setting the picture properties but this isn't available when recording the macro. Using Shift-F10 does bring up the menu, but the option to set the image layout properties is greyed out.
Please help!
Thanks
Yes, that's interesting about the macro recorder...
If you need to do something like this in the future it will help you to know that an object with any kind of "text wrap" formatting (that "floats") is a Shape. An object that behaves like a character is an InlineShape. And you can convert between the two using ConvertToInlineShape / ConvertToShape. For future things of this nature that should give you a starting point :-)
The following code sample uses ConvertToShape so that text wrap formatting can be applied. (The conversion is an extra step involved that you don't have to do in the UI - Word does it for you.)
Before this happens the code changes the size, but it could also be the other way around, changing the size on the Shape object.
What else is happening in the code: When a picture is pasted inline it's not selected. So this code figures out how many pictures (InlineShapes) are already in the document up to the selection. After the paste the code then picks up the existing number of pictures up to that point, plus one, to get the picture that was just pasted.
The code uses CentimetersToPoints to convert the number of centimeters wanted to the Points measurement, since that's what Word uses to size graphical objects (and lots of other things).
How did I know to use wdWrapFront: When shp.WrapFormat.Type = is typed the VBA Editor will automatically show a list of valid entries for text wrap formatting. Similarly, when shp. is typed a list of valid properties for a Shape will appear, and so on. (This is called IntelliSense and is a wonderful help!)
Sub PasteAndSelectPicture()
Dim ils As Word.InlineShape
Dim shp As Word.Shape
Dim lNrIls As Long
Dim rngDoc As Word.Range
Dim rngSel As Word.Range
Set rngDoc = ActiveDocument.content
Set rngSel = Selection.Range
rngDoc.End = rngSel.End + 1
lNrIls = rngDoc.InlineShapes.Count
rngSel.Paste
' Debug.Print rngDoc.InlineShapes.Count, lNrIls
Set ils = rngDoc.InlineShapes(lNrIls + 1)
ils.width = CentimetersToPoints(6.5)
ils.height = CentimetersToPoints(4)
Set shp = ils.ConvertToShape
shp.WrapFormat.Type = wdWrapFront
End SUb

VBA: delete borders from floating images in ms-Word

I have this code to put a border on all images in my Word document. Inline shapes as floating shapes. Works fine. All images have a border. But my images on the first page (like Logo) also have a border.
Can anyone help me out with code for deleting the borders around floating images on the front page? Or specific shapes?
Thank you.
Kem
The Selection.Information(wdActivePageEnd) command can give you the current page number and in your case all you need to do is set the current selection point or working range to the top of the document ... and now you know you are on page 1.
The second challenge is selecting or setting a working range to only the first page. I use the built-in Bookmark "\Page".
The third challenge is identifying the type of shape and for that you use the Shape.Type property. If you are going after images remember they could be embedded or linked so you have to use the two property types.
Finally, in your questions you are asking how to remove borders. Well IMO you don't have to remove them, you only hide them.
Here is example code that you can study and figure out how to integrate with your existing code.
Sub RemoveBorders()
Dim rng As Word.Range, shp As Word.Shape
Set rng = ActiveDocument.Content
rng.Collapse Word.WdCollapseDirection.wdCollapseStart
Set rng = ActiveDocument.Bookmarks("\Page").Range
For Each shp In rng.ShapeRange
If shp.Type = msoPicture Or shp.Type = msoLinkedPicture Then
shp.Line.Visible = False
End If
Next
End Sub

Visio VBA : Connect a line shape to two other shapes

I am dropping shapes on my Page via VBA UserForms. Amongst others I need to drop a "curved line" shape which should connect two specified shapes.
I found out how to directly create a connection here but I want the shape from my specific master because it has some custom Data Properties.
I expected there to be some Fields in the DataSheet of the Connector-Shape where I could reference the start and end shapes? could not find anything more helpful.
Thanks for any hints!
Solution from here
Dim shp As Visio.Shape 'connector
Dim src As Visio.Shape 'connect this
Dim aim As Visio.Shape 'to this
[...] 'Set shape variables
shp.Cells("BeginX").GlueTo src.Cells("PinX")
shp.Cells("EndX").GlueTo aim.Cells("PinX")