0

The code below is supposed to stop at a time at each colon or semi-colon, highlight and copy the text between the cursor position and the occurrence. If “:” or “;” is not found it would look for the next period. However, for the “:” and “;” the code works properly only if they are followed by a paragraph mark, and fails to stop at them in the middle of a sentence. Any idea how to fix this? Thank you very much

    Sub SelectHighlightandCopy()
        Dim regEx As Object 
        Dim sentence As Range
        Set regEx = CreateObject("VBScript.RegExp")
        
        With regEx
            .pattern = "[:|;]"     
            .Global = True
            .IgnoreCase = False
        End With
        
        For Each sentence In Selection.Range.Sentences
            If regEx.Test(sentence.Text) Then
                sentence.Select
                Selection.Range.HighlightColorIndex = wdTurquoise
                Selection.Copy
                Selection.MoveRight unit:=wdCharacter, Count:=1
            Else
                regEx.pattern = "\.(?![\d+.\d+])|\r|\n}"
                If regEx.Test(sentence.Text) Then
                    sentence.Select
                    Selection.Range.HighlightColorIndex = wdGray25
                    Selection.Copy
                    Selection.MoveRight unit:=wdCharacter, Count:=1
                End If
            End If
        Next sentence
    End Sub
Oscar Sun
  • 1,427
  • 2
  • 8
  • 13
Stillme
  • 21
  • 3

1 Answers1

0

You can refer to my this answer.

https://stackoverflow.com/a/76260672/8249058

In that answer, I did not use the copy command, but You can use the Range object I already found when I want to highlight it, apply it's Copy method (if you are sure you want to select it and highlight it, then apply the Select method, otherwise, just to copy it is not necessary.) In this line:

d.Range(match.FirstIndex + 2, match.FirstIndex + match.Length + 2).Font.ColorIndex = wdRed

That will be like :

dim rng as Range
set rng=d.Range(match.FirstIndex + 2, match.FirstIndex + match.Length + 2)
'rng.Font.ColorIndex = wdRed

rem this will just highlight the range found by reExp
rng.HighlightColorIndex = wdGray25

rem this will highlight the sentence where range found by reExp
rng.Sentences(1).HighlightColorIndex = wdGray25

rng.Copy

rem default omit
'rng.Select 'Use only when necessary

If not necessary, try to use Range, not Selection or Selection.Range. see my article here.

If you have any questions, please feel free to discuss them. Thank you

The Code while you want to mark them one by one:

Sub SelectHighlightandCopy()
    Dim regEx As Object, match As Object, matchs As Object
    'Dim regEx As New VBScript_RegExp_55.RegExp, match As VBScript_RegExp_55.match, matchs As VBScript_RegExp_55.MatchCollection
    Dim ur As UndoRecord, d As Document, s As Long, rng As Range
    Set ur = Word.Application.UndoRecord
    ur.StartCustomRecord "SelectHighlightandCopy"
    Set d = ActiveDocument: Set rng = d.Content
    If Selection.Characters.Count > 2 Then Selection.Collapse
    s = Selection.Start
        
    Dim sentence As Range
    Set regEx = CreateObject("VBScript.RegExp")
    
    With regEx
        .Global = False 'True
        .IgnoreCase = False
    End With
    
    Set sentence = Selection.Sentences(1)
    regEx.Pattern = ";"
    If regEx.test(sentence.Text) Then
        GoSub SelectMarkCopy
    Else
        regEx.Pattern = ":"
        If regEx.test(sentence.Text) Then
            GoSub SelectMarkCopy
        Else
            'regEx.Pattern = "\.(?![\d+.\d+])|\r|\n}"
            rng.SetRange s, sentence.End
            rng.Select
            rng.HighlightColorIndex = wdGray25
            rng.Copy
        End If
    End If

    ur.EndCustomRecord
    
'    Selection.Collapse
    
    Exit Sub

SelectMarkCopy:
    Set matchs = regEx.Execute(sentence)
    Set match = matchs(0)
    rng.SetRange s, sentence.Start + match.FirstIndex + 1
    rng.Select
    rng.HighlightColorIndex = wdTurquoise
    rng.Copy
Return

End Sub

The Code while you want to mark them all in once:

suppose in this scenario: enter image description here If this is the result you want to, and all the text is executed by the code.

Sub SelectHighlightandCopy() 'The Code while you want to mark them all in once
    Dim regEx As Object, match As Object, matchs As Object
    'Dim regEx As New VBScript_RegExp_55.RegExp, match As VBScript_RegExp_55.match, matchs As VBScript_RegExp_55.MatchCollection
    Dim ur As UndoRecord, d As Document, s As Long, rng As Range
    Set ur = Word.Application.UndoRecord
    ur.StartCustomRecord "SelectHighlightandCopy"
    Set d = ActiveDocument: Set rng = d.Content
        
    Dim sentence As Range
    Set regEx = CreateObject("VBScript.RegExp")
    
    With regEx
        .Global = False 'True
        .IgnoreCase = False
    End With
    

    For Each sentence In d.Sentences
        s = sentence.Start
        regEx.Pattern = ";"
        If regEx.test(sentence.Text) Then
            GoSub SelectMarkCopy
        Else
            regEx.Pattern = ":"
            If regEx.test(sentence.Text) Then
                GoSub SelectMarkCopy
            Else
                'regEx.Pattern = "\.(?![\d+.\d+])|\r|\n}"
                rng.SetRange s, sentence.End
'                rng.Select
                rng.HighlightColorIndex = wdGray25
                rng.Copy
            End If
        End If
    Next sentence

    ur.EndCustomRecord
    
    
    Exit Sub

SelectMarkCopy:
    Set matchs = regEx.Execute(sentence)
    Set match = matchs(0)
    rng.SetRange s, sentence.Start + match.FirstIndex + 1
'    rng.Select
    rng.HighlightColorIndex = wdTurquoise
    rng.Copy
Return

End Sub

The result of program execution

enter image description here

The Code while you want to mark them all in once from the cursor position(insertion position) beginning

Sub SelectHighlightandCopy() 'The Code while you want to mark them all in once from the cursor position(insertion position) beginning
    Dim regEx As Object, match As Object, matchs As Object
    'Dim regEx As New VBScript_RegExp_55.RegExp, match As VBScript_RegExp_55.match, matchs As VBScript_RegExp_55.MatchCollection
    Dim ur As UndoRecord, d As Document, s As Long, rng As Range
    Set ur = Word.Application.UndoRecord
    ur.StartCustomRecord "SelectHighlightandCopy"
    Set d = ActiveDocument: Set rng = d.Content
    s = Selection.Start
        
    Dim sentence As Range
    Set regEx = CreateObject("VBScript.RegExp")
    
    With regEx
        .Global = False 'True
        .IgnoreCase = False
    End With
    

    For Each sentence In d.Range(s, d.Content.End).Sentences
        regEx.Pattern = ";"
        If regEx.test(sentence.Text) Then
            GoSub SelectMarkCopy
        Else
            regEx.Pattern = ":"
            If regEx.test(sentence.Text) Then
                GoSub SelectMarkCopy
            Else
                'regEx.Pattern = "\.(?![\d+.\d+])|\r|\n}"
                rng.SetRange s, sentence.End
'                rng.Select
                rng.HighlightColorIndex = wdGray25
                rng.Copy
            End If
        End If
        If Not sentence.Next Is Nothing Then
            s = sentence.Next.Start
        End If
    Next sentence

    ur.EndCustomRecord
    
    
    Exit Sub

SelectMarkCopy:
    Set matchs = regEx.Execute(sentence)
    Set match = matchs(0)
    If sentence.Start + match.FirstIndex < s Then
        s = sentence.Start
    End If
    rng.SetRange s, sentence.Start + match.FirstIndex + 1
'    rng.Select
    rng.HighlightColorIndex = wdTurquoise
    rng.Copy
Return

End Sub

The result of program execution

enter image description here

Sentence by Sentence comparison, except sentences containing fields(functional variables)

Sub SelectHighlightandCopy() 'Sentence by Sentence comparison, except sentences containing fields(functional variables)
    Dim regEx As Object, match As Object, matchs As Object
    'Dim regEx As New VBScript_RegExp_55.RegExp, match As VBScript_RegExp_55.match, matchs As VBScript_RegExp_55.MatchCollection
    Dim ur As UndoRecord, d As Document, s As Long, rng As Range, s1 As Long ', txt As String, hasFields As Boolean
    Set ur = Word.Application.UndoRecord
    ur.StartCustomRecord "SelectHighlightandCopy"
    Set d = ActiveDocument: Set rng = d.Content
'    If Selection.Characters.Count > 2 Then Selection.Collapse
        
    Dim sentence As Range
    Set regEx = CreateObject("VBScript.RegExp")
    
    With regEx
        .Global = False 'True
        .IgnoreCase = False
    End With
    
KeepGoing:
    Set sentence = Selection.Sentences(1)
    If sentence.Fields.Count = 0 Then
'        txt = sentence.Text
    Else
'        hasFields = True
'        txt = sentence.Fields(1).Code
        MsgBox "There are fields, please check by yourself!", vbExclamation
        Exit Sub
    End If
    
    If s1 = 0 Then
        s = sentence.Start
    Else
        s = s1
        sentence.SetRange s1, sentence.End
    End If
    regEx.Pattern = ";"
    If regEx.test(sentence.Text) Then
    'If regEx.test(txt) Then
        GoSub SelectMarkCopy
        GoTo KeepGoing
    Else
        regEx.Pattern = ":"
        If regEx.test(sentence.Text) Then
        'If regEx.test(txt) Then
            GoSub SelectMarkCopy
            GoTo KeepGoing
        Else
            'regEx.Pattern = "\.(?![\d+.\d+])|\r|\n}"
            rng.SetRange s, sentence.End
            rng.HighlightColorIndex = wdGray25
            rng.Copy
            rng.Select
            s1 = 0
        End If
    End If
    ur.EndCustomRecord
    
    Selection.Document.ActiveWindow.ScrollIntoView Selection.Range
    
    Selection.Collapse wdCollapseEnd
    
'    If hasFields Then
'        Selection.Range.SetRange Selection.Sentences(1).Next.Start, Selection.Sentences(1).Next.Start
'    End If
    
    Exit Sub

SelectMarkCopy:
    Set matchs = regEx.Execute(sentence)
    'Set matchs = regEx.Execute(txt)
    Set match = matchs(0)
    rng.SetRange s, sentence.Start + match.FirstIndex + 1
    rng.HighlightColorIndex = wdTurquoise
    rng.Copy
    rng.Select
    s1 = rng.End
    Selection.Collapse wdCollapseEnd
'    If hasFields Then
'        Selection.MoveRight
'        'Selection.Range.SetRange Selection.Sentences(1).Next.Start, Selection.Sentences(1).Next.Start
'    End If

Return

End Sub

Oscar Sun
  • 1,427
  • 2
  • 8
  • 13
  • Thank you Oscar Sun for the feedback. I still can't figure out how to fix the code. The range, I think, should be the sentence, but the selection, highlighting and copying should stop each tine the code is triggered at the colon first, if not found the semi-colon, then if not found a period or a paragraph mark. – Stillme May 27 '23 at 20:17
  • @Stillme Why do you want to run Selection.Copy? I don't see any effect in the code! Try my code please, at the end of my answer Is this what you want? – Oscar Sun May 28 '23 at 08:02
  • @Stillme The order you are looking for, 1. colon 2. semicolon 3 period or segment symbol, is that right? If doesn't find a colon, look for a semicolon, and if doesn't find the first two, look for a period. Is that right? What if we find the semicolon first, not the colon? Now the "[:;]" setting is such that the semicolon and colon are equal, regardless of precedence. – Oscar Sun May 28 '23 at 08:21
  • Thank you @Oscar Sun for the code. The code does not work as expected. To answer your questions" 1 - No text should be pre-selected - From the cursor position, the code should look for the first occurrence of a semi-colon, select form the cursor position till the ; highlight that piece of text and copy it – Stillme May 28 '23 at 18:42
  • 2- If a semi-colon, is not found look for a colon and do the same other stuff as in 1 above 4- If a colon, is not found look for a period or a paragraph mark and do the same other stuff as in 2 and 3 above. I hope this clarifies things. Thanks – Stillme May 28 '23 at 18:52
  • @Stillme I rewritten it based on your original code. According to what you said, it is almost different from what the original code is doing. I've updated again, is this what you expect? Can you give a screenshot of the result you would like to see with manual operation and explain it a little? – Oscar Sun May 28 '23 at 19:17
  • Thanks again @ Oscar Sun. The code works properly for periods and paragraph marks. But it gets stuck after colons and semi-colons, i.e. fails to search for the next occurrence. I had to manually move the cursor to the beginning of the next sentence (see screenshot here: https://drive.google.com/file/d/1Ye-Uydbrz3bikyGwBSeRGftJiy8rgvJw/view?usp=sharing). I also got the error: This method or property is not available because no text is selected, because of "rng.Copy". – Stillme May 28 '23 at 20:39
  • @Stillme Your screenshot just shows the problematic situation. Can you give me a screenshot of what you think the result should be, so that I can understand exactly what you want to do. Is that so? – Oscar Sun May 29 '23 at 17:50
  • @Stillme Maybe share with me a .docm file and show what the result you'd like in the text content, better. I'll directly write code in that file and test the text you gave to me and you can immediately test them either. – Oscar Sun May 30 '23 at 02:23
  • @Stillme "I had to manually move the cursor ……", then what does your "cursor" mean? Do you want the program to manipulate the entire document, or do you want the program just to process all the text where behind the user places the cursor? I think you should reorganize and clarify your questions first, otherwise, I or anyone else has to keep guessing what you want. Please rewrite it clearly in your question at the top. If you are still not clear enough, then I have to give up. Even so, when I have time, I'll adapt my code and comment on the context in which it should be used. I've updated mine – Oscar Sun May 30 '23 at 03:48
  • @Stillme *"This method or property is not available because no text is selected, because of "rng.Copy"."* The codes I give are tested and correct before they are published. If an error occurs, you should also give me the text of the test so that I can test to see how the error is caused. Thanks. – Oscar Sun May 30 '23 at 03:56
  • Please @Oscar Sun see this template for text and more clarifications.: https://drive.google.com/file/d/1Mdk38U2ePrc6RMY5xQfDnGkcN1n3iDs3/view?usp=sharing. Thanks. – Stillme May 30 '23 at 18:31
  • @Stillme The methods and objects used in the code I have given you are sufficient to do the job, you just need to change them a little to suit your needs. Why don't you try it yourself? Or are you not asking about the program at all, but asking someone to give you a ready-made program that you don't have to do? – Oscar Sun May 31 '23 at 01:22
  • @Stillme *After every selection and highlighting, the code should place the cusor at the nd of the selection so as to be reday for the next occurance.* Do you mean that you don't need the program to mark up the whole document automatically, but rather a manual decision to do it sentence by sentence? Instead of having the program find and mark for the next sentence itself, so you want to put the insertion point at the end of the previous sentence after the comparison? – Oscar Sun May 31 '23 at 01:27
  • @Stillme Sentence by Sentence comparison, except sentences containing fields(functional variables), is what you want? see my updated code. – Oscar Sun May 31 '23 at 02:39
  • @Stillme Please give me editing privileges so that I can make changes directly in your file. You will have the real-time code for testing, so you don't need to copy and paste it again. If you have important data, please backup it separately first. Thank you. – Oscar Sun May 31 '23 at 03:18
  • 1
    @ScarSunThank you for your time and for the updated code (Sentence by Sentence comparison). It is close to what I am looking for. I will figure out the rest. – Stillme Jun 01 '23 at 23:56
  • @Stillme You're welcome. Feel free to come back to StackOverflow if you have any questions. Thank you. – Oscar Sun Jun 02 '23 at 03:57
  • @Stillme What is the progress? Have you figured it out yet? – Oscar Sun Jun 06 '23 at 17:05
  • 1
    Sun Sorry for the delay. I moved on to something else for the time being. I will let you know. Thanks – Stillme Jun 19 '23 at 19:41