Clairekun
Clairekun

Reputation: 25

Add images and captions programmatically, with bold label

I would like to add captions to figures where chapters would be included in the numbering, and the text "Figure x.x." was bold:

Figure 1.1. Sample figure.

Autocaptions is not possible because it will only allow for styles named Heading 1-9 to be considered as chapters, while I am using a custom style. As I understand, there is no way to include any personalised style to the list.

Please take into consideration that my knowledge of VBA is virtually nonexistant (I usually try to find a similar problem in multiple forums and adapt it using guides or other similar solved problems), so my error might be trivial for those who are more experienced. I could manage to write a macro to do almost everything I needed, but there is this one thing that is not working as expected.

Ideally, the macro would:

Sub PicCaption()
Dim intChoice As Integer
Dim strPath As String
'only allow the user to select one file
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = True
'make the file dialog visible to the user
intChoice = Application.FileDialog(msoFileDialogOpen).Show
'determine what choice the user made
If intChoice <> 0 Then
'get the file path selected by the user
strPath = Application.FileDialog( _
msoFileDialogOpen).SelectedItems(1)
End If
'insert the image
Selection.InlineShapes.AddPicture FileName:= _
strPath, LinkToFile:=False, _
SaveWithDocument:=True
Selection.Range.Style = "Figures"
'Add caption in the form of "Figure x.x. "
Selection.TypeParagraph
Selection.TypeText Text:="Figure "
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"STYLEREF ChapNum \n \t", PreserveFormatting:=False
Selection.TypeText Text:="."
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"SEQ Figure \* ARABIC", PreserveFormatting:=False
Selection.TypeText Text:="."
Selection.Style = ActiveDocument.Styles("Figures")
Selection.TypeText Text:=" "
'Make "Figure x.x." bold (last space not included)
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = False
.Text = "Figure*.*"
.Font.Bold = False
.MatchWildcards = True
.Replacement.Text = "^&"
.Replacement.Font.Bold = True
.Execute Replace:=wdReplaceOne, Forward:=True, _
Wrap:=wdFindContinue
End With
End Sub

The replacing bit does not make the recently inserted "Figure x.x." bold, but the next one in the text, even if I specified the search to be backwards. If I type .Execute Replace:=wdReplaceOne, Forward:=False, _, it goes to the end of the document and moves upwards, making everything bold.

In my sample document I have multiple already captioned images, but that wouldn't normally be the case; I would like to format captions as I insert them, instead of reformatting them when the document is finished.

Where is my mistake and why, if you were so kind to explain?

Thank you kindly.

Upvotes: 0

Views: 878

Answers (2)

freeflow
freeflow

Reputation: 4355

When Word inserts a caption it is basically providing a shortcut for the insertion of a number of fields and their associated switches.

Thus if we insert a Figure caption that references Heading 3 style for the chapter numbers we get something like

Figure 2.1.3-1:    Text for the caption

If we highlight the 'Figure 2.1.3-1' in the Word document and press Shift-F9 this will show that the caption numbering is composed of a styleref field and a seq field

Figure {Styleref 3 \w}-{Seq Figure}

When the field codes are shown we can easily use the built in Find/Replace of word to change the text between the field brackets. So we could search for 'Styleref 3' and replace it with 'Styleref "Heading 2"' or in fact 'Styleref "myStyle"'.

If the Word wildcard search is used then you can simultaneously change the style ref to the desired style and apply the bold effect, thus achieving the effect that the OP desires. I'll leave that to a little research by the OP.

This is fine if we have to convert an existing document. If we are inserting Captions as we type then it would be preferable to use a macro to insert the caption numbering that is desired by firing a macro that inserts the appropriate caption numbering/formatting from a set of keystrokes.

The macro below will insert a caption of the type desired, use the defined style for chapter numbering and apply the bold effect to all the numbering upto the separating tab.

Option Explicit

' Any Leading and Trailing spaces in the Const definition strings are deliberate
' Heading 2 is used for ease of demonstration.  Heading 2 should be replaced by the style
' from which you wish to take the heading numbers.
Const SpecialCaptionStyle               As String = """Heading 2"""     ' Name of the style to reference for the heading number
Const CaptionType                       As String = "Figure "           ' The trailing space is required
Const CaptionNUmberingStyle             As String = " \w "              ' see switches for the styleref field
Const CaptionNumberSeparator            As String = "-"

Public Sub InsertSpecialCaption()
    
    ' Get the range into which we insert the styleref and seq fields
    Dim myFieldRange As Word.Range
    Set myFieldRange = Selection.Range

    'Preserve the srarting range for later use
    Dim myEffectRange As Word.Range
    Set myEffectRange = Selection.Range.Duplicate
    
    'Set the style to Caption style.
    'Caption style will be applied to any text in the paragraph of the selection point
    myFieldRange.Collapse direction:=wdCollapseEnd
    myFieldRange.Paragraphs.Item(1).Style = myFieldRange.Document.Styles(wdStyleCaption)
    
    'Insert the label of the caption type.  In this case it is the text 'Figure'
    myFieldRange.InsertAfter Text:=CaptionType
    myFieldRange.Collapse direction:=wdCollapseEnd
    
    Dim myField As Word.Field
    ' Insert the styleref field to obtain the heading number of the style we specify
    Set myField = myFieldRange.Document.Fields.Add(Range:=myFieldRange, Preserveformatting:=False)
    myField.Code.Text = "Styleref " & SpecialCaptionStyle & CaptionNUmberingStyle
    Set myFieldRange = myField.Result
    
    'Insert the text string used as a seperator between the chapter number and the captiontype number
    myFieldRange.InsertAfter Text:=CaptionNumberSeparator
   myFieldRange.Collapse direction:=wdCollapseEnd
    
    ' Insert the Seq field to get the sequential number of the caption
    ' in this case we use the same name of the label but it could be different
    Set myField = myFieldRange.Document.Fields.Add(Range:=myFieldRange, Type:=wdFieldEmpty, Preserveformatting:=False)
    myField.Code.Text = "Seq " & CaptionType
    Set myFieldRange = myField.Result
    myFieldRange.Collapse direction:=wdCollapseEnd
    
    ' Insert the seperator text from the number to the Caption text NB I always use : followed by a tab
    myFieldRange.InsertAfter Text:=":" & vbTab
    
    ' Adjust the range to omit the tab from formatting
    ' update the fields
    ' Apply bold effect to the inserted caption label
    myFieldRange.MoveEnd unit:=wdCharacter, Count:=-1
    myEffectRange.End = myFieldRange.End
    myEffectRange.Fields.Update
    myEffectRange.Font.Bold = True
    
End Sub

All that is required is to link the macro to a suitable key sequence, which is the provenance of the OP.

First though, I'd strongly suggest using F8 to step through the macro to see how the Caption number is inserted.

Upvotes: 0

Clairekun
Clairekun

Reputation: 25

I found my answer: for whatever reason, once fields are involved, finding and replacing does not work that well; i.e. it won't correctly find periods within "1.1.". I tried it with and without wildcards, using ?, * and anything I could think of.

I resorted to another method:

  • Select whole line
  • Make bold
  • Go to the end of the line
  • Uncheck bold so that the description has normal font width
'Code before this point remains identical
'Make "Figure x.x." bold (last space not included)
'Select from cursor point to beginning of line; make bold
Selection.MoveStart Unit:=wdLine, Count:=-1
Selection.Font.Bold = True
'Move cursor to end of the line; uncheck bold format
Selection.EndKey Unit:=wdLine
Selection.Font.Bold = wdToggle

This way, the cursor is placed right after the caption label, bold not selected. Seems clumsy and highly unprofessional, but works.

Thanks, everyone!

Upvotes: 1

Related Questions