VBA Code
Different Types of Shapes
Shapes can be classified to be any of the following:
● Pictures
● OLE Objects
● AutoShapes
● FreeForms
● ActiveX controls.
Shapes can appear in 2 places
In the Drawing Layer
In the Text Layer - any shapes in this layer are referred to as inline shapes.
What is a Shape ?
A shape object is an object that is in the drawing layer of the document.
They are anchored to a range of text but are free-floating and can be positioned anywhere on the page.
The shape object is a member of the Shapes collection, which includes all the shapes in the main story of a document or in all the headers and footers of a document.
There are two objects that represent shapes.
1) The shapes collection which represents all the shapes in the document
2) The shaperange collection which represents a subset of all the shapes, typically for the current selection.
Dim objShape As Shape
For Each objShape In ActiveDocument.Shapes
With objShape
If .Type = msoShapeType.msoLinkedOLEObject Then
.LinkFormat.Update
.LinkFormat.BreakLink
End If
End With
Next shapeLoop
Converting Shapes and InlineShapes
You can use the ConvertToInlineShape and ConvertToShape methods to convert shapes from one type to the other.
You can only convert pictures, OLE Objects and Active X objects to inline shapes.
This code converts all the inline shapes to actual shapes ??
Dim objShape As Shape
For Each objShape In ActiveDocument.InlineShapes
objShape.ConvertToShape
Next objShape
Selection.PasteSpecial Placement:=wdInLine
The following line generates an error if track changes is on.
Shapes(2).ConvertToInlineShape
Sub Macro1()
Dim oInlineShape As InlineShape
For Each oInlineShape In Selection.InlineShapes
oInlineShape.SoftEdge.Type = msoSoftEdgeType2
Next oInlineShape
End Sub
VBA - Positioning
Shapes(1).GroupItems(2).IncrementTop(-1)
Positioning Pictures and Objects
This is represented in VBA either by the InLineShape object or the Shape Object
ActiveDocument.InLineShapes.Item(4).WrappingStyle =
The following can be used with inline shapes : inlinewithtext, square, tight
ActiveDocument.Shapes.Item(3).WrappingStyle =
The following can be used with shapes: behind text, infront of text
Selection.ShapeRange(1).HeightRelative
Selection.ShapeRange(1).WidthRelative
Selection.ShapeRange(1).LeftRelative
Selection.ShapeRange(1).TopRelative
For Absolute Position
Selection.ShapeRange(1).RelativeHorizontalPosition = wdRelativeHorizontalPosition.wdRelativeHorizontalPositionMargin
Selection.ShapeRange(1).Left = 20
For Absolute Position
Selection.ShapeRange(1).RelativeHorizontalPosition = wdRelativeHorizontalPosition.wdRelativeHorizontalPositionLeftMarginArea
Selection.ShapeRange(1).LeftRelative = 100
If the Vertical position is set to "Paragraph" then the object will move with text
Selection.ShapeRange(1).RelativeVerticalPosition = wdRelativeVerticalPosition.wdRelativeVerticalPositionParagraph
Selection.ShapeRange(1).RelativeVerticalPosition = wdRelativeVerticalPosition.wdRelativeVerticalPositionLine
If the Vertical position is set to anything else then the object will have a "fixed position on page"
Selection.ShapeRange(1).RelativeVerticalPosition = wdRelativeVerticalPosition.wdRelativeVerticalPositionPage
Selection.ShapeRange(1).RelativeHorizontalSize = wdRelativeHorizontalSize.
Selection.ShapeRange(1).RelativeVerticalSize = wdRelativeVerticalSize.
VBA - Shapes
ShapeRange
Represents a set of shapes in a document.
This could be just 1 shape or 2 or more shapes
Most operations you can do with a Shape object you can also do with a ShapeRange object when it contains only 1 shape.
Text Boxes
For adding textboxes refer to [Pages > VBA Code > Text Boxes]
Deleting Shapes
For some reason (msoPicture) objects can only be removed from headers and footers if the header and footer is activated.
This line of code will not work
objHeader.Range.ShapeRange.Item("picturename").Delete
Adding Shapes
ActiveDocument.Shapes.AddShape(Type:=msoAutoShapeType.msoShapeRectangle, _
Left:=10, _
Top:=10, _
Width:=10, _
Height:=10, _
Anchor:=False)
Anchor - Optional Variant. A Range object that represents the text to which the AutoShape is bound. If Anchor is specified, the anchor is positioned at the beginning of the first paragraph in the anchoring range. If this argument is omitted, the anchoring range is selected automatically and the AutoShape is positioned relative to the top and left edges of the page.
ActiveDocument.Shapes.AddCallout(Type:=msoCalloutType.msoCalloutOne, _
Left:=10, Top:=10, Width:=10, Height:=10, Anchor:=False)
ActiveDocument.Shapes.AddCanvas(Left:=10, Top:=10, Width:=10, Height:=10, Anchor:=False)
ActiveDocument.Shapes.AddCurve(SafeArrayOfPoints, Anchor)
ActiveDocument.Shapes.AddDiagram(Type:=msoDiagramType.msoDiagramOrgChart , _
Left:=10, Top:=10, Width:=10, Height:=10, Anchor:=False)
ActiveDocument.Shapes.AddLabel(Type:=msoTextOrientation.msoTextOrientationUpward , _
Left:=10, Top:=10, Width:=10, Height:=10, Anchor:=False)
ActiveDocument.Shapes.AddLine(BeginX:= , _
BeginY:= , _
EndX:= , _
EndY:= ,
Anchor:=False)
BeginX - Single. The horizontal position, measured in points, of the line's starting point, relative to the anchor.
BeginY - Single. The vertical position, measured in points, of the line's starting point, relative to the anchor.
EndX - Single. The horizontal position, measured in points, of the line's end point, relative to the anchor.
EndY - Single. The vertical position, measured in points, of the line's end point, relative to the anchor.
ActiveDocument.Shapes.AddPicture(FileName:= , _
LinkToFile:= , _
SaveWithDocument:= , _
Range:= )
FileName - String. The path and file name of the picture.
LinkToFile - Variant. True to link the picture to the file from which it was created. False to make the picture an independent copy of the file. The default value is False.
SaveWithDocument - Variant. True to save the linked picture with the document. The default value is False.
Range - Variant. The location where the picture will be placed in the text. If the range isn't collapsed, the picture replaces the range; otherwise, the picture is inserted. If this argument is omitted, the picture is placed automatically.
ActiveDocument.Shapes.AddPolyline(SafeArrayOfPoints, Anchor)
Changing the Type
Dim objShape As Shape
objShape.AutoShapeType = msoAutoShapeType.msoShapePentagon
Returning a Shape
Dim objShape As Word.Shape
Set objShape = ActiveDocument.Shapes.Range("shapename")
Set objShape = ActiveDocument.Shapes.Item("shapename")
Set objShape = ActiveDocument.Shapes.Range(1)
Set objShape = ActiveDocument.Shapes.Item(1)
It is often simpler to use Item when you just have a single item
Returning Several Shapes
You can use VBA.Array to construct a list
ActiveDocument.Shapes.Range(Array("shaperange1","shaperange2"))
Change the fill color of the first shape in the selection
Selection.ShapeRange(1).Fill.ForeColor.RGB = RGB(10,20,30)
objShape.TextFrame.HasText
This is not boolean but integer
objShape.TextFrame.TextRange.Fields.Locked
This is not boolean but integer
Sub ShapePositioning2()
Dim objshape As Word.Shape
Set objshape = ActiveDocument.Sections(1).Range.ShapeRange(1)
'this can be a textbox
Debug.Print objshape.Adjustments
Debug.Print objshape.AlternativeText
Debug.Print objshape.Anchor
Debug.Print objshape.AutoShapeType
Debug.Print objshape.Callout
Debug.Print objshape.CanvasItems
Debug.Print objshape.Child
Debug.Print objshape.Diagram
Debug.Print objshape.DiagramNode
Debug.Print objshape.Fill
Debug.Print objshape.GroupItems
Debug.Print objshape.HasDiagram
Debug.Print objshape.HasDiagramNode
Debug.Print objshape.Height
Debug.Print objshape.HorizontalFlip
Debug.Print objshape.Hyperlink
Debug.Print objshape.ID
Debug.Print objshape.LayoutInCell
Debug.Print objshape.Left
Debug.Print objshape.Line
Debug.Print objshape.LinkFormat
Debug.Print objshape.LockAnchor
Debug.Print objshape.LockAspectRatio
Debug.Print objshape.Nodes
Debug.Print objshape.OLEFormat
Debug.Print objshape.Parent
Debug.Print objshape.ParentGroup
Debug.Print objshape.PictureFormat
Debug.Print objshape.RelativeHorizontalPosition
Debug.Print objshape.RelativeVerticalPosition
Debug.Print objshape.Rotation
Debug.Print objshape.ScaleHeight
Debug.Print objshape.ScaleWidth
Debug.Print objshape.Shadow
Debug.Print objshape.TextEffect
Debug.Print objshape.TextFrame
Debug.Print objshape.ThreeD
Debug.Print objshape.Top
Debug.Print objshape.Type
Debug.Print objshape.VerticalFlip
Debug.Print objshape.Vertices
Debug.Print objshape.Width
Debug.Print objshape.WrapFormat
Debug.Print objshape.ZOrderPosition
End Sub
Shapes WrapFormat
This example adds an oval to the active document and specifies that the document text wrap around the left and right sides of the square that circumscribes the oval. The example sets a 0.1-inch margin between the document text and the top, bottom, left side, and right side of the square.
Set myOval = ActiveDocument.Shapes.AddShape(msoShapeOval, 36, 36, 90, 50)
With myOval.WrapFormat
.Type = wdWrapSquare
.Side = wdWrapBoth
.DistanceTop = InchesToPoints(0.1)
.DistanceBottom = InchesToPoints(0.1)
.DistanceLeft = InchesToPoints(0.1)
.DistanceRight = InchesToPoints(0.1)
End With
Shapes LinkFormat Object
What is a LinkFormat Object ?
Represents the linking characteristics for an OLE object or picture.
Properties
| AutoUpdate | True if the links is updated automatically when the container file is opened. |
| Locked | True is the link is locked to prevent automatic updating. This can only be used on Shapes that are Inline. |
| SavePictureWithDocument | True if the specified picture is saved with the document |
| SourceFullName | Returns or sets the path and name of the source file for the specified linked OLE object, picture, or field. Read/write String. |
| SourceName | Returns the name of the source file for the specified linked OLE object, picture, or field. Read-only String. |
| SourcePath | Returns the path of the source file for the specified linked OLE object, picture, or field. Read-only String. |
| Type |
Methods
| BreakLink | Breaks the link between the source file and the specified OLE object, picture, or linked field. |
| Update | Updates the link |
SourceFullName Property
This example sets MyExcel.xls as the source file for shape one on the active document and specifies that the OLE object be updated automatically.
Using this property is equivalent to using in sequence the SourcePath, PathSeparator and SourceName properties.
With ActiveDocument.Shapes(1)
If .Type = msoLinkedOLEObject Then
With .LinkFormat
.SourceFullName = "c:\my documents\myExcel.xls"
.AutoUpdate = True
End With
End If
End With
VBA - Inline Shapes
An inline shape is an object that is in the text layer of the document.
An inline shape can only be a picture, an OLE Object or an ActiveX control.
Represents a object in the text layer of the document.
InlineShapes do not have names.
InlineShape objects are treated like characters and are positioned as characters within a line of text.
The Inlineshapes collection represents all the inline shapes in the document, range or selection.
The Count property for the InLineShapes collection in a document returns the number of shapes in the main story only.
If you want to count the number of inline shapes in other areas then use must use a Range object.
Use the new method to create a new picture as an inline shape
You can use the AddPicture and AddOleObject methods to add pictures or OLE Objects and link them to the source file.
Use the AddOleControl to add an Active X control.
Dim objInlineShape As Word.InlineShape
Dim objshape As Word.Shape
objShape = objInlineShape.ConvertToShape
objInlineShape = objShape.ConvertToInlineShape
Type Property
Use this property to return the type of the Inline Shape
objInlineShape.Type = wdInlineShapeType.wdInlineShapePicture
InlineShape Object
The InlineShape object is a member of the InlineShapes collection.
The InlineShapes collection contains all the shapes in a document, range, or selection.
Use InlineShapes(index), where index is the index number, to return a single InlineShape object.
Inline shapes don't have names.
The following example activates the first inline shape in the active document.
ActiveDocument.InlineShapes(1).Activate
This example saves the linked picture that's defined as the first inline shape in the active document when the document is saved.
Set myPic = ActiveDocument.InlineShapes(1)
If myPic.Type = wdLinkType.wdInlineShapeLinkedPicture Then
End If
InlineShapes Collection
This represents all the InlineShape objects
Field Property
This example inserts a graphic as an inline shape (using an INCLUDEPICTURE field) and then displays the shape's field code.
Dim ishapeNew As InlineShape
Set iShapeNew = _
ActiveDocument.InlineShapes.AddPicture(FileName:="C:\Windows\Tiles.bmp", _
LinkToFile:=True, _
SaveWithDocument:=False, _
Range:=Selection.Range)
MsgBox iShapeNew.Field.Code.Text
IsPictureBullet Property
Indicates if an InlineShape object is a picture bullet. Read-only.
Although picture bullets are considered inline shapes, searching a document's InlineShapes collection will not return picture bullets.
This example formats the selected list if the list if formatted with a picture bullet. If not, a message is displayed.
Public Sub IsSelectionAPictureBullet(shp As InlineShape)
On Error GoTo ErrorHandler
If shp.IsPictureBullet = True Then
shp.Width = InchesToPoints(0.5)
shp.Height = InchesToPoints(0.05)
End If
Exit Sub
ErrorHandler:
MsgBox "The selection is not a list or " & _
"does not contain picture bullets."
End Sub
Use the following code to call the routine above.
Call IsSelectionAPictureBullet(shp:=Selection.Range.ListFormat.ListPictureBullet)
VBA - Pictures
Adding Pictures
ActiveDocument.Shapes.AddPicture(FileName, LinkToFile, SaveWithDocument, Left, Top, Width, Height, Anchor)
FileName - The full folder path
LinkToFile - (Office.Core.msoTriState)
SaveWithDocument - (Office.Core.msoTriState)
Left - (Single) Position in Points of the upper-left corner relative to the column (not the page)
Top - (Single) Position in Points of the upper-left corner relative to the paragraph (not the page)
Width - (Single) Width of the picture in Points
Height - (Single) Height of the picture in Points
VBA - Text Boxes
ActiveDocument.Shapes.AddTextbox(Type:=msoTextOrientation.msoTextOrientationUpward , _
Left:=10, Top:=10, Width:=10, Height:=10, Anchor:=False)
Reading Writing Text
When you read text from a textbox additional characters will be included in your text string.
Dim stext As String
stext = ActiveDocument.Shapes(1).TextFrame.TextRange.Text
Debug.Print stext
For ichar = 1 to Len(stext) Step 1
Debug.Print Asc(Mid(stext, ichar,1)) & " - " & Mid(stext,ichar,1)
Next ichar
Any spaces are represented by Chr(32)
At the end of the text there will also be a Chr(13)
To remove the carriage return at the end of the string you need to include the following:
stext = Repace(stext, Chr(13),"")
Text boxes cannot have the same name if you are renaming using VBA
However testboxes with the same name can be inserted by inserting the same building block multiple times
The following line of code does not include any shapes in the headers or footers
ActiveDocument.Shapes
Public Sub Page_GetTextboxPosition()
Dim oShape As Word.Shape
On Error GoTo ErrorHandler
Set oShape = ActiveDocument.Shapes(1)
Debug.Print "Left - " & oShape.Left
Debug.Print "Top - " & oShape.Top
Debug.Print "Width - " & oShape.Width
Debug.Print "Height - " & oShape.Height
End Sub
Adds a text box to a drawing canvas.
Dim shpCanvas As Shape
'Create a new document and add a drawing canvas
Set shpCanvas = ActiveDocument.Shapes.AddCanvas _
(Left:=10, Top:=10, Width:=150, Height:=200)
shpCanvas.CanvasItems.AddTextbox _
Orientation:=msoTextOrientationHorizontal, _
Left:=40.45, Top:=129.3, Width:=129.5, Height:=205.2
Add the Title text box
Set oShape = ActiveDocument.Shapes.AddTextbox _
(Orientation:=msoTextOrientationHorizontal, _
Left:=105, _
Top:=213, _
Width:=Application.CentimetersToPoints(13.55), _
Height:=Application.CentimetersToPoints(1.74))
oShape.Line.Weight = 1
With oShape.TextFrame.TextRange
.Text = "Document Title"
.ParagraphFormat.Alignment = wdAlignParagraphCenter
.ParagraphFormat.Style = "Title"
End With
Sub ChangeAndUpdate()
Dim objRange As Range
Set objRange = ActiveDocument.Bookmarks("InsideTextBox").Range
objRange.Text = "Saturday"
ActiveDocument.Bookmarks.Add "InsideTextBox", objRange
'ActiveDocument.Shapes(1).Name = "TextBox_1"
ActiveDocument.Shapes.Item("TextBox_Update").TextFrame.TextRange.Fields.Update
End Sub
Size the text in a textbox to fill the textbox
Sub ResizeTextToFitTextBox()
If Selection.StoryType <> wdTextFrameStory Then Exit Sub
Dim myTextRange As Range
Dim myShape As Shape
Set myShape = Selection.ShapeRange(1)
Set myTextRange = myShape.TextFrame.TextRange
myTextRange.Font.Size = 2
If myShape.TextFrame.Overflowing = True Then
ActiveDocument.Undo
MsgBox "Even when set to a size of 2 points, the text overflows the textbox."
Exit Sub
End If
Do Until myShape.TextFrame.Overflowing = True
myTextRange.Font.Size = _
myTextRange.Font.Size + 0.5
Loop
myTextRange.Font.Size = _
myTextRange.Font.Size - 0.5
End Sub
VBA - OLE Objects
Returns the InlineShape object that represents the new OLE object.
ActiveDocument.Shapes.AddOleObject(ClassType, _
FileName, _
LinkToFile, _
DisplayAsIcon, _
IconFileName, _
IconIndex, _
IconLabel, _
Range)
ClassType -
FileName -
LinkToFile -
DisplayAsIcon -
IconFileName -
IconIndex -
IconLabel -
Range -
Returns the Shape object that represents the new OLE object.
ActiveDocument.Shapes.AddOleObject(ClassType, _
FileName, _
LinkToFile, _
DisplayAsIcon, _
IconFileName, _
IconIndex,_
IconLabel, _
Left, _
Top, _
Width, _
Height, _
Anchor)
ClassType -
FileName -
LinkToFile, -
DisplayAsIcon -
IconFileName -
IconIndex -
IconLabel -
Left -
Top -
Width -
Height -
Anchor -
VBA - ActiveX Controls
Adding ActiveX / OLE Controls
ActiveX controls are represented as either Shape objects or InlineShape objects in Microsoft Word.
To modify the properties for an ActiveX control, you use the Object property of the OLEFormat object for the specified shape or inline shape.
Returns the InlineShape object that represents the new ActiveX control.
ActiveDocument.Shapes.AddOleControl(ClassType:=
Range:=Selection.Range)
ClassType - The programmatic identifier for the ActiveX control to be created.
Range -
Returns the Shape object that represents the new ActiveX control.
ActiveDocument.Shapes.AddOleControl(ClassType:=
Left:=10, _
Top:=10, _
Width:=10, _
Height:=10, _
Anchor:=False)
ClassType - The programmatic identifier for the ActiveX control to be created.
Left -
Top -
Width -
Height -
Anchor -
VBA - WordArt
ActiveDocument.Shapes.AddTextEffect(PresetTextEffect:=msoPresetTextEffect.msoTextEffect10, _
Text:= , _
FontName:= ,
FontSize:= ,
FontBold:=msoTriState.msoTrue, _
FontItalic:=msoTriState.msoTrue, _
Left:= ,
Top:= ,
Anchor:=False)
Text - String. The text in the WordArt.
FontName - String. The name of the font used in the WordArt.
FontSize - Single. The size, in points, of the font used in the WordArt.
FontBold - MsoTriState. MsoTrue to bold the WordArt font.
FontItalic - MsoTriState. MsoTrue to italicize the WordArt font.
Left - Single. The position, measured in points, of the left edge of the WordArt shape relative to the anchor.
Top - Single. The position, measured in points, of the top edge of the WordArt shape relative to the anchor.
VBA - Frames
Frame Object
Represents a frame. The Frame object is a member of the Frames collection.
Frames Collection
The Frames collection includes all frames in a selection, range, or document.
Use Frames(index), where index is the index number, to return a single Frame object.
The index number represents the position of the frame in the selection, range, or document.
The following example allows text to wrap around the first frame in the active document.
ActiveDocument.Frames(1).TextWrap = True
Creating Frames
Use the Add method to add a frame around a range.
The following example adds a frame around the first paragraph in the active document.
ActiveDocument.Frames.Add Range:=ActiveDocument.Paragraphs(1).Range
If you want the frame to "move with text" then the relative vertical position must be paragraph
With ActiveDocument.Frames(1)
.RelativeVerticalPosition = wdRelativeVerticalPosition.wdRelativeVerticalPositionParagraph
End With
Tables in the Frames collection
If you have a table in your document which has been positioned in a particular place on the page then this table will appear in the Frames collection
The text wrapping for this table will be "Around"
Text Wrapping
You can wrap text around Shape or ShapeRange objects by using the WrapFormat property.
You can position a Shape or ShapeRange object by using the Top and Left properties.
Sub FramePositioning()
Dim objframe As Word.Frame
Set objframe = ActiveDocument.Frames.Item(1)
'there is no .Left
Debug.Print objframe.Height
Debug.Print objframe.HeightRule
Debug.Print objframe.Borders
Debug.Print objframe.HorizontalDistanceFromText
Debug.Print objframe.HorizontalPosition
Debug.Print objframe.LockAnchor
Debug.Print objframe.RelativeHorizontalPosition
Debug.Print objframe.RelativeVerticalPosition
Debug.Print objframe.Shading
Debug.Print objframe.TextWrap
Debug.Print objframe.VerticalDistanceFromText
Debug.Print objframe.VerticalPosition
Debug.Print objframe.Width
Debug.Print objframe.WidthRule
End Sub
Cut the offending shapes out of the document and paste them back into the document with their anchors at a new location, immediately below the heading paragraph.
Public Sub MoveAnchors
Dim objShape As Shape
For Each objShape In ActiveDocument.Shapes
If Left(objShape.Anchor.Style,7) = "heading" Then
objShape.Select
Selection.Cut
Selection.MoveDown Unit:=wdParagraph, Count:=1
Selection.Paste
End If
Next objShape
End Sub
If you work with Frames.
The TextRange property of the TextFrame object returns a range containing the text within the text frame.
Frame Property
Returns a Frame object that represents the frame formatting for the specified style or find-and-replace operation. Read-only.
This example creates a style with frame formatting and then applies the style to the first paragraph in the selection.
Dim styleNew As Style
Set styleNew = ActiveDocument.Styles _
.Add(Name:="frame", Type:=wdStyleTypeParagraph)
With styleNew.Frame
.RelativeHorizontalPosition = wdRelativeHorizontalPositionMargin
.HeightRule = wdFrameAuto
.WidthRule = wdFrameAuto
.TextWrap = True
End With
Selection.Paragraphs(1).Range.Style = "frame"
This example finds the first frame with wrap around formatting. If such a frame is found, a message is displayed on the status bar.
With ActiveDocument.Content.Find
.Text = ""
.Frame.TextWrap = True
.Execute Forward:=True, Wrap:=wdFindContinue, Format:=True
If .Found = True Then StatusBar = "Frame was found"
.Parent.Select
End With
Selection.Frames(1).TextWrap = false
© 2026 Better Solutions Limited. All Rights Reserved. © 2026 Better Solutions Limited TopPrev