VB 版 (精华区)

发信人: zxfsnow (别怕我伤心), 信区: VB
标  题: 用MS Word作ActiveX自动服务器 
发信站: 哈工大紫丁香 (2000年06月01日19:06:41 星期四), 转信

发信人: lijialie (day), 信区: VB
标  题: 用MS Word作ActiveX自动服务器
发信站: 饮水思源站 (Mon Sep  6 10:46:42 1999) , 站内信件

作为通用的字处理工具,MS Word是非常优秀的,它功能强大,使用方便,并且微软提

供的VBA语言又极大地扩展了其功能。MS Word所见即所得的特性的确令人爱不释手。然
而,
它的局限性也是非常明显的,比如说,想用它的VBA语言来获取数据库中的数据就相当麻
烦,
并且不像独立的Visual Basic那样支持标准的文件、目录和驱动器的列表。
  我们的任务很简单,就是把全系300多名毕业生四年的学习成绩按照规定的格式打印

来,以便存入档案后递交用人单位。每个学生的课程总共约有三、四十门,并且每个人
的课
程都不完全相同,其中选修课大约占30%。仅就输出报表而言,Word是毫无问题的,但是
Word
难以从数据库中读取学生成绩并加以处理。如果不用Word,那么自己编写报表输出程序

怎样呢?先看看现有的开发工具VB、Delphi、BC++、VC++等,用它们读取数据库的数据

然是毫无问题的,但是输出的报表又难以与Word报表相媲美。想赶上Word报表,就不得

深入到令人头痛的打印机编程中去,而且还需要反复调试,非常麻烦。
  1.Delphi和Word联手打天下
  好在Microsoft果然不负众望,Word既是一个优秀的字处理软件,也是一个出色的
ActiveX自动服务器,其自动服务功能非常强大,而且应有尽有。
  为了完成上述任务,我们用Delphi开发主控程序scoreout.exe来操纵Word自动输出

定制的报表。事先将要输出的表格做一份模板,而且给要填写的数据项如班级、姓名、
学号、
课程等留出空位,由scoreout.exe操纵Word填入这些数据项。因为模板是事先用Word做

好的,想怎么排就怎么排,而且不用反复地运行、测试,更不用理会打印机的差异,这
一切
Word都可以处理好。关于数据库的浏览、编辑问题,对于用Delphi开发的scoreout.exe

程序来说也是小菜一碟,友好的用户界面则更不用提了。
  2.让Word俯首听命
  在scoreout.exe中创建一个隐含的Word.application实例,让该实例在后台工作,

Word启动失败,则显示一条提示消息并终止程序的运行。
  首先在uses语句中加入comobj单元,此单元中定义了CreateOLEObject函数,然后在

var表中加入wdApp说明,再定义FormCreate函数,Word启动后再设置其visible属性为
可见或不可见(相应的代码参见程序1)。在分发给最终用户时,建议把visible设置为
False,
因为,若Word可见,则用户可能会干扰其工作,这可能会导致不可预见的后果。
  uses
  ...comobj,... //加入comobj单元
  var
  ...
  wdApp:Variant; //加入wdApp说明
  procedure TForm1.FormCreate(Sender:TObject);
  begin //定义FormCreate函数
   try
   wdApp:=CreateOLEObject('Word.application'); //创建Word实例
   except
   messageDlg('Word起动失败',mtError,[mbOk],0); //提示错误
   application.terminate; //终止程序运行
   end;
  end;
  //设置visible属性
  wdApp.Visible:=True; //令Word可见
  wdApp.Visible:=False; //令Word不可见
  (程序1)
  Word启动后就可以让它进行如程序2操作了。
  wdApp.quit;//退出
  wdApp.run(...);//运行宏
  wdApp.language;//返回所用语言
  wdApp.fontname;//返回字体名
  wdApp.caption;//返回标题
  wdApp.Documents.open('c:\mydocument\biao.doc');//打开文档
  wdApp.Documents.add;//新建文档
  wdApp.Documents('mydoc.doc').close;//关闭文档mydoc.doc
  wdApp.Documents('mydoc.doc').save;//保存文档mydoc.doc
  wdApp.ActiveDocument.close(0);//关闭当前文档,参数0指出不保存
  wdApp.ActiveDocument.SaveAs('filename.doc');
  wdApp.Selection.MoveUp;//插入点上移
  wdApp.Selection.MoveLeft;//插入点左移
  wdApp.Selection.insertafter('string here');//插入文本
  (程序2)
  3.使用剪贴板交换数据
  应用程序和Word交换数据的方法有很多,使用数据交换文件或者DLL都可以,但都比

较麻烦。相比之下,使用剪贴板是一个较好的方法,其缺点是,在应用程序运行时,最
好关
闭其他程序,以避免其他程序使用剪贴板而冲毁数据。剪贴板功能强大,它几乎可以和
Word
交换任何类型的数据。程序3就是一个使用剪贴板的实例。
  //向剪贴板中粘贴数据
  procedure TForm1.Button1Click(Sender:TObject);
  begin
   edit1.SelectAll;
   edit1.CutToClipboard;//或edit1.CopyToClipboard;
  end;
  //将剪贴板中的数据粘贴到Word文档中
  procedure TForm1.Button2Click(Sender: TObject);
  begin
   wdApp.Selection.Paste
  end;
  //将Word中的数据粘贴到剪贴板中:
  procedure TForm1.Button3Click(Sender: TObject);
  begin
   wdApp.Selection.cut;//或wdApp.Selection.copy
  end;
  //将剪贴板中的数据插入edit控件:
  procedure TForm1.Button4Click(Sender:TObject);
  begin
   edit1.PasteFromClipboard;
  end;
  (程序3)
  4.失去控制的危险
  自动操作客户程序(如scoreout.exe)既可以像上面那样以过程方式调用open方法

又可以以函数方式调用open方法,例如
result:=wdApp.Documents.open('c:\mydocument\biao.doc');。以过程方式调用的问题

于它并不等待Word完成操作就立即将控制权返回给客户程序。如果Word执行的是一项很

时间的操作,则有可能在客户发送下一条命令之前,Word还没有完成前一项操作。与此

反,如果以函数方式调用一个方法,则只有在操作完成之后,才能将返回值传给客户程
序,
这样就可以确定Word已做好准备并可以执行下一步操作了。
  5.深入Word对象模型
  与Office 97的其他组件一样,Word被设计成可以用作ActiveX自动操作服务器,因

此好的ActiveX客户程序应该能充分利用其功能。客户程序可以是独立的程序,比如用D
elphi
编写的scoreout.exe或者是Visual Basic编写的其他应用程序,也可以是其他Office组

件中启动的VBA代码。其中,用Delphi编写的应用程序启动Word只需要一条代码
"wdApp:=CreateOleObject('Word.application');",用VB或VBA也很类似。程序4便是使

用CreateObject函数来设置对Microsoft Word的引用(变量名为wdApp),本例使用了该

引用来访问Microsoft Word的Visible属性,然后使用Microsoft Word的Quit方法将它
关闭,最后释放该引用自身。
  Dim wdApp As Object '声明变量来保持引用。
  Set wdApp = CreateObject("Word.application")
  '如果想看见被调用的应用程序,则必须将Visible属性设置为True。
  wdApp.Visible = True
  '用wdApp来访问Microsoft Word的其他对象,比如document。
  wdApp.Quit '结束后用Quit方法来关闭该应用程序,
  Set wdApp = Nothing '释放该引用。
  (程序4)
  要充分利用Word的自动服务功能,则必须对Word的对象模型有较为深入的了解,Wo
rd
对象模型中有一系列属于Application的对象和集合。以下示例程序均是用VB或VBA语言

编写的。
  (1)Application对象代表Word应用程序,包括可以返回最高一级对象的属性和方法

例如ActiveDocument属性可以返回Document对象。在使用可返回最普通的用户界面对象

许多属性和方法(比如活动文档,即ActiveDocument属性)时,可不必用Application对

象进行区分。例如,可写成ActiveDocument.PrintOut,而不必写成
Application.ActiveDocument.PrintOut。使用时不受Application对象限制的属性和方

被看作是“共用”的。Application对象的方法有Move、OnTime、Quit、Run等,属性有

ActiveDocument、ActivePrinter、caption、Documents、FontName、Path、visible、

WindowState、WordBasic等。
  (2)Documents对象是由Word当前打开的所有Document对象所组成的集合,下列示例

显示各打开文档的名称:
  For Each aDoc In Documents
   aName = aName & aDoc.Name & vbCr
  Next aDoc
  MsgBox aName
  用Add方法可以创建新的空文档,并将其添加到Documents集合中。用Open方法可以

打开文档。用Documents(index)可以返回单个的Document对象,其中的index是文档的名

称或索引序号。下面的语句用来关闭Report.doc文档,并且不保存所作的修改:
  Documents("Report.doc").CloseSaveChanges:=wdAppDoNotSaveChanges
  索引序号代表文档在Documents集合中的位置,例如Documents(1).Activate是代表

活Documents集合中的第一个文档,但建议使用Documents("Report.doc")这样的显式引
用,
这样可以使可读性强,而且不易出错。
  (3)Document对象代表一篇文档,Document对象是Documents集合中的一个元素。
Documents集合包含Word当前打开的所有Document对象。
  可用ActiveDocument属性引用处于活动状态的文档。下列示例是用Activate方法激

名为Document1的文档,然后将页面方向设置为横向并打印该文档:
  Documents("Document1").Activate
  ActiveDocument.PageSetup.Orientation = wdAppOrientLandscape
  ActiveDocument.PrintOut
  它的方法和属性各有数十个,不过常用的并不多,如Range、Save、SaveAs、Prote
ct、
Close、Goto、Unprotect等方法和ActiveWindow、FullName、HasPassWord、Name、Pag
eSetup、
Password、Path、ReadOnly、Saved、SaveFormat等属性。
  (4)Selection对象代表一个窗格中的选定内容,该选定内容可以包括文档中的一个

域,也可以仅包括插入点。可用Information属性返回有关选定内容的信息:
  If Selection.Information(wdAppWithInTable) = True Then...
  也可用Select方法选定文档中的一个项目,下例是选定活动文档中的第一个书签并

其显示为红色:
  If ActiveDocument.Bookmarks.Count >= 1 Then
   ActiveDocument.Bookmarks(1).Select
   Selection.Font.ColorIndex = wdAppRed
  End If
  Selection对象还包括几种用于扩展或移动当前选定内容的方法,例如,可以将Mov
eDown
方法的Extend参数设为wdAppExtend。下例在活动窗口中选定接下的三段:
  .StartOf Unit:=wdAppParagraph, Extend:=wdAppMove
  .MoveDown Unit:=wdAppParagraph, Count:=3, Extend:=wdAppExtend
  End With
  记录宏时,宏记录器经常将变化记录到Selection对象中。下例中宏将文档的起始两

词设为加粗格式并新添加一段:
  Selection.HomeKey Unit:=wdAppStory
  Selection.MoveRight Unit:=wdAppWord, Count:=2, Extend:=wdAppExtend
  Selection.Font.Bold = wdAppToggle
  Selection.MoveRight Unit:=wdAppCharacter, Count:=1
  Selection.TypeParagraph
  下例完成与上例相同的操作,但不使用Selection对象:
  Set myRange = ActiveDocument.Range(Start:=0,_
   End:=ActiveDocument.Words(2).End)
  myRange.Bold = True
  myRange.InsertParagraphAfter
  每个窗格中只能有一个Selection对象,但在一个文档中可以有多个Range对象。一

Range对象代表文档中一个已选定或未选定的范围,用Range对象可以很方便地对文档进

操作。
  (5)Range对象代表文档中的一个范围,每一个Range对象由一个起始位置字符和一个

终止位置字符定义,下例返回代表活动文档前10个字符的Range对象:
  Set myRange = ActiveDocument.Range(Start:=0, End:=10)
  (6)Table对象代表一张表格,它是Tables集合的一个成员。该集合包含指定的选定

容、范围或文档中的所有表格。可以使用Tables(index)返回一个Table对象,其中inde
x
为索引序号,代表表格在选定内容、范围或文档中的位置,下例是将活动文档中的第一
张表
格转换为文本:
  ActiveDocument.Tables(1).ConvertToText Separator:=wdAppSeparateByTabs
  使用Add方法可以在指定范围内添加表格。下例在活动文档的起始处添加一张3行x4

列的表格:
  Set myRange = ActiveDocument.Range(Start:=0, End:=0)
  ActiveDocument.Tables.Add Range:=myRange, NumRows:=3, NumColumns:=4
  (7)Goto方法是一个很有用的方法,对于Document或Range对象而言,此方法返回一

个Range对象,该对象代表指定项(例如页、书签或域)的开始位置。对于Selection对
象,
将插入点移动到指定项前面的字符位置。下面的示例将所选内容移动到文档中的第四行

  Selection.GoTo What:=wdAppGoToLine, Which:=wdAppGoToAbsolute, Count:=4
  下面的示例将所选内容向上移动两行:
  Selection.GoTo What:=wdAppGoToLine, Which:=wdAppGoToPrevious, Count:=2
  下面的示例将所选内容移动到下一个表格的第一个单元格:
  Selection.GoTo What:=wdAppGoToTable, Which:=wdAppGoToNext
  程序5是综合处理的例子,它显示如何对既有文本又有图表的文档进行定位;
  Sub ShowCellName()
  '打印出每个单元格的名字
  Set newdAppoc = ActiveDocument
  Set myTable = newdAppoc.Tables(1)
  i = 1
  For Each c In myTable.Range.Cells
   c.Range.InsertAfter "Cell " & i
   i = i + 1
  Next c
  '单元格定位及合并,注意单元格的引用
  Set myTable = ActiveDocument.Tables(1)
  Set myRange = ActiveDocument.Range(myTable.cell(1, 2).Range.Start,
  myTable.cell(1, 3).Range.End)
  myRange.Cells.Merge
  '插入点的定位,绝对定位至Tables(1).cells(1,1)
  Selection.GoTo What:=wdAppGoToTable, Which:=wdAppGoToAbsolute, Count:=1
  End Sub
  (程序5)
  下面的例子是查看插入点的位置:
  if Selection.Information(wdAppWithInTable)
  Then Selection.Tables(1).Select
  如果所选的内容位于一个表格中,则本示例选定该表格。
  6.建议
  (1)在使用别的开发语言操纵word进行自动服务之前,请先多多使用Word VBA,以便

熟悉Word的对象模型。因为它的在线提示功能非常有用,并且查阅Visual Basic参考资

也很方便。
  (2)Word对象模型的文档包含在Microsoft Word Visual Basic Reference(VBAWRD8
.HLP)
帮助文件中,在典型的Office安装过程中,该文件不被安装,但可以在定制安装过程中

择安装它。该文档是很有用的参考,但不能指望仅仅依靠该文档来掌握Word的对象模型

特别是对于初学者而言,更多的应该是进行思考和验证。
  
--

 以科计为本,以产业报国!
  超越自我,飞跃无限!
  

※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.235.249]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:4.271毫秒