Delphi(程序人生)

Delphi Programer DoubleCat

导航

Delphi与Ole,Word,Excel,查找与替换等

Delphi与Word之间的融合技术(下)zt

来自:yzhshi, 时间:2002-2-2 14:24:00, ID:902680
前面我就Delphi中调用Word写了一些,比较注重于具体实现,对于研究的方法则说的比较片面。
今天晚上,我静下心来,总结了一下怎样在Delphi中生成操作Word的代码。如果说前面我写的
是金子,那么下面这篇文章就是点石成金的手指(太自夸了,呵呵)。毕竟已经有半年多没有研
究这些了,只能零碎的写一些心得了。

使用CreateOleObject方式调用Word相比Service控件的最大缺点就是不支持代码的自动生成,
但是我们充分的利用VBA代码就可以弥补这个功能。
Word作为一个功能强大的Com,可以很容易被编程工具调用,成为办公自动化系统中处理文档
的强有力的嵌套工具,尤其是充分Word本身的录制宏的功能,更进一步减轻了编程的负担。
下面就如何在Delphi里面利用Word的VBA代码进行一些总结。
1、  生成VBA代码。Word本身具有很强的可扩展性,尤其是支持用户自定义功能,其实现
的主要方式就是通过VBA代码来实现的。在“工具->宏->Visual Basic编辑器”里面就可以看
到具体的宏代码,可以直接进行编辑。而且还可以使用录制宏的功能自动生成宏代码。方法是
选择“工具->宏->录制新宏”,然后执行自己想通过程序实现的功能,如存盘、打印等功能,
此时Word一边执行你要实现功能,一边将你的操作生成了一个宏,在实现功能后,可以选择
“工具->宏->VisualBasic编辑器”,查看生成的宏代码。

例如:我们要将文档中的“讨论”全部替换成“研讨”。
a.  点击“工具->宏->录制新宏”,直接点击确定,默认的宏保存到了Normal.dot系统公
用模板里面。
b.  点击“编辑->查找”,出现弹出对话框,输入查找和替换的字,点确定。进行替换。
c.  结束宏的录制,点击结束按钮。
d.  按F11或者“工具->宏->Visual Basic 编辑器”,查看宏代码。缺省查看Normal里面
的模块里面的NewMacros模块。
以下是生成的宏代码:
Sub Macro1()
'
' Macro1 Macro
' 宏在 2002-2-1 由 yzhshi 录制
'
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "讨论"
        .Replacement.Text = "研讨"
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchByte = True
        .MatchWildcards = False
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
End Sub
2、  精简宏代码。通常,生成的宏代码有很多语句对你要实现的功能来说都是多余的。我们要
做的就是如何找到我们需要的代码。此时我们查看具体的代码,剔除明显没有用途的代码,然后光
标停留在宏上面,按F5执行,看是否实现功能,逐步精简,得到最小代码。此步骤可参考Word的
VBA帮助来判断代码是否有用。

如上例,精简下来,剩下以下代码。
Sub Macro1()
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = "讨论"
        .Replacement.Text = "研讨"
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
End Sub

3、  转换成Delphi代码。这一步其实很简单,对于VBA代码,只需要在前面添加Word的句柄或者
文档的句柄或者文档的句柄.Application就可以直接操作了。
例:逐句翻译:(Word_Handle是Word的句柄)
(VB)     Selection.Find.ClearFormatting
(Delphi)  Word_Handle.Selection.Find.ClearFormatting;

(VB)     Selection.Find.Replacement.ClearFormatting
(Delphi)  Word_Handle.Selection.Find.Replacement.ClearFormatting;
以上两句简单添加上Word的句柄就可以了。

(VB)     With Selection.Find
              Text = "讨论"
              Replacement.Text = "研讨"
End With
(Delphi)  Word_Handle.Selection.Find.Text := '讨论';
  Word_Handle.Selection.Find.Replacement.Text := '研讨';
以上几句因为Delphi不支持Variant的With结构,所以分开写。同时转换成Delphi语法。

(VB)    Selection.Find.Execute Replace:=wdReplaceAll
(Delphi) Word_Handle.Selection.Find.Execute(Replace:=2);
上面一句存在一个小技巧,如何找到常量wdReplaceAll的数值为2?
这里有几个办法,
一:直接use Word2000或者word97单元,那么直接使用常量wdReplaceAll就可以了;
二:到Word2000.pas或者Word97.pas里面查找wdReplaceAll的数值;
三:直接使用VBA代码见wdReplaceAll的数值显示出来。办法是写一个小过程,然后执行,如下:
Sub ShowValue()
  MsgBox wdReplaceAll
End Sub

最后补充一下,很多关于Word的东西可以从Word的VBA帮助里面获得。具体文件在
?:"Program files"Microsoft Office"Office10"2052(XP)下,VBAWD10.CHM,其他版本路径基本类似。
 


来自:脸谱, 时间:2002-2-3 17:29:00, ID:904233
请问怎么实现:
通过真正的Com技术,将Office软件目录中文件MSWORD9.OLB中的类库全部导入Delphi中,
利用Com技术编程
 

来自:peng_2002, 时间:2002-3-12 15:31:00, ID:978356
yzhshi前辈,我不能帮你。我来这里是为了向您表示我真诚的感谢,您真是太好了
,你帮我解决了哪个保存错误的问题,谢谢
我想和你交朋友,也想时常让您教导我,我想知道您的QQ和电子信箱。
如果前辈高人是神龙见头不见尾,哪我也只好对着苍天高呼:
谢谢您,YZHSHI。

我的QQ是:47292664
我的信箱是:zhento3@sohu.com
 


来自:SeaHawk, 时间:2002-3-14 12:06:00, ID:982533
正在把Office控件封装成Delphi的对应控件,包括PopupMenu,ToolBar,ToolButton等,
可以在Delphi内设计界面和事件,然后放到Office里面去,有人愿意测试吗?请留EMail!
                               
                           我的EMail:  jack_Lee@163.net
 


来自:liuyaook1166, 时间:2002-3-14 20:56:00, ID:983912
我愿意测试学习
MAIL:liuyaook1166@163.com
谢谢! 


来自:liuyaook1166, 时间:2002-3-14 21:03:00, ID:983929
前面讨论了在DELPHI界面外控制OFFICE,各位大侠能不能讨论如何在
OleContainer中,究竟目前能不能作到对它的控制。 


来自:yzhshi, 时间:2002-3-15 14:27:00, ID:985302
呵呵,SeaHawk做的不错!给我发一份吧。my Mail:yzhshi@263.net

to peng_2002
   我们一起学习,一起进步吧!
to all
   对使用Com调用 Word的问题,欢迎给我来信探讨,但是,对于其他方式的调用,我真的涉猎太少。
只能说尽力而为了。 


来自:hq_pan, 时间:2002-3-15 18:30:00, ID:985862
能帮我看看这个问题吗?
http://www.delphibbs.com/delphibbs/dispq.asp?lid=981573 


来自:net_donkey, 时间:2002-3-23 13:31:00, ID:998460
相间狠晚啊!
谁还能细说一下控制word表格(比如每列宽度等)的详细方法吗? 


来自:wk_knife, 时间:2002-3-25 7:47:00, ID:1000438
//设置列宽
Document.Tables.Item(x){第几个表格}.Columns.item(y){第几列}.SetWidth(24,'wdAdjustNone');


  来自:linsb, 时间:2002-3-30 16:53:00, ID:1012587
To SeaHawk
   我愿意测试,给我发一份。
   EMAIL:linsb3031@0451.com
             谢谢!
 


来自:HAPPYBAB, 时间:2002-4-1 10:36:00, ID:1015576
在delphi 打开word 后,word窗口是最小化的,如何让word直接最大化显示? 


来自:liuyaook1166, 时间:2002-4-2 0:42:00, ID:1017373
To SeaHawk:

你的控件VERY COOL  向你学习,好同志啊。
可否将OFFICE菜单选项设置封装在你的控件中。(可随意屏蔽)
另:如果你有什么改进的话能mail me吗?
emial:liuyaook1166@163.com
    

来自:HAPPYBAB, 时间:2002-4-11 14:54:00, ID:1037083
to hubdog:
我照着你的葵花宝典中那篇delphi+word=办公自动化,调用word,程序运行后,第一次调用,没问题,第二次调用,就出现
如下错误:
project cffczx.exe raised exception class eoleexception with message 'RPC服务器不可用',process stopped,
use step or run t continue;
请问这是为什么? 


来自:yzhshi, 时间:2002-4-13 10:50:00, ID:1041311
to HAPPYBAB:
你是否将Word给关闭了,没有通过Delphi关闭,出这个典型的错误原因是Word被关闭了。 


来自:HAPPYBAB, 时间:2002-4-18 15:28:00, ID:1052102
to hubdog:
我利用filecreate('文件名.doc')命令,想通过delphi创建一个新文件,可是程序运行后,
文件是被创建了,可是点击打开时,总是出现如下提示:
文档的名称或路径无效,请使用如下建议:
* 监察文件或驱动器的权限;
*使用文件菜单中的打开命令来定位文档;
恳请指教,不胜感激!!! 


来自:sljfw, 时间:2002-4-19 12:54:00, ID:1053920
使用CreateOleObject将启动Word,然后以Ole方式对Word进行控制。如果用这种方式,那怎么截获word的消息呢,
比如说当文档关闭时我想在自己的程序中处理一些事情? 


来自:SeaHawk, 时间:2002-4-19 14:20:00, ID:1054154
sljfw:
  请看我前面的帖子,就有解答了。用OLEContrainter的那个。 


来自:ndust, 时间:2002-4-19 23:07:00, ID:1055233
我用delphi调有word生成word文档,在win2000和有的98下,office2000下正常,但是在有的
机器win98下运行程序被告知,不能启动服务,有的说数值超出范围,不能调有word,不知哪位高手遇到过这类情况,如何解决?
调用代码:
var
  wapp, wdoc: variant;
  tempj: integer;
begin
  try
    wapp := getactiveoleobject('word.application');
  except
    wapp := createoleobject('word.application');
  end;
  wapp.Documents.add;
......


另:如何能够让office97也好使,运行在office97下告知不支持automatic.

 


来自:yzhshi, 时间:2002-4-20 13:07:00, ID:1055947
很眼熟的问题,呵呵,你应该单独开帖子提问过,我好像也回答过。
>>wapp, wdoc: variant;
改成wapp, wdoc: OleVariant; 


来自:sljfw, 时间:2002-4-21 14:32:00, ID:1057842
SeaHawk
我现在不是用的olecontainer呀, 


来自:qq, 时间:2002-4-26 9:56:00, ID:1069102
受益非浅的同时各位老兄请恕在下贪心的提个问题
帖子中讨论的均是对文件的操作,但是否可以对流进行直接操作呢
比如我将DOC文件存到数据库中,现在想查看但不想生存临时文件,而是想直接利用流不知如何处理 


来自:dfs, 时间:2002-4-26 20:55:00, ID:1070613
FileTemplates  模板和可加载项 
怎么使用,比如我想在NORMAL.DOT中添加一个bbb.dot作为加载项?
谢谢!希望各位能帮帮我,最好有DELPHI的代码。 


来自:yzhshi, 时间:2002-4-27 8:17:00, ID:1071017
注意,以下不少都是自己定义的,主要就是使用AttachedTemplate。具体还可以参考VBA帮助
  Doc_Handle := Word_Ole.Documents.open(FileName := Doc_File, ReadOnly := False, AddToRecentFiles := False);
  {使用代码模板替换格式模板}
  Doc_Handle.AttachedTemplate := Macro_File;
 


来自:qq, 时间:2002-4-27 8:36:00, ID:1071058
OleContainer1.CreateLinkToFile(FileName, False);
时OleContainer1没有滚动条,不知道如何处理,同时如何可以做到象
OleContainer1.InsertObjectDialog;
with OleContainer1 do
  if NewInserted then DoVerb(PrimaryVerb);
时的效果;  我另有帖子,150,望指教 


来自:yzhshi, 时间:2002-6-7 21:28:00, ID:1149888
老兄,别这样跟贴呀,我以为你有什么好的建议呢,赶紧来看一下,谁知道你在做你的广告:-)
就算你的东西再好,这种做法似乎是不可取的呀。希望下不为例![:(!] 


来自:小小武, 时间:2002-6-11 16:52:00, ID:1157071
1,用server的话,生成的菜单调用delphi程序除了SeaHawk说的办法,不知还有没有别的办法!
2,用olecontainer,自己的添加菜单和excel的菜单同时存在,但是,excel的file菜单和window
菜单没了!不知如何让这两个菜单(最重要的是file菜单)保存不被替换掉 


来自:yixin, 时间:2002-6-27 9:41:00, ID:1183740

用OleContainer打开Word文档时出现“无法找到指定模块”的错误,为什么呢?
使用的语句是  OleContainer1.CreateObjectFromFile('C:"1.doc',False);

谢谢。
 


来自:littley, 时间:2002-6-28 15:23:00, ID:1186080
yzhishi和其他各位办公自动化方面的专家:
我有一个帖子,愿意出600分求解,如果各位大侠哪天心情好,请拔刀相助,小弟在此先谢过了!
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1168869
1、在rxlib的rxRichedit中插入WORD或MS GRAPH文档,如何能不借助
rxRichedit.insertObjectDialog达到目的?
2、将windows的画图程序直接OLE到rxRichedit中,不调用insertObject方法的对话框。
使我的编辑器提供用户画图的功能。成功后另外加600分!

因为小弟以前提过类似的帖子,但最终没有得到直接的解决办法。因此我不敢一下子加太多
分,准备得到直接的答案后再加分。我以这种方式送出去过近2000分,信用没得说,大家可以
查得到的。 


来自:wangny, 时间:2002-7-15 22:16:00, ID:1204190
看来和我一样对这个问题感兴趣的人还真多呀!大家有什么好的拿出来吧,谢谢各位前辈的指点![:D] 


来自:Delphi之旅, 时间:2002-7-28 14:57:00, ID:1227709
关于对word的操作,还少了word的关闭实现,我添上。
var
  SaveChanges,
  OriginalFormat,
  RouteDocument: OleVariant;

begin
  SaveChanges := WdDoNotSaveChanges;
  OriginalFormat := UnAssigned;
  RouteDocument := UnAssigned;
  try
    WordApplication.Quit(SaveChanges, OriginalFormat, RouteDocument);
    WordApplication.Disconnect;
    BtnCloseWord.Enabled := False;
    BtnPrint.Enabled := False;
    BtnPreview.Enabled := False;
  except
    on E: Exception do
    begin
      Showmessage(E.Message);
      WordApplication.Disconnect;
    end;
  end; 


来自:LiZhongYu, 时间:2002-8-7 22:02:00, ID:1249870
yzhshi,SeaHawk...各位大侠:
  用server来控制WORD,因为和应用程序不在一个窗口中,看起来好像是两套程序,或者
说连接的不紧密,不像自己应用程序里的东西,看着也不舒服。至少有的客户会这样认为。
所以我更愿意用OleContainer来控制。
  小弟最近正在作一个与数据库有关的程序,想要实现一下功能:开头部分内容几乎
雷同,依次为 供货商代吗,供货商名称,联系人,电话等。 下面是供货情况:货物1:
货物1的描述,也可能有货物的图片。货物2:货物2的描述。。。。
值班操作员可能会有如下纪录:
 供货商代码: 1234567
 供货商名称:xxxxxxxxxx
 联系人:张三
 电话: 1380xxxxxxxx
货物1:
abcdefg...........1000斤
 货物1 的图片.
货物2:
xyzzzzzzzzz.......1500斤
。。。。
供货商代码, 供货商名称,电话对应数据库的一个表,打开时我如何将将这该表的这些
信息添加到word中?加入操作员又修改了供货商电话,我如何能使另外一个表的信息与
之同步呢?
小弟先谢了。我可以再开贴给各位加分,分数有的是。


来自:yzhshi, 时间:2002-10-10 8:31:00, ID:1366984
哈哈,初始我也吓了一跳,我不用QQ的,怎么跑到腾讯的网站上去了,呵呵。仔细一看,呵呵。
谢谢小雨哥。资源共享,大家共同进步最好!

(商万贾[808366]在大作中提到:)
> 兄弟,最少也请说明是谁写的吧?
> 作者:yzhshi 邮箱:yzhshi@263.net
版权声明:本文为 星落→水[81710972] 转载的他人文章!!!
看清楚呀老大,,最后俺不是有说明了吗!!  


来自:darnis, 时间:2002-10-10 15:41:00, ID:1368061
鉴于用 CreateOleObject 创建的 Automation 服务器在编程时不大方便,
我有个小经验是,
 var
   wordApp : _Application;
 begin
  ...
  WordAppp := CreateOleObject('Word.Application') as _Application;
  ..
 end;
    这种方式,GetActiveOleObject 和 CreateOleObject 得到的是 OleVariant
转换成指定的接口就可以了。。
    风中的沙粒   提到的问题,可以用这种方式解决
  
   ACad : IAcadApplication;

   try
     acad := GetActiveOleObject('AutoCAD.Application') as IAcadApplication;
   except
     try
        acad := CreateOleObject('AutoCAD.Application') as IAcadApplication;
     except
        raise Exception.Create('AutoCAD Error!');
     end;
   end;
   这样就可以用 Acad 来控制AutoCAD 了(如果正常驱动),而且在写代码时,也可以
利用代码提示了。。:) 


来自:yzhshi, 时间:2002-10-10 17:59:00, ID:1368358
一个好的方法,但是你这样一改变,编程就CodeInsight有了,但是很多不需要的参数也必须输入了。
word2000.pas等文件将很多原来可以省略的参数都设置成了VAR的,必须输入,且需要定义一个oleVariant,
就是因为这,我最初才决定不用Servers控件的。[:D] 


来自:晓毛, 时间:2002-11-3 2:13:00, ID:1410002
怎样得到ExcelApplication1所在的单元格? 


来自:山泉, 时间:2002-11-3 7:06:00, ID:1410018
办公自动化
http://www.djpate.freeserve.co.uk/Automation.htm
目录
Automation with Delphi
If you have any helpful tips, examples etc of automation with Delphi, please send them to me and I'll include them, with credits. I'm creating 'Automating with...' pages for each automatable program that I have access to, but I'd love to add more - so if there's a program that you use that you can add help for, please email me.

Contents:
Introduction to automation in Delphi
Delphi 5's server components

Automating particular programs
Microsoft Office

Introduction
Access
Binder
Excel
Outlook
PowerPoint
Word

 


来自:Ruth, 时间:2002-11-5 9:27:00, ID:1413516
这一帖让我受益非浅,多谢!但我在打开和存储word文件时,
使用olecontainer,createoleobject()最后一个参数为true,
程序执行时,出现‘消息筛选程序正忙’的提示,按‘确定’后通过,
而olecontainer总是不显示文件图标,双击olecontainer控件也没有
文件打开,怎么回事? 


来自:杨深, 时间:2002-11-22 9:47:00, ID:1450314

前面讨论了在DELPHI界面外控制OFFICE,各位大侠能不能讨论如何在
OleContainer中,究竟目前能不能作到对它
实现多文档
比如 Application.Documents.Open
Application.Documents.Add
之类的的控制。
有分给,谢谢了

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1449645
 


来自:shuszj, 时间:2002-11-25 10:10:00, ID:1456781
各位高手, 我想问一下,在创建 Word or Excel 时,大家都知道,
只有安装过Word or Excel 后再用 Delphi 创建出来,否则是创建不出来的,应该说是找不
到一些注册的共享文件,哪位高手知道是哪些文件吗? 这样在不安装该软件的时候,只要
打包在你的安装文件中,也能创建,不知哪位高手能提供一下,再次谢过了。 


来自:阿当, 时间:2002-12-20 16:27:00, ID:1525199
to ddntyz:
   设置OLEContainer的背景不管用,这是一个Bug,你可以TOLEContainer.Paint中的
   DrawEdge(Canvas.Handle, CR, EDGE_SUNKEN, Flags or BF_MIDDLE);的后面加上:
   Canvas.FillRect(CR);

   重新编译后即可。在运行期有效。 


来自:fanglintao, 时间:2003-2-14 1:40:00, ID:1620835
各位大虾:最近我在用word宏替换时,如果替换字数超过350个时,就会报错。请问一下
word宏替换时有什么限制,怎样解决。十分感谢!!
还有在word2000。pas中ActiveDocument.Range.Find.Execute(var FindText: OleVariant; var MatchCase: OleVariant;
                      var MatchWholeWord: OleVariant; var MatchWildcards: OleVariant;
                      var MatchSoundsLike: OleVariant; var MatchAllWordForms: OleVariant;
                      var Forward: OleVariant; var Wrap: OleVariant; var Format: OleVariant;
                      var ReplaceWith: OleVariant; var Replace: OleVariant;
                      var MatchKashida: OleVariant; var MatchDiacritics: OleVariant;
                      var MatchAlefHamza: OleVariant; var MatchControl: OleVariant):;各参数的意义分别是什么,如果用这个函数解决上面的那个替换问题,应该怎样设置
 


来自:firnwolf, 时间:2003-3-10 11:51:00, ID:1668373
贴一个打印的功能,功能类似word和excel中ctr+p的功能,有选择打印机的界面
var
   PrinterSetupDialog1:TPrinterSetupDialog;
begin
  PrinterSetupDialog1:=TPrinterSetupDialog.create(nil);
  if PrinterSetupDialog1.Execute then
  begin
     excel.application.ActivePrinter:=printer.Printers[printer.PrinterIndex];
     excel.printout;
  end;
  PrinterSetupDialog1.free;
end;

 


来自:xh416, 时间:2003-3-13 8:55:00, ID:1677244
请问下面的VBA(EXCEL) 宏代码如何翻译成DELPHI 的过程?
Sub SortTable(top, left, right, bottom, Col)
    Range(Cells(top, left), Cells(bottom, right)).Select
    Selection.Sort Key1:=Columns(Col), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, SortMethod _
        :=xlPinYin
End Sub
 


来自:Tsir222, 时间:2003-3-28 9:37:00, ID:1716776
看了上面的内容,受益匪浅。我正在写一个ocx组件,需要嵌入IE中,实现对word的操作,
但考虑到正版的问题,客户不一定都装office,所以想把控制word的功能打包进来。
请问大家一下,如果在机器不装office的情况下,象ole一样控制word!当然word不能另外
一个窗体。 


来自:里斯, 时间:2003-5-13 14:16:00, ID:1856376
当我把Table中的数据汇出到Excel时,若数据类似“00123”,
即前面有“0”时汇到Excel中前面的“0”就没有了,
当一连串的字符都是数字,如身份证号,汇出来后也变样了(成了3,456E+17),
请问这些问题怎么解决?能不能在汇出前先指定某列的格式为文本?如何设置,各位高人请帮忙。
谢了。 


来自:hawk.jiang, 时间:2003-6-2 12:43:00, ID:1916722
to 里斯
你可以右键菜单>单元格格式>数字设置单元格的类型,具体类型自己确定,当然也可以写代码实现,
使用录制宏功能可以看到VBA代码,然后改写成Delphi代码

我要强调的是office的录制宏功能非常有用 


来自:hawk.jiang, 时间:2003-6-2 13:06:00, ID:1916805
to Tsir222
基本上不可能 


来自:caili314, 时间:2003-6-8 10:21:00, ID:1934128
MDIForm中定义了主菜单,其菜单项的GroupIndex分别是0,1,2,3,4,5,6,7,8,9,10,254,255
MDIChildForm中使用了
with OleContainer1 do
begin
  CreateObjectFrom('xxx.doc',false);
  DoVerb(PrimaryVerb)
end
结果MDIForm中只有GroupIndex 0,2,4的被保留,其他的全部被替换.Delphi帮助中说
OLE SERVER只使用1,3,5的GroupIndex(help:search for GroupIndex property (TMenuItem)).
谁能告诉我WORD到底使用了哪些GroupIndex?
谢了在先 


来自:大漠孤鸿, 时间:2003-6-9 0:54:00, ID:1935526
各位大侠!
请教,能将Delphi中得DBchart创建得图表直接加入word吗? 


来自:vfphome, 时间:2003-6-16 13:16:00, ID:1955660
在Dephi 5中提供了一组Servers组件,实现了与Office的无缝结合,但有关这一方面的资料却很少,
最近笔者接触了一个用户案例,要求最终将数据库中的结果总结成一份Word文档,Word文档中对于
标题、正文的字体、字号,文档的纸张大小都有一定的要求,而且还要求以表格的形式体现一部分
数据库中的数据。

  笔者通过查找VBA的说明,再对照Dephi的VCL,终于实现了全部功能,现将有关的内容总结如下:


1、在当前程序目录下建立以标题字段命名的Word文件


exepath:=application.ExeName;

  for index:=1 to length(exepath) do

  if exepath[index]='"' then

  i:=index;

  exepath:=copy(exepath,1,i);

  doc_file:=exepath+mc+'.doc';

  以标题字段“mc”命名Word文件

  try

  Wordapplication1.connect;

  except

  messagedlg('没有安装Word',mterror,[mbok],0);

  abort;

  end;

  Wordapplication1.Caption := 'XX计划书';

  Wordapplication1.visible := true;

  Worddocument1.activate;


2、设置纸张大小


Wordapplication1.ActiveDocument.PageSetup.PageWidth:=XXX;

  Wordapplication1.ActiveDocument.PageSetup.PageHeight:=XXX;

  Wordapplication1.ActiveDocument.PageSetup.LeftMargin := XX;

  //设置左边距

  Wordapplication1.ActiveDocument.PageSetup.rightMargin := XX; 

  //设置右边距


3、插入页码


var fpage,pagea:olevariant;

  fpage:=true;

  pagea:=wdAlignPageNumberCenter;

  Wordapplication1.activedocument.sections.item(1).Footers.item(1).PageNumbers.Add(pagea,fpage);


4、设置页面横向打印


s:=Wordapplication1.selection.start;

  e:=Wordapplication1.selection.start;

  aa:=wdSectionBreakNextPage;

  Wordapplication1.ActiveDocument.Range(s,e).InsertBreak(aa);

  Wordapplication1.Selection.Start:=Wordapplication1.Selection.Start + 1;

  s:=Wordapplication1.Selection.start;

  e:=Wordapplication1.ActiveDocument.Content.End_;

  Wordapplication1.ActiveDocument.Range(S,e).PageSetup.Orientation:=wdOrientLandscape;


5、设置字体、字号


Wordapplication1.Selection.Font.Size:=18;

  Wordapplication1.Selection.Font.Name := '黑体';

  Wordapplication1.Selection.TypeParagraph;

  Wordapplication1.Selection.ParagraphFormat.Alignment:= wdAlignParagraphCenter;

  Wordapplication1.Selection.TypeParagraph;

  Wordapplication1.Selection.TypeText(dbedit4.text);

  //标题 

  Wordapplication1.Selection.Font.Size := 14;

  Wordapplication1.Selection.Font.Name := '宋体';

  Wordapplication1.Selection.TypeParagraph;

  Wordapplication1.Selection.TypeParagraph;

  Wordapplication1.Selection.ParagraphFormat.Alignment := wdAlignParagraphJustify;

  Wordapplication1.Selection.TypeText(' '+trim(dbmemo1.text));

  //正文

   ... ...


6、插入表格


Wordapplication1.Selection.Font.Size :=10;

  adoquery2.Active:=false;

  adoquery2.active:=true;

  doc:=Wordapplication1.activedocument;

  counts:=adoquery2.RecordCount;

  //记录数决定表格的行数

  t:=doc.tables.Add(Wordapplication1.selection.range,counts+1,5);//5列

  t.cell(1,1).range.text:= '单位';

  t.Cell(1,1).Width:=120;

  t.cell(1,1).range.Paragraphs.Alignment:= wdAlignParagraphCenter;

  t.cell(1,2).range.text:= '姓名';

   ... ...

  //依次写入其他字段的表头

  for i:=2 to counts+1 do

  begin

  t.cell(i,1).range.text:=adoquery2.field

  byname('dw').asstring;

  t.Cell(i,1).Width:=120;

  t.cell(i,1).range.Paragraphs.Alignment:=

   wdAlignParagraphCenter;

  t.cell(i,2).range.text:=adoquery2.field

  byname('xm').asstring;

  ... ...

  Adoquery2.next;

  End;

  使用Dephi将Word与数据库结合,实现了用户文档的自动生成,大大地方便了用户。 


来自:阿当, 时间:2003-6-25 16:49:00, ID:1980253
    这是一篇非常好的讨论!yzhshi是这方面的专家,在此我有一个问题请yzhshi帮忙,
我想在我的程序中显示Word文档,不要Word的菜单及其它,只有文档,逐页上移、下移、
左移,甚至逐字等。请问该如何做?请各位大虾指点。(我最初的思路是得到并控制文
档的每一页,然后PaintTo当前页面,以前用的是OLEContainer,但有很多缺点)
    一百分相送,不够再加。 


来自:hawk.jiang, 时间:2003-6-26 8:49:00, ID:1981331
用WebBrowser控件,打开Word文档,缺点是速度比较慢(不比打开Word慢),功能一如Word 


来自:caili314, 时间:2003-6-26 9:19:00, ID:1981454
让WORD服务器先运行起来, 再打开文档时就会快很多. 有没有感觉在打开第一个WORD文档时慢, 打开第二个时就快了? 


来自:hawk.jiang, 时间:2003-6-26 9:29:00, ID:1981504
to caili314:
  这个我知道,但是没有实际意义。如果是在客户端,没有理由要求用户常驻一个word进程,而且总有第一次吧,第一次打开不是一样慢。如果在服务器端,可以考虑创建一个对像池。其实如果机器不是特别破(P3 256M以上),速度还是可以认可的。 


来自:Lonestar, 时间:2003-11-15 19:43:00, ID:2296763
还有一个问题:当用下面代码设置纸张大小时,
Wordapplication1.ActiveDocument.PageSetup.PageWidth:=500;
Wordapplication1.ActiveDocument.PageSetup.PageHeight:=400;
使用的单位是象素点,但在Word中一般使用的单位都是厘米呀,怎么样把“象素点”单位转换为“厘米”单位???? 


来自:menxin, 时间:2003-11-22 0:01:00, ID:2309449
比较全的宏 (原创:menxin) 呵呵

文件类

fileclose 关闭活动文档窗口
filecloseall
filecloseorcloseall
filecloseorexit
fileexit
filefind
filenew
fileopen
fileopenfile
filepagesetup
fileprint
fileprintpreview
fileprintsetup
fileproperties
filesave
filesaveall
filesaveas
filesaveaswebpage
filesaveframeas
filesavehtml
filesaveversion
filetemplates
fileversions
organizer
savetemplate
sendtofax
webpagepreview

编辑

atuotext
browsenext
browseprev
copyformat
createautotext
deleteannotation
editautotext
editbookmark
editclear
editcopy
editcopyaspicture
editcut
editfind
editgoto
editlinks
editobject
editpaste
editpasteashyperlink
editpasteasnestedtable
editpastespecial
editredoorrepeat
editreplace
editselectall
editundo
goback
gotonextcomment
gotonextendnote
gotonextfootnote
gotonextpage
gotonextsection
gotopreviouscomment
gotopreviousendnote
gotopreviousfootnote
gotopreviouspage
gotoprevioussection
insertautotext
insertspike
lockfields
nextinsert
pasteformat
repeatfind
selectcuralignment
selectcurcolor
selectcurfont
selectcurindent
selectcurspacing
selectcurtabs
spike
unlinkfields
unlockfields
updatesource

其它部分待续..太多了
 


来自:yzhshi, 时间:2003-11-24 12:26:00, ID:2313205
victor7780,我想问一下,您羞不羞?
这里是一个程序员讨论技术的论坛,请您应该自重一些!
人或者要有骨气,赚钱的方法有很多,不要仅仅看着这些不切实际的东西!

看看你的待答问题和你的参与问题。请扪心自问一下,你到这里来到底为了什么?
请珍惜你的也珍惜大家的美好光阴![:(!]

http://www.delphibbs.com/delphibbs/listq.asp?type=1&userfrom=victor7780
http://www.delphibbs.com/delphibbs/listq.asp?type=1&expert=victor7780 


来自:yzhshi, 时间:2003-11-24 13:00:00, ID:2313305
刚才试验了一下,给大家再贴出一点有用的VBA代码。
上面的可以获得一些命令的信息;
下面的代码可以获得对话框的函数名称,但是不是所有函数的名称。
希望对大家有用。

Sub ListCommands()
    Application.ListCommands (True)
End Sub

Sub ListDialogs()
  On Error Resume Next

  Dim aa As String
  aa = ""
 
   For i = 1 To Dialogs.Count
       aa = aa + Str(i) + " " + Dialogs(i).CommandName + Chr(13)
   Next i
   Selection.TypeText aa
End Sub
 


来自:2180001, 时间:2004-3-7 12:19:13, ID:2489077
哈哈,可以发贴子了!!!(偶已经很久不能发贴子了)
看了各位的讨论,发现大家都忽视了一点:在你控制word时,如何才能不影响用户自己打开的word的正常操作?
    大家自己用word作为编辑器,当然希望完全控制,比如用宏,用OLE什么的,无论如何,你在对word进行控制的时候,你怎么样才可以不影响到用户自己打开的word呢?
比如说,你打开一个doc, 将某些功能禁止,这时用户自己又打开了一个word编辑自己的文件,这个word窗口的那些你禁止的功能同样也没有了,怎么办?
    在你控制word时,如何才能不影响用户自己打开的word的正常操作?
    1 如何建立一个word实例,只给你自己的程序使用,不让用户使用?
    2 如何在内存一个实例的范围控制word,并不影响其它实例?

这个问题有解吗?
 


来自:maxtool, 时间:2004-3-12 8:48:03, ID:2495676
to 2180001:

如果你使用createoleobject
wDoc:=wApp.Documents.add;
的话,是新建一个word文档不影响别的word文档的 


来自:cdtsky, 时间:2004-3-24 14:49:25, ID:2519539
使用olecontainer  调用word
word的菜下拉菜单怎么没有了
    怎么让他显示出来
工具栏为什么不在olecontainer里
   怎么把它放进去

难道非要用vb脚本? 


来自:jakersen, 时间:2004-3-30 22:13:20, ID:2530633
to cdtsky:
  在该form中放一个TMainMenu就可以显示word菜单了! 


来自:gamepower111, 时间:2004-4-2 9:31:27, ID:2535013
delphi 操作 excel 问题,很不错呀。
但大家始终没有对速度慢这个问题提供好的解决方法。 


来自:pat, 时间:2004-4-2 22:11:50, ID:2536960
没有很好的解决速度的方法,就是慢! 


来自:jfyes, 时间:2004-4-2 22:24:28, ID:2536982
阅读:17408
===============
he!he!打破纪录的阅读次数;
再顶
 


来自:maomaoyu810201, 时间:2004-4-7 10:30:15, ID:2544317
各位真牛!!!
请帮忙看看下面问题出在何处?我用的是OleContainer,照SeaHawk讲的方法想做一个
activex。
var
  worddoc:olevariant;
  v:olevariant;
begin
  OleContainer1.CreateObjectFromFile('d:"temp"temp.doc',false);
  OleContainer1.DoVerb(OleContainer1.PrimaryVerb );
  worddoc:=OleContainer1.OleObject;
  v:=worddoc.Application;
  //v.Insert('hhhhhh');      ----这两句报错“不支持此方法”,为什么???
  //v.FileSaveAs('d:"temp"temp.doc');
 end;


SeaHawk,能发个控件给我吗? shh_mao@yahoo.com.cn 


来自:qqggch, 时间:2004-5-5 15:14:18, ID:2594578
我的问题是WORD和数据库问题

我现在要对数据库进行查找NO , NAME ,STREAM; 通过 NAME 来查询 STREAM

把查询出来的STREAM(可能有多个结果哦),都保存到WORD文档中(最好是在OLE中)?

请问各位大侠,我该怎么实现?数据库用的是ACCESS 


来自:workjie, 时间:2004-5-11 11:58:41, ID:2603998
Application.ActiveDocument.Protect(2);

文档不能修改,不能复制  


来自:duhai_lee, 时间:2004-5-11 17:22:09, ID:2604730
看了半天,就是没有可以解决我的问题的方法,不过先对楼上各位大侠致敬。
    我的问题是这样的:http://www.delphibbs.com/delphibbs/dispq.asp?lid=2604145
    200分还没有送出去。 


来自:noah, 时间:2004-5-17 9:46:53, ID:2613553
WordApp.Selection.ParagraphFormat.Alignment:=wdAlignParagraphCenter;提示wdAlignParagraphCenter没有定义,why?谢谢 


来自:xuxiaohan, 时间:2004-5-17 10:13:07, ID:2613622
上面的内容我看了n次,没有谈但oleContainer的速度问题,如果能解决下面的问题,也就解决的oleContainer的速度问题
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2530945 


来自:bzm131313, 时间:2004-5-24 11:24:06, ID:2624406
菜鸟的2个问题
1:有时 调用word函数会提示 "被呼叫方拒绝接受呼叫",请问什么原因造成 ,怎么解决??
2:怎么加快word 打开文档的速度?? 


来自:xzfyes2, 时间:2004-6-25 18:38:28, ID:2681712
to maomaoyu810201
还差好几句
v:=worddoc.Application;
  //v.Selection.TypeText;
   v.Text:="ggfdgfdgfdgdf";
  //v.FileSaveAs('d:"temp"temp.doc');
 end;

 


来自:dirace, 时间:2004-6-27 16:35:00, ID:2683616
六、全局消息的定义
因为word和Delphi程序是两个软件,相互之间通讯比较麻烦,所以使用全局消息的方法进行。
全局消息必须首先注册,Windows返回系统空闲的消息号,当注册的消息相同时,
Windows系统返回同一个值,这样就保证了使用这个消息号在两个程序之间通讯。

定义消息的办法:
    szMessageString: pchar = 'XIDIAN_11_Stone';
    FMyJoinMessage := RegisterWindowMessage(szMessageString);

发送消息的方法:
    SendMessage(对方句柄,消息,消息附带短变量,消息附带长变量)

这个方面,能否给出个例子?谢谢 


来自:mmdberwin, 时间:2004-8-11 3:00:49, ID:2758540
请教一个问题:
  OleContainer1.CreateObjectFromFile('d:"2.xls',true);
  OleContainer1.doVerb(ovShow);//显示文档
  Cur_WorkBook:=OleContainer1.OleObject.Application.WorkBooks[1];
  Cur_WorkSheet:=Cur_WorkBook.WorkSheets[1];
 ¥ Cur_WorkSheet.printPreview;
 为什么这么做的话带¥那一句会出错呢?
 为什么如果我不用OleContainer 而是直接 createoleobject的话就可以呢?
 用OleContainer又怎么预览呢?
 


来自:kai2003, 时间:2004-9-26 22:08:33, ID:2825799
最近遇到一个麻烦的要求,叫我将原来别人作的一个ACCESS数据库中以OLE对象存储的EXCEL文件转出来(记录好多啊,想用程序转),希望各位高手多多帮忙!!!!!
用在数据库上使用Image二进制字段,使用Stream流(loadfromStream,TBlobField)的方式无法读取以在ACCESS数据库中直接插入对象存储的EXCEL文件! 


来自:zyxip, 时间:2004-9-28 0:37:17, ID:2827645
  yzhshi  yzhshi  yzhshi 请注意:

  你上面发的给Word 添加按钮的代码可以成功,只是如何给它添加操作呢?

  请教一下关于 Delphi 和 Word ,Excel等的互相发送消息问题,请给个提示。 


来自:rchen, 时间:2004-12-21 22:29:15, ID:2939742
非常感谢,这个帖子让我学到不少:P
不过我最近碰到这样一个问题:

1. 在进程A中启动一个线程Aa, 在这个线程Aa中嵌套word, 通过CreateFromFile打开doc文档, 然后这个线程Aa在进程A结束前一直没有退出(也就是说没有调用CoUninitialize)
2. 这时候启动进程B, 也是内嵌word, 通过CreateFromFile打开doc文档, 但是会停留在::OleRun不动, 一直等到进程A的线程Aa 调用了CoUninitialize后才能继续往下跑.
3. 现在的问题是, 由于需求, Aa 线程不能退出,而B进程也必须能够打开doc文档.
 
有哪位大侠能够提供解决方法,,不胜感激:P
 


来自:windshow, 时间:2005-2-20 21:12:35, ID:2992464
[^]使用delphi才一天,已经被它吸引了,不过看玩了还是不会,哪个好心人发的范例源码让我学习一下 activeform 做的word控件
email:6144010@qq.com
拜谢了,我只有几百w mp,谁要拿去 


来自:bryantd, 时间:2005-3-7 17:13:33, ID:3006353
四、Delphi程序保存Word文稿
格式:WordDocuments.SaveAs(FileName, FileFormat, LockComments, Password,AddToRecentFiles, WritePassword, ReadOnlyRecommended,
EmbedTrueTypeFonts, SaveNativePictureFormat, SaveFormsData, SaveAsAOCELetter)

楼主能给个具体的例子吗????比如我有一个DOC文件:'e:"test.doc',我想将它转存为一个纯文本文档:'e:"test.doc.txt'。VB代码如下:

Sub 测试保存()
'' 测试保存 Macro
' 宏在 2005-3-7 由 Bryantd 录制
'  ChangeFileOpenDirectory "E:""ActiveDocument.SaveAs FileName:="test.txt", FileFormat:=wdFormatText, _LockComments:=False, Password:="", AddToRecentFiles:=True, WritePassword _:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _ SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _False, Encoding:=936, InsertLineBreaks:=False, AllowSubstitutions:=False, _LineEnding:=wdCRLF
End Sub

用OLE在Delphi中应该怎样实现?我是这样写的:
WordApp:=CreateOleObject('Word.Application');
WordApp.Visible:=False;
WordApp.Documents.Open('e:"test.doc');
中间这句怎么写?????????????????????????????????
WordApp.Documents.Close;
WordApp.Quit;

ShowMessage('转存完毕!') 

 

 

---------------------------------------

 

 DoubleCat

 

 


posted on 2008-08-20 20:47  DoubleCat  阅读(8543)  评论(0编辑  收藏  举报