Find first instance of the acronym - vba

Any help would be awesome. I have a macro that finds acronyms and applies a spell out of the acronym with the acronym in parenthesis. It is applying the spell out and acronym once but randomly. I need the macro to identify the first instance and apply the spell out only to that first instance. So if the first instance should look like this:
Be Right Back (BRB) some text BRB some text BRB
Right know it looks like this: BRB some text Be Right Back (BRB) some text BRB
The macro has the code " .Execute Replace:=wdReplaceOne" but it doesn't seem to be working.
Here's the code I am using:
Sub AcronymManager()
Application.ScreenUpdating = False
Dim FRDoc As Document, FRList As String, j As Long, StrExp As String, StrAcc As String
'Load the strings from the reference doc into a text string to be used as an array.
Set FRDoc = ThisDocument
'Alternative code to use a different document the reference doc:
'Set FRDoc = Documents.Open("C:\Users" & Environ("UserName") & "\Documents\AcronymList.doc")
If ActiveDocument = FRDoc Then
MsgBox "Error: Cannot process this document - it's the source document", vbCritical
Exit Sub
End If
FRList = FRDoc.Range.Text
If FRDoc <> ThisDocument Then FRDoc.Close wdDoNotSaveChanges
Set FRDoc = Nothing
With ActiveDocument.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Replacement.Highlight = True
.MatchWholeWord = True
.MatchCase = True
.Wrap = wdFindContinue
'Process each word from the Check List. Tab-delimited strings are assumed, formatted as:
'Find text <Tab> Replace text
For j = 0 To UBound(Split(FRList, vbCr)) - 1
StrExp = Split(Split(FRList, vbCr)(j), vbTab)(0)
StrAcc = Split(Split(FRList, vbCr)(j), vbTab)(1)
.Text = StrExp
.Replacement.Text = StrAcc
.Execute Replace:=wdReplaceAll
.Text = "(" & StrAcc & ")"
.Execute Replace:=wdReplaceAll
.Text = StrAcc & "^w" & StrAcc
.Execute Replace:=wdReplaceAll
.Text = StrAcc
.Replacement.Text = StrExp & " (" & StrAcc & ")"
.Execute Replace:=wdReplaceOne
Next
End With
Application.ScreenUpdating = True
End Sub

Related

Check Word Document Style for every single lines

I have a Word Document with mixed styles and need to add HTML tags if the line matches h1, h2 or h3.
I'm trying to save the new string into an array and save as .html file
But have no idea how to write the if condition in .vba, so please help.
Public Sub Word2HTML()
Dim NewArray() As String
Dim TextFile As Integer
Dim FilePath As String
FilePath = "C:\Temp\final.html"
TextFile = FreeFile
'Open the text file
Open FilePath For Output As TextFile
For i = 1 To ActiveDocument.Paragraphs.Count
' error on the next line
If ActiveDocument.Paragraphs(i).Style.Text = "Heading 1" Then
ReDim Preserve NewArray(i-1)
NewArray(i-1) = "<h1>" + ActiveDocument.Paragraphs(i) + "</h1>"
Elseif ActiveDocument.Paragraphs(i).Style.Text = "Heading 2" Then
ReDim Preserve NewArray(i-1)
NewArray(i-1) = "<h2>" + ActiveDocument.Paragraphs(i) + "</h2>"
Elseif ActiveDocument.Paragraphs(i).Style.Text = "Heading 3" Then
ReDim Preserve NewArray(i-1)
NewArray(i-1) = "<h3>" + ActiveDocument.Paragraphs(i) + "</h3>"
Else
End If
Next i
For Each headline In NewArray
Print #TextFile, headline
Next
Close TextFile
End Sub
Here is the error message I got from MS Word VB
The following captures all headings and saves them to an HTML file with the same name as the active document:
Sub HeadingsToHTML()
Application.ScreenUpdating = False
Dim Rng As Range, h As Long
With ActiveDocument
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Font.Bold = True
.Wrap = wdFindContinue
.Text = ""
.Replacement.Text = "<strong>^&</strong>"
.Execute Replace:=wdReplaceAll
.Text = "^p"
.Replacement.Text = "</strong>^&<strong>"
.Execute Replace:=wdReplaceAll
End With
Set Rng = .Range(0, 0)
Set Rng = .TablesOfContents.Add(Range:=Rng, UseHeadingStyles:=True, _
UpperHeadingLevel:=1, LowerHeadingLevel:=9, IncludePageNumbers:=False).Range
Rng.Fields.Unlink
Rng.Collapse wdCollapseEnd
Rng.End = .Range.End
Rng.Delete
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.MatchWildcards = True
For h = 1 To 9
.Style = "TOC " & h
.Text = "([!^13]{1,})"
.Replacement.Text = "<h" & h & ">\1</h" & h & ">"
.Execute Replace:=wdReplaceAll
Next
End With
.SaveAs2 FileName:=Split(.FullName, ".doc")(0) & ".html", FileFormat:=wdFormatText, AddToRecentFiles:=False
End With
Application.ScreenUpdating = True
End Sub
Way faster than looping through all paragraphs, too.
If your headings have level #s and you don't want those in the output, replace:
.Text = "([!^13]{1,})"
with:
.Text = "[!^13]#^t([!^13]{1,})"
Styles do not have a .Text property. You probably are trying to do this:
If ActiveDocument.Paragraphs(i).Style = "Heading 1" Then
' do something here
End If

Repetitive search in VB (Word)

I have written a macro in Word to convert US spellings to UK. In summary, it looks like this:
US_spelling = analyze
UK-spelling = analyse
Call Spell_change (US_spelling, UK_spelling)
The Spell_change sub changes the spelling, adds a comment to the document, and adds 1 to a counter.
I repeat the above three lines, i.e. call the Spell_change sub, about 140 times (for 'program', 'dialog' etc).
Is there a more efficient way of doing this?
Many thanks.
Since you've changed the tag to refer to VBA, perhaps:
Sub Demo()
Application.ScreenUpdating = False
Dim StrFnd As String, StrRep As String, i As Long, Cmt As Comment, StrOut As String
StrFnd = "analyze,color,labor"
StrRep = "analyse,colour,labour"
StrOut = "US_spelling" & vbTab & "UK_spelling"
With ActiveDocument
With .Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = True
For i = 0 To UBound(Split(StrFnd, ","))
.Text = Split(StrFnd, ",")(i)
.Replacement.Text = Split(StrRep, ",")(i)
.Execute Replace:=wdReplaceAll
If .Found = True Then StrOut = StrOut & vbCr & Split(StrFnd, ",")(i) & vbTab & Split(StrRep, ",")(i)
Next
End With
Set Cmt = .Comments.Add(Range:=.Range(0, 0), Text:=StrOut & vbCr & "Total: " & UBound(Split(StrOut, vbCr)))
With Cmt
.Author = ""
With .Range.Paragraphs
.First.Range.Font.Bold = True
.Last.Range.Font.Bold = True
End With
End With
End With
Application.ScreenUpdating = True
End Sub
The above code inserts a comment at the top of the document with a record of all words found & changed, plus a count of those words (but not how many times each word was replaced).

Find particular strings in a word document and hyperlink to pdf's located in the ActiveDocument.Path

My example is as such. I have a word document that looks like:
ERN.001.001.0001
Apples and Oranges
ABC.001.001.0002
ERN.001.001.0004
Strawberries
ERN.001.001.0005
Also in the ActiveDocument.Path, I have the following files:
ERN.001.001.0001.pdf, ABC.001.001.0002.pdf, ERN.001.001.0004.pdf, ERN.001.001.0005.pdf
I want to create a script that looks for the pdf documents in the word document and hyperlinks them back to the directory.
My current code looks like this:
Sub AddHyperlinks()
Dim r1 As Range
Dim SearchString As String
SearchString = "[A-Z]{1-3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,4}"
Set r1 = ActiveDocument.Content
With r1.Find
.ClearFormatting
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = True
.MatchWildcards = False
.Text = SearchString
Do While .Execute(Forward = True) = True
r1.Hyperlinks.Add Anchor:=r1, _
Address:=ActiveDocument.Path & "\" & r1.Text & ".pdf", _
SubAddress:="", ScreenTip:="", TextToDisplay:=r1.Text
r1.Collapse wdCollapseStart
Loop
End With
End Sub
When I run this script it finds the SearchString however it doesn't seem to understand what I'm trying to hyperlink. Does anyone have any ideas on what i'm doing wrong?
Copy and Paste this Code in your VBA editor and run the Macro "CreateLinks".
Your Pattern seemed to be wrong also, I don't know why it worked for you though...
Sub CreateLinks()
Dim Rng As Range: Set Rng = ActiveDocument.Range
Dim SearchString$, Link$
Dim strPath$: strPath = ActiveDocument.Path & "\"
SearchString = "[A-Z]{3}[.][0-9]{3}[.][0-9]{3}[.][0-9]{4}" ' If the text characters are not fixed, then use: [A-Z]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,4}
With Rng.Find
.MatchWildcards = True
Do While .Execute(findText:=SearchString, Forward:=False) = True
Link = strPath & Rng & ".pdf"
ActiveDocument.Hyperlinks.Add Anchor:=Rng, _
Address:=Link, _
SubAddress:="", ScreenTip:="", TextToDisplay:=Rng.Text
Rng.Collapse wdCollapseStart
Loop
End With
End Sub
edit - result:

Word VBA - Inserting Inline Picture from filepath in document

I have a Word Document that includes as text the complete filepaths to multiple images (e.g. C:\Users\Name\Documents\Test Logos\alphatest.png). I am trying to create a macro to replace each text filepath with the image it refers to as inline shapes. The script also resizes the images. I am having trouble assigning a valid reference to the inline shape object variable using the Set statement.
((Right now, I am locating the filepaths in the Word document by manually putting "QQQ" before and after the text in the Word Document and then having the script search for text that is flanked by "QQQ." So, in the Word Document, each filepath looks like this: "QQQC:\Users\Name\Documents\Test Logos\alphatest.pngQQQ". This is a temporary kludge and does not seem to be the source of the error.))
Sub InsertAndResizeLogos()
'
' InsertAndResizeLogos Macro
' Insert logos at the correct place in the document, resize to less than 1 inch tall and 2 inches wide.
'
Selection.HomeKey Unit:=wdStory
With Selection.Find
.ClearFormatting
.Text = "QQQ*QQQ"
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
Do While .Execute
While Selection.Find.Found
Dim imagePath As String
Debug.Print Replace(Selection.Text, "QQQ", "")
imagePath = Replace(Selection.Text, "QQQ", "")
imagePath = Replace(imagePath, "\", "//")
imagePath = Replace(imagePath, vbCr, "")
Debug.Print imagePath
Dim SHP As InlineShape
Set SHP = Selection.InlineShapes.AddPicture(FileName:=imagePath, LinkToFile:=False, SaveWithDocument:=True)
SHP.LockAspectRatio = True
SHP.Height = InchesToPoints(1)
If SHP.Width > InchesToPoints(2) Then
SHP.Width = InchesToPoints(2)
End If
Wend
Loop
End With
End Sub
If I don't convert the filepath string to VBA's preferred format (i.e., removing this line from the script:)
imagePath = Replace(imagePath, "\", "//")
then the script successfully combs through the Word Document, finds the first filepath, and replaces it with the correct image. But then it throws a "Runtime Error 5152: This is not a valid file name." on the "Set" line and breaks.
If I do convert the filepath string to VBA format by replacing the \'s with //'s, then it does not successfully insert the image and throws a "Runtime Error 91: Object variable or With block variable not set" on the SHP.LockAspectRation=True line and breaks.
It seems like if I feed the filepath into the Set statement with //'s, it can no longer find the image. Is this something I could fix with error handling, or am I making a more fundamental mistake?
((If I set the filepath within the script, (i.e. imagePath = C:\Users\Name\Documents\Test Logos\alphatest.png), the script will successfully iterate through the entire document and replace all text with the QQQ's with that image.))
SOLUTION
Here is the final code that worked correctly:
Sub InsertAndResizeLogos()
'
' InsertAndResizeLogos Macro
' Insert logos at the correct place in the document, resize to less than 1 inch tall and 2 inches wide.
'
Application.ScreenUpdating = False
Dim i As Long, j As Long, StrNm As String, StrErr As String, iShp As InlineShape
With Selection 'ActiveDocument.Range
With .Find
.ClearFormatting
.Text = "*.[A-Za-z]{3}>"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
StrNm = .Text
If Dir(StrNm) = "" Then
j = j + 1: StrErr = StrErr & vbCr & StrNm
Else
i = i + 1
Set iShp = .InlineShapes.AddPicture(FileName:=StrNm, LinkToFile:=False, SaveWithDocument:=True)
With iShp
.LockAspectRatio = True
.Height = InchesToPoints(1)
If .Width > InchesToPoints(2) Then .Width = InchesToPoints(2)
End With
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
MsgBox i & " images added." & vbCr & j & " image files not found:" & StrErr
End Sub
The problem seems to have been related to pulling the filepath from Selection.Text rather than from .Find.Found.Text
This mostly uses the approach suggested below by Macropod, although applied to Selection rather than to Document.Range to maintain the "replace the text with the image" functionality. For some reason, Find.Execute's ReplaceWith parameter and Find's Replacement property refused to work no matter where in the process I called them.
You don't need all the QQQ circumlocution. You also don't need:
imagePath = Replace(imagePath, "\", "//")
But you should add error-checking to the code in case one or more image files is missing. Try:
Sub Demo()
Application.ScreenUpdating = False
Dim i As Long, j As Long, StrNm As String, StrErr As String, iShp As InlineShape
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "C:\\Users\\*.[A-Za-z]{3}>"
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
StrNm = .Text
If Dir(StrNm) = "" Then
j = j + 1: StrErr = StrErr & vbCr & StrNm
Else
i = i + 1: .Text = vbNullString
Set iShp = .InlineShapes.AddPicture(FileName:=StrNm, LinkToFile:=False, SaveWithDocument:=True, Range:=.Duplicate)
With iShp
.LockAspectRatio = True
.Height = InchesToPoints(1)
If .Width > InchesToPoints(2) Then .Width = InchesToPoints(2)
End With
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
MsgBox i & " images added." & vbCr & j & " image files not found:" & StrErr
End Sub
The following works for me.
I am using *png to identify the strings that end with .png.
I am then using
Right$(imagePath, Len(imagePath) - InStr(1,imagePath,":\") + 2)
to extract the string that holds the filepath on the assumption your filepaths are along the lines of C:\ etc. You could evolve this logic to suit your purposes.
I have removed the other loop and simply allowed the .Execute to continue until False.
Sub Test
Selection.HomeKey Unit:=wdStory
With Selection.Find
.ClearFormatting
.Text = "*png"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
Do While .Execute
Dim imagePath As String
imagePath = Selection.Range.Text
imagePath = Right$(imagePath, Len(imagePath) - InStr(1,imagePath,":\") + 2)
Dim SHP As InlineShape
Set SHP = Selection.InlineShapes.AddPicture(FileName:=imagePath, LinkToFile:=False, SaveWithDocument:=True)
SHP.LockAspectRatio = True
SHP.Height = InchesToPoints(1)
If SHP.Width > InchesToPoints(2) Then
SHP.Width = InchesToPoints(2)
End If
Loop
End With
End Sub
Reference:
https://superuser.com/questions/1009085/find-all-instances-of-a-text-and-make-it-a-hyperlink-with-a-macro

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.