如何利用VBA编写控制Word域的功能.docx

上传人:b****7 文档编号:9512093 上传时间:2023-02-05 格式:DOCX 页数:36 大小:26.88KB
下载 相关 举报
如何利用VBA编写控制Word域的功能.docx_第1页
第1页 / 共36页
如何利用VBA编写控制Word域的功能.docx_第2页
第2页 / 共36页
如何利用VBA编写控制Word域的功能.docx_第3页
第3页 / 共36页
如何利用VBA编写控制Word域的功能.docx_第4页
第4页 / 共36页
如何利用VBA编写控制Word域的功能.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

如何利用VBA编写控制Word域的功能.docx

《如何利用VBA编写控制Word域的功能.docx》由会员分享,可在线阅读,更多相关《如何利用VBA编写控制Word域的功能.docx(36页珍藏版)》请在冰豆网上搜索。

如何利用VBA编写控制Word域的功能.docx

如何利用VBA编写控制Word域的功能

表1:

工程

工程名称

设计阶段

工程检索号

卷册号

项目名称

新制

字数

图片数

建模工具

学习〔2

fw-jm-2002

软件工程专家网

60

1000

3

表2:

校核

序号

校核主要问题

执行情况

1

排列不齐

No

2

文字错

Yes

3

文字错

Yes

4

文字错

No

5

文字错

Yes

6

文字错

No

表2:

注册网址

Word域在软件开发中的应用

liyu

摘要域是Word最具有实用价值的功能之一,它表示文档中可能发生变化的数据或邮件合并文档中套用信函、标签中的占位符。

MicrosoftWord可以在您使用一些特定命令时插入域,如"插入"菜单上的"日期和时间"命令。

您也可使用"插入"菜单上的"域"命令手动插入域。

1.引言

事实上,我们在日常工作中常会脱离MicrosoftWord的操作环境。

一般,用户是先建立好一些Word文件模板,然后利用所提供的应用程序功能向Word文件模板中插入域,然后用该域对应的值取代域值,这样就达到了向MicrosoftWord文件中插入数据的作用。

我们常把数据放入数据库中,数据库的内容不断地变化,我们的域值也跟着不断地变化,取到灵活自动更新的作用,要达到这方面的功能,就应该把数据库与Word域结合起来。

首先要解决这一问题,我们必须先了解Word域有关的知识:

Word域代码位于花括号或大括号<{}>中,域类似于MicrosoftExcel中的公式:

域代码类似于公式,域结果〔域结果:

当MicrosoftWord执行域指令时,在文档中插入的文字或图形。

在打印文档或隐藏域代码时,将以域结果替换域代码。

类似于公式产生的值。

可在文档中切换显示域代码及其结果。

正好,数据库的字段名对应域代码,字段值对应域结果。

2.实现功能

下面是本人利用VBA编写的一通用的处理Word域的程序:

主要功能:

通用VB6编写通用的类,给用户提供可视化的编辑界面,用于用户在Word文件中插入域标志。

针对Word文件或Excel表格文件,扫描整个文件,将其中的域标志〔如Set"aaa"取出来,然后通过从数据库中取出"aaa"字段所对应的值,将值填写到文件中域对应的位置。

若对应位置已有值,则判断该值与要填写的值是否相同,若不同则替换。

插入值分为:

A.单纯的值,直接使用一个值替换域。

B.表格中的单元格。

若该表格填写不下,是否增加表格单元?

以及与该单元关联的域等。

3.操作步骤

3.1建立项目

开发方法:

启动VB6,新建一ActiveXDll工程,把工程名更改为VbaWord,把类名Class1更改为CSetDocField,向工程中增加一窗体Form1,窗体标题为处理Word文档,在Form1上加入2个CommandButton,用于打开文件和保存文件用的命令按钮;2个ComboBox,用于所插入的字段名;2个Label;2个CommonDialog,用于执行打开文件和保存文件。

界面如下:

3.2在项目中加入引用

按工程--引用--MicrosoftWord10.0ObjectLibrary引用Word

3.3增加操作窗体

在Form1的代码窗中定义以下变量:

OptionBase0

'申请Word应该对象及文档对象

PrivatewdAppAsNewWord.Application<>

PrivatewdDocAsNewWord.Document<>

'所处理的Word模板

PrivateFileNameAsString

'申请CSetDocField对象

PrivatemDocFldAsNewCSetDocField<>

'Word工具栏对象及菜单栏对象

DimCommandBarIndex<>AsInteger

DimSaveCommandBarMenuIndex<>AsInteger

'在Form的Load的事件中定义的打开和保存文件的格式,并填充ComboBox数据。

ComboBox数据对应数据库表的字段名,这里由CSetDocField的属性提供。

PrivateSubForm_Load<>

DimiAsInteger

CommonDialog1.DialogTitle="打开"

CommonDialog1.Filter="Word文档<*.doc>|*.doc|Word文档模板<*.dot>|*.dot"

CommonDialog2.DialogTitle="保存文件"

CommonDialog2.Filter=Word文档<*.doc>|*.doc|Word文档模板<*.dot>|*.dot"

FieldCount=0

Me.ScaleY

=vbTwips,toscale:

=vbPoints>

Fori=1TogFieldColl.Count

Combo1.AddItem>

Next

Fori=1TogTableColl.Count

Combo2.AddItem>

Next

EndSub

在Form1的代码窗中定义以下过程和函数:

'定义打开Word文件的过程。

建立Word应该对象及文档对象,并打开文件。

PrivateSubOpenWordDocument

wdApp=CreateObject<"Word.Application">

wdApp.Documents.Open

wdDoc=wdApp.ActiveDocument

wdDoc.ActiveWindow.DocumentMap=False

wdApp.Visible=True

IsWordRunning=True

EndSub

'在文档中插入域.KeyWord:

域的关键字.

这里我们利用Word文档对象的域对象的Add方法向Word文件中插入域。

域的Data属性代表该域的名称。

插入域时应该选取得插入点,既用户光标处位置。

如果该位置是单元格且已插入域应该提示是否覆盖

PrivateFunctionInsertFieldAsInteger

DimmySelectionAsSelection

DimCodeAsString

DimMyFieldAsField

DimmyRangeAsRange

wdApp.Selection.Collapse

=wdCollapseEnd>

mySelection=wdApp.Selection'插入点

IfIsCell=TrueThen

IfCellFieldCount>0Then

IfMsgBox<"该单元格已有域,是否覆盖?

",vbYesNo>=6Then

mySelection.Cells<1>.Select<>

mySelection.Delete<>'.Text=Value

'mySelection.DeleteUnit:

=wdCharacter,Count:

=1

'mySelection.Cells<1>.Range.Fields<1>.Delete

Else

ExitFunction

EndIf

EndIf

EndIf

MyField=wdDoc.Fields.Add

=mySelection.Range,Type:

=wdFieldAddin>

MyField.Data=KeyWord

EndFunction

'选择点<光标>是否是单元格.

我们可以通过选择点的表格数判断插入点的性质。

表格数为0,则选择点不位于单元格中,反则不位于单元格中。

PrivateFunctionIsCellAsBoolean

IfmySelection.Tables.Count>0Then

IsCell=True

Else

IsCell=False

EndIf

EndFunction

'取得选择点<光标>的单元格的域数

PrivateFunctionCellFieldCountAsInteger

EndFunction

'打开Word文件.并使处理界面位于Word最顶端,适当调整Word位置,关闭Word其它功能。

PrivateSubcmdOpenFile_Click<>

CommonDialog1.ShowOpen<>

FileName=CommonDialog1.FileName

IfFileName=""Then

ExitSub

EndIf

OpenWordDocument

IsShowField

SetWordSize<0,42,2000,2000>

CloseCommandBar<>

Me.top=0

Me.Left=0

Me.width=100000

Me.height=850

Picture1.top=Me.top

Picture1.Left=Me.Left+2000

cmdSave.Left=2000

cmdSave.top=cmdOpenFile.top

Combo1.Enabled=True

Combo2.Enabled=True

cmdSave.Visible=True

cmdOpenFile.Visible=False

EndSub

'保存Word文件.

PrivateSubcmdSave_Click<>

IsShowField

CommonDialog2.FileName=gSavePath+FileName

CommonDialog2.FileName=gSavePath+FileName

CommonDialog2.ShowSave<>

wdDoc.SaveAs

EndSub

'用户选择所插入域的域名,并在光标处插入域。

PrivateSubCombo1_Click<>

DimKeyWordAsString

KeyWord=Combo1.Text

InsertField

EndSub

'用户选择所插入域的域名,并在光标处插入域。

域所对应多值时,域只能插入表格中。

且要与单值域区分,标记为多值插入。

PrivateSubCombo2_Click<>

DimKeyWordAsString

mySelection=wdApp.Selection'插入点

IfIsCell<>TrueThen

MsgBox<"该位置不是单元格,请选择单元格",vbOKOnly+vbExclamation>

ExitSub

EndIf

KeyWord=Combo2.Text+"F"'标记是多值

InsertField

EndSub

PrivateSubForm_Load<>

DimiAsInteger

CommonDialog1.DialogTitle="打开"

CommonDialog1.Filter="Word文档<*.doc>|*.doc|Word文档模板<*.dot>|*.dot"

CommonDialog2.DialogTitle="保存文件"

CommonDialog2.Filter="Word文档<*.doc>|*.doc|Word文档模板<*.dot>|*.dot"

FieldCount=0

Me.ScaleY

=vbTwips,toscale:

=vbPoints>

Fori=1TogFieldColl.Count

Combo1.AddItem>

Next

Fori=1TogTableColl.Count

Combo2.AddItem>

Next

EndSub

'**********************************************************

PrivateFunctionInsertFieldByKeyWordAsInteger

DimIDAsInteger

FieldCount=FieldCount+1

ReDimMyField

ID=InsertField

MyField.ID=ID

MyField.KeyWord=KeyWord

EndFunction

PrivateSubSetEnabled

DimobjAsControl

ForEachobjInMe.Controls

IfTypeName="TextBox"Then

obj.Enabled=isEnabled

EndIf

IfTypeName="ComboBox"Then

obj.Enabled=isEnabled

EndIf

IfTypeName="CheckBox"Then

obj.Enabled=isEnabled

EndIf

IfTypeName="CommandButton"Then

obj.Enabled=isEnabled

EndIf

Next

EndSub

'在关闭该界面时应该恢复Word环境。

PrivateSubForm_Unload

IfFileName<>""Then

OpenCommandBar<>

wdApp.ActiveWindow.Close<>

wdApp.Quit<>

EndIf

EndSub

'定义Word环境的大小。

PrivateSubSetWordSize

wdApp.WindowState=wdWindowStateNormal

wdApp.Left=Left

wdApp.top=top

wdApp.width=width

wdApp.height=height

EndSub

'定义Word域代码是否可显示。

PrivateSubIsShowField

wdApp.ActiveWindow.View.ShowFieldCodes=IsShow

EndSub

'关闭Word环境的所有命令及菜单。

PrivateSubCloseCommandBar<>

DimiAsInteger

DimcBar

ReDimCommandBarIndex<1>

ReDimSaveCommandBarMenuIndex<1>

i=0

ForEachcBarInwdDoc.CommandBars

IfcBar.Type=0AndcBar.Enabled=TrueThen

IfcBar.Visible=TrueThen

ReDimCommandBarIndex

CommandBarIndex=cBar.Index

i=i+1

cBar.Visible=False

EndIf

EndIf

Next

i=0

ForEachcBarInwdDoc.CommandBars<"MenuBar">.Controls

IfcBar.Visible=TrueThen

ReDimSaveCommandBarMenuIndex

SaveCommandBarMenuIndex=cBar.Index

i=i+1

cBar.Visible=False

EndIf

Next

EndSub

'恢复Word环境的所有命令及菜单。

PrivateSubOpenCommandBar<>

DimiAsInteger

Fori=0ToUBound-1

wdDoc.CommandBars.Visible=True

Next

Fori=0ToUBound-1

CommandBars<"MenuBar">.Controls.Visible=True

Next

EndSub

3.2增加窗体

下面我们继续编写CSetDocField类的内容。

CSetDocField类应该提供单值域和多值的域名,所以我们把它们定义为CSetDocField类的属性,并提供一运行上面窗口的方法。

这里我们要利用一些技巧,在定义类并向类属性赋性值后,事实赋性值是保存在所定义的实类中,该实类一旦消失,值也随着消失。

如何不通过该实类取得类的属性?

这是困扰许多开发人员的问题。

我的解决方法是申请与类属性对应的全局变量。

向类属性的同时,把值保存在对应的全局变量中,取值时取出对应的全局变量的值就可。

这里我们选增加一Module,其Code如下:

PublicgSavePathAsString

PublicgFieldCollAsCollection

PublicgTableCollAsCollection

SubMain<>

Form1.Show<1>

EndSub

下面我利用全局变量当作类属性使用的技巧:

CSetDocField类的Code:

PublicSubRun<>

StaticFieldCollAsCollection

StaticTableCollAsCollection

Main<>

EndSub

PropertyGetFieldColl<>AsCollection

'SetFieldColl=mFieldColl

SetFieldColl=gFieldColl

EndProperty

PropertyLetFieldColl

SetgFieldColl=Field

EndProperty

PropertyGetTableColl<>AsCollection

SetTableColl=gTableColl

EndProperty

PropertyLetTableColl

SetgTableColl=Field

EndProperty

PropertyLetSavePath

gSavePath=str

EndProperty

这里,我们把插入域的类编写好了,只要在VB6的文件菜单中执行生成该类的文件就可生成DLL文件。

下面编写将值填写到文件中域对应的位置的类。

在VbaWord工程中增加新类CWriteDataToDocument。

类CWriteDataToDocument由调用者提供所处理的文件模板,所以它应该有一文档属性DocumentName,打开DocumentName文件,向DocumentName文件中插入单值和多值。

插入多值时要判断是否增加单元格。

如果对应的值多于所提供的表格行数,则要增加行。

下面是它的完整Code:

PrivatewdAppAsNewWord.Application<>

PrivatewdDocAsNewWord.Document<>

PrivateIsInsertRowAsBoolean'是否已经插入了行

PublicDocumentNameAsString

PublicFunctionFillData<>

OpenWordDocument<>

InsertValue<>

InsertCollection<>

wdDoc.SaveAs

EndFunction

PublicFunctionGetValueByFieldAsString

GetValueByField="liyu"

EndFunction

PublicFunctionGetRecordSetByFieldAsCollection

DimcollAsNewCollection<>

coll.Add<"li">

coll.Add<"yu">

GetRecordSetByField=coll

EndFunction

PrivateSubOpenWordDocument<>

wdApp=CreateObject<"Word.Application">

wdApp.Documents.Open

wdDoc=wdApp.ActiveDocument

wdApp.Visible=True

'wdDoc.Ac

展开阅读全文
相关搜索

当前位置:首页 > 职业教育 > 职业技术培训

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1