ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 2549|回复: 1

[转帖]开发集成的 Office 解决方案

[复制链接]

TA的精华主题

TA的得分主题

发表于 2004-9-27 15:48 | 显示全部楼层 |阅读模式

开发集成的 Office 解决方案

David Shank Microsoft Corporation 2000年5月4日

下面这篇文章原见于 MSDN Online Voices“Office Talk”专栏中 (http://msdn.microsoft.com/voices/office.asp)(英文)。

开始有计划地集成 Microsoft Office 应用程序时,我想起了一句古老的谚语,意思是说:“一个训练有素的团队比各自为战的乌合之众要强大得多”。与每个 Office 应用程序一样强大的是其自身,如果将两个或多个 Office 应用程序的功能集成为一个自定义的解决方案,那么能力和功能都得到了增强。

使一个 Office 应用程序的 Visual Basic(R) for Applications (VBA) 和另一个 Office 应用程序的对象一起工作的过程,称为 Automation。您可以将 Office 应用程序显露的对象想象成一组建筑砖块,您可以将它们合并到您自己的解决方案中 — 沿用生产它们所用的设计、开发和测试,从而缩短您的开发时间。

本月,我将概述 Automation,提供一些实际例子来更好地表述这些概念,指给您一些丰富的资源,从中可以获取在您自己自定义的解决方案中使用 Automation 的附加信息。

什么是 Automation?

Automation 是“组件对象模型 (COM)”技术(以前称“OLE Automation”) ,它允许开发人员使用 VBA 代码创建和控制软件对象,这些软件对象由任意应用程序、动态链接库 (DLL) 或支持相应的编程接口的 ActiveX(R) 控件显露的。理解 Automation 的关键是理解对象和对象模型:它们是什么、它们的工作原理以及它们是如何一起工作的。

COM 软件体系结构允许软件开发者从独立的软件组件建立它们的应用程序和服务。COM 组件由物理的、编译文件组成,它们包含定义可编程对象的代码模块 — classes

Windows 操作系统和 Office 应用程序套件,是使用 COM 软件体系结构开发的产品的例子。仅仅由于软件是使用 COM 开发的这一点,并不一定意味着可以用 VBA 编程。然而,如果应用程序或服务支持被称为 Automation 的 COM 技术,则与可用 VBA 或许多其他编程语言来编程的对象一样,它能够将接口显露给它的组件的特性。为了支持 Automation,应用程序或服务必须允许通过下列两种或任意一种方法,显露它的自定义接口:

  • 提供 IDispatch 接口。用这种方法,可以查询应用程序或服务,来获取它的自定义接口的更多信息。支持 IDispatch 接口的应用程序和服务,使用称为后期绑定的方法,在运行时,提供它们的自定义接口的信息。
  • 允许在设计时,直接访问它的、实现其接口的虚拟函数表或 vtable 中的成员函数。支持直接访问自定义接口的应用程序和服务,支持早期绑定。

如果应用程序支持以上任意一种方法,而不必支持两种,就可以说它是支持 Automation 的。Office 应用程序套件提供对两种方法的支持。

您可以将 Automation 想象成一个神经系统,它使应用程序和组件之间的程序化通信和反馈成为可能,还可想象成让您将 Office 应用程序和其他软件组件的功能集成为一个自定义解决方案的“黏合剂”。

理解基本原理

您可以通过引用希望自动化的程序,来使用另一个 Office 应用程序显露的对象。这将使您的代码可以“看到”其他应用程序显露的对象。引用另一个应用程序的方法有两种 — 并且您使用的方法将决定您是有早期绑定引用还是有后期绑定引用。

设置引用

在使用 Office 应用程序的类型库时,总是创建早期绑定引用。这将让您在编写代码时,使用“对象浏览器”和 Visual Basic Development Environment (VBE) Intellisense 功能,如自动语句完成。另外,使用早期绑定引用会显露显露对象的“帮助”主题,并在运行时提供比使用后期绑定对象更好的性能。早期绑定是 C 程序员调用虚拟函数表绑定或 vtable 绑定的友好名称。要使用早期绑定,宿主应用程序必须建立对类型库 (.tlb) 或对象库 (.olb),或 .exe、.dll,或 .ocx 文件的引用,其中 .ocx 文件包含关于希望自动化的应用程序或服务的对象、方法、属性、和事件的类型信息。

使用 VBE 引用对话框,设置对 Office 应用程序类型库的引用,来创建早期绑定的引用。您可以使用工具菜单中的引用命令打开该对话框。每个 Office 应用程序包含几个默认情况下设置的引用。下图显示了 Word 的引用对话框,其中我添加了对 Outlook 类型库的引用。所显示的前五个引用是 Word 在默认情况下设置的。

创建对象变量

可以利用 CreateObjectGetObject 函数,初始化对象变量,如果应用程序支持使用 New 关键字,也可使用 New 关键字初始化对象变量。所有 Office 应用程序都可以使用 New 关键字初始化,如下列代码片段所示:

Dim olApp As Outlook.Application
Set olApp As New Outlook.Application
With olApp
   ' 此处为使用应用程序对象的代码。
End With

虽然可以在 Dim 语句中使用 New 关键字,但建议不用。定义对象变量,然后使用 Set 语句将其实例化,如上所示,您就可以进一步控制创建变量的方式和时间。

通过 VBA 代码使用另一个 Office 应用程序中的对象,与利用代码使用代码的宿主应用程序内部的对象非常类似。多数情况下,以创建指向 Application 对象的对象变量开始。在将 VBA 代码写入处理同一应用程序内部的对象的应用程序时,对 Application 对象的引用是隐含的。在自动化另一个应用程序时,通常对 Application 对象的引用必须是显式的。在创建了这个显式对象引用之后,便能访问被该应用程序显露为 Application 对象的孩子的所有其他对象。

取消对象变量

虽然过程结束时,过程中声明的变量被取消了,但下面的做法仍不失为一个良好的编程习惯:使用对象变量显式地退出已经自动化的应用程序,并通过将对象变量设置为 Nothing 关键字来取消这个对象变量。下面的示例过程说明了这项技术:

Sub SendDataToWord()
    ' 定义对象变量。
    Dim wdApp As Word.Application
    Dim wdDoc As Word.Document

    ' 实例化对象变量。
    Set wdApp = New Word.Application
    Set wdDoc = wdApp.Documents.Add

    ' 在新文档中添加文本然后保存。
    With wdDoc
        .Range.Text = "Automation is cool!"
        .SaveAs "C:\My Documents\AutomateWord.doc"
        .Close
    End With

    ' 取消对象变量。
    Set wdDoc = Nothing
    wdApp.Quit
    Set wdApp = Nothing
End Sub

要试运行该过程,请将以上代码复制到任意 Office 应用程序的代码模块中,设置对 Word 对象库的引用,将光标置于过程中的任意位置,然后按 F8 单步执行代码。

构造一个真实世界的例子

本例使用包含公司抬头的 Word 模板,和从 Outlook“联系人”文件夹中检索姓名和地址信息的 VBA 代码。在基于这个模板创建了新的文档之后,用户可以从联系人列表中选择收件人,然后将姓名和地址自动插入到文档中。

下图显示了用户在创建新文档时的所见内容:

在此,我不想详细讨论如何创建抬头模板。而集中讨论如何使用 Word 中的 Automation 检索 Outlook 中的数据。

模板的 Document_New 事件过程调用 GetOutlook 过程,后者从 Outlook 中检索联系人信息,并将此数据保存到数组中。GetOutlook 过程首先创建一个代表 Outlook Application 对象的对象变量,然后使用该对象,将需要在联系人数据中获得的 NameSpaceMAPIfolder 对象变量实例化。一旦到了“联系人”文件夹中,即使用 MAPIFolder 对象的 Restrict 方法,来返回只包含已经设置了 BusinessAddress 属性的联系人的集合。然后对于每个带有业务地址的联系人,其联系数据将添加到名为 gavarContactsArray 的全局数组中。然后调用 QuickSort 过程(这里没有表示出来),该数组被排序,其中的项目将按字母顺序排列。

Sub GetOutlook()
    ' 该过程从含有业务地址的 Outlook“联系人”
    ' 文件夹中检索所有联系人,
    ' 并将那些项放入名为 gavarContactsArray 的数组。
    ' 加载 frmShowAllContacts 窗体时,它即用
    ' gavarContactsArray 数组中的数据来填充组合框,
    ' 使用户能为信件地址而选择使用的联系人。

    Dim olapp           As Outlook.Application
    Dim nspNameSpace    As Outlook.NameSpace
    Dim fldContacts     As Outlook.MAPIFolder
    Dim objContacts     As Object
    Dim objContact      As Object
    Dim intCntr         As Integer
    Dim strZLS          As String

    On Error GoTo GetAll_Err
    ' 初始化 Restrict 方法参数中
    ' 使用的零长度字符串变量。
    strZLS = ""
    ' 获取对 Outlook“联系人”文件夹的引用。
    Set olapp = New Outlook.Application
    Set nspNameSpace = olapp.GetNamespace("MAPI")
    Set fldContacts = nspNameSpace.GetDefaultFolder(olFolderContacts)
    Set objContacts = fldContacts.Items.Restrict("[BusinessAddress] <> '" & strZLS & "'")

    ' 将该数组的大小重新调整为 Outlook“联系人”的数量。
    ReDim gavarContactsArray(objContacts.Count - 1)

    For Each objContact In objContacts
        ' 仅添加包含业务地址的项。
            gavarContactsArray(intCntr) = IIf(Len(objContact.FullName) > 0, _
                objContact.FullName & vbCrLf, "") & IIf(Len(objContact.CompanyName) > 0, _
                objContact.CompanyName & vbCrLf, "") & objContact.BusinessAddress
            intCntr = intCntr + 1
    Next objContact

    ' 排序数组。
    QuickSortArray gavarContactsArray

GetAll_Bye:
    Exit Sub
GetAll_Err:
    MsgBox Err.Description, vbOKOnly, "Error = " & Err.Number
    Resume GetAll_Bye
End Sub

当显示前一幅图中出现的窗体时,将使用 FillUsingOutlookData 过程将联系人姓名加载到组合框:

Sub FillUsingOutlookData()
    ' 该过程将来自 Outlook“联系人”
    ' 文件夹的数据填入数组。
    Dim intCurrentContact As Integer

    ' 用数组中的名称填写组合框。
    For intCurrentContact = 0 To UBound(gavarContactsArray) - 1
        cboContacts.AddItem Left(gavarContactsArray(intCurrentContact), _
            InStr(gavarContactsArray(intCurrentContact), _
            vbCrLf) - 1)
    Next intCurrentContact
    ' 显示列表中的第一个项。
    cboContacts.ListIndex = 0
    ' 更新显示名称
    ' 的地址信息。
    UpdateAddress
End Sub

最后,通过调用 UpdateAddress 过程,组合框中显示的姓名的地址信息被添加到该窗体的文本框中:

Sub UpdateAddress()
    Dim intIndex As Integer
    ' 用组合框中选择的项作为
    ' 联系人名字和地址数组的索引,
    ' 并在 txtAddress 文本框中显示地址信息。
    intIndex = cboContacts.ListIndex
    txtAddress.Text = Mid(gavarContactsArray(intIndex), _
        InStr(gavarContactsArray(intIndex), vbCrLf) + 2)
End Sub

一旦用户选定了该信收件人的姓名,并单击了窗体中的确定按钮,则该姓名和地址数据将插入到名为地址的书签所在位置的文档中。

本例说明了一个简单又强大的技术,它将 Word 的文档创建能力添加到 Outlook 的联系人管理能力中,从而创建了任何应用程序自身都不能提供的自定义解决方案。 这也正是 Automation 的真正出色之处。

何处可获得更详细的信息

以下是一些附加的资源,您可以用来研究如何使用 Office Automation:

TA的精华主题

TA的得分主题

 楼主| 发表于 2004-9-27 15:50 | 显示全部楼层
不好意思,在KEVIN的网站上已经有了。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-24 04:01 , Processed in 0.032875 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表