![]() |
|
#1
|
||||
|
||||
|
When images are positioned with text wrapping 'Square', Word inserts their captions into text boxes. In such situations, the caption ordering for multiple shapes anchored to a single paragraph is hard to control because it’s based on the order of the anchors in the document stream (which you can’t see). Captions in textboxes create other problems of their own if you create a Table of Figures (TOF); in that case, Word inserts a fully-qualified path into the TOF, which creates problems when the file is saved as PDF (the TOF links back to the original document).
The following macro resolves these issues by inserting the images into the cells of floating tables, as inlineshapes, with the captions in the tables also. As coded, the macro processes all floating & inline images, but it could be stripped down to work with just the floating images or even just a selected image. Either way, the disconnect between the images and their captions will be resolved. Whatever positioning and text wrapping applied to the original image will apply to the table also. To have the caption row appear above the image, instead of below, change the Rows(1) references to Rows(2), change the Cell(1, 1) references to Cell(2, 1) and change the change the Cell(2, 1) references to Cell(1, 1). Note that, due to the extra space taken up by the caption row, all except for the first of the document's pictures are liable to shift position. Once the macro has run, it will be a simple matter to move any existing captions into the empty cells provided and delete whatever paragraphs/textboxes those captions formerly occupied. Code:
Sub AddImageCaptionTables()
Application.ScreenUpdating = False
'Sourced from: https://www.msofficeforums.com/drawing-and-graphics/49784-work-around-word-limitations-image-captioning.html
Dim iShp As InlineShape, Rng As Range, Tbl As Table
Dim i As Long, PicWdth As Single, PicHght As Single, VPos As Single
Dim HPos As Single, VRel As Long, HRel As Long, BShp As Boolean
With ActiveDocument
For i = 1 To .InlineShapes.Count
If .InlineShapes(i).Range.Information(wdWithInTable) = False Then
With .InlineShapes(i)
.LockAspectRatio = True
PicWdth = .Width
PicHght = .Height
Set Rng = .Range
End With
With Rng
If .Characters.Last.Next.Text = vbCr Then .Characters.Last.Next.Text = vbNullString
.InlineShapes(1).Range.Cut
End With
BShp = False: VRel = 0: HRel = 0: VPos = 0: HPos = 0
Call MakeImageTable(Rng, PicWdth, PicHght, BShp, VRel, HRel, VPos, HPos)
End If
Next
While .Shapes.Count > 0
BShp = True
With .Shapes(1)
.LockAspectRatio = True
PicWdth = .Width
PicHght = .Height
VRel = .RelativeVerticalPosition
HRel = .RelativeHorizontalPosition
VPos = .Top
HPos = .Left
Set iShp = .ConvertToInlineShape
End With
With iShp
Set Rng = .Range
.Range.Cut
End With
Call MakeImageTable(Rng, PicWdth, PicHght, BShp, VRel, HRel, VPos, HPos)
Wend
End With
End Sub
Sub MakeImageTable(Rng As Range, PicWdth As Single, PicHght As Single, BShp As Boolean, _
VRel As Long, HRel As Long, VPos As Single, HPos As Single)
Dim Tbl As Table, sngScl As Single, iShp As InlineShape
'Constrain maximum image size
If PicWdth > CentimetersToPoints(7.5) Then
sngScl = PicWdth / CentimetersToPoints(7.5)
PicWdth = PicWdth / sngScl
PicHght = PicHght / sngScl
End If
If PicHght > CentimetersToPoints(5) Then
sngScl = PicHght / CentimetersToPoints(5)
PicWdth = PicWdth / sngScl
PicHght = PicHght / sngScl
End If
'Create & format the table
Set Tbl = Rng.Tables.Add(Range:=Rng, Numrows:=2, NumColumns:=1)
With Tbl
.Borders.Enable = True
.Columns.Width = PicWdth
.TopPadding = 0
.BottomPadding = 0
.LeftPadding = 0
.RightPadding = 0
.Spacing = 0
.Rows(1).HeightRule = wdRowHeightExactly
.Rows(1).Height = PicHght
With .Rows
.LeftIndent = 0
If BShp = True Then
.WrapAroundText = True
.HorizontalPosition = HPos
.RelativeHorizontalPosition = HRel
.VerticalPosition = VPos
.RelativeVerticalPosition = VRel
.AllowOverlap = False
End If
End With
With .Cell(1, 1).Range
With .ParagraphFormat
.SpaceBefore = 0
.SpaceAfter = 0
.LeftIndent = 0
.RightIndent = 0
.FirstLineIndent = 0
.KeepWithNext = True
End With
.Paste
'Resize the inserted InlineShape
Set iShp = .InlineShapes(1)
With iShp
.Width = PicWdth
.Height = PicHght
End With
End With
'Insert the caption
With .Cell(2, 1).Range
.Style = "Caption"
.End = .End - 1
.InsertAfter vbCr
.InsertCaption Label:="Figure", TitleAutoText:=" ", Title:="", _
Position:=wdCaptionPositionBelow, ExcludeLabel:=0
.Paragraphs.First.Range.Characters.Last.Text = vbNullString
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
.Borders(wdBorderRight).LineStyle = wdLineStyleNone
.Borders(wdBorderTop).LineStyle = wdLineStyleNone
End With
End With
Application.ScreenUpdating = True
End Sub
Code:
With ActiveDocument Code:
With Selection Code:
While .Shapes.Count > 0
With .Shapes(1)
Code:
While .ShapeRange.Count > 0
With .ShapeRange(1)
Note 2: As coded, the 'MakeImageTable' macro inserts the word 'Figure' as the caption label for each caption. That label can be changed to something else, or that part of the code can be omitted entirely. For PC macro installation & usage instructions, see: Installing Macros For Mac macro installation & usage instructions, see: Word:mac - Install a Macro
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| re: How does OneNote's copy from image work? | Tom Layman | OneNote | 0 | 10-17-2017 06:09 AM |
| Trying to work on on image | wabash12 | PowerPoint | 3 | 06-25-2013 07:52 AM |
| Captioning with different Headings | judicial85 | Word | 3 | 03-05-2012 05:06 PM |
| Picture Captioning | judicial85 | Word | 0 | 02-06-2012 06:18 AM |
| Help Relieve Captioning Torture! | trhindc | Word | 0 | 05-12-2010 10:25 AM |