- Joined
- Sep 24, 2012
- Messages
- 3
- Reaction score
- 0
I have a search process that searches for particular valueds (they are, in order "Sub","Function" and "Property"). The .wrap parameter is specified as wdFindStop, and I use the same code for all iterations. The search ends properly, at the end of the document' for the "Sub" and "Function searches, but goes into a loop for the "Property" search.
This is usually due to specifying the search range incorrectly (or so I've read). However, the .find.execute seems to be finding a value outside the search range, to the head of the document.
Here is the code (there are three procedures): (Couldn't find any <Code>, </Code> delimiters anywhere, sorry if this is hard to read)
***
Sub CodePrintPass1()
' Build a list of Procedures (Sub and Function procedures).
' Make certain that there as a section break before each procedure.
Dim SearchRange As Word.Range
Dim DocEnd As Long
DocEnd = ActiveDocument.Range.End
CurrentProcType = synSUB
Set SearchRange = ActiveDocument.Content
GoToTopOfSource
While Not EndOfSource
' Find the next occurrence of the CurrentProc between the start point and the end of the document
Pass1GetNextProc SearchRange
SearchRange.End = DocEnd
Debug.Print "Next range:", SearchRange.Start, SearchRange.End
Wend
CurrentProcType = synFUNC
Set SearchRange = ActiveDocument.Content
GoToTopOfSource
While Not EndOfSource
Pass1GetNextProc SearchRange
SearchRange.End = DocEnd
Debug.Print "Next range:", SearchRange.Start, SearchRange.End
Wend
CurrentProcType = synPROPERTY
Set SearchRange = ActiveDocument.Content
GoToTopOfSource
While Not EndOfSource
Pass1GetNextProc SearchRange
SearchRange.End = DocEnd
Debug.Print "Next range:", SearchRange.Start, SearchRange.End
Wend
End Sub
***
Function Pass1GetNextProc(rng As Word.Range) As tProcEntry
' Find the next occurrence of the keyword CurrentProcType
' Ignore instances on a comment line (' found earlier in this line)
' Discard instances where the word is the end of a token (ThisSub, for example)
Dim t As tProcEntry
Dim CommentRange As Word.Range
Dim IsComment As Boolean
t.ProcType = "" ' Indicator that t contains no useful data.
With rng.Find
.Text = CurrentProcType
.Forward = True
.Wrap = wdFindStop
Debug.Print "Start", rng.Start, rng.End
.Execute
If .Found Then
Debug.Print "Found ", rng.Start, rng.End, rng.Text
' Now see if we are on a comment line
Set CommentRange = rng.Duplicate
IsComment = Pass1TestForCommentLine(CommentRange)
If IsComment Then
Debug.Print "Comment", rng.Start, rng.End, rng.Text
' This is a comment line, leave return value undefined and move on to the next word
Else
' We have a valid source line. Construct a new tProcType entry
Debug.Print "Valid Source", rng.Start, rng.End, rng.Text
' Use CommentRange to get the number of lines between the start of the document and the current ProcType
Set CommentRange = rng.Duplicate
CommentRange.Start = ActiveDocument.Range.Start
' Move on to the next word, which contains the Name of the current procedure
rng.Collapse wdCollapseEnd
rng.MoveEnd unit:=wdWord, Count:=1
Debug.Print "ProcName", rng.Start, rng.End, rng.Text
With t
.ProcType = Trim(CurrentProcType)
.Name = rng.Text
.StartLine = CommentRange.ComputeStatistics(wdStatisticLines)
Debug.Print .ProcType, rng.Start, , .Name, "Line " & .StartLine
End With
End If
' Collapse the range, then advance by 1 word to get the name of the procedure
rng.Collapse wdCollapseEnd
Debug.Print "Collapse", rng.Start, rng.End
rng.MoveEnd unit:=wdWord, Count:=1
Debug.Print "Move On", rng.Start, rng.End
rng.Collapse wdCollapseEnd
Debug.Print "Next up", rng.Start, rng.End, rng.Text
Else
EndOfSource = True
Debug.Print "EOF!", rng.Start, rng.End
End If
Debug.Print
End With
rng.Select
Pass1GetNextProc = t
End Function
***
Function Pass1TestForCommentLine(rng As Word.Range) As Boolean
' See if there is a comment character earlier in the line. If so, then this keyword does not
' count as a valid example of CurrentProcType.
Dim ch As String
While ch <> Chr(13) And ch <> "'"
rng.MoveStart unit:=wdCharacter, Count:=-1
ch = Left(rng.Text, 1)
' Debug.Print rng.Start, rng.End, ch, rng.Text
Wend
If ch = "'" Then
Pass1TestForCommentLine = True
Else
Pass1TestForCommentLine = False
End If
End Function
***
I've uploaded a separate file with this chunk of code (it uses a couple of external modules, so it won't compile as it stands - remove references to the variable t which uses a type called ProcType, and it should be OK). I've also included a copy of the debug.print statements. Again, it's rather long, but you can see, at the end, where the range 6765-11702 is found to contain the search text at position 6751, which is outside the range. However, it is not a straight wrap around to the head of the document, as we've already found earlier instances of the search text, at positions 409, 436, 463, 4875, 4936 and 6751. It's just this last iteration that gets messed up.
Does anyone have any ideas?
Thanks,
Tony
This is usually due to specifying the search range incorrectly (or so I've read). However, the .find.execute seems to be finding a value outside the search range, to the head of the document.
Here is the code (there are three procedures): (Couldn't find any <Code>, </Code> delimiters anywhere, sorry if this is hard to read)
***
Sub CodePrintPass1()
' Build a list of Procedures (Sub and Function procedures).
' Make certain that there as a section break before each procedure.
Dim SearchRange As Word.Range
Dim DocEnd As Long
DocEnd = ActiveDocument.Range.End
CurrentProcType = synSUB
Set SearchRange = ActiveDocument.Content
GoToTopOfSource
While Not EndOfSource
' Find the next occurrence of the CurrentProc between the start point and the end of the document
Pass1GetNextProc SearchRange
SearchRange.End = DocEnd
Debug.Print "Next range:", SearchRange.Start, SearchRange.End
Wend
CurrentProcType = synFUNC
Set SearchRange = ActiveDocument.Content
GoToTopOfSource
While Not EndOfSource
Pass1GetNextProc SearchRange
SearchRange.End = DocEnd
Debug.Print "Next range:", SearchRange.Start, SearchRange.End
Wend
CurrentProcType = synPROPERTY
Set SearchRange = ActiveDocument.Content
GoToTopOfSource
While Not EndOfSource
Pass1GetNextProc SearchRange
SearchRange.End = DocEnd
Debug.Print "Next range:", SearchRange.Start, SearchRange.End
Wend
End Sub
***
Function Pass1GetNextProc(rng As Word.Range) As tProcEntry
' Find the next occurrence of the keyword CurrentProcType
' Ignore instances on a comment line (' found earlier in this line)
' Discard instances where the word is the end of a token (ThisSub, for example)
Dim t As tProcEntry
Dim CommentRange As Word.Range
Dim IsComment As Boolean
t.ProcType = "" ' Indicator that t contains no useful data.
With rng.Find
.Text = CurrentProcType
.Forward = True
.Wrap = wdFindStop
Debug.Print "Start", rng.Start, rng.End
.Execute
If .Found Then
Debug.Print "Found ", rng.Start, rng.End, rng.Text
' Now see if we are on a comment line
Set CommentRange = rng.Duplicate
IsComment = Pass1TestForCommentLine(CommentRange)
If IsComment Then
Debug.Print "Comment", rng.Start, rng.End, rng.Text
' This is a comment line, leave return value undefined and move on to the next word
Else
' We have a valid source line. Construct a new tProcType entry
Debug.Print "Valid Source", rng.Start, rng.End, rng.Text
' Use CommentRange to get the number of lines between the start of the document and the current ProcType
Set CommentRange = rng.Duplicate
CommentRange.Start = ActiveDocument.Range.Start
' Move on to the next word, which contains the Name of the current procedure
rng.Collapse wdCollapseEnd
rng.MoveEnd unit:=wdWord, Count:=1
Debug.Print "ProcName", rng.Start, rng.End, rng.Text
With t
.ProcType = Trim(CurrentProcType)
.Name = rng.Text
.StartLine = CommentRange.ComputeStatistics(wdStatisticLines)
Debug.Print .ProcType, rng.Start, , .Name, "Line " & .StartLine
End With
End If
' Collapse the range, then advance by 1 word to get the name of the procedure
rng.Collapse wdCollapseEnd
Debug.Print "Collapse", rng.Start, rng.End
rng.MoveEnd unit:=wdWord, Count:=1
Debug.Print "Move On", rng.Start, rng.End
rng.Collapse wdCollapseEnd
Debug.Print "Next up", rng.Start, rng.End, rng.Text
Else
EndOfSource = True
Debug.Print "EOF!", rng.Start, rng.End
End If
Debug.Print
End With
rng.Select
Pass1GetNextProc = t
End Function
***
Function Pass1TestForCommentLine(rng As Word.Range) As Boolean
' See if there is a comment character earlier in the line. If so, then this keyword does not
' count as a valid example of CurrentProcType.
Dim ch As String
While ch <> Chr(13) And ch <> "'"
rng.MoveStart unit:=wdCharacter, Count:=-1
ch = Left(rng.Text, 1)
' Debug.Print rng.Start, rng.End, ch, rng.Text
Wend
If ch = "'" Then
Pass1TestForCommentLine = True
Else
Pass1TestForCommentLine = False
End If
End Function
***
I've uploaded a separate file with this chunk of code (it uses a couple of external modules, so it won't compile as it stands - remove references to the variable t which uses a type called ProcType, and it should be OK). I've also included a copy of the debug.print statements. Again, it's rather long, but you can see, at the end, where the range 6765-11702 is found to contain the search text at position 6751, which is outside the range. However, it is not a straight wrap around to the head of the document, as we've already found earlier instances of the search text, at positions 409, 436, 463, 4875, 4936 and 6751. It's just this last iteration that gets messed up.
Does anyone have any ideas?
Thanks,
Tony