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

AutoUpdateTrue if the links is updated automatically when the container file is opened.
LockedTrue is the link is locked to prevent automatic updating. This can only be used on Shapes that are Inline.
SavePictureWithDocumentTrue if the specified picture is saved with the document
SourceFullNameReturns or sets the path and name of the source file for the specified linked OLE object, picture, or field. Read/write String.
SourceNameReturns the name of the source file for the specified linked OLE object, picture, or field. Read-only String.
SourcePathReturns the path of the source file for the specified linked OLE object, picture, or field. Read-only String.
Type 

Methods

BreakLinkBreaks the link between the source file and the specified OLE object, picture, or linked field.
UpdateUpdates 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