一、问题描述
作为初学者,在实践过程中遇到了这样一个问题:
该代码是在word文档中的第一段后面加上指定字符
Sub SetParagraphRange()
ThisDocument.Paragraphs(1).range.Collapse 0
ThisDocument.Paragraphs(1).range.Move 1, -1
ThisDocument.Paragraphs(1).range.Text = 999
End Sub
比如文档中有这么几段话:
今天天气真好
你晚上吃的什么好东西
按理说代码运行后的结果会是:
今天天气真好999
你晚上吃的什么好东西
但结果却是:
999你晚上吃的什么好东西
二、解决办法
找了解决办法,把ThisDocument.Paragraphs(1).range赋给一个变量即可解决:
Sub SetParagraphRange1()
Set pg = ThisDocument.Paragraphs(1).Range
pg.Collapse 0
pg.Move 1, -1
pg.Text = 999
End Sub
三、问题分析
所以我产生了这样一个疑问:
为什么把ThisDocument.Paragraphs(1).range赋给一个变量和不赋给一个变量的结果完全不同?
但教程里说的不明不白的,网上也没找到通俗易懂的适合新手的答疑。
经过一天的研究终于知道了其中的区别!
1、如果将一个Range对象赋给一个变量时,实际上是在创建该对象的一个引用,后面可以多次重复的使用,结果可以传递。而且range范围会随着你修改而变动。
2、如果不将Range对象赋给一个变量,而是在每次需要引用它时都重新创建它,那么就有可能因为文档内容的变化(例如,用户手动编辑或删除了某些段落)而导致Range的引用出现问题。用一次之后产生的结果不会传给下一次,如上面例子中,每次都会重新调用ThisDocument.Paragraphs(1),所以相当于三次变动中,前两次的没有用,只有第三次的才是最终调用。
举个例子:
还是刚才的那几段话:
今天天气真好
你晚上吃的什么好东西
使用赋值的情况:
Sub SetParagraphRange()
Dim p As Paragraph
For Each p In ThisDocument.Paragraphs
Set pg = p.Range
MsgBox pg.Start & pg.End
pg.Collapse 0
MsgBox pg.Start & pg.End
pg.Move 1, -1
MsgBox pg.Start & pg.End
pg.Text = p.Range.Characters.Count
MsgBox pg.Start & pg.End
Next
End Sub
运行之后会依次出现(循环只循环一次,用vba中的逐语句):
弹窗 07(出现7个字符是因为把换行符算进去了)
弹窗 77
弹窗 66
第一段文字变为:今天天气真好7
弹窗 67
不使用赋值的情况:
Sub SetParagraphRange1()
Dim p As Paragraph
For Each p In ThisDocument.Paragraphs
MsgBox p.Range.Start & p.Range.End
p.Range.Collapse 0
MsgBox p.Range.Start & p.Range.End
p.Range.Move 1, -1
MsgBox p.Range.Start & p.Range.End
p.Range.Text = p.Range.Characters.Count
MsgBox p.Range.Start & p.Range.End
Next
End Sub
运行之后会依次出现(循环只循环一次,用vba中的逐语句):
弹窗 07
弹窗 07
弹窗 07
第一段文字变为:7 你晚上吃的什么好东西
弹窗 012
从上面的例子可以看出来赋值的range会随着collapse、move等方法的使用,范围也会跟着变化。而不赋值的话,每一次使用collapse、move,范围都只会是第一段,因为每一次使用都是重新调用p的range范围。
四、有趣的实验
Sub demo2()
Set pg = ThisDocument.Paragraphs(1).Range
MsgBox pg
MsgBox ThisDocument.Paragraphs(1).Range
'到文档中对一段进行修改
MsgBox pg
MsgBox ThisDocument.Paragraphs(1).Range
End Sub
你会发现,无论在第一段中间、开端、还是结尾添加字符,两者的结果都是一样的,但是当你把第一段删掉后,结果就会不一样了。
因为第一段始终的pg的范围内,如下图所示:
“今天天气真好”以及换行符是位于pg的范围内,当光标移到第一段末尾,其实还是在换行符前,所以还是位于pg的范围内。
你可以试下整个文档只有一句话的时候,在运行上面代码,你会发现两者的结果始终会是一样的,因为第一段话删掉后,换行是不会被删除的,所以始终会是在pg的范围内。