# [SOLVED] Word macro - searching for a string between two strings



## Nic H (Jul 19, 2009)

I am trying to find a way to search to see if a string (ftFindTag) is present between two other specified strings (ftFindTag and ftOpposite) and have got stuck.

Do While MsgBox("Do you want to continue searching for " + ftFindTag + " ?", vbQuestion + vbYesNoCancel, "Tag Search") = vbYes
Selection.Find.Execute (ftFindTag)
StartRange = Selection.End
Selection.MoveRight
Selection.Find.Execute (ftOpposite)
StopRange = Selection.Start
Selection.Range(StartRange, StopRange)
If Selection.Find.Execute(ftFindTag) = True Then
Selection.Find.Execute (ftFindTag)
End If

Is it possible to search between strings using range?

Cheers, Nic


----------



## macropod (Apr 11, 2008)

*Re: Word macro - searching for a string between two strings*

Hi Nic,

You could use something along the lines of:

```
Sub Demo()
Dim ftFindTag As String, ftOpposite As String, myRng As Range
ftFindTag = InputBox("First String to Find")
ftOpposite = InputBox("Last String to Find")
With Selection.Find
  .ClearFormatting
  .Text = ftFindTag & "*" & ftOpposite
  .Forward = True
  .Wrap = wdFindContinue
  .Format = False
  .MatchCase = False
  .MatchWholeWord = False
  .MatchAllWordForms = False
  .MatchSoundsLike = False
  .MatchWildcards = True
  Selection.Find.Execute
  If .Found = True Then
    Set myRng = Selection.Range
    myRng.MoveStart wdCharacter, Len(ftFindTag)
    myRng.MoveEnd wdCharacter, -Len(ftOpposite)
    If InStr(myRng, ftFindTag) > 0 Then MsgBox "A second occurrence of """ _
      & ftFindTag & """" & " exists within the found string:" & vbCr & _
      ftFindTag & myRng & ftOpposite
  End If
End With
End Sub
```


----------



## Nic H (Jul 19, 2009)

*Re: Word macro - searching for a string between two strings*

I'm trying to find if I have missing tags that I then hide in word e.g. <!CustA> and </!CustA> and this doesn't work because it says a pattern match expression is not valid? Will this work using non alphanumeric characters?

Cheers, Nic


----------



## Nic H (Jul 19, 2009)

*Re: Word macro - searching for a string between two strings*

Additionally I'd like it to continue down the document if the first tag isn't found between the first occurence of ftFindTag and ftOpposite until if find one where it does, or the end of the document is reached - do you think this is possible?

Cheers, Nic


----------



## Nic H (Jul 19, 2009)

*Re: Word macro - searching for a string between two strings*

I've tried something like this and if does search the tags but only the first occurence and it doesn't select the text range in the document like yours did - any ideas?
ftFindTag = InputBox("Enter the missing tag")
ftOpposite = InputBox("Enter the opposite tag")
While Selection.Find.Execute(ftOpposite)
StartRange = Selection.End
Selection.MoveRight
Selection.Find.Execute (ftFindTag)
StopRange = Selection.Start
Selection.MoveRight
Selection.Find.Execute
Set myRng = ActiveDocument.Range(StartRange, StopRange)
If InStr(myRng, ftOpposite) > 0 Then answer = MsgBox("A missing " + ftFindTag + " exists within the selected range", vbExclamation, "Find Missing Tag")
Wend

Thanks for your help.

Cheeers, Nic


----------



## macropod (Apr 11, 2008)

*Re: Word macro - searching for a string between two strings*

Hi Nic,

The reason <!CustA> and </!CustA> returns 'a pattern match expression is not valid' is that the macro I posted uses a wildcard search and certain characters (eg []{}()<>\!?*@#) are control characters in such a search. If you're going to search for those characters explicitly using wildcards, you need to prefix them with a '\'. So, you need to either encode the input string correctly or get the macro to parse it for you (not too difficult).

I'm not sure what the point would be of continuing the search until no unbalanced sets are found as, having found that they're unbalanced, you'd need to eyeball the found range and work out manually where the error occurs. That error could occur anywhere within the found range - and could even extend beyond it if the flaw is with the positioning of the 'ftOpposite' tags. It would be possible, though, to get a count of how many of the found strings there are in the range.


----------



## Nic H (Jul 19, 2009)

*Re: Word macro - searching for a string between two strings*

Hi

You're right about running until the end of the document. I can return the number of occassions and then run the macro that many times, fixing the missing tags each time one is found.

Your original coding was much better than mine. What would the parse look like?

Cheers, Nic


----------



## macropod (Apr 11, 2008)

*Re: Word macro - searching for a string between two strings*

Hi Nic,

try the following:

```
Sub FindMisMatches()
Dim ftFindTag As String, ftOpposite As String, myRng As Range, i As Integer
Dim fStart As String, fEnd As String, pStr As String, StrChr As String
pStr = "\,[,],{,},(,),<,>,!,?,*,@,#"
ftFindTag = InputBox("First String to Find")
ftOpposite = InputBox("Last String to Find")
If ftFindTag = "" Or ftOpposite = "" Then End
fStart = ftFindTag
fEnd = ftOpposite
For i = 0 To UBound(Split(pStr, ","))
  StrChr = Split(pStr, ",")(i)
  fStart = Replace(fStart, StrChr, "\" & StrChr)
  fEnd = Replace(fEnd, StrChr, "\" & StrChr)
Next
Selection.HomeKey
With Selection.Find
  .ClearFormatting
  .Text = fStart & "*" & fEnd
  .Forward = True
  .Format = False
  .MatchCase = False
  .MatchWholeWord = False
  .MatchAllWordForms = False
  .MatchSoundsLike = False
  .MatchWildcards = True
  .Wrap = wdFindContinue
  .Execute
  Do While .Found
    Set myRng = Selection.Range
    myRng.MoveStart wdCharacter, Len(ftFindTag)
    myRng.MoveEnd wdCharacter, -Len(ftOpposite)
    If InStr(myRng, ftFindTag) > 0 Then
      i = (Len(myRng.Text) - Len(Replace(myRng.Text, ftFindTag, ""))) / Len(ftFindTag)
      MsgBox i + 1 & " occurrences of """ & ftFindTag & """" & _
      " exists within the found string:" & vbCr & _
      ftFindTag & myRng & ftOpposite
      If MsgBox("Continue", vbYesNo) = vbNo Then End
    End If
    Selection.Collapse (wdCollapseEnd)
    .Execute
  Loop
End With
End Sub
```
This version of the macro reports each errant string and asks if you want to continue. I've added the parsing code also.


----------



## Nic H (Jul 19, 2009)

*Re: Word macro - searching for a string between two strings*

Great, that works a gem. Can vb search for the tags within headings? It seems to skip these?

Cheers, Nic


----------



## macropod (Apr 11, 2008)

*Re: Word macro - searching for a string between two strings*

Hi Nic,

You could simply open the header before running the macro.

The alternative is to re-work the code so that it process all StoryRanges. For example, you could replace:
Selection.HomeKey
with:
For Each oRng In ActiveDocument.StoryRanges
oRng.Select
Selection.Collapse
and add:
Next
before:
End Sub

These changes will also process textboxes etc. Note, though that this will leave the document in 'Normal' view ratr than, say, Print Layout view - and probably with the last-processed header or footer active.


----------

