【发布时间】:2018-08-20 17:55:42
【问题描述】:
我正在尝试在 Word 文档中搜索特定字符串的出现。 代码应该只在目录之后搜索。 我完成的代码如下:
Private Sub cmdFindNextAbbr_Click()
Dim myRange As range
'CREATING DICTONARY for Selected Items
If firstClickAbr = True Then
txtNew = ""
abSelIndex = 0
Set abSel = CreateObject("scripting.dictionary")
Set abSelFirstStart = CreateObject("scripting.dictionary")
firstClickAbr = False
iAbbr = 0
For x = 0 To lstAbbreviations.ListCount - 1
If lstAbbreviations.Selected(x) = True Then
If Not abSel.Exists(lstAbbreviations.List(x, 1)) Then
abSel.Add lstAbbreviations.List(x, 0), lstAbbreviations.List(x, 1)
abSelFirstStart.Add lstAbbreviations.List(x, 0), lstAbbreviations.List(x, 5)
End If
End If
Next x
End If
Dim Word, findText As String
Dim chkAbbrLast, fsCountExt, firstOccEnd As Integer
Do While abSelIndex < abSel.count
chkAbbrLast = 0
Set myRange = ActiveDocument.Content
If txtNew <> abSel.keys()(abSelIndex) Then
fnCountAbr = 0
locInteger = abbrTableEnd
End If
firstOccEnd = abSelFirstStart.items()(abSelIndex) + Len(abSel.items()(abSelIndex) & " (" & abSel.keys()(abSelIndex) & ")")
fnCountAbr = fnCountAbr + 1
Word = abSel.keys()(abSelIndex)
'initially search for full text
findText = abSel.items()(abSelIndex)
myRange.Start = locInteger
myRange.Find.ClearFormatting
Do While myRange.Find.Execute( _
findText:=findText, _
MatchCase:=False, _
MatchWholeWord:=True, _
Wrap:=wdFindStop, _
Forward:=True _
)
If Left(myRange.Style, 7) <> "Heading" Then
If abSelFirstStart.items()(abSelIndex) <> myRange.Start Then 'ignore the first occurrence
locInteger = myRange.End
tCount = tCount + 1
'check for full term and abbreviation
fsCountExt = Len(abSel.items()(abSelIndex) & "s (" & abSel.keys()(abSelIndex) & "s)")
myRange.End = myRange.Start + fsCountExt
If InStr(UCase(myRange.Text), UCase(abSel.items()(abSelIndex) & "s (" & abSel.keys()(abSelIndex) & "s)")) > 0 Then
txtNew = abSel.keys()(abSelIndex) & "s"
myRange.Select
Exit Sub
Else
fsCountExt = Len(abSel.items()(abSelIndex) & " (" & abSel.keys()(abSelIndex) & ")")
myRange.End = myRange.Start + fsCountExt
End If
If InStr(UCase(myRange.Text), UCase(abSel.items()(abSelIndex) & " (" & abSel.keys()(abSelIndex) & ")")) > 0 Then
txtNew = abSel.keys()(abSelIndex)
myRange.Select
Exit Sub
End If
'check for full term only
fsCountExt = Len(abSel.items()(abSelIndex) & "s (" & abSel.keys()(abSelIndex) & "s)")
myRange.End = myRange.Start + fsCountExt
If InStr(UCase(myRange.Text), UCase(abSel.items()(abSelIndex) & "s")) > 0 Then
txtNew = abSel.keys()(abSelIndex) & "s"
myRange.Select
Exit Sub
Else
fsCountExt = Len(abSel.items()(abSelIndex))
myRange.End = myRange.Start + fsCountExt
End If
If InStr(UCase(myRange.Text), UCase(abSel.items()(abSelIndex))) > 0 Then
txtNew = abSel.keys()(abSelIndex)
myRange.Select
Exit Sub
End If
End If
End If
chkAbbrLast = chkAbbrLast + 1 ' check to prevent infinite loop
myRange.End = ActiveDocument.Content.End
If chkAbbrLast > 2 Then
Exit Do
End If
Loop
'now search for abbreviation
findText = abSel.keys()(abSelIndex)
chkAbbrLast = 0
myRange.Start = locInteger
myRange.Find.ClearFormatting
Do While myRange.Find.Execute( _
findText:=findText, _
MatchCase:=True, _
MatchWholeWord:=True _
)
If Left(myRange.Style, 7) <> "Heading" And myRange.Start > firstOccEnd Then
If abbIgnoreList.contains(myRange.Start) Then ' skip if match is in ignore list
If abSelIndex = abSel.count - 1 Then
chkAbbrLast = chkAbbrLast + 1 ' check to prevent infinite loop
End If
locInteger = myRange.End
Else
locInteger = myRange.End
tCount = tCount + 1
fsCountExt = Len(abSel.keys()(abSelIndex) & "s")
myRange.End = myRange.Start + fsCountExt
If InStr(UCase(myRange.Text), UCase(abSel.keys()(abSelIndex) & "s")) > 0 Then
txtNew = abSel.keys()(abSelIndex) & "s"
myRange.Select
Exit Sub
Else
fsCountExt = Len(abSel.keys()(abSelIndex))
myRange.End = myRange.Start + fsCountExt
End If
If InStr(UCase(myRange.Text), UCase(abSel.keys()(abSelIndex))) > 0 Then
txtNew = abSel.keys()(abSelIndex)
myRange.Select
Exit Sub
End If
End If
End If
chkAbbrLast = chkAbbrLast + 1 ' check to prevent infinite loop
If chkAbbrLast > 2 Then
Exit Do
End If
myRange.End = ActiveDocument.Content.End
Loop
'loop to next/first item
If abSelIndex <= abSel.count - 1 Then
abSelIndex = abSelIndex + 1
Else
abSelIndex = 0 ' start again at beginning
End If
Loop
MsgBox "No further occurrences found"
End Sub
ToCEnd 是 4085。
我能够找到第一个结果。当我单击调用相同方法的查找下一个按钮时,我有以下值:
myRange.Start : 18046
myRange.End : 21467
但是,在.Find.Execute 之后,我有以下值:
myRange.Start : 18022
myRange.End : 18046
为什么找到的文本会在我之前定义的起点处结束?
Start 和 End 的区别在于我的字符串长度,24
编辑: 我已经添加了完整的代码。
我在代码中所做的是查找用户可以替换的文本。 替换是从另一个按钮触发的。
在Find Next 按钮事件中,我验证了一个结果,将范围的结尾存储到一个变量并退出子。
下次单击时,我会尝试从存储的位置开始搜索。
我更新了我的代码,使其与this link 的代码相同,但我的行为仍然相同。
【问题讨论】:
-
向我们展示与 Find 相关的整个代码 - 一个 [mvce]。我们无法对所提供的内容进行任何分析。另外,包括
ToCEnd是什么。 -
如果你在哪里执行全部替换,那么你就不会使用 Do While。你说你按下了一个下一步按钮......如果它执行你在这里暗示的相同代码,那么根据你替换的确切内容,例程只会找到它在之前的查找/替换中部分替换的内容。如果您确实需要遍历文档,那么这与必须手动单击下一步是不一致的。 @CindyMeister 是正确的,您需要通过提供完整代码来正确完成您的问题,我会添加......对您尝试做的事情的更全面的解释。
-
从您的第二个问题开始:请编辑 this 问题,并提供有关问题的信息,即“查找”出现在表格中时。那是一个特例。完成后请“ping”。
-
@CindyMeister 我目前已经对我的 UI 和代码进行了相当多的修改,并使用了 Selection.Find,即“查找”出现在表格中。
-
问题是,Selection.Find 通常不是一个好主意; Range.Find 通常更可取。无论如何,不要不依赖开始和结束数字 - 这些是可以改变的。如果您想回到某个位置,请在该位置设置一个(临时)书签。