In the below macro, I cannot have the shapes IconDish and ChevronNavigator to reset to 1 for each slide, so that later I can select them for further editing of their properties.
I tried also to place the counter right after the shape is created, but it looks like it does not really matter where it is and the counter does not stop. I also tried to stop it at iColumn's value, but nothing.
Option Explicit
Sub NavigatorX()
Dim oSlide As Slide
Dim oShapeNavigator As Shape
Dim IconDishNavigator As Shape
Dim ChevronNavigator As Shape
Dim nCounter As Long
Dim CellLeft As Single
Dim CellTop As Single
Dim CellWidth As Single
Dim CellHeight As Single
Dim CellWidth_2 As Single
Dim iRow As Integer
Dim iColumn As Integer
Dim Shp_Cntr As Single 'Center of Selected Shapes
Dim Shp_Mid As Single
Dim NavWidth As Single
Dim EvenCell_W As Single
Dim DishCounter As Long
Dim ChevronCounter As Long
ChevronCounter = 0
DishCounter = 0
For Each oSlide In ActivePresentation.Slides
If oSlide.CustomLayout.Name = "Section Header" Then
nCounter = nCounter + 1
ElseIf nCounter > 0 Then
Set oShapeNavigator = oSlide.Shapes.AddTable(1, 10, Left:=10, Top:=10, Width:=500, Height:=2)
oShapeNavigator.Fill.ForeColor.RGB = RGB(255, 128, 128)
oShapeNavigator.Name = "Navigator " & nCounter
With oShapeNavigator.Table '## TABLE ##
For iRow = 1 To .Rows.Count
For iColumn = 1 To .Columns.Count Step 2
EvenCell_W = (oShapeNavigator.Width / .Columns.Count / 2) * IIf(iColumn Mod 2 = 0, 5 / 7, 2 / 7)
With .Columns(iColumn)
.Width = EvenCell_W
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
DishCounter = DishCounter + 1
' <---- i put it here before, but it was still not counting right
Set IconDishNavigator = oSlide.Shapes.AddShape(Type:=msoShapeOval, Left:=Shp_Cntr - CellHeight / 2, Top:=Shp_Mid - CellHeight / 2, Width:=CellHeight, Height:=CellHeight)
IconDishNavigator.Fill.ForeColor.RGB = RGB(100, 250, 140)
IconDishNavigator.Line.Weight = 0.75
IconDishNavigator.Line.Visible = msoFalse
IconDishNavigator.LockAspectRatio = msoTrue
IconDishNavigator.Name = "IconDish" & DishCounter
End With
Next iColumn
Next iRow
End With
'
With oShapeNavigator.Table '## TABLE ##
For iRow = 1 To .Rows.Count
For iColumn = 2 To .Columns.Count Step 2
With .Columns(iColumn)
' .Width = EvenCell_W
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
ChevronCounter = ChevronCounter + 1
' <---- i put it here before, but it was still not counting right
Set ChevronNavigator = oSlide.Shapes.AddShape(Type:=msoShapeChevron, Left:=Shp_Cntr - CellHeight / 2, Top:=Shp_Mid - CellHeight / 2, Width:=CellWidth, Height:=CellHeight)
ChevronNavigator.Fill.ForeColor.RGB = RGB(100, 100, 100)
ChevronNavigator.Line.Weight = 0.75
ChevronNavigator.Line.Visible = msoFalse
ChevronNavigator.LockAspectRatio = msoTrue
ChevronNavigator.Name = "Chevron" & ChevronCounter
End With
Next iColumn
Next iRow
End With
End If
Next oSlide
DishCounter = 0
ChevronCounter = 0
End Sub
Related
After the table with the number of column equal to the shapes selected is created, I would like to realign each of them (the shapes) respectively to the relative column (here the third, fifth etc.) and duplicate them in the following slides that are not using a Layout named Section. However I am not able to declare this, could someone help please?
Option Explicit
Sub NavigatorX()
Dim nCounter As Long
Dim oSlide As Slide
Dim oSlides As Slides
Set oSlides = ActivePresentation.Slides
Dim oShapeNavigator As Shape
Dim Shapesarray() As Shape
ReDim Shapesarray(1 To ActiveWindow.Selection.ShapeRange.Count) - 1
Dim V As Long
Dim iIcon As Shape
For V = 1 To ActiveWindow.Selection.ShapeRange.Count
Set Shapesarray(V) = ActiveWindow.Selection.ShapeRange(V)
Next V
Debug.Print V
For Each oSlide In oSlides
If oSlide.CustomLayout.Name = "Section Header" Then
nCounter = nCounter + 1
Set oShapeNavigator = oSlide.Shapes.AddTable(1, V, Left:=10, Top:=10, Width:=MasterTitle.Width * 2 / 3, Height:=2)
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
Next
With oShapeNavigator.Table '## TABLE ##
For iRow = 1 To .Rows.Count
For iColumn = 1 To .Columns.Count Step 2
For Each iIcon In Shapesarray ' Here is where I am having problems figuring out how to do it
If V = nCounter Then
Icon.Left = Shp_Cntr - CellHeight
Icon.Top = Shp_Mid - CellHeight
Icon.Width = CellHeight
Icon.Height = CellHeight
Next
'
Next iColumn
Next iRow
Next oSlide
End Sub
I tried the below also (Shp_Cntr and the rest to be defined, but thats's not the issue at the moment as I get Only one shape moving):
Currently it's like below, it's copying but pasting all in the same slide
...
For V = 1 To ActiveWindow.Selection.ShapeRange.Count - 1 'Set Selected Array of Shapes
Set Shapesarray(V) = ActiveWindow.Selection.ShapeRange(V)
Set iIcon = Shapesarray(V)
Next V
...
With oShapeNavigator.Table '## TABLE ##
For iRow = 1 To .Rows.Count
For iColumn = 1 To .Columns.Count Step 2
For V = LBound(Shapesarray) To UBound(Shapesarray) - 1
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
With iIcon.Duplicate
iIcon.Left = Shp_Cntr - CellHeight
iIcon.Top = Shp_Mid - CellHeight
iIcon.Width = CellHeight
iIcon.Height = CellHeight
End With
' End If
Next V
Next iColumn
Next iRow
End With
But only one shape (with three selected, the second) gets cloned and only in the first slide.
Also, I noticed there is a massive amount of shapes created, here (Copy paste shape by using VBA in PowerPoint) they mention to set a new collection, but it did not help as I am not able to integrate it.
Currently it's like below but it's pasting in the first slide
For V = LBound(Shapesarray) To UBound(Shapesarray) - 1
Set iIcon = ActiveWindow.Selection.ShapeRange(V)
' For Each Icon In ShapeRange
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
iIcon.Left = Shp_Cntr - (CellHeight * IconRatio / 2)
iIcon.Top = Shp_Mid - (CellHeight * IconRatio / 2)
iIcon.Width = CellHeight * IconRatio
iIcon.Height = CellHeight * IconRatio
iIcon.ZOrder msoBringToFront
iIcon.Fill.ForeColor.RGB = RGB(0, 0, 0)
iIcon.Line.Weight = 0#
iIcon.Line.Visible = msoFalse
iIcon.LockAspectRatio = msoTrue
' Next
' For nCounter = 1 To oSlides.Count
iIcon.Copy
For nCounter = 1 To oSlides.Count
'
' oSlide.Shapes.Paste
End If
' Next
Next V
Looping through I can see If I remove the iIcon.Copy part it moves the selected icons all the way to the last column together, so it seems it should deselect the shapes one by one first.
In the below, the circles and chevrons created in the cells of the table are centered only if the dimensions are not changed, if a constant is given later they end up misplaced. I signaled below where their parameters are set differently and cause issues, Width:=CellWidth * 0.7, Height:=CellHeight * 0.7) for example
Why can it be?
Option Explicit
Sub NavigatorX()
Dim oSlide As Slide
Dim oShapeNavigator As Shape
Dim IconDishNavigator As Shape
Dim ChevronNavigator As Shape
Dim nCounter As Long
Dim CellLeft As Single
Dim CellTop As Single
Dim CellWidth As Single
Dim CellHeight As Single
Dim CellWidth_2 As Single
Dim iRow As Integer
Dim iColumn As Integer
Dim Shp_Cntr As Single 'Center of Selected Shapes
Dim Shp_Mid As Single
Dim NavWidth As Single
Dim EvenCell_W As Single
Dim DishCounter As Long
Dim ChevronCounter As Long
ChevronCounter = 0
DishCounter = 0
For Each oSlide In ActivePresentation.Slides
If oSlide.CustomLayout.Name = "Section Header" Then
nCounter = nCounter + 1
ElseIf nCounter > 0 Then
Set oShapeNavigator = oSlide.Shapes.AddTable(1, 10, Left:=10, Top:=10, Width:=500, Height:=2)
oShapeNavigator.Fill.ForeColor.RGB = RGB(255, 128, 128)
oShapeNavigator.Name = "Navigator " & nCounter
With oShapeNavigator.Table '## TABLE ##
For iRow = 1 To .Rows.Count
For iColumn = 1 To .Columns.Count Step 2
EvenCell_W = (oShapeNavigator.Width / .Columns.Count / 2) * IIf(iColumn Mod 2 = 0, 5 / 7, 2 / 7)
With .Columns(iColumn)
.Width = EvenCell_W
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
DishCounter = DishCounter + 1
Set IconDishNavigator = oSlide.Shapes.AddShape(Type:=msoShapeOval, Left:=Shp_Cntr - CellHeight / 2, Top:=Shp_Mid - CellHeight / 2, Width:=CellHeight, Height:=CellHeight)
' Set IconDishNavigator = oSlide.Shapes.AddShape(Type:=msoShapeOval, Left:=Shp_Cntr - CellHeight / 2, Top:=Shp_Mid - CellHeight / 2, Width:=CellHeight * 0.8, Height:=CellHeight * 0.8) <--- while with a different value the shape is not centered
IconDishNavigator.Fill.ForeColor.RGB = RGB(100, 250, 140)
IconDishNavigator.Line.Weight = 0.75
IconDishNavigator.Line.Visible = msoFalse
IconDishNavigator.LockAspectRatio = msoTrue
IconDishNavigator.Name = "IconDish" & DishCounter
End With
Next iColumn
Next iRow
End With
'
With oShapeNavigator.Table '## TABLE ##
For iRow = 1 To .Rows.Count
For iColumn = 2 To .Columns.Count Step 2
With .Columns(iColumn)
' .Width = EvenCell_W
CellLeft = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Left
CellTop = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Top
CellWidth = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Width
CellHeight = oShapeNavigator.Table.Cell(iRow, iColumn).Shape.Height
Debug.Print CellWidth
Debug.Print CellHeight
Shp_Cntr = CellLeft + CellWidth / 2
Shp_Mid = CellTop + CellHeight / 2
ChevronCounter = ChevronCounter + 1
Set ChevronNavigator = oSlide.Shapes.AddShape(Type:=msoShapeChevron, Left:=Shp_Cntr - CellHeight / 2, Top:=Shp_Mid - CellHeight / 2, Width:=CellWidth, Height:=CellHeight)
' Set ChevronNavigator = oSlide.Shapes.AddShape(Type:=msoShapeChevron, Left:=Shp_Cntr - CellHeight / 2, Top:=Shp_Mid - CellHeight / 2, Width:=CellWidth * 0.7, Height:=CellHeight * 0.7) <--- while with a different value the shape is not centered
ChevronNavigator.Fill.ForeColor.RGB = RGB(100, 100, 100)
ChevronNavigator.Line.Weight = 0.75
ChevronNavigator.Line.Visible = msoFalse
ChevronNavigator.LockAspectRatio = msoTrue
ChevronNavigator.Name = "Chevron" & ChevronCounter
End With
Next iColumn
Next iRow
End With
End If
Next oSlide
DishCounter = 0
ChevronCounter = 0
End Sub
I wrote the below to create tables on selected slides. I would like to set the column width of the even columns to 2/3 of the odd ones, however when I try to set the width I cannot find the correct way to do it.
I tried with Set Columns.Width giving the table name, but with no success.
Sub NavigatorX()
Dim oSlide As Slide
Dim oShapeNavigator As Shape
Dim nCounter As Long
Dim iRow As Integer
Dim iColumn As Integer
Dim EvenCell_W As Single
For Each oSlide In ActivePresentation.Slides
If oSlide.CustomLayout.Name = "Section Header" Then
nCounter = nCounter + 1
ElseIf nCounter > 0 Then
Set oShapeNavigator = oSlide.Shapes.AddTable(1, 10, Left:=10, Top:=10, Width:=200, Height:=2)
oShapeNavigator.Fill.ForeColor.RGB = RGB(255, 128, 128)
oShapeNavigator.Name = "Navigator " & nCounter
With oShapeNavigator.Table
For iColumn = 2 To .Columns.Count Step 2
EvenCell_W = (oShapeNavigator.Width / .Columns.Count) * 2 / 3
With .Table.Columns(iColumn)
Set .Width = EvenCell_W ' <-- here is where I cannot find a way to properly fit the column size
End With
End If
Next
End Sub
Simplified to demo column sizing:
Sub NavigatorX()
Dim oSlide As Slide
Dim oShapeNavigator As Shape
Dim w, wNew, numCols As Long
Dim iColumn As Integer, nCounter As Long
Set oSlide = ActivePresentation.Slides(1)
Set oShapeNavigator = oSlide.Shapes.AddTable(1, 10, Left:=10, Top:=10, _
Width:=200, Height:=2)
nCounter = 1 'eg
With oShapeNavigator
.Fill.ForeColor.RGB = RGB(255, 128, 128)
.Name = "Navigator " & nCounter
w = .Width
With .Table
numCols = .Columns.Count
For iColumn = 1 To numCols
wNew = w / (numCols / 2) * IIf(iColumn Mod 2 = 0, 2 / 5, 3 / 5)
.Columns(iColumn).Width = wNew
Next
End With
End With
End Sub
I have two shapes that are near each other, one of them is selected. I need to be able to group it together with the selected shape.
Thanks for your help!
Here's the code I came with but it doesn't seem to match the nearby shape. In particular its not finding a 20ptx20pt rectangle offset about half its with to the left and half its height to the top:
Option Explicit
Sub Test()
Dim oSl As slide
Dim oSh As Shape
Dim oSh2 As Shape
Dim MainHeight As Long
Dim MainWidth As Long
MainHeight = 48.76
MainWidth = 88.45
Set oSl = Application.ActiveWindow.View.slide
Set oSh = ActiveWindow.Selection.ShapeRange(1)
For Each oSh2 In oSl.Shapes
If IsWithinRangey(oSh, oSh2, 0.4) Then
oSh2.Select (False)
End If
Next
'' ActiveWindow.Selection.ShapeRange.Group
End Sub
Function IsWithinRangey(oSh As Shape, oSh2 As Shape, _
AreaTolerance As Single) As Boolean
' Is the shape within the coordinates supplied?
Dim WidthMin As Single
Dim WidthMax As Single
Dim HeightMin As Single
Dim HeightMax As Single
With oSh
HeightMin = oSh.Height * (1 - AreaTolerance)
HeightMax = oSh.Height * (1 + AreaTolerance)
WidthMin = oSh.Width * (1 - AreaTolerance)
WidthMax = oSh.Width * (1 + AreaTolerance)
Debug.Print "==========================="
Debug.Print "Shp: " & .Width & " x " & .Height
Debug.Print "Min: " & WidthMin & " x " & HeightMin
Debug.Print "Max: " & WidthMax & " x " & HeightMax
End With
With oSh2
If oSh.Id <> oSh2.Id Then
ShapeLeft = oSh.Left - (19.85) / 1
ShapeTop = oSh.Top - (19.85) / 1
Debug.Print ShapeLeft
Debug.Print ShapeTop
If .Left >= ShapeLeft And .Left < ShapeLeft + WidthMax Then
If .Top >= ShapeTop And .Top < ShapeTop + HeightMax Then
If .Width >= WidthMin And .Width <= WidthMax Then
If .Height > HeightMin And .Height < HeightMax Then
IsWithinRangey = True
End If
End If
End If
End If
End If
End With
End Function
To make your code more efficient, I would restructure as follows:
Dim WidthMin As Single
Dim WidthMax As Single
Dim HeightMin As Single
Dim HeightMax As Single
Sub GroupCloseShapes()
Dim oSl As Slide
Dim oSh As Shape
Dim oSh2 As Shape
Dim MainHeight As Long
Dim MainWidth As Long
MainHeight = 48.76
MainWidth = 88.45
Set oSl = Application.ActiveWindow.View.Slide
Set oSh = ActiveWindow.Selection.ShapeRange(1)
With oSh
HeightMin = oSh.Height * (1 - AreaTolerance)
HeightMax = oSh.Height * (1 + AreaTolerance)
WidthMin = oSh.Width * (1 - AreaTolerance)
WidthMax = oSh.Width * (1 + AreaTolerance)
End With
For Each oSh2 In oSl.Shapes
If oSh.ID <> oSh2.ID Then
If IsWithinRangey(oSh, oSh2, 0.4) Then
oSh2.Select (False)
End If
End If
Next
'' ActiveWindow.Selection.ShapeRange.Group
End Sub
Function IsWithinRangey(oSh As Shape, oSh2 As Shape, AreaTolerance As Single) As Boolean ' Is the shape within the coordinates supplied?
With oSh2
.Select
ShapeLeft = oSh.Left - (19.85) / 1
ShapeTop = oSh.Top - (19.85) / 1
Debug.Print ShapeLeft
Debug.Print ShapeTop
If .Left >= ShapeLeft And .Left < ShapeLeft + WidthMax Then
If .Top >= ShapeTop And .Top < ShapeTop + HeightMax Then
If .Width >= WidthMin And .Width <= WidthMax Then
If .Height > HeightMin And .Height < HeightMax Then
IsWithinRangey = True
End If
End If
End If
End If
End With
End Function
I've added a .Select method to make it clear which shape is currently being checked. Your problem is with the math calculations in the IsWithinRangey function. To debug them, click on the grey bar to the left of the code. This inserts a breakpoint:
Run the macro. It will stop at the breakpoint. Press F8 to step through each statement. Hover your mouse over the variable names to see their current values. Then adjust your calculations to find the shape you want and ignore the shape you don't want.
Thanks to #JohnKorchok! Final code follows
Option Explicit
Dim WidthMax As Single
Dim HeightMax As Single
Dim ShapeLeft As Single
Dim ShapeTop As Single
Dim AreaTolerance As Single
Dim StepNumberWidth As Single
Dim StepNumberHeight As Single
Dim oNewShape As Shape
Sub GroupCloseShapes()
Dim oSl As Slide
Dim oSh As Shape
Dim oSh2 As Shape
Dim MainHeight As Long
Dim MainWidth As Long
MainHeight = 48.76
MainWidth = 88.45
StepNumberWidth = 19.85
StepNumberHeight = 19.85
Set oSl = Application.ActiveWindow.View.Slide
Set oSh = ActiveWindow.Selection.ShapeRange(1)
With oSh
HeightMax = oSh.Height * (1 + AreaTolerance)
WidthMax = oSh.Width * (1 + AreaTolerance)
ShapeLeft = oSh.Left - StepNumberWidth / 1
ShapeTop = oSh.Top - StepNumberHeight / 1
End With
For Each oSh2 In oSl.Shapes
If oSh.Id <> oSh2.Id Then
If IsWithinRangey(oSh, oSh2, 0.4) Then
oSh2.Select (False)
End If
End If
Next
'' ActiveWindow.Selection.ShapeRange.Group
End Sub
Function IsWithinRangey(oSh As Shape, oSh2 As Shape, AreaTolerance As Single) As Boolean ' Is the shape within the coordinates supplied?
With oSh2
If .Left >= ShapeLeft And .Left <= ShapeLeft + WidthMax Then
If .Top >= ShapeTop And .Top <= ShapeTop + HeightMax Then
If .Width <= WidthMax Then
If .Height <= HeightMax Then
IsWithinRangey = True
End If
End If
End If
End If
End With
End Function
I have a circle that has a fixed diameter and center. What I need to do now is to insert the circle into the given range. Eg, given 11 boxes of column and 10 boxes of rows to be inserted in excel cell. After entering the given range, the circle will be within the selected range with its fixed center but the boxes would have different measurement for its height and width. My question is how do I insert the circle into any given range (as in 11 x 10 or 9 x 12) with different height and width of the cells?
My code:
Sub DrawCircleWithCenter()
Dim cellwidth As Single
Dim cellheight As Single
Dim ws As Worksheet
Dim rng As Range
Dim Shp2 As Shape
CellLeft = Selection.Left
CellTop = Selection.Top
ActiveSheet.Shapes.AddShape(msoShapeOval, CellLeft, CellTop, 565 / 2, 565 / 2).Select
Selection.ShapeRange.Fill.Visible = msoFalse
With Selection.ShapeRange.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(0, 0, 0)
.Transparency = 0
End With
i = 182
Set Shp2 = ActiveSheet.Shapes.AddShape(i, CellLeft, CellTop, 20, 20)
Shp2.ShapeStyle = msoShapeStylePreset1
Set rng = ActiveWindow.VisibleRange
Selection.Left = rng.Width / 2 - Selection.Width / 2
Selection.Top = rng.Height / 2 - Selection.Height / 2
Shp2.Left = rng.Width / 2 - Shp2.Width / 2
Shp2.Top = rng.Height / 2 - Shp2.Height / 2
End Sub
If I'm understanding you correctly this could be what you're after:
Sub DrawCircleWithCenter(rng As Range)
Dim Shp1 As Shape, Shp2 As Shape
Set Shp1 = ActiveSheet.Shapes.AddShape(msoShapeOval, rng.Left, rng.Top, rng.Width, rng.Height)
Shp1.Fill.Visible = msoFalse
With Shp1.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(0, 0, 0)
.Transparency = 0
End With
Set Shp2 = ActiveSheet.Shapes.AddShape(182, rng.Left, rng.Top, 20, 20)
Shp2.ShapeStyle = msoShapeStylePreset1
Shp1.Left = rng.Left
Shp1.Top = rng.Top
Shp2.Left = rng.Left + rng.Width / 2 - Shp2.Width / 2
Shp2.Top = rng.Top + rng.Height / 2 - Shp2.Height / 2
End Sub
Sub Test()
Dim rng As Range
Set rng = Selection
DrawCircleWithCenter rng
End Sub
You can modify the Test subroutine to supply the range you're after. In the above case I use the selection that the user has highlighted in the present worksheet to draw the cross and oval centered inside it. If you choose a square area the oval becomes a circle, with a rectangular area it'll be squashed into an ellipse. It'll also work if you have varying cell widths and heights in the range you select.