Word VBA Find Passive Voice - vba

I have written a procedure to find passive constructions, e.g. 'was solved', 'been written', i.e. passives ending in 'ed' or 'en', but not things like 'was fruitful'. A comment is inserted for each find.
I'm almost there - but cannot fix a couple of anomalies:
It works for 'was solved.' , 'was solved .' and 'was solved ', (NB spaces in two of these) but not in 'was solved today', i.e. where there are more words after the final verb. This last error is the one I wish to fix.
It also finds the passives in 'is being completed', i.e. two auxiliary verbs together, whether spaces follow the final verb or not. This is an added bonus, apart from the fact that the find is indicated twice.
I suspect this is to do with my Is_Alpha function, which strips punctuation from the end of the main verb.
Thanks folks, any help appreciated.
Sub Passives3()
Dim P_Flag As Boolean
Dim P_Cmt As Comment
Dim P_Rng As Range
Dim P_Rng2 As String
Dim P_New As String
Dim P_Fnd As Boolean
Dim Cmt As Comment
Dim P_Range As Range
Dim P_Ctr As Long
Dim Com_plete As Integer
Dim P_Word(7) As String
P_Word(0) = "am "
P_Word(1) = "are "
P_Word(2) = "be "
P_Word(3) = "been "
P_Word(4) = "being "
P_Word(5) = "is "
P_Word(6) = "was "
P_Word(7) = "were "
For P_Ctr = LBound(P_Word) To UBound(P_Word)
Set P_Rng = ActiveDocument.Range
With P_Rng.Find
.ClearFormatting
.text = P_Word(P_Ctr)
Debug.Print .text
.MatchCase = False
.MatchWholeWord = True
While .Execute
If P_Rng.Find.Found Then
Dim P_test As Range
Set P_test = P_Rng.Duplicate
With P_test
.MoveEnd wdWord, 2
.Select
P_New = P_test
Call Is_Alpha(P_New, P_Flag)
If P_Flag = False Then
P_New = Left(P_New, Len(P_New) - 1)
End If
End With
If (Right(Trim(P_New), 2)) = "ed" _
Or (Right(Trim(P_New), 2)) = "en" Then
Set P_Cmt = P_Rng.Comments.Add(Range:=P_Rng, text:="Passive? " & P_New)
P_Cmt.Author = "Passives"
P_Cmt.Initial = "PSV "
P_Cmt.Range.Font.ColorIndex = wdGreen
End If
End If
Wend
End With
Next
End Sub
Function Is_Alpha(P_New As String, P_Flag As Boolean) As Boolean
If Asc(Right(P_New, 1)) > 64 And Asc(Right(P_New, 1)) < 90 Or _
Asc(Right(P_New, 1)) > 96 And Asc(Right(P_New, 1)) < 123 Then
P_Flag = True
Else
P_Flag = False
End If
End Function

How about:
Sub Passives()
Dim i As Long, j As Long, Cmt As Comment, P_Words, X_Words
P_Words = Array("am ", "are ", "be ", "been ", "being ", "is ", "was ", "were ")
X_Words = Array("am ", "are ", "being ", "is ", "was ", "were ", "has ", "have ")
For i = LBound(P_Words) To UBound(P_Words)
With ActiveDocument.Range
With .Find
.ClearFormatting
.Text = "<" & P_Words(i) & "[! ]#e[dn]>"
.MatchWildcards = True
End With
Do While .Find.Execute
For j = LBound(X_Words) To UBound(X_Words)
If .Words.First.Previous.Words.First.Text = X_Words(j) Then
.Start = .Words.First.Previous.Words.First.Start
End If
Next
Set Cmt = .Comments.Add(Range:=.Duplicate, Text:="Passive?")
With Cmt
.Author = "Passives"
.Initial = "PSV "
.Range.Font.ColorIndex = wdGreen
End With
.Collapse wdCollapseEnd
Loop
End With
Next
End Sub

Related

Delete duplicate words from document more efficiently

I compare each word with other and check if that is the duplicate if yes then delete it. For 1 to 4 pages it takes at most 5 minutes.
For a document of 50 or 100 pages I need of modification or a new idea to compare and delete duplicates with less time.
Sub Delete_Duplicates()
'***********'
'By
'MBA
'***********'
Dim AD As Range
Dim F As Range
Dim i As Long
Set AD = ActiveDocument.Range
Z = AD.Words.Count
y = 1
For i = Z To 1 Step -1
y = y + 1
Set F = AD.Words(i)
On Error Resume Next
Set s = AD.Words(i - 1)
If Trim(AD.Words(i - 1)) = "," Then Set s = AD.Words(i - 2): Set c = AD.Words(i - 1)
If Err.Number > 0 Then Exit Sub
If Not F.Text = Chr(13) And UCase(Trim(F.Text)) = UCase(Trim(s.Text)) Then
F.Text = ""
If Not c Is Nothing Then c.Text = " ": Set c = Nothing
End If
If Not c Is Nothing Then Set c = Nothing
On Error Resume Next
Call ProgressBar.Progress(y / Z * 100, True) '<<-- Progress Bar
On Error GoTo 0
Next
Beep
End Sub
Before/After
Assuming that the entire document is plain text, we can assign the entire document's text and use Split to convert it into array of words.
Since it's in array, it will be faster to process through them all vs accessing the Words collection.
This is all I can think of but perhaps there's a better way to do this? Below example uses Regex to search through and replace all matched duplicate:
Option Explicit
Sub Delete_Duplicate()
Const maxWord As Long = 2 'Change this to increase the max amount of words should be used to match as a phrase.
Dim fullTxt As String
fullTxt = ActiveDocument.Range.Text
Dim txtArr() As String
txtArr = Split(fullTxt, " ")
Dim regex As RegExp
Set regex = New RegExp
regex.Global = True
regex.IgnoreCase = True
Dim outputTxt As String
outputTxt = fullTxt
Dim n As Long
Dim i As Long
For i = UBound(txtArr) To 0 Step -1
Dim matchWord As String
matchWord = vbNullString
For n = 0 To maxWord - 1
If (i - n) < 0 Then Exit For
matchWord = txtArr(i - n) & " " & matchWord
matchWord = Trim$(Replace(matchWord, vbCr, vbNullString))
regex.Pattern = matchWord & "[, ]{0,}" & matchWord
If regex.test(outputTxt) Then
outputTxt = regex.Replace(outputTxt, matchWord)
End If
Next n
Next i
Set regex = Nothing
Application.UndoRecord.StartCustomRecord "Delete Duplicates"
ActiveDocument.Range.Text = outputTxt
Application.UndoRecord.EndCustomRecord
End Sub
You might try something along the lines of:
Sub Demo()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Replacement.Text = "\1"
.Forward = True
.Wrap = wdFindContinue
.MatchWildcards = True
.Text = "([A-Za-z0-9'’]#)[, ]#\1"
.Execute
Do While .Found = True
.Execute Replace:=wdReplaceAll
Loop
.Text = "([A-Za-z0-9'’]#[, ]#[A-Za-z0-9'’]#)[, ]#\1"
.Execute
Do While .Found = True
.Execute Replace:=wdReplaceAll
Loop
End With
End With
Application.ScreenUpdating = True
End Sub
It is only conception but try to prepare list of all words in document and replace double or triple words if existing.
Private Sub DeleteDuplicate()
Dim wholeTxt As String
Dim w As Range
Dim col As New Collection
Dim c
For Each w In ActiveDocument.Words
AddUniqueItem col, Trim(w.Text)
Next w
wholeTxt = ActiveDocument.Range.Text
For Each c In col
'add case with ","
'maybe one letter word should be forbidden, or add extra boundary
If InStr(1, wholeTxt, c & " " & c, vbBinaryCompare) <> 0 Then
'start of doc
Selection.HomeKey wdStory
'here should be all stuff to prepare replacement
'(...)
Selection.Find.Execute Findtext:=c & " " & c, ReplaceWith:=c
wholeTxt = ActiveDocument.Range.Text
End If
Next c
Set col = Nothing
End Sub
Private Sub AddUniqueItem(ByRef col As Collection, ByVal itemValAndKey As String)
Dim s As String
On Error Resume Next
s = col(itemValAndKey)
If Err.Number <> 0 Then
col.Add itemValAndKey, itemValAndKey
Err.Clear
End If
On Error GoTo 0
End Sub

How to select a text in Word and convert it to stacked fraction with vba?

I try to select the text in Word, for example:
10/8
18/6
12/4
And with macros convert it to this type of fractions with the horizontal line:
Sub EscribeFraccion()
Dim objRango As Range
Dim objEq As OMath
Set objRango = Selection.Range
objRango.Text = "9/36"
Set objRango = Selection.OMaths.Add(objRango)
Set objEq = objRango.OMaths(1)
objEq.BuildUp
End Sub
I would like all that text to be selected and each item to be converted like this.
I have this code that what it does is ask you through a text box, the fraction:
Sub MakeFraction ()
Dim Fraction As String, Numerator As String, Denominator As String
ActiveWindow.View.ShowFieldCodes = True
With Selection
'For user input, you could use the following 2 lines to create a fraction
Fraction = InputBox ("Please input the Fraction (ex: 1/2, 5/32)")
.Collapse (wdCollapseStart)
'Alternatively, to convert a selection, use the following line
'Fraction = Trim (.Text)
Numerator = Split (Fraction, "/") (0)
Denominator = Split (Fraction, "/") (1)
.Font.Size = Round (.Font.Size) / 2
.Fields.Add Range: = Selection.Range, Type: = wdFieldEmpty, _
PreserveFormatting: = False, Text: = "EQ \ f (" & Numerator & "," & Denominator & ")"
.MoveLeft wdCharacter, 2
.Delete
.Fields.Update
End With
ActiveWindow.View.ShowFieldCodes = False
End Sub
But instead of the imput, I would like to implement this:StrFrac = Split (Selection.Text, "/")
How could I do it? I thank you very much in advance for your support. Greetings!
Try this code:
Sub EscribeFraccion()
With ActiveDocument.Range.Find 'or Selection.Range.Find
.Text = "[0-9]#/[0-9]#"
.MatchWildcards = True
Do While .Execute
.Parent.OMaths.Add(.Parent).OMaths(1).BuildUp
Loop
End With
End Sub
Edit2
Sub EscribeFraccionSel()
With Selection.Range.Find
.Text = "[0-9]#/[0-9]#"
.MatchWildcards = True
Do While .Execute
.Parent.Text = InputBox("Please input the Fraction (ex: 1/2, 5/32)", "Input the Fraction", .Parent.Text)
.Parent.OMaths.Add(.Parent).OMaths(1).BuildUp
Loop
End With
End Sub
Edit3
Sub EscribeFraccionSel()
Dim inp
With Selection.Range.Find
.Text = "[0-9]#/[0-9]#"
.MatchWildcards = True
Do While .Execute
inp = Trim(InputBox("Please input the Fraction (ex: 1/2, 5/32)", "Input the Fraction", .Parent.Text))
inp = Split(inp, "/")
If UBound(inp) = 1 Then
If IsNumeric(inp(0)) And IsNumeric(inp(1)) Then
.Parent.Text = inp(0) & "/" & inp(1)
.Parent.OMaths.Add(.Parent).OMaths(1).BuildUp
Else
MsgBox "Error in the entered fraction"
End If
Else
MsgBox "Error in the entered fraction"
End If
Loop
End With
End Sub

Word VBA: recursive word search and work count

I am trying to create a Word macro VBA to do the following:
for the active Word document
find the name “Bob” and count how many times “this is new” is associated to Bob (recursion search and count)
For example. Bob = 2, Matthew = 1, Mark = 0
Report – JP
PQR – Bob, Mark
· Some text
Report – SH
JKL – Bob, Mark
· Some text
GHI – Bob
· This is new.
· More text
Report – JM
MNO – Bob, Mark
· Some text
DEF – Bob
· This is new.
· More text
ABC – Matthew
· This is new.
· More text
Report – BB
PQR – Bob, Mark
· Some text
I believe that my attempt using this code is not correct. Any help?
sResponse = "is new"
iCount = 0
Application.ScreenUpdating = False
With Selection
.HomeKey Unit:=wdStory
With .Find
.ClearFormatting
.Text = sResponse
' Loop until Word can no longer
' find the search string and
' count each instance
Do While .Execute
iCount = iCount + 1
Selection.MoveRight
Loop
End With
MsgBox sResponse & " appears " & iCount & " times
For example:
Sub Demo()
Application.ScreenUpdating = False
Dim StrNm As String, StrOut As String, i As Long
StrOut = "Bob = 0, " & _
"Matthew = 0, " & _
"Mark = 0, "
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "<[! ]# · This is new"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
End With
Do While .Find.Execute
If .Text = "" Then Exit Do
StrNm = Split(.Text, " ")(0)
If InStr(StrOut, StrNm) > 0 Then
i = Split(Split(StrOut, StrNm & " = ")(1), ", ")(0)
StrOut = Replace(StrOut, StrNm & " = " & i, StrNm & " = " & i + 1)
Else
StrOut = StrOut & StrNm & " = " & 1 & ", "
End If
.Collapse wdCollapseEnd
Loop
End With
Application.ScreenUpdating = True
MsgBox "Frequency Report:" & StrOut
End Sub
If you've missed any names with 'This is new', the code above will simply add them to the pre-defined StrOut list.
A part of your stated original problem was that you wanted to list ALL of the names, including names that NEVER show up as lines with the phrase "This is new". So the code must build a Dictionary of names and keep track of each name and its count as all the lines are scanned. (See this site for good information on dictionaries.)
There are a couple of "gotchas" in the ultimate solution, including allowing for names with accented characters (e.g. José) and names with spaces (e.g. "Bob Smith"). So I created a special "trim" function to scan each name and make sure the string is really just the name.
Assumptions:
Lines that DO NOT begin with "Report" are the lines that have names
The words separated by commas after the dash character are the names
The list of names ends when you find the special "separator" character
Here is the example code:
Option Explicit
Sub CountPhrase()
'--- define the dash and separator characters/strings - may be special codes
Dim dash As String
Dim separator As String
Dim phrase As String
dash = "–" 'this is not a keyboard dash
separator = "·" 'this is not a keyboard period
phrase = "This is new"
Dim nameCount As Scripting.Dictionary
Set nameCount = New Scripting.Dictionary
Dim i As Long
For i = 1 To ThisDocument.Sentences.Count
'--- locate the beginning of the names lines (that DO NOT have start with "Report")
If Not (ThisDocument.Sentences(i) Like "Report*") Then
'--- pick out the names for this report
Dim dashPosition As Long
Dim separatorPosition As Long
dashPosition = InStr(1, ThisDocument.Sentences(i), dash, vbTextCompare)
separatorPosition = InStr(1, ThisDocument.Sentences(i), separator, vbTextCompare)
Dim names() As String
names = Split(Mid$(ThisDocument.Sentences(i), _
dashPosition + 1, _
separatorPosition - dashPosition), ",")
'--- now check if the phrase exists in this sentence or not
Dim phrasePosition As Long
phrasePosition = InStr(1, ThisDocument.Sentences(i), phrase, vbTextCompare)
'--- add names to the dictionary if they don't exist, and increment
' the name count if the phrase exists in this sentence
Dim name As Variant
For Each name In names
Dim thisName As String
thisName = SpecialTrim$(name)
If Len(thisName) > 0 Then
If nameCount.Exists(thisName) Then
If phrasePosition > 0 Then
nameCount(thisName) = nameCount(thisName) + 1
End If
Else
If phrasePosition > 0 Then
nameCount.Add thisName, 1
Else
nameCount.Add thisName, 0
End If
End If
End If
Next name
End If
Next i
'--- show your work
Dim popUpMsg As String
popUpMsg = "Frequency Report:"
For Each name In nameCount.Keys
popUpMsg = popUpMsg & vbCrLf & name & _
": count = " & nameCount(name)
Next name
MsgBox popUpMsg, vbInformation + vbOKOnly
End Sub
Function SpecialTrim(ByVal inString As String) As String
'--- this function can be tricky, because you have to allow
' for characters with accents and you must allow for names
' with spaces (e.g., "Bob Smith")
'--- trim from the left until the first allowable letter
Dim keepString As String
Dim thisLetter As String
Dim i As Long
For i = 1 To Len(inString)
thisLetter = Mid$(inString, i, 1)
If LetterIsAllowed(thisLetter) Then
Exit For
End If
Next i
'-- special case: if ALL of the letters are not allowed, return
' an empty string
If i = Len(inString) Then
SpecialTrim = vbNullString
Exit Function
End If
'--- now transfer allowable characters to the keeper
' we're done when we reach the first unallowable letter (or the end)
For i = i To Len(inString)
thisLetter = Mid$(inString, i, 1)
If LetterIsAllowed(thisLetter) Then
keepString = keepString & thisLetter
Else
Exit For
End If
Next i
SpecialTrim = Trim$(keepString)
End Function
Function LetterIsAllowed(ByVal inString As String) As Boolean
'--- inString is expected to be a single character
' NOTE: a space " " is allowed in the middle, so the caller must
' Trim the returned string
Const LETTERS = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" & _
"àáâãäåçèéêëìíîïðñòóôõöùúûüýÿŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝ"
Dim i As Long
For i = 1 To Len(LETTERS)
If inString = Mid$(LETTERS, i, 1) Then
LetterIsAllowed = True
Exit Function
End If
Next i
LetterIsAllowed = False
End Function

Looking for a way in VBA to split a large chunk of text in MS Word to ensure it ends in a period AND is less than 280 characters

I'm currently trying to split a large chunk of text into tweets (it's an ebook I'm tweeting). I've got the code to split it into 280 character chunks, but I want it to end each tweet on a period (full stop) if possible whilst remaining within the 280 character limit.
I'm fairly new to VBA so there may be a much easier way of doing this. At the moment it looks fine split into 280 character chunks for Twitter, but I want it to read better by appearing as full sentences.
Sub SetLineLength()
'Requires setting reference to Microsoft VBScript Regular Expressions 5.5
'Will split at a space UNLESS a single word is longer than LineLength, in
which
'case it will split at LineLength characters
Const LineLength As Long = 280
Dim RE As RegExp, MC As MatchCollection, M As Match
Dim Ps As Paragraphs, P As Paragraph
Dim i As Long
Dim doc As Document
Dim sIn As String, sOut As String
Set RE = New RegExp
RE.Global = True
Set doc = ActiveDocument
'Replace multiple spaces with one
'Leave paragraphs intact
'Trim to line length
Set Ps = doc.Paragraphs
For i = Ps.Count To 1 Step -1
Set P = Ps(i)
RE.Pattern = "\s{2,}"
sIn = RE.Replace(P.Range.Text, " ")
RE.Pattern = "\S.{0," & LineLength - 1 & "}(?=\s|$)|\S{" & LineLength & "}"
If RE.Test(sIn) = True Then
Set MC = RE.Execute(sIn)
sOut = ""
For Each M In MC
sOut = sOut & M & vbNewLine
Next M
P.Range.Text = sOut
End If
'Uncomment for debugging
' Stop
Next i
End Sub
Any help would be greatly appreciated!
You need InStrRev to find the position of the last period within the next 280 characters. Put into a loop and advancing the starting position by the last found period with Mid should split up the paragraph into <=280 character pieces.
Option Explicit
Sub tweetThis()
Dim p As Paragraph, doc As Document
Dim i As Long, prd As Long, str As String
Const ll As Long = 280
ReDim tw(0) As Variant
Set doc = ActiveDocument
For Each p In doc.Paragraphs
str = p.Range.Text & Space(ll)
prd = InStrRev(str, Chr(46), ll, vbBinaryCompare)
Do While prd > 0
ReDim Preserve tw(i)
tw(i) = Trim(Mid(str, 1, prd))
i = i + 1
str = Mid(str, prd + 1)
prd = InStrRev(str, Chr(46), ll, vbBinaryCompare)
Loop
Next p
For i = LBound(tw) To UBound(tw)
Debug.Print tw(i)
Next i
End Sub
You might try something based on:
Sub TextSplitter()
Dim Rng As Range
Application.ScreenUpdating = False
With ActiveDocument
.Fields.Unlink
Set Rng = .Range(0, 0)
Do While Rng.End < .Range.End - 1
With Rng
.MoveEnd wdCharacter, 280
' Check whether the last character is a punctuation mark, paragraph break or line break
If Not .Characters.Last.Text Like "[.?!," & vbCr & Chr(11) & "]" Then
' Find the last preceding space
.End = .Start + InStrRev(Rng.Text, " ")
' Find the last preceding punctuation mark, paragraph break or line break
If InStr(.Text, ".") > 0 Then
.End = .Start + InStrRev(.Text, ".") + 1
ElseIf InStr(.Text, "?") > 0 Then
.End = .Start + InStrRev(.Text, "?") + 1
ElseIf InStr(.Text, "!") > 0 Then
.End = .Start + InStrRev(.Text, "!") + 1
ElseIf InStr(.Text, ",") > 0 Then
.End = .Start + InStrRev(.Text, ",") + 1
ElseIf InStr(Rng.Text, Chr(11)) > 0 Then
.End = .Start + InStrRev(.Text, Chr(11))
ElseIf InStr(Rng.Text, vbCr) > 0 Then
.End = .Start + InStrRev(.Text, vbCr)
End If
.Characters.Last.Text = vbCr
End If
DoEvents
.Collapse wdCollapseEnd
End With
Loop
End With
Set Rng = Nothing
Application.ScreenUpdating = True
End Sub
Do be aware that, with the above code where a range contains multiple punctuation marks, etc, the If/ElseIf hierarchy determines the splitting priority, which could result in later punctuation marks in the same range being overlooked.
The following code takes a different approach, simply looking for the last punctuation mark of any kind.
Sub TextSplitter()
Dim Rng As Range
Application.ScreenUpdating = False
With ActiveDocument
.Fields.Unlink
Set Rng = .Range(0, 0)
Do While Rng.End < .Range.End - 1
With Rng
.MoveEnd wdCharacter, 280
' Check whether the last character is not a punctuation mark, paragraph break or manual line break
If Not .Characters.Last.Text Like "[.?!," & vbCr & Chr(11) & "]" Then
' Find the last preceding space
.End = .Start + InStrRev(.Text, " ") + 1
' Find the last preceding punctuation mark, paragraph break or line break
With .Find
.Text = "[.\?\!,^13^11]"
.Replacement.Text = ""
.Forward = False
.Format = False
.Wrap = wdFindStop
.MatchWildcards = True
.Execute
End With
If .Find.Found = True Then
' Test the found character. If it's not a paragraph break, extend the range one character
If .Characters.Last.Text <> vbCr Then
If .Characters.Last.Text Like "[.?!,]" Then .End = .End + 1
End If
End If
' Replace the new last character with a paragraph break
.Characters.Last.Text = vbCr
' The Find was unsuccessful, so retest the last character for a line break
ElseIf .Characters.Last.Text = Chr(11) Then
' The last character is a manual line break, replace it with a paragraph break
.Characters.Last.Text = vbCr
Else
' The last character is a manual line break, so extend the range one character and
' replace the new last character with a paragraph break
.End = .End + 1
.Characters.Last.Text = vbCr
End If
DoEvents
.Collapse wdCollapseEnd
End With
Loop
End With
Set Rng = Nothing
Application.ScreenUpdating = True
End Sub

VBA find word and replace with a Hyperlink in Word 2010

I've a word document with some text. At some paragraphs I've words that I want to add the hyperlink to. Here's an example:
The book "When the sun goes up", ABC-1212321-DEF, have been released today.......
The "ABC-1212321-DEF" should be found and apply a hyperlink as follows: http://google.com/ABC-sometext-1212321-anothertext-DEF
All the strings in the document starts with "ABC-" and ends with "-DEF".
Thanks in advanced.
EDIT:
This is what I've got this far:
Sub InsertLinks()
Dim r As Range
Dim SearchString As String
Set r = ActiveDocument.Range
SearchString = "ABC-"
With r.Find
.MatchWildcards = True
Do While .Execute(findText:=SearchString, Forward:=True) = True
ActiveDocument.Hyperlinks.Add Anchor:=r, _
Address:=Replace(r.Text, " ", ""), _
SubAddress:="", ScreenTip:="", TextToDisplay:=r.Text
With r
.End = r.Hyperlinks(1).Range.End
.Collapse 0
End With
Loop
End With
End Sub
This now detects ABC- and add some random link. But need to get the number between ABC- and -DEF. The length is not the same.
SOLUTION
This is the code that solved my problem:
Sub InsertLinksTB()
Dim Rng As Range
Dim SearchString As String
Dim EndString As String
Dim Id As String
Dim Link As String
Set Rng = ActiveDocument.Range
SearchString = "ABC-"
EndString = "-DEF"
With Rng.Find
.MatchWildcards = True
Do While .Execute(findText:=SearchString, Forward:=False) = True
Rng.MoveStartUntil ("ABC-")
Rng.MoveEndUntil (" ")
'MsgBox (Rng.Text)
Id = Split(Split(Rng.Text, "ABC-")(1), "-DEF")(0)
'MsgBox (Id)
Link = "http://google.com/" & Id
ActiveDocument.Hyperlinks.Add Anchor:=Rng, _
Address:=Link, _
SubAddress:="", ScreenTip:="", TextToDisplay:=Rng.Text
Rng.Collapse wdCollapseStart
Loop
End With
End Sub
So if the text "ABC-1234-DEF" is found in the text, it will hyperlink this text with http://google.com/1234
Hope this is helpful for someone.