开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜