简体   繁体   中英

Sub fails to find long sentences if there is not a space between the period and endnote citations (superscripts)

I have a simple loop (below) that looks for sentences over 30 words long. If found, it adds a comment box to the selected sentence. It worked fine in testing. Then I added some test endnote citations...and it fails to find the long sentences.

However, it only fails when there is no space between the period and the citation superscript . If I add a space, it finds it and works perfectly. The problem is, there is not suposed to be a space between the period and the citation, per the style guide I have to follow at work.

This related Stack thread discusses the need for a space after a period to delineate the end of a sentence. I am assuming the space must be directly after the period, because I have spaces in my citations like this 1, 2, 3

Question

How can I find instances of period+superscript (with no space like this --> This is a sentence.1, 2, 3) and add a space? Ideally I would like this to happen within the below loop so I can remove the space after the comment gets added.

Sub Comment_on_Long_Sentences ()

Dim iWords as Integer

iWords = 0

For Each MySent in ActiveDocument.Sentences

If MySent.Words.Count > iWords Then

    MySent.Select

    'find and delete space

    ActiveDocument.Comments.Add Range:= Selection.Range, Text:= "Long Sentence: " & iWords & " words"

    'put the space back

End if

Next MySent

End Sub

There appears to be issues in VBA when trying to access Sentences that end with a superscript character. Your code also has problems with non-declared variables, so I have no idea how it ever worked for you in the first place.

Try this following VBA routine, it works in my environment. Also notice the special handling that I found is required for 1st sentences in paragraphs and when that sentence ends with a superscript character.

Sub Comment_on_Long_Sentences()
    Dim doc As word.Document, rng As word.Range, para As word.Paragraph
    Dim i As Long

    Set doc = ActiveDocument
    For Each para In doc.Paragraphs
        Debug.Print para.Range.Sentences.Count
        For i = 1 To para.Range.Sentences.Count
            Set rng = para.Range.Sentences(i)
            If i = 1 And rng.Characters.First.Font.Superscript = True Then
                rng.MoveStart word.WdUnits.wdSentence, Count:=-1
            End If
            If rng.words.Count > 30 Then
                doc.Comments.Add Range:=rng, Text:="Long Sentence: " & rng.words.Count & " words"
            End If
        Next
    Next
End Sub

Here is an alternative solution. Note the option explicit at the start. Its good VBA practice to put this at the top of every module.

The problem you have is very common. Find something then rather than do a replace, do some other non replace related stuff. The subs to add and remove spaces before citations implement this pattern and are well worth studying.

If you don't understand anything then in the VBA IDE just put your cursor on the relevant keyword and press F1. This will bring up the relevant MS help page.

Option explicit

Sub Comment_on_Long_Sentences()

Dim iWords                          As Integer
Dim my_sentence                     As Variant

    iWords = 30

    AddSpaceBeforeCitations

    For Each my_sentence In ActiveDocument.Sentences

        If my_sentence.Words.Count > iWords Then

          my_sentence.Comments.Add Range:=my_sentence, Text:="Long Sentence: " & iWords & " words"

        End If

    Next my_sentence

    RemoveSpaceBeforeCitations

    End Sub

Sub AddSpaceBeforeCitations()

    With ActiveDocument.Content

        With .Find

            .ClearFormatting
            .Format = True
            .Text = ""
            .Wrap = wdFindStop
            .Font.Superscript = True
            .Execute

        End With

        Do While .Find.Found

            With .Previous(unit:=wdCharacter, Count:=1).characters

                If .Last.Text = "." Then

                    .Last.Text = ". "

                End If

              End With

            .Collapse direction:=wdCollapseEnd
            .Move unit:=wdCharacter, Count:=1
            .Find.Execute

        Loop

    End With

End Sub

Sub RemoveSpaceBeforeCitations()

    With ActiveDocument.Content

        With .Find

            .ClearFormatting
            .Format = True
            .Text = ""
            .Wrap = wdFindStop
            .Font.Superscript = True
            .Execute

        End With

        Do While .Find.Found

            With .Previous(unit:=wdCharacter, Count:=2).characters

                If (.Last.Text = ".") Then

                     .Last.Next(unit:=wdCharacter, Count:=1).characters.Last.Text = vbNullString

                End If

            End With

            .Collapse direction:=wdCollapseEnd
            .Move unit:=wdCharacter, Count:=1
            .Find.Execute

        Loop

    End With

End Sub

No matter what approach you take, any code that relies on the VBA .Sentence property or .Word property is going to produce unreliable results. That's because .Sentence has no idea what a grammatical sentence and .Word has no idea what a grammatical word 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, 26-word sentence; for VBA it counts as 5 sentences containing 45 words overall. For an accurate word count, use .ComputeStatistics(wdStatisticWords). Sadly there is no .ComputeStatistics(wdStatisticSentences) equivalent for sentences.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM