发布时间:2008-02-02 来源:网络/责编:编程入门 作者:陈明
Microsoft Word是一个集成化环境,是美国微软公司的字处理系统,但是它决不仅仅是一个字处理系统,它集成了Microsoft Visual Basic,可以通过编程来实现对Word功能的扩展。
Microsoft Visual Basic在word中的代码即Word的宏,通过编写Word宏,可实现一些文档处理的自动化,如实现文档的自动备份、存盘等,可扩展Word文档的功能,因此,能够充分利用Word的特性,甚至使Word成为自己软件的一部分。Word的宏既有有利的一部分,因为它能够帮助我们实现文档的自动化,但是Word的宏也不是纯粹的有利,有时它可能危害我们的文档、计算机系统甚至网络,从最开始的Taiwan NO1宏病毒到现在的Melissa宏病毒,从最开始的简单的提示,耗尽系统资源到现在的乱发电子邮件,将个人的信息发送到网络上,甚至向硬盘的Autoexec.bat(自动批处理文件)中添加Deltree C: -y,破坏整个Windows系统。 Word中内嵌的Com技术
可以说Word是对Com技术支持最好的软件,这样说似乎是太极端了一点,但是Word提供的强大的编程接口技术却能够是我们通过程序控制Word的任何一部分。无论是文件的打开、存盘、打印还是文档中表格的自动绘制。
通过编程软件,可以灵活的操纵word,这里只以Borland Delphi为例,进行详细描述:
1、 在Delphi中调用Word软件/文件的方法 在Word中调用Word软件,归纳起来有三种可通过Delphi的控件TOleContainer 将Word嵌入的方法
a.使用Delphi提供的Servers控件调用Word,使用Word的属性
b.通过真正的Com技术,将Office软件目录中文件MSWORD9.OLB中的类库全部导入Delphi中,
c.使用CreateOleObject将启动Word,然后以Ole方式对Word进行控制。 2、 对几种方法的难易程度的判别
a.通过Delphi的控件TOleContainer 将Word嵌入
这是最简单的Ole嵌入,能够直接将Word文档调用,只需要使用ToleContainer.Run就可以将Word文档直接启动。且这样启动的Word文档与Delphi程序是一个整体(从界面上看),但是它存在不可克服的缺点,即不能通过Delphi控制Word文档,也就不能实现将灵活操纵Word的目的。
b.使用Delphi提供的Servers控件调用Word,使用Word的属性。
使用Delphi的Servers控件来操纵Word,在编程时Delphi能够实现代码提示,总体上看能够较好的实现Delphi对Word的控制,但是还有一些Word的功能不能在Delphi中调用(比如自己编写的VBA宏代码)。
且实现功能时本来在VBA代码中可选则参数在Delphi调用的时候必须添加,否则,连编译都不能通过。
这种方式启动的Word与Delphi程序分属两个窗体。此办法仅能作为一个参考。 c.通过真正的Com技术,将Office软件目录中文件MSWORD9.OLB中的类库全部导入Delphi中,利用Com技术编程,利用真正的Com技术,将MsWord9.OLD文件类库导入,然后利用Com技术进行使用。
整体上类似使用Delphi的Servers控件,稍微比Servers控件麻烦,优缺点与Servers控件相同。
d.使用CreateOleObject将启动Word,然后以Ole方式对Word进行控制。
1
这种办法是使用以CreateOleObjects方式调用Word,实际上还是Ole,但是这种方式能够真正做到完全控制Word文件,能够使用Word的所有属性,包括自己编写的VBA宏代码。
与Servers控件和com技术相比,本方法能够真正地使用Word的各种属性,和在VBA中编写自己的代码基本一样,可以缺省的代码也不需要使用。 本方式启动的Word与Delphi程序分属两个窗体。
缺点是使用本方法没有Delphi代码提示,所有异常处理均需要自己编写,可能编写时探索性知识比较多。 Word宏编辑器
进入Word宏编辑器的方法:工具->宏->Visual Basic编辑器,可进入Visual Basic编辑器界面。Word的Visual Basic编辑器界面和真正的Visual Basic编辑器基本相同,在此不再向详述。
在VBA代码中,可以添加用户窗体、模块、类模块。用户窗体、模块、类模块的概念和Visual Basic完全相同。注释也与Visual Basic完全相同。
可以将光标停留在窗体、模块的任何一个子程序上,直接按“F5”运行当前子程序。 Word的宏的概述
Word充分地将文档编辑和VB结合起来,真正地实现文档的自动化。使用Word编程,类似于使用Visual Basic,所不同的是,在Word中,能够直接运行某一个子程序,直接看见结果,Word的宏,
只能解释运行,而Visual Basic,现在已经能够编写成真正的机器码,从代码的保护上来说,应该尽可能地减少Word的VBA代码数量,尤其是关键的代码。 VBA宏,可分成四种: 1、和命令名相同的宏
如FileSave,FileOpen,如果在VBA代码中包含与Word同名的函数,则直接执行这些VBA代码,忽略Word本身的命令。 2、Word内特定的宏
这些宏包含AutoExec(启动 Word 或加载全局模板)、AutoNew(每次新建文档时)、AutoOpen(每次打开已有文档时)、AutoClose(每次关闭文档时),AutoExit(退出 Word 或卸载全局模板时)。
如果VBA代码中含有这些名称的函数,则满足相应的条件,相应代码就自动执行。 3、相应事件的VBA宏
这些宏是由事件触发的宏,如Document_Close在文档关闭的时候触发事件,Document_New在新建文档的时候触发,Document_Open在打开文档的时候触发。 4、的宏
自己编写的VBA代码,即不属于上面几种情况的VBA代码,可以被其他VBA代码调用,更重要的是,可以被其他程序调用。 这样,我们就可以屏弃Word自动执行的宏,通过Delphi直接调用相应宏来达到目的。 Word命令宏的详细描述
Word本身的命令函数包含很多,但是无论是word联机帮助还是MSDN帮助,都没有这方面的介绍,因此只能凭自己的实验取探索,初步探测的函数如下: 宏名 解释 FileNew 新建 FileNewDefault 新建空白文档 FileSaveAs 另存为 FileOpen 打开 FileClose 关闭
2
FilePrint 打印 FilePrintPreview 打印预览 ToolsCustomize 工具栏里面的自定义 ToolsOptions 工具选项 ToolsRevisions 突出显示修订 ToolsReviewRevisions 接受或拒绝修订 ToolsRevisionMarksAccept 接受修订 ToolsRevisionMarksReject 拒绝修订 ToolsRevisionMarksToggle 修订 ToolsMacro 宏 ToolsRecordMacroToggle 录制新宏 ViewSecurity 安全性 ViewVBCode 查看VB编辑器环境 FileTemplates 模板和可加载项 ToolsProtectUnprotectDocument 解除对文档的保护 InsertHyperlink 插入超级链接 EditHyperlink 编辑超级链接 DeleteHyperlink 删除超级链接 EditLinks 查看、删除链接 EditPasteAsHyperlink 粘贴超级链接 FormatStyle 样式 EditBookMark 书签
下面举例说明:
一、Delphi程序启动Word
采用CreateOleObjects的方法来启动Word,调用VBA代码,具体实现过程为: 首先使用GetActiveOleObject('Word.Application')判断当前内存中是否存在Word程序,如果存在,则直接连接,如果没有Word程序,则使用CreateOleObject('Word.Application')启动Word 二、Delphi程序新建Word文稿
格式:WordDocuments.Add(Template,NewTemplate,DocumentType,Visible) Template: 使用模板的名称,
NewTemplate: 新建文档的类型,True表示为模板,False表示为文档 DocumentType: 文档类型,默认为空白文档 Visible: 打捞的窗口是否可见 举例:Doc_Handle:=Word_Ole.Documents.Add(Template:='C:\\Temlate.dot',NewTemplate:=False);
三、Delphi程序打开Word文稿 格式:WordDocuments.Open(FileName,ConfirmConversions,ReadOnly,PassWordDocument,
PasswordTemplate,Revent,WritePasswordDocument,WritePassWordTemplate,Format,Encoding,Visible)
3
FileName: 文档名(包含路径)
Confirmconversions: 是否显示文件转换对话框 ReadOnly: 是否以只读方式打开文档
AddToRecentFiles: 是否将文件添加到\"文件\"菜单底部的最近使用文件列表中 PassWordDocument: 打开此文档时所需要的密码 PasswordTemplate: 打开此模板时所需要的密码 Revert: 如果文档已经,是否重新打开文档
WritePasswordDocument: 保存对文档更改时所需要的密码 WritePasswordTemplate: 保存对模板进行更改时所需要的密码 Format: 打开文档时所需使用的文件转换器 Encoding: 所使用的文档代码页 Visible: 打开文档的窗口是否可见 举例:
Doc_Handle:=Word_Ole.Documents.open(FileName:=Doc_File,ReadOnly:=False, AddToRecentFiles:=False); 四、Delphi程序保存Word文稿
格式:WordDocuments.SaveAs(FileName, FileFormat, LockComments, Password, AddToRecentFiles, WritePassword, ReadOnlyRecommended, EmbedTrueTypeFonts, SaveNativePictureFormat, SaveFormsData, SaveAsAOCELetter) FileName: 文件名。默认为当前文件夹和文件名。 FileFormat 文档保存的格式。
LockComments 如果为 True,则此文档只允许进行批注。 Password 打开文档时的口令。 AddToRecentFiles 如果为True,则将文档添至\"文件\"菜单中最近使用的文档列表中。 WritePassword 保存对文档的修改所需的口令。---www.bianceng.cn
ReadOnlyRecommended 如果为 True,在每次打开文档时,Word 将建议用户采用只读方式。
EmbedTrueTypeFonts 如果为 True,则将文档与 TrueType 字体一起保存。
SaveNativePictureFormat 如果为 True,则从其他系统平台(例如 Macintosh)导入的图形仅保存其 Windows 版本。
SaveFormsData 如果为 True,则将窗体中用户输入的数据存为一条数据记录。 SaveAsAOCELetter 如果文档包含一个附加,当此属性值为 True 时,将文档存为一篇 AOCE 信笺(同时保存邮件)。 举例:
Word_Ole.Documents.SaveAs(FileName:=Doc_File,FileFormat=wdFormatDocument,AddToRecentFiles=False);
五、从数据库读取文件到本地硬盘和从本地硬盘读取文件到数据库 在数据库上使用Image二进制字段保存,使用Stream流的方式。 创建文件流:
Word_FileStream:=TFileStream.Create(Target_Name,fmOpenWrite or fmCreate); Word_FileStream.Position:=0; 保存到数据库的Image字段:
TBlobField(AdoQuery1.FieldByName(Column_Name)).SaveToStream(Word_FileStream); 从数据库读取文件到本地硬盘:
4
TBlobField(ADOQuery1.FieldByName(Column_Name)).loadfromStream(Word_FileStream);
释放文件流:
Word_FileStream.Free; 六、全局消息的定义
因为word和Delphi程序是两个软件,相互之间通讯比较麻烦,所以使用全局消息的方法进行。全局消息必须首先注册,Windows返回系统空闲的消息号,当注册的消息相同时,Windows系统返回同一个值,这样就保证了使用这个消息号在两个程序之间通讯。 定义消息的办法:
szMessageString: pchar = 'XIDIAN_11_Stone';
FMyJoinMessage := RegisterWindowMessage(szMessageString); 发送消息的方法:
SendMessage(对方句柄,消息,消息附带短变量,消息附带长变量) 七、Delphi程序接收消息的方法
Delphi接收消息有两种,一是重载特定消息,二是重载WndProc函数,在里面选择相应消息进行处理。
方法一,每次只能处理一条消息,而法二能够同时处理多条消息。 对于法二,声明如下:
procedure WndProc(var Message: TMessage);override
必须注意,使用时需要在处理完自己消息处理后继承WndProc(Message)函数,否则系统会崩溃!
八、Word中Combo对话框的动态生成以及Change事件 建立类模块Combohander,在内部定义事件
Public WithEvents ComboBoxEvent As Office.CommandBarComboBox 定义Combo控件产生事件的模块
Dim ctlComboBoxHandler As New ComboBoxHandler 产生Combo对话框 Set Cbo_ChooseDoc = CommandBars(\"添加的菜单\").Controls.Add(Type:=msoControlComboBox, Temporary:=True) 进行文件句柄设置,以产生Combo_Change事件
Set ctlComboBoxHandler.ComboBoxEvent = Cbo_ChooseDoc
产生事件后,在类模块Combohander内选择ComboBoxEvent的Change事件,即可书写事件代码
Sub ComboBoxEvent_Change(ByVal Ctrl As Office.CommandBarComboBox) 九、一些Word的事件
VBA代码中处理的Word事件有:Document_Close
Application事件中需要处理的有:DocumentBeforeClose,DocumentChange。 Document_Close:事件在文档关闭时产生事件
DocumentBeforeClose:在文档被关闭以前先于Word判断文档是否保存,给出相应提示并进行相应处理。
DocumentChange:文档切换,在文档从自己修改的文稿和其他人修改的文稿之间切换产生事件,主要处理设置文档权限等。
5
用Delphi合并Word表格中单元格 //合并Word 表格中单元格 procedure mergeWordCell;
var WordApp: TWordApplication; WordDoc: TWordDocument;
DocInx,oFileName,CfCversions,oReadOnly,AddToRctFiles,PswDocument, PswTemplate,oRevert,WPswDocument,WPswTemplate,oFormat: OleVariant; i,iRow,iCol:integer; myCell:Cell; myRow:Row; begin
memo1.Lines.Clear ;
// ===== 创建对象 =====
if not Assigned(WordApp) then begin
WordApp:= TWordApplication.Create(nil); WordApp.Visible := false; end;
if not Assigned(WordDoc) then
WordDoc:= TWordDocument.Create(nil); try
DocInx:=1;
oFileName := 'd: est.doc'; oReadOnly:=true;
CfCversions := EmptyParam; AddToRctFiles:= EmptyParam; PswDocument:= EmptyParam; PswTemplate:= EmptyParam; oRevert:= EmptyParam;
WPswDocument:= EmptyParam; WPswTemplate:= EmptyParam; oFormat:= EmptyParam;
// ===== 打开文件 =====
WordApp.Documents.open(oFileName,CfCversions,oReadOnly,AddToRctFiles, PswDocument,PswTemplate,oRevert,WPswDocument,WPswTemplate,oFormat); // ===== 关联文件 =====
WordDoc.ConnectTo(WordApp.Documents.Item(DocInx));
//合并第一、二列
iStart:=WordDoc.Tables.Item(i).Cell(1,1).Range.Start; myCol:= WordDoc.Tables.Item(i).Columns.Item(2);
iEnd:=myCol.Cells.Item(myCol.Cells.Count).Range.End_; myRange:=WordDoc.Range; myRange.Start:=iStart; myRange.End_ :=iEnd; myRange.Cells.Merge; finally
if Assigned(WordDoc) then // ===== 关闭文件 =====
6
begin
WordDoc.Close;
WordDoc.Disconnect; WordDoc.Destroy; WordDoc := nil; end;
if Assigned(WordApp) then // ===== 关闭Word ===== begin
WordApp.Quit;
WordApp.Disconnect; WordApp.Destroy; WordApp := nil; end; end; end;
取得Word 表格中的数据 //取得Word 表格中的数据 procedure getWordCellStr;
var WordApp: TWordApplication; WordDoc: TWordDocument;
DocInx,oFileName,CfCversions,oReadOnly,AddToRctFiles,PswDocument, PswTemplate,oRevert,WPswDocument,WPswTemplate,oFormat: OleVariant; i,iRow,iCol:integer; myCell:Cell; myRow:Row; begin
memo1.Lines.Clear ;
// ===== 创建对象 =====
if not Assigned(WordApp) then begin
WordApp:= TWordApplication.Create(nil); WordApp.Visible := false; end;
if not Assigned(WordDoc) then
WordDoc:= TWordDocument.Create(nil); try
DocInx:=1;
oFileName := 'd: est.doc'; oReadOnly:=true;
CfCversions := EmptyParam; AddToRctFiles:= EmptyParam; PswDocument:= EmptyParam; PswTemplate:= EmptyParam; oRevert:= EmptyParam;
WPswDocument:= EmptyParam; WPswTemplate:= EmptyParam; oFormat:= EmptyParam;
7
// ===== 打开文件 =====
WordApp.Documents.open(oFileName,CfCversions,oReadOnly,AddToRctFiles, PswDocument,PswTemplate,oRevert,WPswDocument,WPswTemplate,oFormat); // ===== 关联文件 =====
WordDoc.ConnectTo(WordApp.Documents.Item(DocInx)); //方法(1)==> 规则表
For i := 1 To WordDoc.Tables.Count do //第 i 个表 begin //第 iRow 行
For iRow := 1 To WordDoc.Tables.Item(i).Rows.Count do begin //第 iCol列 For icol := 1 To WordDoc.Tables.Item(i).Columns.Count do begin
myCell:=WordDoc.Tables.Item(i).Cell(iRow,icol); memo1.Lines.add(myCell.Range.Text); end; end; end;
//方法(2)==> 不规则表:只有横向合并时
For i := 1 To WordDoc.Tables.Count do //第 i 个表 begin
For iRow := 1 To WordDoc.Tables.Item(i).Rows.Count do begin
myRow:=WordDoc.Tables.Item(i).Rows.Item(iRow);//第 iRow 行 For icol := 1 To myRow.Cells.Count do //第 iCol列 begin
myCell:= myRow.Cells.Item(iCol) ; memo1.Lines.add(myCell.Range.Text); end; end; end;
8
Delphi + Word = 数据库 + 公文处理
Delphi擅长做数据库类的MIS开发,但对于OA就有点力不从心了。不过随着Microsoft的COM技术逐渐成熟,现在普通Windows应用已经可以和Office 97无缝结合了,尤其是在Delphi 5中提供了一组Servers组件,更是简化了程序开发。
最近接触了一个用户的案例,用Delphi控制Word做一个合同管理程序。办公人员先根据业务需要,写好合同的文字,但在用户名称、产品名称等变化的位置填写指定的标记字符串,然后通过Delphi把数据库中的实际数据替换掉Word中的文字,最后让Word打印出合同。
Delphi自带了一个简单的Word例题,但功能太简单。通过查找VBA的说明,再对照Delphi的VCL,编写了如下代码,实现了基本的公文管理功能。 启动Word时用如下代码: begin try
Wordapplication.Connect; except
MessageDlg(Word may not be installed, mtError, [mbOk], 0); Abort; end;
Wordapplication.Visible := True;
WordApplication.Caption := Delphi automation; end;
关闭Word用如下代码。如果想保存Doc文件,请修改SaveChanges变量的内容: var
SaveChanges, OriginalFormat, RouteDocument: OleVariant; begin
SaveChanges := WdDoNotSaveChanges; OriginalFormat := UnAssigned; RouteDocument := UnAssigned; try
WordApplication.Quit(SaveChanges, OriginalFormat, RouteDocument); WordApplication.Disconnect; except
on E: Exception do begin
Showmessage(E.Message); WordApplication.Disconnect; end; end; end;
让Word打开一个指定的文件,需要先放置OpenDialog,然后调用WordApplication.Documents.Open: var
ItemIndex :OleVariant;
FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert,
WritePasswordDocument, WritePasswordTemplate, Format: OleVariant; begin
9
if not dlgOpen.Execute then Exit;
{Open document}
FileName := dlgOpen.FileName; ConfirmConversions := False; ReadOnly := False;
AddToRecentFiles := False; PasswordDocument := ; PasswordTemplate := ; Revert := True;
WritePasswordDocument := ; WritePasswordTemplate := ;
Format := wdOpenFormatDocument;
WordApplication.Documents.Open( FileName, ConfirmConversions, ReadOnly, AddToRecentFiles, PasswordDocument, PasswordTemplate, Revert, WritePasswordDocument, WritePasswordTemplate, Format );
{Assign WordDocument component} ItemIndex := 1;
WordDocument.ConnectTo(WordApplication.Documents.Item(ItemIndex));
{Turn Spell checking of because it takes a long time if enabled and slows down Winword}
WordApplication.Options.CheckSpellingAsYouType := False; WordApplication.Options.CheckGrammarAsYouType := False; end;
让Word替换标记字符串要使用WordDocument.Range.Find.Execute,这里用Delphi替换了<#Name>: var
FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike,
MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace: OleVariant; begin
FindText := <#Name>; MatchCase := False; MatchWholeWord := True; MatchWildcards := False; MatchSoundsLike := False; MatchAllWordForms := False; Forward := True;
Wrap := wdFindContinue; Format := False;
ReplaceWith := Delphi; Replace := True;
WordDocument.Range.Find.Execute( FindText, MatchCase, MatchWholeWord,
10
MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace ); end;
上面这4段代码完成了公文管理的基本功能,再把它和数据库结合起来,就可以开发一个与Lotus Notes类似的产品了。 孙立
11
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- huatuo0.cn 版权所有 湘ICP备2023017654号-2
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务