Powerpoint VBA - adjust positions of chart and axis titles - vba

I have the following code:
Sub StandardiseChart(ByVal control As IRibbonControl)
Dim activeShape As Shape
'Determine Which Shape is Active
If ActiveWindow.Selection.Type = ppSelectionShapes Then
'Loop in case multiples shapes selected
Dim shp As Shape
For Each shp In ActiveWindow.Selection.ShapeRange
Set activeShape = shp ' First shape selected
Exit For
Next
'Now, reformat the selected shape if it is a chart
With activeShape
If .HasChart Then
' Chart title
.Chart.HasTitle = True
With .Chart.ChartTitle
.Left = 0
.Top = 0
End With
' Y axis
With .Chart.Axes(xlValue, xlPrimary)
.HasTitle = True
.AxisTitle.Text = "Placeholder"
.AxisTitle.Left = 0
.AxisTitle.Top = 20
.AxisTitle.Orientation = 0
End With
' Plot Area
With .Chart.PlotArea
.Left = 10
.Top = 50
End With
End If
End With ' activeShape
End If
End Sub
What I'd like it to do is 3 things:
Pin the Chart Title to the top left corner of the entire object (this seems fine)
Set the y-axis title so that there is 20pt of space between it and the chart title (also seems fine)
Create a further 50pt of space between the plot area and the y-axis title (not fine).
No matter what I do (I've tried adjusting the number to 70 rather than 50, and even bigger), I can't seem to adjust the space to achieve (3). Specifically, the plot area doesn't move no matter what I do.
What am I doing wrong?

If you add a dot to the end of Chart.Plotarea, you can see the list of methods. In your case, you're looking for .InsideLeft and .InsideTop, since you want to adjust the inside distance from the chart area:
With .Chart.PlotArea
.InsideLeft = 70
.InsideTop = 70
End With

Related

How to remove pictures located at specific position(eg. top-right cornor) from every PPT slide

I have many powerpoint files which have a picture at the top-right corner on every single slide. It is neither a master slide, NOT a custom layout shape.
They were pasted one by one to all slides.
I have some codes as below to remove all shapes(pictures) from slides, but how to locate the shapes(pictures) at a specific location of a slide?
For Each Slide In SlideList
Set sldTemp = ActivePresentation.Slides(Slide)
For lngCount = sldTemp.Shapes.Count To 1 Step -1
With sldTemp.Shapes(lngCount)
'----------Delete All shapes = picture----------
If .Type = msoPicture Then
.Delete
End If
End With
Next
Next
'-----------------------------------------
I am not very good at VBA for powerpoint coding, any suggestion is appreciated.
thank you.
You can check the position by looking at the Top and Left properties. You could also check the size if they're all the same size.
Eg:
If .Type = msoPicture Then
If .Top > x and .Top < y and .Left > a and .Left < b Then
.Delete
Exit For
End If
End If
Where x,y, a and b are variables or hard-coded values.
thanks to Tim Williams very much.
The pilot codes run correctly on 3 Win10 x86 computers.
by the way, according to this saying
By default, the size of the new presentation in PowerPoint, is currently a widescreen type presentation, 13.333 inch by 7.5 inch. Mostly you will have 96 dots per inch (dpi) on your screen settings, so this means that a default PowerPoint presentation has a resolution of 1280 by 720 pixels.
though the top-left values set below can match exactly the top-right small logo(shape) in my powerpoint slide, and the same results from 3 different display ,and one of which is in low definition mode.
Sub DeleteAllTopRightShapes()
Dim sldTemp As Slide
Dim lngTemp As Long
Dim lngCount As Long
For Each sldTemp In ActivePresentation.Slides
For lngCount = sldTemp.Shapes.Count To 1 Step -1
With sldTemp.Shapes(lngCount)
If .Type = msoPicture Then
If .Top >= 0 And .Top < 60 And .Left >= 400 Then
.Delete
End If
End If
End With
Next
Next
MsgBox "Process complete!"
End Sub

Change the text color of the chart title in a PowerPoint Histogram chart

I am trying to change the text color of the chart title of a histogram chart in PowerPoint.
Here is what I do:
var colorFormat = chart.ChartTitle.Format.TextFrame2.TextRange.Font.Fill.ForeColor;
colorFormat.RGB = ...;
// or
colorFormat.ObjectThemeColor = ...;
This works for the standard charts like line charts. But it doesn't work for other chart types like histogram, waterfall, tree map etc.
In these cases, setting ObjectThemeColor sets the text to black. Setting RGB does actually set the correct color. However, in both cases, as soon as the user changes the selection, the text color jumps back to the one it had previously.
How can I set the text color of the title of one of these charts?
I am using VSTO and C# but a VBA solution is just as welcome as long as it can be translated to C# and still work.
Based on what info you gave I built a histogram and waterfall chart in PowerPoint and was successful using:
Sub ChartTitleFontColor()
Dim oShp As Shape
Dim oCht As Chart
'Waterfall on slide 1
Set oShp = ActivePresentation.Slides(1).Shapes(1)
If oShp.HasChart Then
Set oCht = oShp.Chart
End If
' Do stuff with your chart
If oCht.HasTitle Then
Debug.Print oCht.ChartTitle.Text
oCht.ChartTitle.Format.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(251, 5, 40)
End If
'Histogram on slide 2
Set oShp = ActivePresentation.Slides(2).Shapes(1)
If oShp.HasChart Then
Set oCht = oShp.Chart
End If
' Do stuff with your chart
If oCht.HasTitle Then Debug.Print oCht.ChartTitle.Text
oCht.ChartTitle.Format.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(251, 5, 40)
End If
' Clean up
Set oShp = Nothing
Set oCht = Nothing
End Sub
Your code works in my test. I created two charts in PowerPoint 2016, the first one a waterfall, and the second another type. The following code changes the title color only (and text just a proof of it being changed) and nothing else. I can select the other chart and nothing changes. I could not find a bug about this in a search. Perhaps something in the remaining code is changing it back?
Sub test()
Dim myPresentation As Presentation
Set myPresentation = ActivePresentation
Dim myShape As Shape
Set myShape = myPresentation.Slides(1).Shapes(1)
Dim theChart As Chart
If myShape.HasChart Then
Set theChart = myShape.Chart
If theChart.ChartTitle.Text = "This is blue" Then
theChart.ChartTitle.Text = "This is yellow"
theChart.ChartTitle.Format.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(255, 255, 0)
Else
theChart.ChartTitle.Text = "This is blue"
theChart.ChartTitle.Format.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(0, 255, 255)
End If
End If
End Sub
This is not exactly an answer but I think you should name your object.
Instead of using
ActivePresentation.Slides(1).Shapes(1)
You can name the object.

VBA Word Shape location - top left corner

I have written a small function, based on example provided by producer of Stroke Scribe ActiveX object. This is an plugin which allows us to create in Microsoft Word by VBA Macro an QR Code object.
The problem is with setting up a shape location
shp.Left = 0 + LeftMargin
shp.Top = 0 + TopMargin
I would like to put this shape (QR Code) on specific page on the most left top corner. But sometimes shape jumps to previous page (on bottom) or other location (vertical center).
Can you help me recognize a problem and fix it to locate Shape Object every time top left corner?
Code:
Sub QRCodeGenerator(SOP, BookmarkID, Page, TopMargin, LeftMargin)
Dim doc As Document
Set doc = Application.ActiveDocument
For Each sh In doc.Shapes
If sh.Type = msoOLEControlObject Then
If sh.OLEFormat.ProgID = "STROKESCRIBE.StrokeScribeCtrl.1" Then
sh.Delete
End If
End If
Next
With doc.PageSetup
usable_w = .PageWidth
usable_h = .PageHeight
End With
Dim pg As Range
Set pg = doc.GoTo(wdGoToPage, wdGoToRelative, Page)
Dim shp As Shape
Set shp = doc.Shapes.AddOLEControl(ClassType:="STROKESCRIBE.StrokeScribeCtrl.1", Anchor:=pg)
Dim sMyString As String
sMyString = ActiveDocument.Bookmarks(BookmarkID).Range.Text
sMyString = Replace(sMyString, "FORMTEXT ", "")
shp.LockAspectRatio = msoFalse
shp.Height = InchesToPoints(0.6)
shp.Width = shp.Height
shp.Left = 0 + LeftMargin
shp.Top = 0 + TopMargin ' // usable_h - shp.Height * 3 + TopMargin
Dim ss As StrokeScribe
Set ss = shp.OLEFormat.Object
ss.Alphabet = QRCODE 'StrokeScribe will draw a QR code picture
ss.Text = SOP & ";" & sMyString 'Any text you want to encode in the barcode
ss.QrECL = H 'Changes the default error correction level. This can be omitted
ss.QrMinVersion = 3 'Specifies the minimum barcode size. This can be omitted
ss.FontColor = RGB(0, 0, 0)
' ss.UTF8 = True 'Enable this, if you want to encode national characters for smartphones
If ss.Error Then
MsgBox ss.ErrorDescription
End If
End Sub
Word SHAPE objects must be anchored to a Range. The page location of that Range determines on which page the Shape will display. There's nothing you can do to "lock" a Shape to a particular page.
That said, it is possible to dictate that a Shape always appears in the same location on whichever page the anchoring Range lies.
This is always tricky if you add such a Shape before document editing is finished, because editing can move the anchoring paragraph to a different page. It can help to choose a paragraph as the anchor that's unlikely to move, for example perhaps the first paragraph on the page.
Something I did once, long ago, was write a macro that checks the page locations of Shapes before printing or saving. When inserting and positioning the Shape, I give it a Name that includes the page number. Before printing/saving the macro checks the page number in the Shape name with the page on which the Shape is located. If the two don't match, CUT the Shape and PASTE it to a paragraph on the correct page (it remembers its position settings).
The code sample below demonstrates how to name the Shape, lock the anchor to a specific paragraph and position the Shape flush to the top, left corner of the page.
Sub ShapePosTopLeft()
Dim doc As word.Document
Dim shp As word.Shape
Dim rng As word.Range
Set doc = ActiveDocument
Set rng = doc.GoTo(wdGoToPage, wdGoToRelative, Page)
Set rng = rng.Paragraphs(1).Range
Set shp = doc.Shapes.AddOLEControl(ClassType:="STROKESCRIBE.StrokeScribeCtrl.1", Anchor:=rng)
With shp
.Name = "Shape_Page" & Page
.LockAnchor = True
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Left = 0
.Top = 0
End With
End Sub

VBA PowerPoint Display and Hide Shapes

I have several PowerPoint slides with objects (arrows and rectangles) I like to display and hide. At the moment I just use
ActivePresentation.Slides("Slide100").Shapes("Rectangle 99").Visible = False or True
ActivePresentation.Slides("Slide100").Shapes("Straight Arrow Connector 118").Visible = False or True
Now it can be that one rectangle or arrow has to be deleted in that template. This leads to VBA errors when you run the macro because the rectangle or arrow couldn't be found. Is there any way to write a macro to check all the used rectangles and arrows and then hides or displays them all instead of using single variables?
I found something like this:
For Each sObject In ActivePresentation.Slides(2).Shapes
sObject.Visible = False
Next
But I just need to hide rectangles and arrows, nothing more.
Best regards
Peter
Take that loop as a starting point and apply some logic within it. There are two properties of the shape that could be useful, autoshapetype and name
Two examples below:
For Each shp In ActivePresentation.Slides(x).Shapes
If InStr(1, shp.Name, "Rectangle") > 0 Then
shp.Visible = False
End If
Next shp
or
For Each shp In ActivePresentation.Slides(x).Shapes
If shp.AutoShapeType = msoShapeRectangle Then
shp.Visible = False
End If
Next shp
This will hide all rectangle types and a subset of arrow types across all slides in the active presentation:
' PowerPoint VBA Macro
' Purpose : hide rectangles and shapes across slides
' Written by : Jamie Garroch of YOUpresent Ltd. http://youpresent.co.uk.
Sub HideRectanglesAndArrows()
Dim oSld As Slide
Dim oShp As Shape
For Each oSld In ActivePresentation.Slides
For Each oShp In oSld.Shapes
If oShp.Type = msoAutoShape Then
Select Case oShp.AutoShapeType
' Basic Arrows (4)
Case msoShapeUpArrow, msoShapeDownArrow, msoShapeLeftArrow, msoShapeRightArrow
oShp.Visible = msoFalse
' Double Arrows (2)
Case msoShapeUpDownArrow, msoShapeLeftRightArrow
oShp.Visible = msoFalse
' Add other arrow types as required
'
' Basic Rectangles (1)
Case msoShapeRectangle
oShp.Visible = msoFalse
' Rounded Rectangles (4)
Case msoShapeRound1Rectangle, msoShapeRound2DiagRectangle, msoShapeRound2SameRectangle, msoShapeRoundedRectangle
oShp.Visible = msoFalse
' Snipped Rectangles (4)
Case msoShapeSnip1Rectangle, msoShapeSnip2DiagRectangle, msoShapeSnip2SameRectangle, msoShapeSnipRoundRectangle
oShp.Visible = msoFalse
End Select
End If
Next
Next
End Sub
You can then add logic to delete specific shapes using the .Name property or position properties (.Left, .Top) or size properties (.Width, .Height). If you want o be more elaborate (users can change the names of shapes) then you could add Tags to shapes to identify them in a way that the user cannot change and then write a procedure to check the .Tags property in your logic.

VBA: Left and bottom align 2 shapes, then delete the shape in thebackground

I am searching for a way to perform the following operation on two shapes that are selected in powerpoint.
Take the shape in the foreground (i.e. the shape that is more in the front) of the two shapes and left and bottom align it with the one that is in the background.
2. Delete the shape in the background.
What I have got so far is the operation for the bottom and left align which looks as follows:
Sub LeftandBottom_Align()
ActiveWindow.Selection.ShapeRange.Align msoAlignLefts, False
ActiveWindow.Selection.ShapeRange.Align msoAlignBottoms, False
End Sub
How do i get the delete-part done?
A little bit of basic explanation would be great
You can delete the rearmost shape like so:
Dim oBackShape As Shape
With ActiveWindow.Selection
' Get a reference to the rearmost of the two selected shapes
' so you can use it later to delete the shape
If .ShapeRange(1).ZOrderPosition > .ShapeRange(2).ZOrderPosition Then
Set oBackShape = .ShapeRange(2)
Else
Set oBackShape = .ShapeRange(1)
End If
' Align the shapes
' .Align may not always work the way you'd expect it to
' so if not, ask
.ShapeRange.Align msoAlignLefts, False
.ShapeRange.Align msoAlignBottoms, False
End With
' Delete the rearmost shape
oBackShape.Delete
You can use Shapes ZOrderPosition Property to determine which shape is in the background
Sub LeftandBottom_Align()
ActiveWindow.Selection.ShapeRange.Align msoAlignLefts, False
ActiveWindow.Selection.ShapeRange.Align msoAlignBottoms, False
Dim i As Integer
i = 2 'Assuming two shapes
While i >= 1
With ActiveWindow.Selection.ShapeRange(i)
If (.ZOrderPosition = 1) Then
.Delete
Exit Sub
End If
i = i - 1
End With
Wend
End Sub