Internet Explorer から Word オートメーションに VB ActiveX コンポーネントを使用する方法

概要

この記事では、Internet Explorer でレンダリングされる Web ページから、クライアント側の Word オートメーションに ActiveX コンポーネントを使用する方法について説明します。 Web ページ自体に埋め込まれているスクリプトの代わりに、Web ページから ActiveX コンポーネントを使用すると、いくつかの利点があります。

  • Microsoft Word を自動化する Visual Basic コードが既にある場合は、Visual Basic プロジェクトを ActiveX EXE または ActiveX DLL に変換することで、ブラウザーでコードを再利用できます。
  • Word はスクリプトに対して安全であるとマークされていません。 Internet Explorer のセキュリティ設定によっては、スクリプト内の Word Automation コードが実行されないか、ユーザーにセキュリティ警告が表示される場合があります。 ActiveX コンポーネントが特定のガイドラインを満たしていると仮定すると、これらのセキュリティの問題を回避するためにスクリプトを作成しても安全であるとマークされる場合があります。
  • Visual Basic には、Web ページのスクリプトでは使用できないいくつかの機能があります。 たとえば、Visual Basic では使用できますが、Web ページ スクリプトでは使用できない機能の 1 つは、Windows アプリケーション プログラミング インターフェイス (API) を呼び出す機能です。

一般的な開発者向けシナリオでは、一部の外部ソースまたはロジックのデータを使用して Word 文書を作成するための Web ページ インターフェイスをユーザーに提示します。 サーバー側の Word Automation を使用してドキュメントを生成し、クライアントにストリーミングすることができますが、Word Automation を含むサーバー側のアプローチを使用することには多くの欠点があります。 主な欠点はスケーラビリティです。Word は非常にリソースを消費するオートメーション サーバーであり、Web サーバーでのドキュメント生成にはお勧めしません。

ActiveX コンポーネントを使用してクライアントでドキュメントの生成を実行することで、リソースを消費する Word Automation を Web サーバーから離すことができます。 これは、この記事で説明するサンプル ActiveX コンポーネントによって提示されるソリューションです。 サンプルは Word Automation に固有ですが、Microsoft Excel などの他の Microsoft Office アプリケーションの自動化にも同じ原則が適用される場合があります。

詳細情報

Visual Basic ActiveX コンポーネント

このサンプルの Visual Basic ActiveX コンポーネントは、Web ページ スクリプトと対話して、ユーザーの要求に応じて注文請求書ドキュメントを生成します。 Web アプリケーションでは、ActiveX コンポーネントが特定の注文 ID の注文情報を取得できる場合があります。Web アプリケーションは、注文情報を XML としてパッケージ化し、処理のために ActiveX コンポーネントに送信することを選択できます。 どちらの場合も、コンポーネントが注文情報を取得した後、Word を自動化して注文の請求書ドキュメントを作成して表示できます。

ActiveX コンポーネント (AutomateWord) には、3 つのメソッドを公開する 1 つのクラスである Invoice クラスが含まれています。

  • GetData メソッドは、ActiveX Data Objects (ADO) を使用して、Northwind サンプル データベース内の順序に関する情報を抽出します。 注文情報は、m_Dataプライベート メンバー変数に格納されます。 GetData メソッドを呼び出して、データ抽出をクライアント側で行うことができます。
  • SendData メソッドは Microsoft XML (MSXML) を使用して、m_Dataプライベート メンバー変数に、呼び出し元から提供される注文情報を入力します。 SendData では、注文情報の DOMDocument オブジェクトを表す 1 つのパラメーターが必要です。 SendData メソッドを呼び出して、Web ページからコンポーネントに注文情報を送信できます。 この方法では、ASP を使用してデータ サーバー側を抽出し、ドキュメント生成に使用できる XML データ アイランドをクライアントに提示できます。
  • MakeInvoice メソッドでは、Word Automation を使用して、m_Dataプライベート メンバー変数の注文情報を含むドキュメントを作成します。 Web サーバーに格納されているドキュメントは、請求書の開始点として使用されます。 呼び出し元は、完成した Word 文書をブラウザーの外部に表示するか、後で使用するために完成した文書をディスクに保存するかを選択できます。

Invoice.cls

Option Explicit

Private Type InvoiceData
    OrderID As String
    OrderDate As Date
    CustID As String
    CustInfo As String
    ProdInfo As Variant
End Type

Private m_Data As InvoiceData

Public Sub GetData(sOrderID As Variant, sConn As Variant)

Dim oConn As Object, oRS As Object

'Connect to the Northwind database.
    Set oConn = CreateObject("ADODB.Connection")
    oConn.Open sConn

'Obtain the Customer ID and Order Date.
    Set oRS = CreateObject("ADODB.Recordset")
    oRS.Open "Select [OrderDate], [CustomerID] from Orders where " & _
             "[OrderID]=" & sOrderID, oConn, 3 'adOpenStatic=3
    m_Data.OrderID = sOrderID
    m_Data.OrderDate = CDate(oRS.Fields("OrderDate").Value)
    m_Data.CustID = oRS.Fields("CustomerID").Value
    oRS.Close

'Obtain Customer information.
    Set oRS = CreateObject("ADODB.Recordset")
    oRS.Open "Select * from Customers Where CustomerID='" & _
             m_Data.CustID & "'", oConn, 3 'adOpenStatic=3
    m_Data.CustInfo = oRS.Fields("CompanyName").Value & vbCrLf & _
                      oRS.Fields("City") & " "
    If Not (IsNull(oRS.Fields("Region"))) Then
       m_Data.CustInfo = m_Data.CustInfo & oRS.Fields("Region").Value & " "
    End If
    m_Data.CustInfo = m_Data.CustInfo & oRS.Fields("PostalCode").Value & _
                      vbCrLf & oRS.Fields("Country").Value
    oRS.Close

'Obtain Product information.
    Set oRS = CreateObject("ADODB.Recordset")
    oRS.Open "Select ProductName, Quantity, [Order Details].UnitPrice," & _
             "Discount from Products Inner Join [Order Details] on " & _
             "Products.ProductID = [Order Details].ProductID " & _
             "Where OrderID = " & sOrderID, oConn, 3 'adOpenStatic=3
    m_Data.ProdInfo = oRS.GetRows
    oRS.Close

'Close the connection to the database.
    oConn.Close

End Sub

Public Sub SendData(oXML As Variant)

'Extract the information from the DOMDocument object oXML and store
    'it in the private member variable m_Data.

m_Data.OrderID = oXML.getElementsByTagName("OrderID").Item(0).Text
    m_Data.OrderDate = oXML.getElementsByTagName("OrderDate").Item(0).Text
    m_Data.CustID = oXML.getElementsByTagName("CustID").Item(0).Text
    m_Data.CustInfo = oXML.getElementsByTagName("CustInfo").Item(0).Text

Dim oItems As Object, oItem As Object
    Set oItems = oXML.getElementsByTagName("Items").Item(0)
    ReDim vArray(0 To 3, 0 To oItems.childNodes.Length - 1) As Variant
    Dim i As Integer
    For i = 0 To UBound(vArray, 2)
        Set oItem = oItems.childNodes(i)
        vArray(0, i) = oItem.getAttribute("Desc")
        vArray(1, i) = oItem.getAttribute("Qty")
        vArray(2, i) = oItem.getAttribute("Price")
        vArray(3, i) = oItem.getAttribute("Disc")
    Next
    m_Data.ProdInfo = vArray

End Sub

Public Sub MakeInvoice(sTemplate As Variant, Optional bSave As Variant)

Dim oWord As Object
    Dim oDoc As Object
    Dim oTable As Object

If IsMissing(bSave) Then bSave = False

'Open the document as read-only.
    Set oWord = CreateObject("Word.Application")
    Set oDoc = oWord.Documents.Open(sTemplate, , True)

'Fill in the bookmarks.
    oDoc.Bookmarks("Customer_Info").Range.Text = m_Data.CustInfo
    oDoc.Bookmarks("Customer_ID").Range.Text = m_Data.CustID
    oDoc.Bookmarks("Order_ID").Range.Text = m_Data.OrderID
    oDoc.Bookmarks("Order_Date").Range.Text = m_Data.OrderDate

'Fill in the table with the product information.
    '** Note that the table starts out with three rows -- the first row
    '   contains headers for the table, the second row is for
    '   the first set of product data, and the third row contains a total.
    '   New rows are added for additional products before the "total row".

Set oTable = oDoc.Tables(1)
    Dim r As Integer, c As Integer
    For r = 1 To UBound(m_Data.ProdInfo, 2) + 1
        If r > 1 Then oTable.Rows.Add (oTable.Rows(oTable.Rows.Count))
        For c = 1 To 4
            oTable.Cell(r + 1, c).Range.Text = _
               m_Data.ProdInfo(c - 1, r - 1)
        Next
        oTable.Cell(r + 1, 5).Formula _
            "=(B" & r + 1 & "*C" & r + 1 & ")*(1-D" & r + 1 & ")", _
            "#,##0.00"
    Next

'Update the field for the grand total and protect the document.
    oTable.Cell(oTable.Rows.Count, 5).Range.Fields.Update
    oDoc.Protect 1 'wdAllowOnlyComments=1

If bSave Then
        'Save the document as "c:\invoice.doc" and quit Word.
        Dim nResult As Long
        nResult = MsgBox("Are you sure you wish to create the document" & _
             " ""c:\invoice.doc""? If this document already exists, " & _
             "it will be replaced", vbYesNo, "AutomateWord")
        If nResult = vbYes Then oDoc.SaveAs "c:\invoice.doc"
        oDoc.Close False
        oWord.Quit
    Else
        'Make Word visible.
        oWord.Visible = True
    End If

End Sub

Web ページから ActiveX コンポーネントを使用する

Autoword1.htmでは、GetData メソッドを使用して ActiveX コンポーネントが注文データクライアント側を取得し、ドキュメントをビルドできるようにする方法について説明します。

Autoword1.htm

<HTML>
<HEAD>
   <OBJECT ID="AutoWord"
    CLASSID="CLSID:32646EBA-0919-4C2F-94D6-599F46DC34F2"
    CODEBASE="https://YourWebServer/invoice/package/AutomateWord.CAB#version=1,0,0,0">
   </OBJECT>
</HEAD>
<BODY>
Enter an order id between 10248 and 11077 and click the button to view the invoice for the order:
<P/><INPUT TYPE="text" VALUE="10500" ID="OrderID">
<P/><BUTTON ID="InvoiceButton">Create Invoice</BUTTON>
</BODY>

<SCRIPT Language="VBScript">

Function InvoiceButton_OnClick()
      Dim sConn
      sConn = "Provider=sqloledb;Data Source=YourSQLServer;Initial Catalog=Northwind;UID=sa;"
      AutoWord.GetData OrderID.Value, sConn
      AutoWord.MakeInvoice "https://YourWebServer/invoice/invoice.doc"
   End Function

</SCRIPT>
</HTML>

Autoword1.htmのスクリプトでは、ActiveX コンポーネントを使用して、完成したドキュメントをブラウザーの外部に表示します。 完成したドキュメントを保存し、ブラウザーに表示することもできます。ただし、これを行うには、Word 文書をディスクに保存する必要があります。 コンポーネントは、ドキュメントをクライアントのローカル ドライブにC:\Invoice.docとして保存できます。 ActiveX コンポーネントはスクリプトに対して安全であるとマークされているため、クライアントは保存を確認するように求められます。

完了したドキュメントをブラウザーに表示する場合は、Autoword1.htmで MakeInvoice の呼び出しを次のように変更します。

      AutoWord.MakeInvoice "https://YourWebServer/invoice/invoice.doc", True
      window.navigate "c:\invoice.doc"

Autoword2.htmでは、SendData メソッドを使用して、完了したドキュメントを生成するために注文データを DOMDocument オブジェクトとして ActiveX コンポーネントに送信する方法について説明します。 DOMDocument は、Web ページに存在する XML データ アイランドから作成されます。 ActiveX コンポーネントが呼び出し元によって送信される注文情報を適切に処理するには、コンポーネントが注文情報として解釈できるように、XML が整形式で構造化されている必要があります。

Autoword2.htm

<HTML>
<HEAD>
   <OBJECT ID="AutoWord"
    CLASSID="CLSID:32646EBA-0919-4C2F-94D6-599F46DC34F2"
    CODEBASE="https://YourWebServer/invoice/package/AutomateWord.CAB#version=1,0,0,0">
   </OBJECT>
</HEAD>
<BODY>
   <BUTTON ID="InvoiceButton">Create Invoice</BUTTON>
   <XML ID="DataXML">
     <Order>
        <OrderID>10700</OrderID>
        <OrderDate>10/10/2000</OrderDate>
        <CustID>SAVEA</CustID>
        <CustInfo>Save-a-lot
Markets Boise ID 83720
USA</CustInfo>
        <Items>
           <Product Desc="Chai" Qty="5" Price="18" Disc="0.2"/>
           <Product Desc="Sasquatch Ale" Qty="12" Price="14" Disc="0.2"/>
           <Product Desc="Scottish Longbreads" Qty="40" Price="12.5" Disc="0.2"/>
           <Product Desc="Flotemysost" Qty="60" Price="21.5" Disc="0.2"/>
        </Items>        
     </Order>
   </XML>
</BODY>

<SCRIPT Language="VBScript">

Function InvoiceButton_OnClick()
      AutoWord.SendData DataXML.XMLDocument
      AutoWord.MakeInvoice "https://YourWebServer/invoice/invoice.doc"
   End Function

</SCRIPT>
</HTML>

Autoword1.htmとAutoword2.htmの両方で、CreateObject 関数ではなくタグを使用して ActiveX コンポーネントがインスタンス化されることに注意してください。 タグを使用する目的は、コンポーネントがまだインストールされていないユーザーに対して ActiveX コンポーネントの自動ダウンロードを有効にすることです。 ユーザーがこれらのページのいずれかにアクセスし、コンポーネントがインストールされていない場合は、CODEBASE 属性に示されている URL のキャビネット (CAB) ファイルからコンポーネントがダウンロードされます。 Internet Explorer のユーザーのセキュリティ設定によっては、最初にダウンロードを確認するプロンプトが表示されることがあります。

注: Autoword.exeに含まれる CAB ファイルは、Visual Basic のパッケージと展開ウィザードを使用して作成されました。 パッケージ内の ActiveX コンポーネントは、スクリプトと初期化に対して安全であるとマークされていますが、デジタル署名は行われません。

インターネット コンポーネントのダウンロード、デジタル署名、およびスクリプトと初期化に安全なコンポーネントの作成の詳細については、次の Microsoft Developer Network (MSDN) Web サイトを参照してください。

Authenticode を使用したコードの署名と確認 https://msdn.microsoft.com/en-us/library/ms537364.aspx

ActiveX コントロールの安全な初期化とスクリプト作成 https://msdn.microsoft.com/en-us/library/Aa751977.aspx

関連情報

詳細については、次の記事番号をクリックして、Microsoft サポート技術情報の記事を表示します。

257757 INFO: 無人実行のための Office の自動化はお勧めできません。サポートされていません

(c) Microsoft Corporation 2001、All Rights reserved。 Lori B. Turner(Microsoft Corporation) による寄稿。