PowerPoint Macro - Need to add Rectangle with Notes to each Slide - vba

I have a PowerPoint with notes for each slide. For each slide, I want to copy the notes, create a yellow rectangle with black border, and paste the notes into the rectangle.
I started "splicing" a macro together. Here is what I have so far. It works but rectangle is at the top (need at bottom) and not sure how to copy and paste the notes into the rectangle:
Dim oPPT As Presentation
Dim oSlide As Slide
Dim r As Integer
Dim i As Integer
Dim shapectr As Integer
Dim maxshapes As Integer
Dim oShape As Shape
Set oPPT = ActivePresentation
For i = 1 To oPPT.Slides.Count
For shapectr = 1 To oPPT.Slides(i).Shapes.Count
ActiveWindow.View.GotoSlide i
Set oShape = ActiveWindow.Selection.SlideRange.Shapes.AddShape(msoShapeRectangle, 575.5, 9.12, 124.75, 34.12)
oShape.Fill.ForeColor.RGB = RGB(255, 255, 204)
oShape.Fill.BackColor.RGB = RGB(137, 143, 75)
With oShape
With .TextFrame.TextRange
.Text = "TEST"
With .Font
.Name = "Arial"
.Size = 18
.Bold = msoFalse
.Italic = msoFalse
.Underline = msoFalse
.Shadow = msoFalse
.Emboss = msoFalse
.BaselineOffset = 0
.AutoRotateNumbers = msoFalse
.Color.SchemeColor = ppForeground
End With
End With
End With
Next shapectr
Next i
I need to replace "TEST" with the text that is in the notes area of the slide (could be several sentences).
I appreciate your help!

Sub addShp()
Dim osld As Slide
Dim oshp As Shape
Dim oTR As TextRange
For Each osld In ActivePresentation.Slides
On Error Resume Next
osld.Shapes("NOTES").Delete
Set oshp = osld.Shapes.AddShape(msoShapeRectangle, 10, 400, 400, 100)
oshp.Name = "NOTES"
oshp.TextFrame.AutoSize = ppAutoSizeShapeToFitText
oshp.Fill.ForeColor.RGB = RGB(255, 255, 204)
oshp.Line.ForeColor.RGB = RGB(0, 0, 0)
With oshp.TextFrame.TextRange
If Not getNotes(osld) Is Nothing Then .Text = getNotes(osld).Text
.Font.Name = "Arial"
.Font.Size = 10
.Font.Color.RGB = vbBlack
End With
oshp.Top = ActivePresentation.PageSetup.SlideHeight - oshp.Height
Next osld
End Sub
Function getNotes(osld As Slide) As TextRange
' usually shapes(2) but not always
Dim oshp As Shape
For Each oshp In osld.NotesPage.Shapes
If oshp.Type = msoPlaceholder Then
If oshp.PlaceholderFormat.Type = ppPlaceholderBody Then
If oshp.TextFrame.HasText Then
Set getNotes = oshp.TextFrame.TextRange
End If
End If
End If
Next oshp
End Function
See if this is closer

I figured out the "tweaks" I needed to left justify the text and specify a set height. Here is the final code:
Dim osld As Slide
Dim oshp As Shape
Dim oTR As TextRange
For Each osld In ActivePresentation.Slides
On Error Resume Next
osld.Shapes("NOTES").Delete
Set oshp = osld.Shapes.AddShape(msoShapeRectangle, 20, 400, 400, 300)
oshp.Name = "NOTES"
oshp.TextFrame.AutoSize = ppAutoSizeShapeToFitText
oshp.Fill.ForeColor.RGB = RGB(255, 255, 204)
oshp.Line.ForeColor.RGB = RGB(0, 0, 0)
oshp.Line.Weight = 1.5
With oshp.TextFrame.TextRange
If Not getNotes(osld) Is Nothing Then .Text = getNotes(osld).Text
.Font.Name = "Arial"
.Font.Size = 14
.Font.Color.RGB = vbBlack
.ParagraphFormat.Alignment = msoAlignLeft
End With
oshp.Width = 717
If oshp.Height < 105 Then
oshp.Height = 105
End If
oshp.Left = 1
oshp.Top = ActivePresentation.PageSetup.SlideHeight - oshp.Height
Next osld
End Sub
Function getNotes(osld As Slide) As TextRange
' usually shapes(2) but not always
Dim oshp As Shape
For Each oshp In osld.NotesPage.Shapes
If oshp.Type = msoPlaceholder Then
If oshp.PlaceholderFormat.Type = ppPlaceholderBody Then
If oshp.TextFrame.HasText Then
Set getNotes = oshp.TextFrame.TextRange
End If
End If
End If
Next oshp
End Function
Many thanks for your help!!!

Related

Macro update for VBA PPT to fit contents of a slide to a specific predefined workarea

I have a macro for VBA PPT to fit contents of a slide to a specific predefined workarea, now I select the required shapes to be fit into workarea and run this tool slide by slide. can anybody suggest how can I select multiple slides and get all the shapes (except placeholders) in those slides fit to the same work area
Sub FitContents()
Dim shp, grid, ZenSmartGroup, ZenWorkGrid As Shape
Dim SelectShapes As Variant
Dim targetSlides As SlideRange
Dim thisSlide, oSld As Slide
Dim theseShapes As ShapeRange
Set thisSlide = ActivePresentation.Slides(1)
Dim GridTop, GridLeft, GridHeight, GridWidth As Single
If ActiveWindow.Selection.Type = ppSelectionSlides Then
Set targetSlides = ActiveWindow.Selection.SlideRange
End If
For Each oSld In targetSlides
For Each shp In oSld.Shapes
If Not ActivePresentation.Slides(1).Tags("Font Size") = "" Then
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
shp.TextFrame.TextRange.Font.Size = ActivePresentation.Slides(1).Tags("Font Size")
End If
End If
End If
Next
If ActivePresentation.Slides(1).Tags("Grid Height") = "" Then
MsgBox "Please set grid size in Prezent Admin > Settings", vbInformation, "Set Grid Size"
End
End If
GridTop = ActivePresentation.Slides(1).Tags("Grid Top")
GridLeft = ActivePresentation.Slides(1).Tags("Grid Left")
GridHeight = ActivePresentation.Slides(1).Tags("Grid Height")
GridWidth = ActivePresentation.Slides(1).Tags("Grid Width")
oSld.Select
ActiveWindow.ViewType = ppViewSlide
ActiveWindow.Selection.ShapeRange.Group.Select
With ActiveWindow.Selection.ShapeRange(1)
.Top = GridTop
.Left = GridLeft
.LockAspectRatio = frmFitToGrid.chkAspectRatio
.Width = GridWidth
.Height = GridHeight
If frmFitToGrid.optHeight = True Then
.Height = GridHeight
End If
'If .Width > GridWidth Then
If frmFitToGrid.optWidth = True Then
.Width = GridWidth
End If
.Tags.Add "Type", "ZenSmartGroup"
.Name = "ZenSmartGroup"
End With
Set grid = oSld.Shapes.AddShape(msoShapeRectangle, GridLeft, GridTop, GridWidth, GridHeight)
grid.Fill.Visible = msoFalse
grid.Line.Visible = msoTrue
grid.Line.ForeColor.RGB = RGB(0, 255, 0)
grid.Line.Weight = 2.25
'grid.Select
grid.Name = "ZenWorkGrid"
SelectShapes = Array("ZenSmartGroup", "ZenWorkGrid")
'Set theseShapes = thisSlide.Shapes.Range(SelectShapes)
'theseShapes.Align msoAlignMiddles, msoFalse
'theseShapes.Align msoAlignCenters, msoFalse
Set ZenSmartGroup = oSld.Shapes("ZenSmartGroup")
Set ZenWorkGrid = oSld.Shapes("ZenWorkGrid")
'Align Middle (Horizontal Center)
If Not (frmFitToGrid.chkAlignLeft) Then
ZenSmartGroup.Top = ZenWorkGrid.Top + ((ZenWorkGrid.Height - ZenSmartGroup.Height) / 2)
End If
'Align Center (Vertical Center)
If Not (frmFitToGrid.chkAlignTop) Then
ZenSmartGroup.Left = ZenWorkGrid.Left + ((ZenWorkGrid.Width - ZenSmartGroup.Width) / 2)
End If
grid.Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, msoFalse
'ActiveWindow.Selection.ShapeRange(1).Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, msoTrue
oSld.Shapes.Range.Ungroup
Next
End Sub
NOTE: code below serves as an example, as it cannot be tested given the information in your post. Please adapt it to your situation as needed.
I've included several (hopefully) helpful additions to your code in order to improve readability and maintainability. These include:
Error Checking - make sure the user has provided all the values required for the macro to effectively execute, and...
... declare your variables as close as possible to their first use.
Note the use of targetSlides as the focus object for all the selected slides. This way you avoid to continually reference ActivePresentation.Slides(1). (Note this was an assumption on my part, adjust the code as necessary)
'--- make sure the user has selected at least two slides
Dim targetSlides As SlideRange
If ActiveWindow.Selection.Type = ppSelectionSlides Then
Set targetSlides = ActiveWindow.Selection.SlideRange
Else
MsgBox "Please select two or more slides in the left-hand slide overview panel.", _
vbCritical + vbInformation + vbOKOnly, "Select Slides for Grids"
Exit Sub
End If
'--- make sure the grid values are set
If targetSlides(1).Tags("Grid Height") = vbNullString Then
MsgBox "Please set grid size in Prezent Admin > Settings", _
vbCritical + vbInformation + vbOKOnly, "Set Grid Size"
End
End If
'--- assumes ONLY the first slide in the target slides has the Grid tags
Dim gridTop As Long
Dim gridLeft As Long
Dim gridHeight As Long
Dim gridWidth As Long
Dim fontSize As Double
With targetSlides(1)
gridTop = .Tags("GRID TOP")
gridLeft = .Tags("GRID LEFT")
gridHeight = .Tags("GRID HEIGHT")
gridWidth = .Tags("GRID WIDTH")
fontSize = IIf(.Tags("FONT SIZE") <> vbNullString, .Tags("FONT SIZE"), 0#)
End With
Break code into separate subs or functions to increase the readability of the logic.
It's easy to get lose the overall point of the solution when you have to mentally summarize large blocks of code. In my example, the main logic loop is:
Dim sld As Slide
For Each sld In targetSlides
ResetTextSize fontSize, sld
Dim slideShapes As ShapeRange
Set slideShapes = SelectAllShapes(sld)
CreateShapeGrid sld, slideShapes, _
gridTop, gridLeft, gridHeight, gridWidth
Next
Before looking at the full solution below, look at some of the supporting subs and functions. Most especially, note the function IsPlaceholder which checks a Shape on any slide to see if it's part of the layout (and shouldn't be selected) or not.
Full code module:
Option Explicit
Sub FitContents()
'--- make sure the user has selected at least two slides
Dim targetSlides As SlideRange
If ActiveWindow.Selection.Type = ppSelectionSlides Then
Set targetSlides = ActiveWindow.Selection.SlideRange
Else
MsgBox "Please select two or more slides in the left-hand slide overview panel.", _
vbCritical + vbInformation + vbOKOnly, "Select Slides for Grids"
Exit Sub
End If
'--- make sure the grid values are set
If targetSlides(1).Tags("Grid Height") = vbNullString Then
MsgBox "Please set grid size in Prezent Admin > Settings", _
vbCritical + vbInformation + vbOKOnly, "Set Grid Size"
End
End If
'--- assumes ONLY the first slide in the target slides has the Grid tags
Dim gridTop As Long
Dim gridLeft As Long
Dim gridHeight As Long
Dim gridWidth As Long
Dim fontSize As Double
With targetSlides(1)
gridTop = .Tags("GRID TOP")
gridLeft = .Tags("GRID LEFT")
gridHeight = .Tags("GRID HEIGHT")
gridWidth = .Tags("GRID WIDTH")
fontSize = IIf(.Tags("FONT SIZE") <> vbNullString, .Tags("FONT SIZE"), 0#)
End With
Dim sld As Slide
For Each sld In targetSlides
ResetTextSize fontSize, sld
Dim slideShapes As ShapeRange
Set slideShapes = SelectAllShapes(sld)
CreateShapeGrid sld, slideShapes, _
gridTop, gridLeft, gridHeight, gridWidth
Next
End Sub
Sub ResetTextSize(ByVal fontSize As Double, ByRef sld As Slide)
'--- (re)set the font sizes in all shapes with text, as long
' as it's not a placeholder shape on the current slide
If fontSize > 0 Then
Dim shp As Shape
For Each shp In sld.Shapes
If Not IsPlaceholder(sld, shp) Then
If shp.HasTextFrame Then
If shp.TextFrame.HasText Then
shp.TextFrame.TextRange.Font.Size = fontSize
End If
End If
End If
Next
End If
End Sub
Function IsPlaceholder(ByRef sld As Slide, ByRef shp As Shape) As Boolean
With sld.Shapes.Placeholders
IsPlaceholder = False
If .Count > 0 Then
Dim i As Long
For i = 1 To .Count
If .Item(i).Name = shp.Name Then
IsPlaceholder = True
Exit Function
End If
Next i
End If
End With
End Function
Function CollectionToArray(ByRef c As Collection) As Variant()
Dim a() As Variant: ReDim a(0 To c.Count - 1)
Dim i As Integer
For i = 1 To c.Count
a(i - 1) = c.Item(i)
Next
CollectionToArray = a
End Function
Function SelectAllShapes(ByRef sld As Slide) As ShapeRange
'--- creates a Collection of all the non-placeholder shape names, then
' convert the names to an array to create a ShapeRange object
Dim shp As Shape
Dim shps As Collection
Set shps = New Collection
For Each shp In sld.Shapes
If Not IsPlaceholder(sld, shp) Then
shps.Add shp.Name
End If
Next shp
If shps.Count > 0 Then
Dim shpsArray() As Variant
shpsArray = CollectionToArray(shps)
Set SelectAllShapes = sld.Shapes.Range(shpsArray)
Else
Set SelectAllShapes = Nothing
End If
End Function
Sub CreateShapeGrid(ByRef sld As Slide, ByRef slideShapes As ShapeRange, _
ByVal gridTop As Long, ByVal gridLeft As Long, _
ByVal gridHeight As Long, ByVal gridWidth As Long)
'--- position the group of shapes
With slideShapes.Group
.top = gridTop
.left = gridLeft
.LockAspectRatio = frmFitToGrid.chkAspectRatio
.width = gridWidth
.height = gridHeight
If frmFitToGrid.optHeight = True Then
.height = gridHeight
End If
'If .Width > GridWidth Then
If frmFitToGrid.optWidth = True Then
.width = gridWidth
End If
.Tags.Add "Type", "ZenSmartGroup"
.Name = "ZenSmartGroup"
End With
'--- now create a grid over the shapes
Dim grid As Shape
Set grid = sld.Shapes.AddShape(msoShapeRectangle, gridLeft, gridTop, gridWidth, gridHeight)
grid.Fill.Visible = msoFalse
grid.Line.Visible = msoTrue
grid.Line.ForeColor.RGB = RGB(0, 255, 0)
grid.Line.Weight = 2.25
'grid.Select
grid.Name = "ZenWorkGrid"
SelectShapes = Array("ZenSmartGroup", "ZenWorkGrid")
'Set theseShapes = thisSlide.Shapes.Range(SelectShapes)
'theseShapes.Align msoAlignMiddles, msoFalse
'theseShapes.Align msoAlignCenters, msoFalse
Set ZenSmartGroup = sld.Shapes("ZenSmartGroup")
Set ZenWorkGrid = sld.Shapes("ZenWorkGrid")
'Align Middle (Horizontal Center)
' If Not (frmFitToGrid.chkAlignLeft) Then
' ZenSmartGroup.Top = ZenWorkGrid.Top + ((ZenWorkGrid.Height - ZenSmartGroup.Height) / 2)
' End If
'
' 'Align Center (Vertical Center)
' If Not (frmFitToGrid.chkAlignTop) Then
' ZenSmartGroup.Left = ZenWorkGrid.Left + ((ZenWorkGrid.Width - ZenSmartGroup.Width) / 2)
' End If
grid.Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignMiddles, msoFalse
'ActiveWindow.Selection.ShapeRange(1).Delete
'ActiveWindow.Selection.ShapeRange.Align msoAlignCenters, msoTrue
slideShapes.Ungroup
End Sub

PPT VBA: Change a shape's accent color from one theme color to another

In PPT VBA, I'm trying to change all shapes in a file that are in one accent color to another. I supply the values from this form to my function, but its not accepting the OldColor and NewColor (themecolors) as msoThemeColorAccent1 but only takes as 15 instead. but it is accepting when I give msoThemeColorAccent1 for Fill.ForeColor.ObjectThemeColor; just not accepting when supplied from the function arguments. can anybody please suggest a solution?
this is my form:
these are my code blocks:
Private Sub cmdApply_Click()
ReplaceColors cboOldColor.Value, cboNewColor.Value, cboOldTint.Text, cboNewTint.Text
End Sub
Sub ReplaceColors(OldColor As Variant, NewColor As Variant, OldTint As String, NewTint As String)
Dim i As Integer
Dim t As Integer
Dim oSld As Slide
Dim oShp As Shape
Dim x, y As Integer
Dim sBrightness
Dim oColor, nColor As ThemeColor
Dim oPP As Placeholders
For Each oSld In ActivePresentation.Slides
For Each oShp In oSld.Shapes
'groups
If oShp.Type = msoGroup Then
'not groups
Else
With oShp 'other shapes
' Fill
If .Fill.ForeColor.ObjectThemeColor = OldColor And .Fill.ForeColor.Brightness = OldTint Then
.Fill.ForeColor.ObjectThemeColor = NewColor
.Fill.BackColor.Brightness = NewTint
End If
' Line
If Not .Type = msoTable Then
If .Line.Visible = msoTrue Then
If .Line.ForeColor.ObjectThemeColor = OldColor And .Line.ForeColor.Brightness = OldTint Then
.Line.ForeColor.ObjectThemeColor = NewColor
.Line.ForeColor.Brightness = NewTint
End If
End If
End If
' Text
If .HasTextFrame Then
If .TextFrame.HasText Then
For y = 1 To .TextFrame.TextRange.Runs.count
If .TextFrame.TextRange.Runs(y).Font.Color.ObjectThemeColor = OldColor And .TextFrame.TextRange.Runs(y).Font.Color.Brightness = OldTint Then
.TextFrame.TextRange.Runs(y).Font.Color.ObjectThemeColor = NewColor
.TextFrame.TextRange.Runs(y).Font.Color.Brightness = NewTint
End If
Next
End If
End If
End With
End If
'oShp = Nothing
Next oShp
Next oSld
End Sub

PowerPoint Macro: Change font size based on colour of font

I want to write a powerpoint macro where if my text colour is blue it will change the text size in shape. Not sure if it is possible? Appreciate your comments on the same
Sub thing()
Dim oSh As Shape
Dim oSl As Slide
Dim RGBColor As Long
' Change this as needed
RGBColor = RGB(255, 0, 0)
For Each oSl In ActivePresentation.Slides
For Each oSh In oSl.Shapes
If oSh.HasTextFrame Then
If oSh.TextFrame.HasText Then
With oSh.TextFrame.TextRange
If .Font.Color.RGB = RGB(255, 0, 0) Then
.Font.Size = 12
End If
End With
End If
End If
Next
Next
End Sub
Or to change just the selected shape:
Sub ChangeFontByColor()
Dim oSh As Shape
Dim RGBColor As Long
' Change this as needed
RGBColor = RGB(255, 0, 0)
Set oSh = ActiveWindow.Selection.Shaperange(1)
If oSh.HasTextFrame Then
If oSh.TextFrame.HasText Then
With oSh.TextFrame.TextRange
If .Font.Color.RGB = RGB(255, 0, 0) Then
.Font.Size = 12
End If
End With
End If
End If
End Sub

Creating hyperlink on shape to slide

I am trying to create a hyperlink on the newly created shape oSh to the newly created slide oSlide through VBA.
The shape is on a different slide than the newly created slide.
Code to create the shape and the slide.
Private Function GetSectionNumber( _
ByVal sectionName As String, _
Optional ParentPresentation As Presentation = Nothing) As Long
If ParentPresentation Is Nothing Then
Set ParentPresentation = ActivePresentation
End If
GetSectionNumber = -1
With ParentPresentation.SectionProperties
Dim i As Long
For i = 1 To .Count
If .Name(i) = sectionName Then
GetSectionNumber = i
Exit Function
End If
Next i
End With
End Function
Public Function GetLayout( _
LayoutName As String, _
Optional ParentPresentation As Presentation = Nothing) As CustomLayout
If ParentPresentation Is Nothing Then
Set ParentPresentation = ActivePresentation
End If
Dim oLayout As CustomLayout
For Each oLayout In ParentPresentation.SlideMaster.CustomLayouts
If oLayout.Name = LayoutName Then
Set GetLayout = oLayout
Exit For
End If
Next
End Function
Private Sub CommandButton1_Click()
Dim Sld As Slide
Dim Shp As Shape
'ERROR HANDLING
If ActivePresentation.Slides.Count < 5 Then
MsgBox "You do not have any slides in your PowerPoint project."
Exit Sub
End If
Set Sld = Application.ActiveWindow.View.Slide
If Sld.SlideIndex <> 5 Then
MsgBox "You are not on the correct slide."
Exit Sub
End If
Set Sld = Application.ActiveWindow.View.Slide
Call AddCustomSlide
Unload UserForm1
End Sub
Sub AddCustomSlide()
'Create new slide
Dim oSlides As Slides, oSlide As Slide
Dim Shp As Shape
Dim Sld As Slide
Dim SecNum As Integer, SlideCount As Integer, FirstSecSlide As Integer
Set oSlides = ActivePresentation.Slides
Set oSlide = oSlides.AddSlide(oSlides.Count - 2, GetLayout("Processwindow"))
SecNum = GetSectionNumber("Main Process")
With ActivePresentation.SectionProperties
SlideCount = .SlidesCount(SecNum)
FirstSecSlide = .FirstSlide(SecNum)
End With
oSlide.MoveTo toPos:=FirstSecSlide + SlideCount - 1
If oSlide.Shapes.HasTitle = msoTrue Then
oSlide.Shapes.Title.TextFrame.TextRange.Text = TextBox1
End If
'Add SmartArt
'Set Shp = oSlide.Shapes.AddSmartArtApplication.SmartArtLayouts(1)
'Create Flowchart Shape
Dim oSh As Shape
Set oSh = ActiveWindow.Selection.SlideRange.Shapes.AddShape(msoShapeFlowchartPredefinedProcess, 50, 100, 83.52, 41.62)
With oSh
With .TextFrame.TextRange
.Text = TextBox1
With .Font
.Name = "Verdana (Body)"
.Size = 8
.Bold = msoFalse
.Italic = msoFalse
.Underline = msoFalse
.Shadow = msoFalse
.Emboss = msoFalse
.BaselineOffset = 0
.AutoRotateNumbers = msoFalse
'.Color.SchemeColor = RGB(255, 255, 255)
End With ' Font
End With ' TextRange
End With ' oSh, the shape itself
End Sub
I'm guessing you want this in the last part that does the font formatting:
Dim URLorLinkLocationText as String
With oSh.TextFrame.TextRange.ActionSettings(ppMouseClick)
.Action = ppActionHyperlink
.Hyperlink.SubAddress = URLorLinkLocationText
End With

Convert charts to picture powerpoint

I usually use this one couple times for converting charts to image in PPT. But this time, when running this code, it shown " Error 242, Subject Required"
Anyone master of VBA can help me fix it?
Here the code:
`Sub EnumChartsInPresentation()
Dim sld As Slide
Dim shp As Shape
Dim ctr As Long
For Each sld In ActivePresentation.Slides
For ctr = sld.Shapes.Count To 1 Step -1
If GetShapeType(sld.Shapes(ctr)) = msoChart Then
Call ConvertChartToImage(sld, sld.Shapes(ctr))
End If
Next
Next
End Sub
Function GetShapeType(shp As Shape) As MsoShapeType
If shp.Type = msoPlaceholder Then
If shp.PlaceholderFormat.ContainedType = msoChart Then
GetShapeType = msoChart
Exit Function
End If
End If
GetShapeType = shp.Type
End Function
Sub ConvertChartToImage(sld As Slide, shp As Shape)
Dim shpChartImage As Object
shp.Copy
DoEvents
Set shpChartImage = sld.Shapes.PasteSpecial(ppPastePNG)
With shpChartImage
.Left = shp.Left
.Top = shp.Top
Do While shp.ZOrderPosition < shpChartImage.ZOrderPosition
Call shpChartImage.ZOrder(msoSendBackward)
Loop
shp.Visible = False
'shp.Delete
'Set shp = Nothing
End With
End Sub`