六神无主为了你,七个美女不如你,八抬大轿娶了你,九颗真心掏给你,全家幸福指望你

Word域与数据库的结合编程

上一篇 / 下一篇  2007-11-02 15:02:33

本文介绍了Word域与数据库结合的方法,给用户提供一个插入Word域的界面,并把数据库的数据填充到Word文件中。PHPChina 开源社区门户G p(F+B2b4H
PHPChina 开源社区门户}(i]5GpG"a0r Y3iJ
  域是Word中最具有实用价值的功能之一,它表示文档中可能发生变化的数据或邮件合并文档中套用信函、标签中的占位符。Microsoft Word 可以在您使用一些特定命令时插入域,如"插入"菜单上的"日期和时间"命令。您也可使用"插入"菜单上的"域"命令手动插入域。事实上,我们在日常工作中常会脱离Microsoft Word的操作环境。一般,用户是先建立好一些Word文件模板,然后利用所提供的应用程序功能向Word文件模板中插入域,用该域对应的值取代域值,这样就达到了向Microsoft Word文件中插入数据的作用。我们常把数据放入数据库中,数据库的内容不断地变化,我们的域值也跟着不断地变化,取到灵活自动更新的作用,要达到这方面的功能,就应该把
数据库与Word域结合起来。 
/wa3F3`9Un'k9k0PHPChina 开源社区门户;ly O!P(A
解决方法PHPChina 开源社区门户c-}V snf;K
PHPChina 开源社区门户5cL0b+\zs&U{9Z
  首先要解决这一问题,我们必须先了解Word域有关的知识:Word域代码位于花括号或大括号 ( { } )中,域类似于 Microsoft Excel 中的公式:域代码类似于公式,域结果(域结果:当 Microsoft Word 执行域指令时,在文档中插入的文字或图形。在打印文档或隐藏域代码时,将以域结果替换域代码。)类似于公式产生的值。可在文档中切换显示域代码及其结果。正好,数据库的字段名对应域代码,字段值对应域值。我们利用VBA编程可以达到目的。VBA for Word 中有关域的类型很多,其中Type:=wdFieldAddin是一种关于字段与字段值对应的特殊域,正是借助它的功能解决问题。我们可以这么设想,用户先打开Word文件,然后向打开的Word文件中插入域,然后用数据库的数据填充。插入域时有二种可能,一种是单值域,即一个域代码对应一个域值(一对一关系),这种情况的域可以插入任何地方;另一种情况是多值域,即一个域代码对应多个域值(一对多关系)。这种情况的域只能插入表格中,并且当表格的行数比域值少时,要能自动提供增加表格行的功能。
@a I+r0qS ih]0
E&c%M.KZ0
实例说明

ab-y8f&jY0
A.n/ddz6I4o5Qt0  利用Visual Basic。Net编写通用的类,给用户提供可视化的编辑界面,用于用户在Word文件中插入域标志。针对Word文件或Excel表格文件,扫描整个文件,将其中的域标志取出来,然后通过从数据库中取出字段所对应的值,将值填写到文件中域对应的位置。若对应位置已有值,则判断该值与要填写的值是否相同,若不同则替换之。插入值分为:
[9l{/~,q?"V"Q9?0
6wX!A \2tN0A。单纯的值,直接使用一个值替换域。
R^p` F+c o0
w-a*k?,zqg0B。表格中的单元格。若该表格填写不下,是否增加表格单元?以及与该单元关联的域等。PHPChina 开源社区门户A9S3_%W.t.X&Dc

}*g"Rs&?^nW)Nc0例如,有二个ACCESS数据库的表(:表1对应单值域,表2对应多值域)如下:
y }%II:]1\+F0PHPChina 开源社区门户Y ZV~!IL \'w
表1:工程
PHPChina 开源社区门户1W%`$TX;`;tv:Fd

M&`Vhx\_E1L0
工程名称设计阶段工程检索号项目名称新制字数图片数
建模工具学习(2)http://www.21cmm.comfw-jm-2002软件工程专家网6010003
PHPChina 开源社区门户2R&Y7_:tZ ue,FZ
PHPChina 开源社区门户V3iH7HrP;BU
表2:校核

0nE f;N(bPz0PHPChina 开源社区门户5w0O&t+i]8R \
序号校核主要问题执行情况
1排列不齐No
2文字错Yes
3文字错Yes
4内容提要不详细No
5文字错Yes
6数据有误No

Y a)G5A_ Q0PHPChina 开源社区门户 ?/Uz_PW F

#R?2x$g"_K}0利用VBA编写的一个通用的处理Word域的程序。开发步骤如下 :PHPChina 开源社区门户b,W$yn$f

1cX p&o/gXBI7t01.建立项目,向项目中增加处理Word域的类
o%w|p,IG M7]&U$X[0PHPChina 开源社区门户R"L:E"}F5^ok
启动Visual Studio。NET。在新建项目中选择Visual Basic项目,在模板中选择Windows应用程序,把工程名更改为WordDoc。
m `!C s:U0PHPChina 开源社区门户+V4c;FN,i7l&{
● 向工程中增加名称为CWordDoc的类。PHPChina 开源社区门户3j["nZ/Q:l3\

y0p6LtE0● 定义的CWordDoc类的属性。代码如下:

"U.wW5y3v!?&T t0

ec!U9Evb l+X'{0

'定义Word应用对象及文档对象PHPChina 开源社区门户 x#DRAB&X
Private wdApp As New Word..Application()PHPChina 开源社区门户CTtaZ:C(R
Private wdDoc As New Word.Document()PHPChina 开源社区门户 tbL"w G|)p
'所处理的Word模板文件
B4m:i0C| V/y0Private FileName As String
:n0hbx&u;L0'域的个数及对应的数组PHPChina 开源社区门户5WkO lUj.I] L
Dim FieldCount As Int16PHPChina 开源社区门户Q F%i{h\J-W
Dim MyField()PHPChina 开源社区门户p \*ds#f{'n9k
'Word是否已运行
K%LNs%NZJK0Private IsWordRunning As BooleanPHPChina 开源社区门户;W+fu[J4wK;C%?
'是否已经插入了表格行PHPChina 开源社区门户%z#Qwyl
Private IsInsertRow As Boolean 
bK~ iCfS@ K0'Word工具栏对象及菜单栏对象数组
7_'E~s"Y3mbn0Dim CommandBarIndex() As IntegerPHPChina 开源社区门户(U4hd$Cq}*}%XE
Dim SaveCommandBarMenuIndex() As Integer
PHPChina 开源社区门户];t!hsZYV-j4E

%U}9y|;Nmj0● 定义的CWordDoc类的方法。
LX rb!|_U0
z6KrZ _-?'{P;_0  定义打开Word文件的方法。建立Word应用对象和文档对象,并打开Word文件。设定Word已经运行。VBA编程主要是先建立某一个应用程序的对象,然后按需要处理应用对象。Word应用对象是“Word.Application”,通过CreateObject方法建立之。代码如下:PHPChina 开源社区门户 }Zy6p~CWv
PHPChina 开源社区门户]'TDh6H+rWY
Public Sub OpenWordDocument(ByVal FileName As String)
~%zYi5YLw n^0        wdApp = CreateObject("Word。Application")PHPChina 开源社区门户k\i Y%k0`M9Z0y
        wdApp.Documents。Open(FileName)
.HM/g-@b ^ H0        wdDoc = wdApp.ActiveDocumentPHPChina 开源社区门户#`*x\o }jF&D G4t,r
        wdDoc.ActiveWindow.DocumentMap = FalsePHPChina 开源社区门户B^4S[ qEX
        wdApp.Visible = True
$w!|+Uu{7e ij!v&Z0        IsWordRunning = TruePHPChina 开源社区门户6`-gJZr_Tg&g[
End Sub

hy*?(PX'k Q"w0
~(P'Z0G.z,Kn3q-f0保存Word文件。 代码如下:PHPChina 开源社区门户3j)^ S3b i)S{2N w

9D0d/kb;_l1M l:D0
Public Sub SaveWordDocument()PHPChina 开源社区门户6^u"yj2F%Ls8{6l
        wdDoc.SaveAs(FileName)PHPChina 开源社区门户eLA n#Q5N{-P'b
End Sub
PHPChina 开源社区门户b&NT?l N+s
PHPChina 开源社区门户{{(Ls9V~
定义Word环境的大小。
'@+t$GK5t8F!a0
hulz-F N Rr)K0  Word启动后一般是全屏幕(最大化),要把用户操作界面显示出来,不被Word遮蔽,处理的方法是把用户界面设为顶层窗体,也可使用户界面与Word各自处在自己位置,平行布置。这里是让用户界面位于屏幕的最顶上,Word位于用户界面的下面。因此要重新调整Word的位置,这需要设置Word窗体状态为普通类型(wdWindowStateNormal)。代码如下:
(j MD^X*x,n0C0PHPChina 开源社区门户1GLm6r2wC ]!\C/{Q
Public Sub SetWordSize(ByVal Left As Integer, ByVal top As Integer,
PSjFiduR Z0    ByVal width As Integer, ByVal height As Integer)
/v/r}|&]0        wdApp。WindowState = Word.WdWindowState.wdWindowStateNormalPHPChina 开源社区门户bw!Vw?[IYl3^
        wdApp。Left = LeftPHPChina 开源社区门户1SfgS0n3[6b?Z
        wdApp。Top = top
-e H2` n.q]] y0        wdApp。Width = widthPHPChina 开源社区门户[?WW n+nc
        wdApp。Height = height
H zL%K(Z0Y0End Sub
PHPChina 开源社区门户aSH1CvK.c3G

`:CmD9w}9p q0  这里我们利用Word文档对象中域对象的Add方法向Word文件中插入域。域的Data属性代表该域的名称。插入域时应该选取插入点(Selection),即用户光标处位置。如果该位置是单元格且已插入域,应该提示是否覆盖。插入域时要分析是插入单值域还是多值域。根据关键字的后缀识别,关键字的最后一个字符是'F'时则为多值域。多值域只能插入在表格中。是否是表格以插入点的单元格识别。实现该功能的代码如下:
6qv} p#J)f0PHPChina 开源社区门户:v/Q'Um,}D&S~
'在文档中插入域
}G/RKbY0    'KeyWord:域的关键字
x3g0?~[Du0    Public Function InsertField(ByVal KeyWord As String) As Integer
9\J{[w0        Dim mySelection As Selection
0^ ~!v#B8mI b9A0        Dim Code As StringPHPChina 开源社区门户jI#^4~ {9H9FU
        Dim MyField As Field
)mK1~-E+n0        Dim myRange As Range
L's }rDHnO+T0        wdApp。Selection。Collapse(Direction:=wdCollapseEnd)PHPChina 开源社区门户0dh;G;x%@9c"H `a
        mySelection = wdApp。Selection      '插入点PHPChina 开源社区门户5X M;Sw?kt2{Ds
        If KeyWord。Chars(KeyWord。Length - 1) = "F" Then
(O0D%Yg#nB A0            If IsCell(mySelection) <> True Then
i rG9O"K5F| @0                MsgBox("该位置不是单元格,请选择单元格", vbOKOnly +VBExclamation)
'|nQ4N9he0                Exit Function
4WV0U*zA/L#I,b.EF2k0            End IfPHPChina 开源社区门户^?Gt)[$G.u&lQ
        End IfPHPChina 开源社区门户m p m7TQ9m
        If IsCell(mySelection) = True Then
wZA+ZZ[0            If CellFieldCount(mySelection) > 0 ThenPHPChina 开源社区门户0p7a+] S?"?N a@Z8m1|
                If MsgBox("该单元格已有域,是否覆盖?",VBYesNo) = 6 ThenPHPChina 开源社区门户 sT:mo^k4Fx9u
                    mySelection.Cells.Item(1).Select()PHPChina 开源社区门户a'W(hqP3| c2r
                    mySelection.Delete()
g@8Z ml~L}vi0                ElsePHPChina 开源社区门户nS"qKD%Zs
                    Exit FunctionPHPChina 开源社区门户P;| KO6}:q(Pu
                End If
]&A"Nv!rm3O"qG0X&p0            End If
UBygL,`h`0        End If
x;O:A&Y%Q Y+n UVY0        MyField = wdDoc.Fields.Add(Range:=mySelection.Range, Type:=wdFieldAddin)
AlXjC CX's0        MyField.Data = KeyWordPHPChina 开源社区门户C1G2cOI4w g,r p%H
    End Function
PHPChina 开源社区门户)if `&x9?Q


4fjd%g9C9laK^IB a0  我们可以通过选择点的表格数判断插入点的性质。表格数为0,则选择点不位于单元格中,反则不位于单元格中。

5JI"lZ M~U!a0

'选择点(光标)是否是单元格。
u3wT~6GN!_B)YI0    Private Function IsCell(ByVal mySelection As Selection) As BooleanPHPChina 开源社区门户 Gn n/e'_%@N0c1~l
        If mySelection.Tables.Count > 0 ThenPHPChina 开源社区门户%}py\2W1Z\;ye
            Return TruePHPChina 开源社区门户k#WM8\pn2Sg5F
        Else
/ClEeT+H5i0            Return False
jH$sW\+x2R0        End IfPHPChina 开源社区门户;A1u9I3x1w bq%w
    End FunctionPHPChina 开源社区门户&zX}:c#j)U4S
    '计算选择点(光标)的单元格的域数
cQ/y ~:Xf)k0    Private Function CellFieldCount(ByVal mySelection As Selection) As Integer
$~o#xv'kAD0        CellFieldCount = mySelection.Cells.Item(1).Range.Fields.CountPHPChina 开源社区门户;R'P?AR!tg
End FunctionPHPChina 开源社区门户? WydP I"Ld5blb
'记录插入域代码及关键字。这里主要是调用上面的InsertField方法。PHPChina 开源社区门户+o&eo aFm$LF B?
    Public Function InsertFieldByKeyWord(ByVal KeyWord As String) As IntegerPHPChina 开源社区门户 Q tK{2{ f&k h^
        Dim ID As Integer
"^+Im LKt;G,r:nF0        FieldCount = FieldCount + 1PHPChina 开源社区门户Y e z?{8wwk
        ReDim MyField(FieldCount)
-Es/[3E#j*L.w0        ID = InsertField(KeyWord)PHPChina 开源社区门户8WG |@;C$Z |d-MX
        MyField(FieldCount).ID = ID
0o q$\~+eyq0        MyField(FieldCount).KeyWord = KeyWord
OyBsXffX;J#|B+J0End Function

#Y*b3bAX0

  当Word文件已经插入了域,就要填充域值。填充域值应该分为二种情况考虑。一种是单值域,一种是多值域。单值域是一一对应关系,仅取出值域插入到对应的位置。实现的方法是扫描整个文档,找出是用户插入的域(Fields.Type = 81),用域值取代之,这里用到了一个由关键字得到值的方法GetFieldValues,这个方法在后面将会讲到,对应的是数据库的"工程"表。怎样保证永远仅插入一个值呢?方法是先清除掉原域值和域代码,再在当前插入点插入域代码和域值。实现的方法如下:PHPChina 开源社区门户(YtKL8} {3a`^*nV

+Rs#g ad:[$KSw0

'用关键字对应的值插入值,在文档中在有域的地方插入对应的值PHPChina 开源社区门户lQ]!A q1e3fP
    Public Function InsertValue() As Boolean
)aFl@aUwrgM0        Dim i, Count As IntegerPHPChina 开源社区门户/hB6Op9{f/hYW[
        Dim KeyWord As String
6sR0z z B Ni0        Dim Value, DataPHPChina 开源社区门户3wbf/?.Q:M:O$e%z3V!m)of
        Dim mySelection As Selection
4fd4L*~:~~ { J{ I/M0        Count = wdDoc.Fields.CountPHPChina 开源社区门户b1i^%bv|x t
        For i = 1 To Count
!f*IHT6LdD!N \0            If wdDoc.Fields.Item(i).Type = 81 ThenPHPChina 开源社区门户$?.zkT E]]
                KeyWord = wdDoc.Fields.Item(i).DataPHPChina 开源社区门户A'| mb9@,q
                If Right(KeyWord, 1) <> "F" ThenPHPChina 开源社区门户Qm)}#X.k,e T5g/H+G `
                    Value = clsDB.GetFieldValues("工程", KeyWord)
LIe ^^0                    wdDoc.Fields.Item(i).Select()
Thi+K3K/s&R/UG0                    mySelection = wdApp.Selection      '插入点PHPChina 开源社区门户bD3|!?u?8giLT@
                    If mySelection.Tables.Count <> 0 ThenPHPChina 开源社区门户[XM h}J[q}
                        'clear  textPHPChina 开源社区门户(j0@ES0Q ^Og'T n"g*z
                        mySelection.Cells.Item(1).Select()
"qY5Jy'V8l$_1\0                        mySelection.Delete()
4n;]'ESD0                        '还原原域PHPChina 开源社区门户}2G"e0RCg
                        InsertField(KeyWord)PHPChina 开源社区门户2k?:kh8t.}!PP{M#E
                    End If
x5|3h(ouP0                    wdDoc.Fields.Item(i).Result.Text = Value(0).itemarray(0)PHPChina 开源社区门户7|.h^mQ \ \LF s
                End IfPHPChina 开源社区门户u\4e0kqHr#F Om
            End IfPHPChina 开源社区门户 G8G?bM
        NextPHPChina 开源社区门户E"ib [[+MLIn/Y
    End Function

+};oZk}*Ji Q0

GB3A6tA5d0 PHPChina 开源社区门户;F~%w rr(]p}&YU


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

数据统计

  • 访问量: 5716
  • 日志数: 72
  • 图片数: 7
  • 建立时间: 2007-09-12
  • 更新时间: 2008-01-02

RSS订阅

Open Toolbar