引子:在本论坛中,对于WORD VBA的研究,总体处于较低水平(其它各个OFFICE网站可能还略逊),探索\讨论和开发WORD VBA的功能,也是任重而道远.考虑到目前对于VBA中的嵌套域的介绍和禁用宏功能的空白,笔者归纳和示例以下代码,希望对后来之人有更多的启迪和减少由此探索过程的增加.
目的:旨在解决WORD中嵌套域的VBA自动插入的问题,以及通过对WORD命令的结合使用,来简化WORD VBA代码.( 包含一个对原页眉中文本删除的操作,具体应用见下面), 和本论坛中对WORD中某些领域的空白.
适用范围如:如有网友问: 有十个文件,文件名各不同(如DOS1...DOS10)DOS1有15页,DOS2有13页,DOS3有11页,DOS4有17页....在DOS1文件中实现页码自动排列没问题1-15页,但如何在DOS2文件中从第16页开始排列(即第16页到28页),在DOS3文件中从第29页开始排列(即第29页到39页)......,甚至说DOS2的页码变化后,DOS3等后面的文件的页码也会自动改变?
Sub test()
Dim Pc As Integer
Pc = 5
Application.Run "ViewHeader" '打开页眉页脚
'以下为典型的嵌套域的域代码:第{ = { page }+Pc }页共{ = { numpages }+Pc }页
With Selection
.WholeStory'全选页眉中的文本
.Text = "共页第页"'重新设置新文本,其实是替换了原文本
.HomeKey'移到文本之首
.MoveRight Count:=1'移到文本的第一个字符后(光标右移一个字符)
Application.Run "InsertFieldchars"'插入域标志(或称空域)
.Text = "= page+ " & Pc'插入域代码,并使其加上一个初始变量
.Words(2).Select'第二个词选定,其实是将page这个单词选定
Application.Run "InsertFieldchars"'插入域标志(已是嵌套域)注意此时是第二个域(嵌套域中的域代码为Page了)
.EndKey'将光标移至文本末
.MoveLeft Count:=1'光标左移一个字符
Application.Run "InsertFieldchars"'插入域标志
.Text = "= numpages+ " & Pc'插入域代码(相当于共?页,并加上初始变量值)
.Words(2).Select'第二个词选定,其实是将numpages这个单词选定
Application.Run "InsertFieldchars"'插入域标志(已是嵌套域)注意此时是第二个域(嵌套域中的域代码为numPages了)
End With
Application.Run "ViewHeader"'关闭页眉页脚
End Sub
下面我们来对比一下基于相同目的的工作(需要包含一个对原页眉中文本删除的操作,具体应用见下面),用录制宏的方法,并经过简化了的代码,比对一下:
Sub Macro1()
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
With Selection
.WholeStory
.Delete Unit:=wdCharacter, Count:=1
.TypeText Text:="第页共页"
.MoveLeft Unit:=wdCharacter, Count:=3
.Fields.Add Range:=.Range, Type:=wdFieldEmpty, _
PreserveFormatting:=False
.TypeText Text:="= "
.Fields.Add Range:=.Range, Type:=wdFieldEmpty, _
PreserveFormatting:=False
.TypeText Text:="page"
.MoveRight Unit:=wdCharacter, Count:=3
.TypeText Text:="+5 "
.MoveRight Unit:=wdCharacter, Count:=3
.Fields.Add Range:=.Range, Type:=wdFieldEmpty, _
PreserveFormatting:=False
.TypeText Text:="= "
.Fields.Add Range:=.Range, Type:=wdFieldEmpty, _
PreserveFormatting:=False
.TypeText Text:="numpages"
.MoveRight Unit:=wdCharacter, Count:=3
.TypeText Text:="+5 "
.MoveRight Unit:=wdCharacter, Count:=2
End With
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
End Sub
通过比对,双方从打开页眉开始,前一个过程使用了18行347个字符(不计空格),后一个过程使用了22行781个字符,相差4行和434个字符(比一半还多,所以感觉特噜嗦)
以下代码为第一个过程中WORD实战中的应用,它旨在解决多个文件的页码相互延续的功能,比如有N个文件,第二个文件的起始数是第一个文件的总页数加1,即如100页,第二个文件的第一页即为101页,关键是第一个文件页数随时会修改,以此类推.
Private Sub Document_Open()
Dim i As Byte, Pc As Integer, MyPath As String, MyDoc As String, n As Byte
On Error Resume Next
Application.ScreenUpdating = False
MyDoc = Me.Name
MyPath = "d:\temp\"
i = CByte(Mid(MyDoc, 4, Len(MyPath) - 6)) '获得循环变量值
' MsgBox i
For n = 1 To i - 1
WordBasic.DisableAutoMacros '禁用自动宏(Document_open触发)
Documents.Open FileName:=MyPath & "dos" & n & ".doc"
Pc = ActiveDocument.Content.Information(wdNumberOfPagesInDocument) + Pc
ActiveDocument.Close
WordBasic.DisableAutoMacros
Next
' MsgBox Pc
Documents(MyDoc).Activate
Application.Run "ViewHeader" '进入页眉页脚视图
'以下是典型的嵌套域的代码:第{ = { page }+Pc }页共{ = { numpages }+Pc }页
With Selection
.WholeStory
.Text = "第页共页"
.HomeKey
.MoveRight Count:=1
Application.Run "InsertFieldchars"
.Text = "= page+ " & Pc
.Words(2).Select
Application.Run "InsertFieldchars"
.EndKey
.MoveLeft Count:=1
Application.Run "InsertFieldchars"
.Text = "= numpages+ " & Pc
.Words(2).Select
Application.Run "InsertFieldchars"
End With
Application.Run "ViewHeader"
Me.Save
Application.ScreenUpdating = True
End Sub
此代码不但很好地解决了嵌套域的解决方法,也解决了如何不触发用代码打开的文档中包含自动运行的代码(如上题意,N个文件中(也许第一个可以不要),都包含一个打开时运行的宏,来检测和累加前面几个文档的总页数),经笔者试验和验证,使用二次WordBasic.DisableAutoMacros可以从禁用到恢复,相当于EXCEL中Application.EnableEvents = False(禁用), Application.EnableEvents = True(恢复),但在帮助文件中WORD对此没有论述,仅谈到禁止自动宏(AUTO类)的运行,也没有二次使用的介绍.
结束语:本文章只是本人的研究心得,非VBA爱好者可以视而不见. |