加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

【VBA宏】在Word中运用Range对象详解

(2011-04-06 23:46:43)
标签:

vba

vb

range

杂谈

分类: 算法设计
当使用Visual Basic时一个常见的任务就是在文档中指定一块区域,然后对它进行处理,比如插入文字或应用格式等。例如,用户可能想编写一个宏,来对文档中某个部分里的某个单词或短语进行定位。那就可以使用一个Range对象来表示想在其中搜索特定单词或短语的部分文档。在确定Range对象后,用户能够应用该对象的方法和属性来修改相应范围中的内容。

  一个Range对象代表了文档中的一块连续的区域。每一个Range对象都由一个起始字符位置和一个终止字符位置来定义。与用户在文档中使用书签的方法类似,可以在Visual Basic中使用Range对象来识别一个文档的特定部分。一个Range对象既可以和插入点一样小,也可以和整个文档一样大。但是,与书签不同,Range对象仅仅在定义它的过程正在运行时才存在。

  Range对象同选定内容相互独立;也就是说,可以定义和修改范围而不会改变选定内容。用户也可以在文档中定义多个范围,而此时每个文档窗格中仅有一个选定内容。

  Start、End和StoryType属性唯一地确定了一个Range对象。Start和End属性分别返回或者设置Range对象的起始和结束字符的位置。每个文档构成部分起始处的字符位置是0 (zero),而第一个字符之后的位置是1,依此类推。StoryType 属性的WdStoryType常量可以表示十一种不同的文档构成部分类型。例如,如果在注脚区域中有一个Range对象,那么StoryType属性返回wdFootnotesStory。要对文档构成部分作进一步了解,请参阅本节后面的“运用文档构成部分”一节的有关内容。

使用Range对象来代替Selection对象

  宏录制器会经常创建一个使用Selection属性来控制操纵Selection对象的宏。但是,用户通常可以用一个或几个Range对象来以很少的命令完成相同的任务。以下的示例是用宏录制器创建的。该宏对文档中的前两个单词进行加粗。
Selection. HomeKey Unit :=wdStory

Selection. MoveRight Unit :=wdWord, Count:=2, Extend :=wdExtend

Selection. Font.Bold = wdToggle

以下的示例没有使用Selection对象而完成了相同的任务。

ActiveDocument. Range (Start:=0, End :=ActiveDocument. Words(2). End) .Bold = True

以下的示例对文档中的前两个单词进行加粗,然后插入一个新的段落。
Selection. HomeKey Unit :=wdStory

Selection. MoveRight Unit :=wdWord, Count :=2, Extend :=wdExtend

Selection. Font.Bold = wdToggle

Selection. MoveRight Unit :=wdCharacter, Count:=1

Selection. TypeParagraph

以下的示例没有使用Selection对象就完成了上述示例中的同样任务。
Set myRange = ActiveDocument. Range(Start:=0, End :=ActiveDocument. Words(2). End)

myRange. Bold = True

myRange. InsertParagraphAfter

  前面的两个示例改变了活动文档中的格式但没有改变选定内容。在大多数的场合下,Range对象比Selection对象更可取,原因如下:

用户可以定义和使用多个Range对象,而在每个文档窗口中只能有一个Selection对象。
控制管理Range对象不会改变所选择的文字内容。
控制管理Range对象比运用Selection对象速度要快。

使用Range方法返回Range对象

  可以使用Range方法在特定文档中创建一个Range对象。Range方法(可以从Document对象使用)返回一个Range对象,该对象定位于主文档构成部分中,有给定的起始点和结束点。以下示例创建了一个Range对象,并且赋给myRange变量。
Set myRange = ActiveDocument. Range (Start :=0, End :=10)

在上述示例中,myRange表示活动文档中的前十个字符。当对保存在myRange变量中的Range对象应用一种属性或方法时,就可以看到已经创建的Range对象。以下的示例对活动文档中的前十个字符进行加粗。
Set myRange = ActiveDocument. Range(Start :=0, End :=10)

myRange. Bold = True

  当用户需要对一个Range对象进行多次引用时,可以使用Set语句来设置一个等价于Range对象的变量。但是,如果用户需要在一个对象上执行一次操作,那么就没有必要将对象保存到变量中。用户可以使用一条确定范围并且改变Bold属性的命令来取得同样的结果;如以下示例所示。
ActiveDocument. Range(Start :=0, End :=10). Bold = True

  和书签类似,一个范围能够在文档中横跨一组字符,也可以标记其中的一个位置。在以下的示例中,Range对象的起始和终止点相同,并且该范围内不包含任何文字。该示例在活动文档的起始处插入文字。
ActiveDocument. Range(Start :=0, End :=0). InsertBefore Text :="Hello "

  用户可以通过使用如上述示例所示的字符位置数字,或者随同Selection对象、Bookmark对象或Range对象使用Start属性和End属性,来定义一个范围的起始和终止位置。以下示例创建了一个Range对象,来表示活动文档中的第三和第四个句子。
Set myDoc = ActiveDocument

Set myRange = myDoc. Range (Start :=myDoc. Sentences(3). Start, _

End :=myDoc. Sentences (4). End)

  技巧 Range对象在文档中的表示不可见。但是,用户可以使用Select方法来选定一个Range对象,以保证Range对象表示正确的文字范围。在以下示例中的Range对象表示活动文档中的前三个段落。在该宏运行完毕之后,选定内容是指包含在aRange变量中的文字范围。
Set aRange = ActiveDocument.Range (Start :=0, _

End :=ActiveDocument. Paragraphs (3). Range. End)

aRange. Select

使用Range属性来返回一个Range对象

在许多对象都可以使用Range属性-例如,Paragraph对象、Bookmark对象、Endnote对象以及Cell对象-Range属性用来返回一个Range对象。以下的示例返回了一个Range对象,该对象表示活动文档的第一段。
Set myRange = ActiveDocument.Paragraphs (1). Range

在创建了对Range对象的引用之后,用户可以使用它的任何属性或方法来修改该范围。以下的示例复制了活动文档中的第一段。

Set myRange = ActiveDocument. Paragraphs (1). Range

myRange. Copy

以下的示例复制了活动文档中表格一的第一行。

ActiveDocument. Tables(1). Rows(1). Range. Copy

  以下的示例显示了活动文档中由第一个书签标记的文字。Range属性可以在Bookmark对象中使用。

MsgBox ActiveDocument. Bookmarks (1). Range. Text

  如果用户需要对同一个Range对象应用多种属性或方法,那么可以使用With…End With语句。以下的示例为活动文档的第一段设定了文字的格式。
Set myRange = ActiveDocument. Paragraphs (1). Range

With myRange

.Bold = True

.ParagraphFormat. Alignment = wdAlignParagraphCenter

.Font. Name = "Arial"

End With

要获得关于返回Range对象的其他示例,请参阅“帮助”中的“Range属性”。

修改文档的一部分

Visual Basic包含了一些对象,可以使用它们来修改以下类型的文档元素:字符、单词、句子、段落以及节。下面的表格包含了对应于这些文档元素的属性和属性所返回的对象。
表 达 式

返 回 的 对 象

Word (index)

Range对象

Characters (index)

Range对象

Sentences (index)

Range对象

Paragraphs (index)

Paragraph对象

Sections (index)

Section对象

  当用户不带index来使用这些属性时,就返回一个同名的集合-例如,Paragraphs属性返回Paragraphs集合。但是,如果用户使用index来确定在某个集合中的一项,就返回上述表格第二列中的对象-例如,Words(1)返回一个Range对象。用户可以使用任何范围属性或方法来修改Range对象,如以下示例所示,该示例将选定内容中的第一个单词复制到剪贴板中。

Selection. Words (1). Copy

在Paragraphs集合以及Sections集合中的集合项分别是Paragraph对象和Section对象,而不是Range对象。但是,在Paragraph对象和Section对象中都可以使用Range属性(它返回一个Range对象)。以下的示例将获得文档中的第一段复制到剪贴板中。

ActiveDocument. Paragraphs(1). Range. Copy

上述表格中所有的文档元素属性都可以在Document对象、Selection对象以及Range对象中使用,如以下三个示例所示。

本例设置活动文档中第一个单词的大小写。

ActiveDocument. Words(1). Case = wdUpperCase

本例设置选中的第一节的下边距为0.5英寸。

Selection.Sections(1). PageSetup. BottomMargin = InchesToPoints(0.5)

本例设置活动文档中的文字为两倍行距(Content属性返回一个Range对象,该对象表示主文档构成部分)。

ActiveDocument. Content. ParagraphFormat. Space2

修改一组文档元素

要修改由一组文本元素(字符、单词、句子、段落或节)构成的范围,可以创建一个包含文档元素的Range对象。随同Range对象使用Start和End属性,用户可以新建一个Range对象,该对象引用了一组文档元素。以下的示例创建了一个Range对象(myRange),该对象引用了活动文档中的前三个单词,然后将这些单词的字体改为Arial。

Set Doc = ActiveDocument

Set myRange = Doc.Range (Start :=Doc. Words(1). Start, End :=Doc. Words(3). End)

myRange. Font. Name = "Arial"

以下的示例创建了一个Range对象,该对象起始于第二段的开头,到第四段之后结束。

Set myDoc = ActiveDocument

Set myRange = myDoc. Range (Start :=myDoc. Paragraphs(2). Range. Start, _

End :=myDoc. Paragraphs(4). Range. End)

以下的示例创建了一个Range对象(aRange),该对象起始于第二段的开头,到第三段之后结束。ParagraphFormat属性用来访问诸如SpaceBefore和SpaceAfter这样的设置段落格式的属性。

Set Doc = ActiveDocument

Set aRange = Doc. Range (Start :=Doc. Paragraphs(2). Range. Start, _

End :=Doc. Paragraphs(3). Range. End)

With aRange. ParagraphFormat

.Space1

.SpaceAfter = 6

.SpaceBefore = 6

End With

返回或设置范围中的文字

可以使用Text属性来返回或设置一个Range对象中的内容。以下的示例返回了活动文档中的第一个单词。

strText = ActiveDocument. Words(1). Text

以下示例将活动文档中的第一个单词改为“Hello”。

ActiveDocument. Words(1). Text = "Hello"

可以使用InsertAfter 方法或者InsertBefore方法在一个范围的前面或后面插入文字。以下的示例在活动文档的第二段之前插入文字。

ActiveDocument. Paragraphs(2). Range. InsertBefore Text :="In the beginning "

在使用InsertAfter 方法或者InsertBefore方法之后,范围随之扩大,包含新的文字。但是,也可以使用Collapse方法将范围折叠到起始位置或终止位置。以下的示例在现有文档之前插入单词“Hello”,然后将范围折叠到它的起始位置(在单词“Hello”之前)。

With ActiveDocument.Paragraphs(2).Range

.InsertBefore Text:="Hello "

.Collapse Direction:=wdCollapseStart

End With

设置范围中文字的格式

可以使用Font属性来取得设置字符格式的属性和方法,而使用ParagraphFormat属性来取得设置段落格式的属性和方法。以下的示例设置了活动文档中第一段的字符格式和段落格式。

With ActiveDocument. Paragraphs(1). Range. Font

.Name = "Times New Roman"

.Size = 14

.AllCaps = True

End With

With ActiveDocument. Paragraphs(1). Range. ParagraphFormat

.LeftIndent = InchesToPoints(0.5)

.Space1

End With

重新定义Range对象

可以使用SetRange方法来重新定义一个已经存在的Range对象。以下的示例定义myRange为当前的选定内容。SetRange方法重新定义myRange,使它表示当前的选定内容加上随后的十个字符。

Set myRange = Selection. Range

myRange. SetRange Start :=myRange. Start, End :=myRange. End + 10

要获得重新定义Range对象的其他信息和示例,请参阅“帮助”中“SetRange方法”。

用户也可以通过改变Start属性和End属性的值,或者使用MoveStart方法或MoveEnd方法来重新定义一个Range对象。以下的示例重新定义myRange对象,使它表示当前的选定内容加上随后的十个字符。

Set myRange = Selection. Range

myRange. End = myRange. End + 10

以下的示例使用MoveEnd方法扩展了myRange,使它包含下一段。

Set myRange = ActiveDocument. Paragraphs(2)

myRange. MoveEnd Unit :=wdParagraph, Count :=1

在范围内的段落中循环

可以通过几种不同的方法在范围内的段落中进行循环。本节包含使用For Each...Next语句和Next属性及方法在范围内的段落中进行循环的内容。也可以使用同样的技术在范围内的字符、单词或句子中进行循环。

使用For Each...Next语句

建议在范围内进行段落循环时使用For Each...Next语句,另外建议在集合内进行循环时也同样使用该语句。以下的示例在获得文档的前五段中进行循环,在每段之前添加文字。

Set myDoc = ActiveDocument

Set myRange = myDoc.Range (Start:=myDoc. Paragraphs(1). Range. Start, _

End :=myDoc. Paragraphs(5). Range. End)

For Each para In myRange. Paragraphs

para.Range. InsertBefore "Question:" & vbTab

Next para

假定用户想修改上述的代码,在范围内对用户选定的段落进行循环。可以使用Selection属性来表示选定内容中的各个段落。以下的示例在选定内容的段落中进行循环,去除加粗格式。

For Each para In Selection. Paragraphs

para.Range. Bold = False

Next para

使用Next属性或方法

用户也可以使用Next属性和方法在范围的段落中进行循环。以下的示例说明了怎样在范围的单词中进行循环,将每个单词增大一点字号。

Set myRange = ActiveDocument.Words(1)

For i = 1 To 5

myRange. Font. Size = myRange. Font. Size + i

Set myRange = myRange. Next(Unit :=wdWord, Count :=1)

Next i

以下的示例在范围的段落中进行循环,将范围的对齐方式由居中改为左对齐。该示例也使用Next属性重新定义了myRange,使它表示下一段。

Set myRange = ActiveDocument. Paragraphs(1). Range

For i = 1 To 5

If myRange. Paragraphs(1). Alignment = wdAlignParagraphCenter Then

myRange. Paragraphs(1). Alignment = wdAlignParagraphLeft

End If

Set myRange = myRange. Paragraphs(1). Next. Range

Next i

将Range对象赋值给变量

可以通过几种途径来把一个已经存在的Range对象赋给一个变量。在以下示例中,变量Range1和变量Range2都表示Range对象。在该示例中命令把活动文档中第一和第二个单词分别赋值给变量Range1和Range2。

Set Range1 = ActiveDocument. Words(1)

Set Range2 = ActiveDocument. Words(2)

设置一个Range对象变量等价于另一个Range对象变量

以下的示例创建变量Range2,并且与Range1相同。

Set Range2 = Range1

现在就有两个变量表示着同样的范围。当用户调整Range2的起始位置、终止位置或者文字时,所做的更改也同样会影响到Range1,反之亦然。

以下的示例将Range1默认属性 (Text属性)的值赋给Range2的默认属性。在此示例中的代码等价于Range2. Text = Range1. Text,它没有改变Range对象实际所表示的内容,它仅仅改变Range2的contents (text)。

Range2 = Range1

这两个范围(Range2和Range1)包含有相同的内容,但是它们可能指向文档中的不同位置,或者干脆是不同的文档。

使用Duplicate属性

以下的示例创建了一个新复制的Range对象,Range2,该对象有着和Range1一样的起始位置、终止位置以及文字内容。

Set Range2 = Range1. Duplicate

如果改变了Range1的起始位置或是终止位置,这种改变并不会影响到Range2,反之亦然。但是,因为这两个范围指向文档的相同位置,改变一个范围中的文字内容也会同时改变另一个范围的文字内容。

运用文档构成部分

一个文档构成部分是文档中的一个区域,该区域中的文字区别于文档中的其他区域。例如,如果一个文档包含了正文文字、脚注和页眉,则该文档就包含了文档正文部分、脚注部分和页眉部分。

可以使用StoryType属性来返回指定范围、选定内容或书签的文档构成部分。如果在脚注部分中包含了选定内容,那么下例将关闭活动窗口中的脚注窗格。

ActiveWindow. View. Type = wdNormalView

If Selection. StoryType = wdFootnotesStory Then ActiveWindow. ActivePane. Close

StoryRanges集合包含了一个文档中每种有效的文档构成部分类型的第一个过程部分范围。可以使用NextStoryRange方法来返回以后的文档构成部分。以下的示例搜索活动文档中的每个文档过程部分来找出文字“Microsoft Word”。该示例也将它每次找到的文字全部设置为斜体。
For Each myStoryRange In ActiveDocument. StoryRanges

myStoryRange. Find. Execute FindText :="Microsoft Word", Forward :=True

While myStoryRange. Find. Found

myStoryRange. Italic = True

myStoryRange. Find.Execute FindText :="Microsoft Word", _

Forward :=True, Format :=True

Wend

While Not (myStoryRange. NextStoryRange Is Nothing)

Set myStoryRange = myStoryRange. NextStoryRange

myStoryRange. Find.Execute FindText :="Microsoft Word", Forward :=True

While myStoryRange. Find. Found

myStoryRange. Italic = True

myStoryRange. Find.Execute FindText :="Microsoft Word", _

Forward :=True, Format :=True

Wend

Wend

Next myStoryRange

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有