How can I select each shapes in loop? - vba

Powerpoint 2010
I am trying to select on each new shape in the loop. But not all shapes in loop are selected. Always only the last shape is selected. What is wrong?
Thank you
Private Sub AddShapeRectangleOnSelectedText()
Dim oText As TextRange
Dim linesCount As Integer
Dim myDocument As Slide
Dim i As Integer
Dim s As Shape
' Get an object reference to the selected text range.
Set oText = ActiveWindow.Selection.TextRange
Set myDocument = ActiveWindow.View.Slide
linesCount = oText.Lines.Count
For i = 1 To linesCount
Set s = myDocument.Shapes.AddShape(msoShapeRectangle, _
oText.Lines(i).BoundLeft, oText.Lines(i).BoundTop, oText.Lines(i).BoundWidth, oText.Lines(i).BoundHeight)
With s
.Select
.Fill.Visible = msoTrue
.Fill.Solid
.Fill.ForeColor.RGB = RGB(255, 255, 153)
.Fill.Transparency = 0.7
.Line.Visible = msoFalse
.Line.Transparency = 0#
End With
Next
End Sub

Select has an optional parameter to indicate whether the selection should replace the previous selection or not...
you can modify your code like this
.Select IIf(i = 1, True, False)

Related

Find some shapes by name, other shapes by specific color and delete them

I have a few presentations with shapes I need to delete, with
specific .Name
specific color
Those shapes with specific .Name can be grouped (not in my code). I found code in stackoverflow and tried to modify it.
Find shape by name and delete it: Specific .Name can be "XXName1" as well "Name1".
If there are no shapes with .Name = "Name1" I get an Error
"Object does not exist"
on the line If .Name = "Name1" Or .Name = "Name2" Then
Sometimes the code works, and then, if there are a lot slides in the presentation, I have an error.
When I test with a 1-slide presentation - no error.
Find shape by color and delete it:
I have an Error
"Object variable or With block variable not set"
I don't understand how to declare variable
Sub DeleteShapes()
Dim oSld As Slide
Dim oShp As Shape
Dim oshpGroup As Shape
Dim Y As Long
Dim L As Long
Dim str As String
For Each oSld In ActivePresentation.Slides
For L = oSld.Shapes.Count To 1 Step -1
With oSld.Shapes(L)
' Find shape by name and delete it
If .Name = "XXName1" Or .Name = "XXName2" Then
.Delete
End If
If .Name = "Name1" Or .Name = "Name2" Then
.Delete
End If
' Find shape by color and delete it
If oShp.Fill.ForeColor.RGB = RGB(0, 0, 0) Or _
oShp.Fill.ForeColor.RGB = RGB(1, 1, 1) Or _
oShp.Fill.ForeColor.RGB = RGB(2, 2, 2) Or _
oShp.Fill.ForeColor.RGB = RGB(3, 3, 3) Then
oShp.Delete
End If
End With
Next L
Next oSld
End Sub
You can't refer to a shape after you've deleted it (which you've done
previously). Change your sequential If...End If, If...End If to
If...ElseIf....ElseIf...End If. – #BigBen
My revised code:
Sub DeleteShapes()
Dim oSld As Slide
Dim oShp As Shape
Dim L As Long
For Each oSld In ActivePresentation.Slides
For L = oSld.Shapes.Count To 1 Step -1
With oSld.Shapes(L)
If .Name = "XXName1" Or .Name = "XXName2" Then
.Delete
ElseIf .Name = "Name1" Or .Name = "Name2" Then
.Delete
ElseIf .Fill.ForeColor.RGB = RGB(0, 0, 0) Then
.Delete
ElseIf .Fill.ForeColor.RGB = RGB(1, 1, 1) Then
.Delete
ElseIf .Fill.ForeColor.RGB = RGB(2, 2, 2) Then
.Delete
ElseIf .Fill.ForeColor.RGB = RGB(3, 3, 3) Then
.Delete
End If
End With
Next L
Next oSld
End Sub

find the next shape with a special tag

For internal communication purposes in a group of people I have created a macro adding comment fields to a slide - not those of PPT itself.
Dim shp As Shape
Dim sld As Slide
'Comment field
On Error GoTo ErrMsg
If ActiveWindow.Selection.SlideRange.Count <> 1 Then
MsgBox "This function cannot be used for several slides at the same time"
Exit Sub
Else
Set sld = Application.ActiveWindow.View.Slide
Set shp = sld.Shapes.AddShape(Type:=msoShapeRectangle, Left:=0, Top:=104.88182, Width:=198.42507, Height:=28.913368)
shp.Fill.Visible = msoTrue
shp.Fill.Transparency = 0
shp.Fill.ForeColor.RGB = RGB(211, 61, 95)
shp.Line.Visible = msoTrue
shp.Line.ForeColor.RGB = RGB(255, 255, 255)
shp.Line.Weight = 0.75
shp.Tags.Add "COMMENT", "YES"
shp.Select
shp.TextFrame.TextRange.Font.Color.RGB = RGB(255, 255, 255)
shp.TextFrame.TextRange.Characters.Text = "Comment: "
shp.TextFrame.TextRange.Paragraphs.ParagraphFormat.Alignment = ppAlignLeft
shp.TextFrame.VerticalAnchor = msoAnchorTop
shp.TextFrame.TextRange.Font.Size = 12
shp.TextFrame.TextRange.Font.Name = "Arial"
shp.TextFrame.TextRange.Font.Bold = msoTrue
shp.TextFrame.TextRange.Font.Italic = msoFalse
shp.TextFrame.TextRange.Font.Underline = msoFalse
shp.TextFrame.Orientation = msoTextOrientationHorizontal
shp.TextFrame.MarginBottom = 7.0866097
shp.TextFrame.MarginLeft = 7.0866097
shp.TextFrame.MarginRight = 7.0866097
shp.TextFrame.MarginTop = 7.0866097
shp.TextFrame.WordWrap = msoTrue
shp.TextFrame.AutoSize = ppAutoSizeShapeToFitText
shp.TextFrame.TextRange.Select
End If
Exit Sub
ErrMsg:
MsgBox "Please select a slide"
End Sub
Works well.
I have tagged them, because I want it to be easy to delete all of them at once, e.g., in case you find comments 5 minutes before you have to present. Here's my way to delete them:
Sub CommDel()
Dim sld As Slide
Dim L As Long
If MsgBox("Do you want to delete ALL comments from the entire presentation?", vbYesNo) <> vbYes Then Exit Sub
On Error Resume Next
For Each sld In ActivePresentation.Slides
For L = sld.Shapes.Count To 1 Step -1
If sld.Shapes(L).Tags("COMMENT") = "YES" Then sld.Shapes(L).Delete
Next L
Next sld
End Sub
Works fine, too.
Third step I would like to do, is creating a third macro, called "find next comment". On every click it jumps to the next shape tagged with the tag "COMMENT", no matter if that shape is on the same slide or the next or somewhere else in the presentation. Just the next one, where ever it is. And now I'm completely lost. I am able to do something to all tagged shapes on one slide or inthe entire presentation - as you can see in the function to delete. But what I'm looking for is not selecting all shapes at the same time. In another try I was able to find the first one - but after clicking the macro again nothing seemed to happen, because the macro started searching at the same point and selected the same shape again and again, never jumping to the next one, except I deleted the first one.
Would be great to read your ideas. Thank you in advance. But be careful, I'm far from being a good programmer. ;-)
This starts at the current slide and works toward the end, dropping out of the Sub as soon as the first comment is found:
Sub FindNextComment()
Dim oSlide As Slide
Dim oShape As Shape
Set oSlide = ActiveWindow.View.Slide
For Each oShape In oSlide.Shapes
If oShape.Tags.Count > 0 Then
For y = 1 To oShape.Tags.Count
If oShape.Tags.Name(y) = "COMMENT" Then
oShape.Select
Exit Sub
End If
Next y
End If
Next oShape
For x = oSlide.SlideIndex + 1 To ActivePresentation.Slides.Count
For Each oShape In ActivePresentation.Slides(x).Shapes
If oShape.Tags.Count > 0 Then
For y = 1 To oShape.Tags.Count
If oShape.Tags.Name(y) = "COMMENT" Then
ActivePresentation.Slides(x).Select
oShape.Select
Exit Sub
End If
Next y
End If
Next oShape
Next x
End Sub
Bonus VBA Tip: You can make your code run a little faster by using With statements:
With shp.TextFrame
.MarginBottom = 7.0866097
.MarginLeft = 7.0866097
.MarginRight = 7.0866097
.MarginTop = 7.0866097
.WordWrap = msoTrue
.AutoSize = ppAutoSizeShapeToFitText
.Orientation = msoTextOrientationHorizontal
.VerticalAnchor = msoAnchorTop
With .TextRange
.Characters.Text = "Comment: "
.Paragraphs.ParagraphFormat.Alignment = ppAlignLeft
With .Font
.Size = 12
.Name = "Arial"
.Bold = msoTrue
.Italic = msoFalse
.Underline = msoFalse
End With
End With
End With

PowerPoint VBA Recognizing Shapes in a Grouping

I am trying to create a simple PowerPoint file to capture a series of milestones for a project portfolio. I have created the following Macro to create the milestone visual and group the shapes. However, I am looking to create another macro for updating/statusing the milestone. Specifically, I want the user to select the group and then run a macro to that will allow the user to update the date and move the shapes accordingly or, if the task is complete, fill in the shape.
I struggle with the initiation of the update macro to identify the shapes and its' content to complete the calculation. For example, I don't know how to read in the date in to move the milestone left/right based on the new date. Any help is appreciated!
Code:
Private Sub EnterTask_Click()
Dim Sld As Slide
Dim shapeMile As Shape
Dim shapeTask As Shape
Dim shapeECD As Shape
Dim dateECD As String
Dim taskText As String
Dim StatusBox As Shape
dateECD = "6/12/18"
taskText = "Task #1"
Set Sld = Application.ActiveWindow.View.Slide
With Sld
'Create shape with Specified Dimensions and Slide Position
Set shapeMile = Sld.Shapes.AddShape(Type:=msoShapeIsoscelesTriangle, _
Left:=25, Top:=150, Width:=15, Height:=15)
With shapeMile
.Rotation = 180
.Tags.Add "Milestone", "Bug"
.Line.Visible = msoTrue
.Fill.Visible = msoFalse
.Shadow.Visible = msoFalse
End With
Set shapeECD = Sld.Shapes.AddTextbox(msoTextOrientationHorizontal, _
Left:=8, Top:=165, Width:=50, Height:=30)
With shapeECD
.Tags.Add "Milestone", "ECD"
.Line.Visible = msoFalse
.Fill.Visible = msoFalse
.Shadow.Visible = msoFalse
.TextFrame.TextRange.Characters.Text = dateECD
.TextFrame.TextRange.Paragraphs.ParagraphFormat.Alignment = ppAlignCenter
.TextFrame.VerticalAnchor = msoAnchorTop
.TextFrame.HorizontalAnchor = msoAnchorCenter
.TextFrame.TextRange.Font.Size = 8
.TextFrame.TextRange.Font.Name = "Arial"
.TextFrame.TextRange.Font.Italic = msoFalse
.TextFrame.TextRange.Font.Color.RGB = RGB(0, 0, 0)
End With
Set shapeTask = Sld.Shapes.AddTextbox(msoTextOrientationHorizontal, _
Left:=8, Top:=135, Width:=50, Height:=30)
With shapeTask
.Tags.Add "Milestone", "Task"
.Line.Visible = msoFalse
.Fill.Visible = msoFalse
.Shadow.Visible = msoFalse
.TextFrame.TextRange.Characters.Text = taskText
.TextFrame.TextRange.Paragraphs.ParagraphFormat.Alignment = ppAlignCenter
.TextFrame.VerticalAnchor = msoAnchorTop
.TextFrame.HorizontalAnchor = msoAnchorCenter
.TextFrame.TextRange.Font.Size = 8
.TextFrame.TextRange.Font.Name = "Arial"
.TextFrame.TextRange.Font.Italic = msoFalse
.TextFrame.TextRange.Font.Color.RGB = RGB(0, 0, 0)
End With
.Shapes.Range(Array(shapeMile.Name, shapeECD.Name, shapeTask.Name)).Group
End With
End Sub

Add a TextBox below an Inline Shape on MS Word using VBA

I'm trying to insert a textbox below a chosen image with Inline text wrapping and position it at the left bottom of the image. I'm using the below code without much success. I'm not too sure whether to use a ShapeRange or an InlineShape. Any pointers?
Dim shp As Object
'Set shp = Selection.ShapeRange(1)
'Set rng = shp.Anchor
Set shp = Selection.InlineShapes(1)
Set rng = shp.Range
With ActiveDocument.Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, Left:=shp.Left, Top:=(shp.Top + shp.Height), Width:=shp.Width / 3, Height:=shp.Height / 6, Anchor:=rng)
.TextFrame.TextRange.Font.Size = 14
.TextFrame.TextRange.Font.Color = RGB(186, 14, 29)
.TextFrame.TextRange.Font.Name = "Sabon MT"
.TextFrame.TextRange = "T"
End With
I managed to find a solution for getting the coordinates for the shape from here: http://www.vbaexpress.com/forum/archive/index.php/t-48831.html
Here's my code:
Sub AddTextBox
Set shp = Selection.InlineShapes(1)
Set rng = shp.Range
Set tb = ActiveDocument.Shapes.AddTextbox(1, fcnXCoord, fcnYCoord + shp.Height, shp.Width, shp.Height / 6)
End Sub
Function fcnXCoord() As Double
fcnXCoord = Selection.Information(wdHorizontalPositionRelativeToPage)
End Function
Function fcnYCoord() As Double
fcnYCoord = Selection.Information(wdVerticalPositionRelativeToPage)
End Function

Change font colour of a textbox

I want to open an Excel file, go to the first sheet in the file, and change the text colour of textbox1 to red.
The only way I have managed to do it so far is via recording the macro.
It gives me
Workbooks.Open (fPath & sName)
Sheets(1).Select
ActiveSheet.Shapes.Range(Array("TextBox1")).Select
With Selection.ShapeRange(1).TextFrame2.TextRange.Characters(1, 262).Font.Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 0, 0)
.Transparency = 0
.Solid
End With
That's fine; however the length of the text is variable so I get an error with the code if it is less than the 262 characters above.
I tried to introduce
CharCount = Len(textbox1.Text)
However I get error 424 Object required
I initially tried
Sheets(1).Select
ActiveSheet.TextBox1.ForeColor = RGB(255, 0, 0)
but got error 438 Object doesn't support this property or method.
If you want to change the font colour of the entire textbox (i.e. not just certain characters) then skip the Characters method. Also you shouldn't rely on .Select, ActiveSheet and the likes. Set proper references instead.
This works:
Dim wb As Workbook
Dim ws As Worksheet
Dim s As Shape
Set wb = Workbooks.Open(fPath & sName)
Set ws = wb.Sheets(1)
Set s = ws.Shapes("TextBox 1")
s.TextFrame2.TextRange.Font.Fill.ForeColor.RGB = RGB(255, 0, 0)
try this,
Sub Button2()
Dim sh As Shape
Set sh = Sheets("Sheet1").Shapes("Textbox1")
sh.TextFrame.Characters.Font.Color = vbRed
End Sub
I'm using Excel 2000 (long story) and I conditionally set the color of text box "M_in_out" in "Sheet7" with the following.
Private Sub M_in_out_LostFocus()
Dim sh As Sheet7
Set sh = Sheet7
vx = CInt(M_in_out.Value)
If vx > 0 Then
sh.M_in_out.ForeColor = vbBlack
Else
sh.M_in_out.ForeColor = vbRed
End If
sh.Cells(23, 6).Value = sh.Cells(23, 6).Value + vx
End Sub
You should probably use more meaningful variable names etc!.