Sorry for the fundamental question but I am a LONGtime Access VBA developer who is getting my butt kicked by Word.
I am building a solution for someone who uses a Legal Case Management System with a specific numbering scheme (aaa-aaa-##-##-###). I need to search a document for hyphens and then grab the whole paragraph where a hyphen is found. I then need to send the text from that paragraph to a separate function which parses out the file number from the paragraph (this function already works).
If that function is successful, it returns the File Number, otherwise it returns "NOT FOUND". So, I need to:
Find all hyphens
Capture the paragraph with a hyphen
Pass that text to the function
GO TO THE NEXT HYPHEN IF function returns "NOT FOUND"
I have tried dozens of options without success. I typically get stuck in an infinite loop (and do not seem to move forward) or I get to the end of the process with a false failure.
I do not know how to move to the NEXT occurrence of a hyphen and repeat the process. I also do not know how to run the process to the end of the document or stop at the end (without starting all over - because the hyphens REMAIN since this is NOT a replace process).
I have tried so many different versions, but I included one below.
Thanks for any guidance. I do appreciate it.
DGP
Public Sub TestFind77() '
Selection.HomeKey Unit:=wdStory
With Selection.Find
.ClearFormatting
.Text = "-"
.Execute Forward:=True
Do While .Found = True
.Parent.Expand Unit:=wdParagraph
Dim strWTF As String
strWTF = .Parent
'MsgBox strWTF
strResult = fnGetFileNumberFromString(strWTF) ' This works
If strResult <> "NOT FOUND" Then
GoTo success
End If
.Execute Forward:=True
Loop
End With
success:
MsgBox strResult
End Sub
I understand... Good start and you're missing only tiny pieces.
One thing you need is Word's Range
object. Best to use that with Find - unlike Selection
you can work with multiple Ranges in your code.
Sometimes, when working with Find it's necessary to refer back to the original Range (the entire document, in your case). That doesn't appear to be the case, here, but I've built it in, anyway, on general principle - so you have it if it turns out you need it.
I've found it more reliable to save the result of Find.Execute
in a boolean variable, rather than relying on .Found
, so I've put that in, as well.
You can pick up the paragraph in which the Range is located using Range.Paragraphs(1)
. I tried to stick to what you have, but if you want to tighten up your code even more, you could do this as long as you don't need the paragraph for anything else:
strWTF = rngSearch.Paragraphs(1).Range.Text
Good luck!
Public Sub TestFind77()
Dim rngDoc as Word.Range
Dim rngSearch as Word.Range
Dim bFound as boolean
Dim para as Word.Paragraph
Set rngDoc = ActiveDocument.Range
Set rngSearch = rngDoc.Duplicate
With rngSearch.Find
.ClearFormatting
.Text = "-"
bFound = .Execute(Forward:=True)
Do While bFound = True
Set para = rngSearch.Paragraphs(1)
Dim strWTF As String
strWTF = para.Range.Text '???.Parent
'MsgBox strWTF
strResult = fnGetFileNumberFromString(strWTF) ' This works
If strResult <> "NOT FOUND" Then
GoTo success
End If
rngSearch.Collapse wdCollapseEnd 'search from after the found to the end of the doc
bFound = .Execute(Forward:=True)
Loop
End With
success:
MsgBox strResult
End Sub
Thanks Cindy,
I am still not sure that I understand the Word Object Model well enough to understand why...but your answer got it to work.
I did incorporate your suggestion re
strWTF = rngSearch.Paragraphs(1).Range.Text
Here is the final code, including that input:
Public Sub TestFind99()
Dim rngDoc As Word.Range
Dim rngSearch As Word.Range
Dim bFound As Boolean
Dim strWTF As String
Set rngDoc = ActiveDocument.Range
Set rngSearch = rngDoc.Duplicate
With rngSearch.Find
.ClearFormatting
.Text = "-"
bFound = .Execute(Forward:=True)
Do While bFound = True
strWTF = rngSearch.Paragraphs(1).Range.Text
strResult = fnGetFileNumberFromString(strWTF) ' This works
If strResult <> "NOT FOUND" Then
GoTo success
End If
rngSearch.Collapse wdCollapseEnd 'search from after the found to the end of the doc
bFound = .Execute(Forward:=True)
Loop
End With
success:
MsgBox strResult
End Sub