VBA find first occurance of a string
I have the following data
]
Word1
Word2
Word3
Word4[ Data1
]
Word1
Word2
Word3
Word4[ Data2
]
Basically my macro searches for ]*[
finding the data above the [*]
- it then does some checks. Then I want to find the next part (the [*]
) and do some more checks on the content before moving on to the next ]*[
at the moment it is basically finding the first ]*[
then each of the [*]
but not the next ]*[
headerSearch.Fi开发者_StackOverflownd.ClearFormatting
With headerSearch.Find
.text = "(\])(*)(\[)"
.Replacement.text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
itemCount = 0
multipleRespoErrors = 0
Do While headerSearch.Find.Execute = True
Dim contentSearch As Object
Set contentSearch = Application.Selection
'find the item content
contentSearch.Find.ClearFormatting
With contentSearch.Find
.text = "(\[)(*)(\])"
.Replacement.text = ""
.Forward = True
.Wrap = wdFindStop
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
End With
contentSearch.Find.Execute
findContent = lcase(Selection)
loop
Any Ideas?
I think the code below will solve your problem. However, as we need to use an alternating search pattern, Word's search functionality will not be enough. To compensate I created a bookmark (an invisible marker within Word that can be accessed via VBA code) wherever a bracket was and used this system to alternate the search pattern.
The first step is to generate the bookmarks. Two separate searches -- one each for the left and right brackets -- accomplish this. Each bookmark is given the name "Bookmark" with a number appended so that they are labeled numerically in order of appearance.
Public Sub PlaceBookmarks()
Dim SearchRange As Range
Dim BookmarkRange As Range
Dim x As Integer
x = 1
Set SearchRange = ActiveDocument.Range
SearchRange.Find.ClearFormatting
With SearchRange.Find
.Text = "(\])"
.Forward = True
.Wrap = wdFindStop 'end bookmark creation at end of document
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
While .Execute
If .Found = True Then
.Parent.Select
Selection.Collapse
Selection.MoveRight unit:=wdCharacter, Count:=1 'place bookmark to right of bracket
Set BookmarkRange = Selection.Range
ActiveDocument.Bookmarks.Add "Bookmark" & x, BookmarkRange
x = x + 2
End If
Wend
End With
x = 2
Set SearchRange = ActiveDocument.Range
SearchRange.Find.ClearFormatting
With SearchRange.Find
.Text = "(\[)"
.Forward = True
.Wrap = wdFindStop 'end bookmark creation at end of document
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchWildcards = True
While .Execute
If .Found = True Then
.Parent.Select
Selection.Collapse
Selection.MoveRight unit:=wdCharacter, Count:=1 'place bookmark to right of bracket
Set BookmarkRange = Selection.Range
ActiveDocument.Bookmarks.Add "Bookmark" & x, BookmarkRange
x = x + 2
End If
Wend
End With
End Sub
Next is to add the code to adjust the placement of the bookmarks, define the range of the text needed, and perform whatever operations are necessary. I adjusted the placement of the bookmarks so that the range of the text needed during searches would not include the brackets. If you need to include brackets in the text that undergoes the checks you mentioned, then adjust as necessary.
Public Sub FindRange()
Dim BookmarkCount As Integer
Dim x As Integer
Dim BookmarkRange As Range
Dim FirstPatternRange As Range
BookmarkCount = ActiveDocument.Bookmarks.Count
With ActiveDocument
For x = 1 To BookmarkCount
If .Bookmarks.Exists("Bookmark" & x + 1) Then
'Move end bookmark to exclude bracket
.Bookmarks("Bookmark" & x + 1).Select
Selection.MoveLeft unit:=wdCharacter, Count:=1
Set BookmarkRange = Selection.Range
.Bookmarks.Add "Bookmark" & x + 1, BookmarkRange 'this moves the bookmark by re-adding it
Set FirstPatternRange = .Range(.Bookmarks("Bookmark" & x).Range.Start, .Bookmarks("Bookmark" & x + 1).Range.End)
'Perform checks on data between ][
'Move leading bookmark to exclude bracket
.Bookmarks("Bookmark" & x + 1).Select
Selection.MoveRight unit:=wdCharacter, Count:=1
Set BookmarkRange = Selection.Range
.Bookmarks.Add "Bookmark" & x + 1, BookmarkRange 'this moves the bookmark by re-adding it
'Move trailing bookmark to exclude bracket
.Bookmarks("Bookmark" & x + 2).Select
Selection.MoveLeft unit:=wdCharacter, Count:=1
Set BookmarkRange = Selection.Range
.Bookmarks.Add "Bookmark" & x + 2, BookmarkRange 'this moves the bookmark by re-adding it
Set FirstPatternRange = .Range(.Bookmarks("Bookmark" & x + 1).Range.Start, .Bookmarks("Bookmark" & x + 2).Range.End)
'Perform checks on data between []
'Reset trailing bookmark for next iteration
.Bookmarks("Bookmark" & x + 2).Select
Selection.MoveRight unit:=wdCharacter, Count:=1
Set BookmarkRange = Selection.Range
.Bookmarks.Add "Bookmark" & x + 2, BookmarkRange 'this moves the bookmark by re-adding it
x = x + 1
End If
Next
End With
End Sub
If you plan on performing VBA operations on the text in the future, you'll probably want to write a For Each/Next to remove all bookmarks created. Hope this helps.
You could use something based on the following. By modifying the wildcard Find expressions, the process is quite straightforward.
With headerSearch
With .Find
.ClearFormatting
'Find ranges bounded by ] & [, excluding the final [
.Text = "\][!\[\]]{1,}"
.Replacement.Text = ""
.Forward = True
.Format = False
.Wrap = wdFindStop
.MatchWildcards = True
.Execute
End With
Do While .Find.Found = True
'Confirm that the next character is a [, just
'in case we've gone beyond the last ] & [ pair
If .Characters.Last.Next = "[" Then
'Exclude the leading ], so all we're left with is the range between ] & [
.Start = .Start + 1
MsgBox "Text bounded by ] & [:" & vbCr & .Text
With .Duplicate
With .Find
'Find the next range bounded by [ & ], excluding the final ]
.Text = "\[[!\[\]]{1,}"
.Forward = True
.Format = False
.Wrap = wdFindContinue
.MatchWildcards = True
.Execute
End With
If .Find.Found = True Then
'Confirm that the next character is a ], just
'in case we've gone beyond the last [ & ] pair
If .Characters.Last.Next = "]" Then
'Exclude the leading [, so all we're left with is the range between [ & ]
.Start = .Start + 1
MsgBox "Text bounded by [ & ]:" & vbCr & .Text
End If
End If
End With
End If
.Collapse wdCollapseEnd
.Find.Execute
Loop
End With
精彩评论