Find Text strings containing "_" - vba
I am looking the for the correct syntax to use a text function to find strings that contain underscores. I have a very large document that has numerous tables names with underscores. They are in the format abc_def or abc_def_ghi or abc_def_ghi_jkl etc.
I have tried various combinations and cannot get anything to work as I expect it to. Below is my latest iteration.
Sub ExtractTablesToNewDocument()
'=========================
'Macro created 2008 by Lene Fredborg, DocTools - www.thedoctools.com
'THIS MACRO IS COPYRIGHT. YOU ARE WELCOME TO USE THE MACRO BUT YOU MUST KEEP THE LINE ABOVE.
'YOU ARE NOT ALLOWED TO PUBLISH THE MACRO AS YOUR OWN, IN WHOLE OR IN PART.
'=========================
'The macro creates a new document,
'finds all words consisting of 3 or more uppercase letters
'in the active document and inserts the words
'in column 1 of a 3-column table in the new document
'Each acronym is added only once
'Use column 2 for definitions
'Page number of first occurrence is added by the macro in column 3
'Minor adjustments are made to the styles used
'You may need to change the style settings and table layout to fit your needs
'=========================
Dim oDoc_Source As Document
Dim oDoc_Target As Document
Dim strListSep As String
Dim strAcronym As String
Dim oTable As Table
Dim oRange As Range
Dim n As Long
Dim strAllFound As String
Dim Title As String
Dim Msg As String
Title = "Extract Acronyms to New Document"
'Show msg - stop if user does not click Yes
Msg = "This macro finds all words consisting of 3 or more " & _
"uppercase letters and extracts the words to a table " & _
"in a new document where you can add definitions." & vbCr & vbCr & _
"Do you want to continue?"
If MsgBox(Msg, vbYesNo + vbQuestion, Title) <> vbYes Then
Exit Sub
End If
Application.ScreenUpdating = False
'Find the list separator from international settings
'May be a comma or semicolon depending on the country
strListSep = Application.International(wdListSeparator)
'Start a string to be used for storing names of acronyms found
strAllFound = "#"
Set oDoc_Source = ActiveDocument
'Create new document for acronyms
Set oDoc_Target = Documents.Add
With oDoc_Target
'Make sure document is empty
.Range = ""
'Insert info in header - change date format as you wish
.PageSetup.TopMargin = CentimetersToPoints(3)
.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = _
"Acronyms extracted from: " & oDoc_Source.FullName & vbCr & _
"Created by: " & Application.UserName & vbCr & _
"Creation date: " & Format(Date, "MMMM d, yyyy")
'Adjust the Normal style and Header style
With .Styles(wdStyleNormal)
.Font.Name = "Arial"
.Font.Size = 10
.ParagraphFormat.LeftIndent = 0
.ParagraphFormat.SpaceAfter = 6
End With
With .Styles(wdStyleHeader)
.Font.Size = 8
.ParagraphFormat.SpaceAfter = 0
End With
'Insert a table with room for acronym and definition
Set oTable = .Tables.Add(Range:=.Range, NumRows:=2, NumColumns:=3)
With oTable
'Format the table a bit
'Insert headings
.Range.Style = wdStyleNormal
.AllowAutoFit = False
.Cell(1, 1).Range.Text = "Acronym"
.Cell(1, 2).Range.Text = "Definition"
.Cell(1, 3).Range.Text = "Page"
'Set row as heading row
.Rows(1).HeadingFormat = True
.Rows(1).Range.Font.Bold = True
.PreferredWidthType = wdPreferredWidthPercent
.Columns(1).PreferredWidth = 20
.Columns(2).PreferredWidth = 70
.Columns(3).PreferredWidth = 10
End With
End With
With oDoc_Source
Set oRange = .Range
n = 1 'used to count below
With oRange.Find
'Use wildcard search to find strings consisting of 3 or more uppercase letters
'Set the search conditions
'NOTE: If you want to find acronyms with e.g. 2 or more letters,
'change 3 to 2 in the line below
.Text = "<*>[_]<*>"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWildcards = True
'Perform the search
Do While .Execute
'Continue while found
strAcronym = oRange
'Insert in target doc
'If strAcronym is already in strAllFound, do not add again
If InStr(1, strAllFound, "#" & strAcronym & "#") = 0 Then
'Add new row in table from second acronym
If n > 1 Then oTable.Rows.Add
'Was not found before
strAllFound = strAllFound & strAcronym & "#"
'Insert in column 1 in oTable
'Compensate for heading row
With oTable
.Cell(n + 1, 1).Range.Text = strAcronym
'Insert page number in column 3
.Cell(n + 1, 3).Range.Text = oRange.Information(wdActiveEndPageNumber)
End With
n = n + 1
End If
Loop
End With
End With
'Sort the acronyms alphabetically - skip if only 1 found
If n > 2 Then
With Selection
.Sort ExcludeHeader:=True, FieldNumber:="Column 1", SortFieldType _
:=wdSortFieldAlphanumeric, SortOrder:=wdSortOrderAscending
'Go to start of document
.HomeKey (wdStory)
End With
End If
Application.ScreenUpdating = True
'If no acronyms found, show msg and close new document without saving
'Else keep open
If n = 1 Then
Msg = "No acronyms found."
oDoc_Target.Close savechanges:=wdDoNotSaveChanges
Else
Msg = "Finished extracting " & n - 1 & " acronymn(s) to a new document."
End If
MsgBox Msg, vbOKOnly, Title
'Clean up
Set oRange = Nothing
Set oDoc_Source = Nothing
Set oDoc_Target = Nothing
Set oTable = Nothing
End Sub
Try:
.Text = "[! ]#_[! ]{1,}"
This will find strings containing however many underscores there might be, including where those strings start or end with an underscore.
Try:
Sub AcronymLister()
Application.ScreenUpdating = False
Dim StrTmp As String, StrAcronyms As String, i As Long, j As Long, k As Long, Rng As Range, Tbl As Table
StrAcronyms = "Acronym" & vbTab & "Page" & vbCr
With ActiveDocument
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.MatchWildcards = True
.Wrap = wdFindStop
.Text = "[! ^13^t^11]#_[! ^13^t^11]{1,}"
.Replacement.Text = ""
.Execute
End With
Do While .Find.Found = True
If InStr(1, StrAcronyms, .Text, vbBinaryCompare) = 0 Then
StrAcronyms = StrAcronyms & .Text & vbTab & .Information(wdActiveEndAdjustedPageNumber) & vbCr
End If
If Len(.Text) = 0 Then .End = .Paragraphs(1).Range.Next.Start
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
With .Range
Set Rng = .Characters.Last
With Rng
If .Characters.First.Previous <> vbCr Then .InsertAfter vbCr
.InsertAfter Chr(12)
.Collapse wdCollapseEnd
.Style = "Normal"
.Text = StrAcronyms
Set Tbl = .ConvertToTable(Separator:=vbTab, NumRows:=.Paragraphs.Count, NumColumns:=2)
With Tbl
.Columns.AutoFit
.Rows(1).HeadingFormat = True
.Rows(1).Range.Style = "Strong"
.Rows.Alignment = wdAlignRowCenter
End With
.Collapse wdCollapseStart
End With
End With
End With
Set Rng = Nothing: Set Tbl = Nothing
Application.ScreenUpdating = True
End Sub
Note: The above code puts the acronym table at the end of the current document. I've modified the Find expression to exclude tabs, paragraph breaks & line breaks.
Sub AcronymLister()
Application.ScreenUpdating = False
Dim StrTmp As String, StrAcronyms As String, i As Long, j As Long, k As Long, Rng As Range, Tbl As Table
StrAcronyms = "Acronym" & vbTab & "Page" & vbCr
With ActiveDocument
With .Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.MatchWildcards = True
.Wrap = wdFindStop
.Text = "[! ^13^t^11]#_[! ^13^t^11]{1,}"
.Replacement.Text = ""
.Execute
End With
Do While .Find.Found = True
If InStr(.Text, "_") = 0 Then
If InStr(1, StrAcronyms, .Text, vbBinaryCompare) = 0 Then
StrAcronyms = StrAcronyms & .Text & vbTab & .Information(wdActiveEndAdjustedPageNumber) & vbCr
Else
.End = .Paragraphs(1).Range.Next.Start
End If
End If
If InStr(.Text, "_") > 0 Then
If InStr(1, StrAcronyms, .Text, vbBinaryCompare) = 0 Then
StrAcronyms = StrAcronyms & .Text & vbTab & .Information(wdActiveEndAdjustedPageNumber) & vbCr
Else
.End = .Paragraphs(1).Range.Next.Start
End If
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
With .Range
Set Rng = .Characters.Last
With Rng
If .Characters.First.Previous <> vbCr Then .InsertAfter vbCr
.InsertAfter Chr(12)
.Collapse wdCollapseEnd
.Style = "Normal"
.Text = StrAcronyms
Set Tbl = .ConvertToTable(Separator:=vbTab, NumRows:=.Paragraphs.Count, NumColumns:=2)
With Tbl
.Columns.AutoFit
.Rows(1).HeadingFormat = True
.Rows(1).Range.Style = "Strong"
.Rows.Alignment = wdAlignRowCenter
End With
.Collapse wdCollapseStart
End With
End With
End With
Set Rng = Nothing: Set Tbl = Nothing
Application.ScreenUpdating = True
End Sub
#macropod i added a loop to handle zero length strings and the code appears to be working. I know this is not the most efficient method, do you have any suggestions for improvement? Thank you again for walking me through this i really appreciate all your help and knowledge.
Related
VB.NET MS Word - How to store a ms word table cell corresponding to a FOUND word.range into a table.Cell variable
I am trying to find a string in my word document header table. I can find the range but I want to store the specific cell which this found range is located in into a table.cell variable. How can I do it?
In VBA, for example, to retrieve the cell's table#, row # & column #: Sub GetCellRef() Application.ScreenUpdating = False Dim Rng As Range, t As Long, r As Long, c As Long With ActiveDocument.Sections.First.Headers(wdHeaderFooterPrimary) Set Rng = .Range With .Range With .Find .Text = "Text to Find" .Forward = True .Wrap = wdFindStop .MatchCase = False .MatchWholeWord = True .Execute End With If .Find.Found = True Then If .Information(wdWithInTable) = True Then Rng.End = .Cells(1).Range.End - 1 t = Rng.Tables.Count Rng.Start = .Start r = .Cells(1).RowIndex c = .Cells(1).ColumnIndex MsgBox Chr(34) & Rng.Text & Chr(34) & vbCr & _ "Found in table " & t & " at row " & r & " column " & c End If End If End With End With Application.ScreenUpdating = True End Sub
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
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...
Determine if a word is within 125 words of a match
I want to loop through a document, and for each word, see if there is a match within 250 words (125 behind and 125 ahead). If there is a match(s), highlight it. Certain words are excluded. These are stored in a dictionary. To test the loop I am using, For Each para In ActiveDocument.Paragraphs For Each wrd In para.Range.Words Debug.Print wrd & "----" & wrd.Start Next wrd Next para The problem: "World" in the sentence "I hate traveling to the spirit world", prints 32 when I am looking for 7. I want to do something like: If wrd < 125 Then Set wrdRng = ActiveDocument.Range(Start:=wrd - 125, End:=ActiveDocument.Words(wrd + 125).End) Else Set wrdRng = ActiveDocument.Range(Start:=0, End:=ActiveDocument.Words(250 - wrd).End) End if Edit: The current code I'm using completes a loop on a 50,000 word document in about 13 minutes. That is entirely too long. Anyone have a better alternative? Sub Demo() Application.ScreenUpdating = False Dim i As Long Dim StartTime As Double Dim MinutesElapsed As String StartTime = Timer For Each Para In ActiveDocument.Paragraphs For Each wrd In Para.Range.Words With ActiveDocument.Range With .Find .ClearFormatting .Replacement.ClearFormatting .Text = "<(McKnight)*\1>" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .MatchCase = False .MatchWildcards = True End With Do While .Find.Execute If .ComputeStatistics(wdStatisticWords) < 100 Then i = i + 1 .Words.First.HighlightColorIndex = wdBrightGreen .Words.Last.HighlightColorIndex = wdBrightGreen End If .End = .End - Len(.Words.Last) .Collapse wdCollapseEnd Loop End With Application.ScreenUpdating = True 'MsgBox i & " instances found." Debug.Print wrd Next wrd Next Para MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss") MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation End Sub EDIT: Sub Demo() Application.ScreenUpdating = False Dim i As Long Dim StartTime As Double Dim MinutesElapsed As String StartTime = Timer For Each para In ActiveDocument.Paragraphs For Each wrd In para.Range.Words With ActiveDocument.Range With .Find .ClearFormatting .Replacement.ClearFormatting .Text = "<(wrd)*\1>" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .MatchCase = False .MatchWildcards = True End With Do While .Find.Execute If .ComputeStatistics(wdStatisticWords) < 100 Then i = i + 1 .Words.First.HighlightColorIndex = wdBrightGreen .Words.Last.HighlightColorIndex = wdBrightGreen End If .End = .End - Len(.Words.Last) .Collapse wdCollapseEnd Loop End With Application.ScreenUpdating = True 'MsgBox i & " instances found." 'Debug.Print wrd Next wrd Next para MinutesElapsed = Format((Timer - StartTime) / 86400, "hh:mm:ss") MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation End Sub
Try the following. Amongst other things, it allows you to specify words to ignore (e.g. prepositions, articles, etc.). Additionally different highlights are used to identify all 'hits' on a given word. A progress report is given on the status bar. On my laptop, it takes about 6:40 for a 50,000 word 'lorem' document. Option Explicit Dim ArrOut() As String Sub Demo() ' Turn Off Screen Updating Application.ScreenUpdating = False Dim eTime As Single ' Start Timing eTime = Timer Dim wdDoc As Document, StrFnd As String, StrTmp As String, Rng As Range Dim SBar As Boolean, bTrk As Boolean, h As Long, i As Long, j As Long ' Store current Status Bar status, then switch on SBar = Application.DisplayStatusBar Application.DisplayStatusBar = True Set wdDoc = ActiveDocument With wdDoc ' Store current Track Changes status, then switch off bTrk = .TrackRevisions: .TrackRevisions = False 'Display status Application.StatusBar = "Building word list" 'Compile the Find list Call BuildWordList(.Range.Text) With .Range.Find .ClearFormatting .Replacement.ClearFormatting .Text = "" .Replacement.Text = "" .Format = False .MatchCase = False .MatchWholeWord = True .Wrap = wdFindStop .Execute End With End With 'Process all words in the concordance For i = 0 To UBound(ArrOut()) StrFnd = ArrOut(i) h = i Mod 14 If h < 6 Then h = h + 2 Else h = h + 3 End If 'Display current word Application.StatusBar = "Processing: " & StrFnd 'Use wildcards, if possible, for extra speed If Len(StrFnd) < 4 Then StrTmp = "" For j = 1 To Len(StrFnd) StrTmp = StrTmp & "[" & UCase(Mid(StrFnd, j, 1)) & Mid(StrFnd, j, 1) & "]" Next StrFnd = StrTmp With wdDoc.Range With .Find .MatchWildcards = True .Text = "<(" & StrFnd & ")>*<(" & StrFnd & ")>" .Forward = True .Wrap = wdFindStop End With Do While .Find.Execute If .ComputeStatistics(wdStatisticWords) < 100 Then If .Words.First.HighlightColorIndex <> h Then .Words.First.HighlightColorIndex = h .Words.Last.HighlightColorIndex = h End If .End = .End - Len(.Words.Last) .Collapse wdCollapseEnd Loop End With Else With wdDoc.Range With .Find .MatchWildcards = False .Text = StrFnd .Forward = True .Wrap = wdFindStop .Execute End With Set Rng = .Duplicate Do While .Find.Execute Rng.End = .Duplicate.End With Rng If .ComputeStatistics(wdStatisticWords) < 100 Then If .Words.First.HighlightColorIndex <> h Then .Words.First.HighlightColorIndex = h .Words.Last.HighlightColorIndex = h End If End With Set Rng = .Duplicate .Collapse wdCollapseEnd Loop End With End If DoEvents Next ' Restore original Track Changes status wdDoc.TrackRevisions = bTrk ' Clear the Status Bar Application.StatusBar = False ' Restore original Status Bar status Application.DisplayStatusBar = SBar ' Restore Screen Updating Application.ScreenUpdating = True ' Calculate elapsed time eTime = (Timer - eTime + 86400) Mod 86400 ' Just in case execution time spans midnight MsgBox "Execution took " & Format(eTime / 86400, "hh:mm:ss") & " to process" End Sub Sub BuildWordList(StrIn As String) Dim StrFnd As String, i As Long, j As Long, k As Long 'Define the exlusions list Const StrExcl As String = "a,am,and,are,as,at,be,but,by,can,cm,did,do,does,eg," & _ "en,eq,etc,for,get,go,got,has,have,he,her,him,how,i,ie,if,in,into,is," & _ "it,its,me,mi,mm,my,na,nb,no,not,of,off,ok,on,one,or,our,out,re,she," & _ "so,the,their,them,they,t,to,was,we,were,who,will,would,yd,you,your" 'Strip out unwanted characters For i = 1 To 255 Select Case i Case 1 To 31, 33 To 64, 91 To 96, 123 To 144, 147 To 191, 247 Do While InStr(StrIn, Chr(i)) > 0 StrIn = Replace(StrIn, Chr(i), " ") Loop End Select Next 'Convert smart single quotes to plain single quotes & delete any at the start/end of a word StrIn = Replace(Replace(Replace(Replace(StrIn, Chr(145), "'"), Chr(146), "'"), "' ", " "), " '", " ") 'Convert to lowercase StrIn = " " & LCase(StrIn) & " " 'Process the exclusions list For i = 0 To UBound(Split(StrExcl, ",")) StrFnd = " " & Split(StrExcl, ",")(i) & " " Do While InStr(StrIn, StrFnd) > 0 StrIn = Replace(StrIn, " " & Split(StrExcl, ",")(i) & " ", " ") Loop Next 'Clean up any duplicate spaces Do While InStr(StrIn, " ") > 0 StrIn = Replace(StrIn, " ", " ") Loop i = 0 Do While UBound(Split(StrIn, " ")) > 1 StrFnd = " " & Split(StrIn, " ")(1) & " ": j = Len(StrIn) 'Find how many occurences of each word there are in the document StrIn = Replace(StrIn, StrFnd, " ") k = (j - Len(StrIn)) / (Len(StrFnd) - 1) 'If there's more than one occurence, add the word to our Find list If k > 1 Then ReDim Preserve ArrOut(i) ArrOut(i) = Trim(StrFnd) i = i + 1 End If Loop WordBasic.SortArray ArrOut() End Sub
How to work with selection
I am trying to convert perfectly working macro to hyperlink with activedoccument.range to selection.range. code is With Selection.Range With .Find .ClearFormatting .Replacement.ClearFormatting .Text = "String String1" .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .MatchWildcards = True .Execute End With Do While .Find.Found strtxt = Split(.Text, " ")(1) strtxt = Right(strtxt, 2) & "/" & Left(strtxt, 4) & "/" & Mid(strtxt, 8, 2) & "/" & Mid(strtxt, 5, 3) .Hyperlinks.Add Anchor:=.Duplicate, Address:="Address" & strtxt & "/0.pdf", TextToDisplay:=.Text .End = .Fields(1).Result.End .Collapse wdCollapseEnd .Find.Execute Loop End With How to collapse correctly to make this work. Currently it hyperlinks all in the doccument instead selection.
As far as I can tell, the problem is basically that the found range's end needs to be increased by 1 when the hyperlink is inserted. But I believe you also have to check that you have not gone past the original Selection.Range end, so you need an additional test. This seemed OK in Tables, but (a) I am currently testing in Mac Word 2011, which may well be different, and (b), if you actually select a column or noncontiguous ranges, you would have to work a lot harder to make the changes only in the selection (because of well-known lack of support for such selections). Sub fandr() Const strText As String = "String String1" Dim dr As Word.Range Dim sr As Word.Range Set sr = Selection.Range 'Debug.Print sr.Start, sr.End Set dr = sr.Duplicate ' Try to deal with the problem where Find fails to find ' the Find text if it is exactly the same as the selection sr.Collapse wdCollapseStart With sr.Find .ClearFormatting .Replacement.ClearFormatting .Text = strText .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .MatchWildcards = True Do While .Execute(Replace:=False) If sr.InRange(dr) Then 'Debug.Print sr.Start, sr.End, dr.Start, dr.End strtxt = Split(.Text, " ")(1) strtxt = Right(strtxt, 2) & "/" & Left(strtxt, 4) & "/" & Mid(strtxt, 8, 2) & "/" & Mid(strtxt, 5, 3) sr.Hyperlinks.Add Anchor:=sr, Address:="Address" & strtxt & "/0.pdf", TextToDisplay:=.Text sr.Collapse wdCollapseEnd sr.End = sr.End + 1 sr.Start = sr.End 'Debug.Print sr.Start, sr.End, dr.Start, dr.End Else Exit Do End If Loop End With Set sr = Nothing Set dr = Nothing End Sub
So I have changed a few things. Somehow the Range was getting messed up after adding the HyperLink. so I just reset the SearchRange after adding the hyperlink. This will work perfectly if the selection is not part of a Table I have added some checks to see if its in side the table but dont have time now to complete the cell shift. Sub SearchTextAddHyperLink() Dim SearchRange As Range Dim OriginalRange As Range Dim FoundRange As Range Set SearchRange = Selection.Range Set OriginalRange = Selection.Range Dim strtxt As String Dim SearchText As String Dim CellPosition As String SearchText = "String String1" With SearchRange With .Find .ClearFormatting .Replacement.ClearFormatting .Text = SearchText .Replacement.Text = "" .Forward = True .Wrap = wdFindStop .Format = False .MatchWildcards = True End With Do While .Find.Execute '.Select If .Find.Found = True Then Set FoundRange = SearchRange FoundRange.Select strtxt = Split(.Text, " ")(1) strtxt = Right(strtxt, 2) & "/" & Left(strtxt, 4) & "/" & Mid(strtxt, 8, 2) & "/" & Mid(strtxt, 5, 3) .Hyperlinks.Add Anchor:=.Duplicate, Address:="Address" & strtxt & "/0.pdf", TextToDisplay:=.Text If Not FoundRange.Information(wdWithInTable) Then 'Resetting the SearchRange for outside a table 'For some reason the Hyperlink messes up the Range 'Len(SearchText) + 1 just caters for the changing the Search Text 'and adding an additional character to move passed the hyperlink SearchRange.Start = FoundRange.End + Len(SearchText) + 1 SearchRange.End = OriginalRange.End Else 'Resetting the SearchRange for inside a table 'Need to then be clever with determinign which cell you are in and then moving to the next cell 'SearchRange.Start = FoundRange.End 'Len(SearchText) + 1 'SearchRange.End = OriginalRange.End End If End If 'Just to check the SearchRange SearchRange.Select Loop End With End Sub NOTE: Also, remember to also Dim all your variables going forward.
Search for text and check for underline
How can i search for text and check the same text for underline in the word document. Can anyone help me out?? Sub Underline() Dim fnd As String Dim n As Long fnd = InputBox("Enter text to search" & vbCr & vbCr _ & "Click OK to search the entire workbook for all instances of the search text.") Dim x As Integer x = 0 Do While x = 0 With Selection.Find .ClearFormatting End With If fnd = False Then x = 1 Exit Do End If Selection.Find.Execute If .Underline = False Then Selection.Comments.Add Range:=Selection.Range, Text:="pls underline text" Selection.Find.Execute End If Loop End Sub
Is this what you are trying? Sub Sample() Dim c As Range Dim fnd As String fnd = InputBox("Enter text to search" & vbCr & vbCr _ & "Click OK to search the entire document for all instances of the search text.") If fnd = "" Then Exit Sub Set c = ActiveDocument.Content c.Find.ClearFormatting c.Find.Replacement.ClearFormatting With c.Find .Text = fnd .Replacement.Text = "" .Forward = True .Wrap = wdFindStop End With c.Find.Execute While c.Find.Found If c.Font.Underline = wdUnderlineNone Then c.Select c.Comments.Add Range:=Selection.Range, Text:="pls underline text" End If c.Find.Execute Wend End Sub
comment the below line in code from Siddharth Rout c.Comments.Add Range:=Selection.Range, Text:="pls underline text"