Search code examples
vbams-wordparagraph

Change cross-reference text in middle of the text to lowercase using showfieldcodes


I want to change all the cross-reference text that are in middle of the text to lowercase, but not the ones at the beginning of a sentence.

The problem is that ActiveDocument.Paragraphs(row).Range.Text is going through the original text, not the ShowFieldCodes (or Alt+F9 view), which generates longer paragraphs and rows.

Sub SetLowerCase()
Dim bBig As Boolean
Dim txt As String, row As String, pos As Integer
ActiveWindow.View.ShowFieldCodes = True
Selection.HomeKey unit:=wdStory
    With Selection.Find
        .ClearFormatting
        .Text = "^d REF"
        .Forward = True
        .Wrap = wdFindStop
        .Format = False
        .MatchWildcards = False
        Do While .Execute
            pos = Selection.Information(wdFirstCharacterColumnNumber)
            row = Selection.Information(wdFirstCharacterLineNumber)
            'The problem is that "ShowFieldCodes" generates longer paragraphs and more rows, which the next line does not take into account
            txt = ActiveDocument.Paragraphs(row).Range.Text
            If pos = 1 Then
                bBig = True
            ElseIf Mid(txt, pos - 2, 2) = ". " Then
                bBig = True
            ElseIf Mid(txt, pos - 1, 1) = "." Then
                bBig = True
            End If
            If bBig = False Then
                If Not Selection.Text Like "*Lower*" Then
                    With Selection
                        .MoveRight unit:=wdCharacter, Count:=1
                        .MoveLeft unit:=wdCharacter, Count:=1
                        .TypeText Text:="\*Lower "
                        .Fields.Update
                    End With
                End If
            Else
                bBig = False
            End If
            Selection.Collapse wdCollapseEnd
        Loop
    End With
ActiveWindow.View.ShowFieldCodes = False
End Sub

Solution

  • For example:

    Sub Demo()
    Application.ScreenUpdating = False
    Dim Fld As Field, Rng As Range, StrRef As String
    With ActiveDocument
      .ActiveWindow.View.ShowFieldCodes = False
      For Each Fld In .Range.Fields
        With Fld
          If .Type = wdFieldRef Then
            Set Rng = .Result: StrRef = Split(Trim(.Code.Text), " ")(1)
            Rng.MoveStart wdSentence, -1
            Rng.MoveEnd wdSentence, 1
            If Rng.Sentences.Count = 1 Then
              .Code.Text = "REF " & StrRef & " \* Lower \h"
            Else
              .Code.Text = "REF " & StrRef & " \* FirstCap \h"
            End If
          End If
        End With
      Next
      .Fields.Update
    End With
    Application.ScreenUpdating = True
    End Sub
    

    Whichever approach you take, you'll run up against VBA's ignorance of what a grammatical sentence is. For example, consider the following:

    Mr. Smith spent $1,234.56 at Dr. John's Grocery Store, to buy: 10.25kg of potatoes; 10kg of avocados; and 15.1kg of Mrs. Green's Mt. Pleasant macadamia nuts.

    For you and me, that would count as one sentence; for VBA it counts as 5...