使用 Microsoft Office System 的 Visual Studio 工具在 Excel 中访问 Web

  • 来源: 论坛整理 作者: 若水   2008-04-01/10:37
  • 现在有一个功能非常强大的工具可供开发人员使用,该工具可用于为 Microsoft® Office 2003 创建智能客户端应用程序。这个工具就是 Microsoft Office System 的 Microsoft Visual Studio® 工具。使用 Microsoft Visual Studio .NET 2003 的这个外接程序,开发人员可以为特定的 Office 2003 模板快速创建托管 DLL,并且仅需很少的精力。之后,创建的 DLL 会挂接到某个 Microsoft Office Excel 或 Microsoft Office Word 文件中。该文件打开时,创建的 DLL 会无缝地加载到背景中。现在开发人员可以将 Microsoft .NET Framework 类与 Excel 或 Word 对象模型一起使用,创建功能强大的智能客户端应用程序。

    现在,开发 Office 模板的人员可以充分利用 Visual Studio .NET 集成开发环境 (IDE) 及其功能强大的调试程序。在托管代码中进行开发的另外优点意味着,开发人员可以更好地控制内存、类型转换等。在本文中,我将一步步讲解如何访问股票 Web 服务并将此 Web 服务挂接到 Excel 2003 应用程序中(我不会涉及如何处理该数据;您可以使用自己的想象力!)本文假定您已经具备一定的 Microsoft .NET Framework 编程知识。

    返回页首

    前提条件

    首先,您必须确保已安装所有正确的部分。这里我不打算详细说明这一点,但是请确保已按正确顺序安装了所有部分,以使其正常工作。有关详细信息,请参阅 How to:Install Visual Studio Tools for the Microsoft Office System(英文)。

    返回页首

    在 Visual Studio .NET 中创建 Excel 项目

    我要在 Microsoft Visual Basic® .NET 而不是 Microsoft Visual C#® 中进行此开发,有以下几点原因。首先,Visual Basic .NET 支持可选参数,而 C# 并不支持。这意味着,C# 开发人员必须为 Office 方法中的每个可选参数提供值,而 Visual Basic .NET 开发人员仅需要为所需的值提供参数。另外,C# 开发人员使用的访问器方法必须与 Visual Basic .NET 开发人员所用的不同,因为 C# 并不支持属性的参数(索引生成器是例外)。因为我很讨厌冗长的代码,所以决定使用 Visual Basic .NET。

    在 Visual Studio .NET 中,创建用于 Excel 的 Visual Basic Office 新项目。

    创建新的 Excel 工作簿项目

    1. 在“文件”菜单中,指向“新建”,然后单击“项目”。

      将显示“新建项目”对话框。

      odc_vstexlweb_fig01

      1. Visual Studio .NET 中的 新建项目 对话框
    2. 在“项目类型”窗格中,展开“Microsoft Office 系统项目”,然后选择“Visual Basic 项目”。

    3. 在“模板”窗格中,选择“Excel 工作簿”。

    4. 命名此项目,并将其存储在一个方便的本地路径中。

      我将此项目命名为 WebServiceStockExcelProject,不过这个名称可能有点拗口。可以随意命名此项目。

    5. 接受“Microsoft Office 项目向导”中的默认值,然后单击“完成”创建此项目。

    请注意,自动生成的代码已将类命名为 OfficeCodeBehind,不用费心更改此名称。它也为您提供了对两个友元对象的访问:ThisWorkbookThisApplication。可以在合适的时候使用这两个对象访问 Excel 应用程序。因为托管代码中有挂钩,因而 Office 应用程序启动时,该代码会自动与程序一起启动。Office 应用程序关闭时,代码也会正常关闭(这样就无须担心封送任何 COM 对象。)

    返回页首

    添加 Web 引用

    首先,将 Web 引用添加到“项目引用”文件夹中。

    添加 Web 引用

    • 在“项目”菜单上,选择“添加 Web 引用”。

    • 将要在代码中使用免费的 Web 服务,其网址为 http://www.nexus6studio.org/Services/StockQoute.asmx?WSDL。请注意此服务是一个免费服务,在读取时它可能是不可用的。将其放置在此处并单击“转到”:

      odc_vstexlweb_fig02

      2. 添加 Web 引用

      仅需关注 GetDetailQuote 及其返回的结构 DetailQuote

    • 单击“添加引用”。

      此时您就具有了对这两个 Web 服务的引用。

    返回页首

    准备 Excel 工作表

    Microsoft Office 项目向导为该项目创建初始的内含代码的文件时,它也在工作目录中创建一个 Excel 工作表。应将此项添加到项目,以便于引用。

    打开工作表,并使其如 3 中所示。

    注意:因为您还没有编译该程序集,可能会出现一个警告,提示程序集名称或程序集链接位置属性被破坏。单击“确定”关闭警告。

    odc_vstexlweb_fig03 #p#分页标题#e#

    3. Excel 工作表

    此处唯一棘手的部分是超链接“获取股票信息”的创建(其他都直接设置了格式)。该超链接很重要,因为它可以启动 Web 服务。这需要进行以下几步:

    在工作表中创建超链接

    1. 在“插入”菜单中,指向“名称”,然后单击“定义”。

    2. 将命名区域定义为 Get_Stock 并将其定义为区域 =Sheet1!$A$6

    3. 在“插入”菜单中,单击“超链接”打开超链接创建窗口。

    4. 在左侧,单击“放置在此文档中”,选择 Get_Stock 作为命名引用,然后单击“确定”。

    5. 保存并关闭工作簿。

    返回页首

    编写 OfficeCodeBehind 的代码

    这部分非常有意思,您可能一直在等待这部分。现在,开始使用 Excel 对象模型,来放置 Web 服务值并为其设置格式。

    首先,创建一个事件处理程序,用于处理对应用程序中创建的超链接的单击。将该子例程紧邻 ThisWorkbook_BeforeClose 子例程的下方进行放置:

    Private Sub ThisApplication_SheetFollowHyperlink _
        (ByVal Sh As Object, ByVal Target As Excel.Hyperlink) _
        Handles ThisApplication.SheetFollowHyperlink
    
            If Target.SubAddress = "Get_Stock" Then
                GetStock(Sh)
            End If
    
    End Sub
    

    发生对应用程序中任何超链接的任何单击时,该子例程都将执行。它传递两个参数,其中一个是 Sh,表示 Excel 工作表。另一个是 Target,表示实际的超链接。

    是否还记得如何将超链接区域命名为 Get_Stock?现在检查 Target.SubAddress 属性,确定该超链接是否已被单击。如果该超链接已被单击,您就可以开始工作了,调用 GetStock 子例程并传递 Sh 工作表对象变量。

    现在已编写完 GetStock 子例程的代码。将其放置在以前编码的 ThisApplication_ SheetFollowHyperlink 子例程的下面。

        Private Sub GetStock(ByVal Sh As Object)
            Dim sheet As Excel.Worksheet = CType(Sh, Excel.Worksheet)
            Dim stockSnapshot As New _   
                org.nexus6studio.www.Nexus6StudioStockQuote
            Dim snapShot As org.nexus6studio.www.DetailQuote
            Dim symbol As String = sheet.Range("F6").Value
    
            ' 这是一个错误消息区域。
            sheet.Range("A21:H32").Merge()
    
            Try
                snapShot = stockSnapshot.GetDetailQuote(symbol)
            Catch ex As Exception
                ' 可以使用上面的 Range 类,也可以使用下面的 Cells 类。
                ' 对于 Range 类,则必须设置 Value 属性。
                ' 请参阅 Try 块后面的示例。
                ' 这两个是相同的:
                ' sheet.Range("A21").Value = ex
                sheet.Cells(21, "A") = ex
    
            End Try
    
            sheet.Range("E10").Value = snapShot.Bid
            sheet.Range("E11").Value = snapShot.Ask
            sheet.Range("E16").Value = snapShot.Open
            sheet.Range("F14").Value = snapShot.High
            sheet.Range("F18").Value = snapShot.Low
            sheet.Range("F16").Value = snapShot.Price
            sheet.Range("F16").Font.Bold = True
            sheet.Range("F16").Font.Underline = True
            sheet.Range("E12").Value = snapShot.Change_Points
    
        End Sub
    

    您可能已注意到,Excel 互操作性将当前的工作表表示为一般对象。由于无法方便地在代码中使用一般对象,因此实例化类 Excel.Worksheet 的一个对象。而且,由于要对此“sheet”对象进行拆箱,因此必须使用 CType 显式转换它。

    然后,必须实例化 Web 服务本身及其返回的结构。实例化的 Web 服务对象是 stockSnapshot,实例化的结构是 snapShot。最后,获取股票符号。正如可以在 3 中看到的,单元格“F6”已被指定为放置该符号的位置。

    下一步,将工作表区域 A21H32 指定为一个合并区域,这样就可以在此放置捕获的任何异常。

    现在,由于您不知道在对 Web 服务的调用失败时可能会发生什么情况,因此我将其放置在 Try/Catch 块中。在 Try 块之内,调用 Web 服务,传入符号并取回包含当日的相关股票价值的 snapshot 结构。

    注意:可以使用多种方法访问单元格的值。正如您所看到的,既可以通过 Range 对象访问它们,也可以通过 Cells 对象访问它们。我在 Catch 块中使用 Cells 对象编写了代码以显示语法,但现在我想使用 Range 对象。我个人看来,这个对象在用于操作单元格区域时更加灵活。

    最后,子例程的最后几行将结构值放置在电子表格中。结构的值均被定义为字符串,但是在将其放置到电子表格之前无须对其进行任何显式转换。这是因为 Excel 使用任何传递到其 Value 属性的数值为您进行了该操作。

    我还添加了两行,使当前的股票价值突出;我将 Font.BoldFont.Underline 属性设置为 True#p#分页标题#e#

    返回页首

    执行

    现在就运行吗?编译刚编写的代码,然后转到保存该项目的文件夹。在此文件夹中激活 Excel 文件。您应该获取创建的 Excel 工作表。因为我想知道现在 Microsoft 股票的行情如何,那就让我们进入单元格 F6 中的 MSFT(或者是小写的,这没关系),按 ENTER 键并单击“获取股票信息”超链接。所获取的信息应类似于 4

    odc_vstexlweb_fig04

    4. Web 服务结果

    啊,股票价格会走高……

    注意到区域 A21H32 了吗?现在它是一个大的合并区域,与您在上面的代码中定义的完全相同。可以捕获任何异常。


    评论 {{userinfo.comments}}

    {{money}}

    {{question.question}}

    A {{question.A}}
    B {{question.B}}
    C {{question.C}}
    D {{question.D}}
    提交

    驱动号 更多