【发布时间】:2016-06-28 16:22:00
【问题描述】:
我有一个循环遍历文档的代码,然后将每个单词存储在字典中。字典中的每个键都是“单词”本身和每个字典。与该键对应的项目是一个数组,其中包含该单词的(开始和结束)范围。如果显示多次,我们只需将新范围添加到字典中。 item 数组,这意味着 item 数组已成为一个数组数组,其中每个子数组保存单词实例“n”的范围。如图所示。
问题是:每个字典项中的每个第一个子数组都分为两个数组,一个存储开始范围,一个存储结束范围,如手表窗口中所示。我只需要一个数组来存储这两个值,后面的子数组就可以了。
当我到达高亮代码时,我想根据一些用户输入高亮显示“x”次数的单词。虽然上述问题仍然存在,但每个单词似乎显示“x + 1”次,例如如果一个单词找到“3”次,该单词的项目数说它显示“4”次这是错误的,我可以通过减去 (1) 来修复它,但我不希望这样。是的,我可以编写一个代码,使用“查找”方法突出显示频率为“x”的单词。
这里是完整的代码
Sub MapWordsAndHighlight()
Dim WordsDict As Object
'a dict. to hold words and their range values
Set WordsDict = CreateObject("Scripting.Dictionary")
'an object representing each word in the cgosen document
Dim WordObject As Variant
'a temp. arr. to hold range values while adding new ones
Dim TmpRangeArrOfDupWords() As Variant
'the new upper bound of the tmp arr to recive the new values
Dim TmpArrayNewUpperBound As Long
'string that represents each words in the chosen document
Dim SingleWord As String
Dim i As Long
'loop through each word in current document
For Each WordObject In ActiveDocument.Range.Words
'remove the surrounding spaces and store the word string
SingleWord = Trim(WordObject.Text)
'skip single characters
If Len(SingleWord) > 1 Then
'check if the word is not stored previously in the dict
If Not WordsDict.Exists(SingleWord) Then
WordsDict.Add Key:=SingleWord, Item:=GetWordRangeArray(WordObject)
Else
'dump old range vlaues into tmp array
TmpRangeArrOfDupWords = WordsDict(SingleWord)
'make a new place in tmp arr for new ranges
TmpArrayNewUpperBound = UBound(TmpRangeArrOfDupWords) + 1
'expand the tmp array
ReDim Preserve TmpRangeArrOfDupWords(1 To TmpArrayNewUpperBound)
'store new ranges at the last placein tmp arr
TmpRangeArrOfDupWords(TmpArrayNewUpperBound) = GetWordRangeArray(WordObject)
WordsDict(SingleWord) = TmpRangeArrOfDupWords
Erase TmpRangeArrOfDupWords
End If
End If
Next
'============================================================
'** this part highlights words that are repeated "n" times
'loop through dict. items array
For Each var In WordsDict.Keys
'replace the "2" with "n" if you want to highlight the words that are repeated "n" times
If UBound(WordsDict.Item(var)) = 2 Then
ThisDocument.Range(WordsDict.Item(var)(1), WordsDict.Item(var)(2)).HighlightColorIndex = wdBrightGreen
End If
Next
'============================================================
End Sub
Function GetWordRangeArray(WordObject) As Variant()
'static variant array of two item
Dim RangeValue(1 To 2)
'store the starting range
RangeValue(1) = WordObject.Start
'store the end range, (-1) neglect space at the end of word
RangeValue(2) = WordObject.End - 1
'returned value
GetWordRangeArray = RangeValue
'clear the array
Erase RangeValue
End Function
【问题讨论】:
-
鉴于一个词的长度很容易确定,为什么不只存储每个出现的开头?
-
@John Coleman ..谢谢你的想法有效。但我需要解决这个问题。这是根据您的想法内联的新代码更改
codeDim RangeValue(1 To 1) RangeValue(1) = WordObject.Start 和codeThisDocument.Range(WordsDict.Item(var)(1), WordsDict .Item(var)(1) + Len(var)) -
Arrays based 1 是必须的吗?
-
@omegastripes...不,这不是必须的。我尝试从零开始,结果相同
-
WordObject.End - 1也有问题:单词后面的点或逗号等会切断最后一个字母。
标签: arrays vba dictionary ms-word