Jak używać składnika ActiveX VB do automatyzacji programu Word z programu Internet Explorer

Podsumowanie

W tym artykule przedstawiono sposób używania składnika ActiveX do automatyzacji programu Word po stronie klienta ze strony sieci Web renderowanego w programie Internet Explorer. Korzystanie ze składnika ActiveX ze strony sieci Web zamiast skryptu osadzonego na samej stronie sieci Web ma kilka korzyści:

  • Jeśli masz już kod języka Visual Basic automatyzujący program Microsoft Word, możesz ponownie użyć kodu w przeglądarce, konwertując projekt visual basic na bibliotekę ActiveX EXE lub ActiveX DLL.
  • Program Word nie jest oznaczony jako bezpieczny do obsługi skryptów. W zależności od ustawień zabezpieczeń w programie Internet Explorer kod usługi Word Automation w skryptze może nie zostać uruchomiony lub może zostać wyświetlony monit z ostrzeżeniem o zabezpieczeniach. Zakładając, że składnik ActiveX spełnia określone wytyczne, może być oznaczony jako bezpieczny dla skryptów, aby uniknąć tych problemów z zabezpieczeniami.
  • Język Visual Basic zawiera kilka funkcji, których nie można używać ze skryptem na stronie sieci Web. Na przykład jedną z funkcji, która jest dostępna dla języka Visual Basic, ale nie dla skryptu strony sieci Web, jest możliwość wywoływania interfejsu programowania aplikacji systemu Windows (API).

Typowym scenariuszem dewelopera jest prezentowanie użytkownikom interfejsu strony internetowej do tworzenia dokumentu programu Word przy użyciu danych z jakiegoś zewnętrznego źródła lub logiki. Mimo że do generowania dokumentu i przesyłania strumieniowego z powrotem do klienta można użyć usługi Word Automation po stronie serwera, istnieje wiele wad korzystania z podejścia po stronie serwera, które obejmuje usługę Word Automation. Główną wadą jest skalowalność; Program Word jest bardzo zasobochłonnym serwerem usługi Automation i nie jest zalecany do generowania dokumentów na serwerze sieci Web.

Używając składnika ActiveX do generowania dokumentów na kliencie, możesz przenieść usługę Word Automation intensywnie korzystającą z zasobów z serwera sieci Web. Jest to rozwiązanie przedstawione przez przykładowy składnik ActiveX omówiony w tym artykule. Chociaż przykład jest specyficzny dla usługi Word Automation, te same zasady mogą być stosowane do automatyzowania innych aplikacji pakietu Microsoft Office, takich jak Microsoft Excel.

Więcej informacji

Składnik ActiveX języka Visual Basic

Składnik ActiveX języka Visual Basic w tym przykładzie współdziała ze skryptem strony internetowej w celu wygenerowania dokumentu faktury zamówienia na żądanie użytkownika. Aplikacja internetowa może zezwolić składnikowi ActiveX na uzyskanie informacji o zamówieniu dla danego identyfikatora zamówienia lub aplikacja internetowa może zdecydować się na spakowanie informacji o zamówieniu jako xml i wysłanie ich do składnika ActiveX w celu przetworzenia. W obu przypadkach po uzyskaniu informacji o zamówieniu przez składnik program Word może zautomatyzować tworzenie i wyświetlanie dokumentu faktury dla zamówienia.

Składnik ActiveX (AutomateWord) zawiera jedną klasę , klasę Invoice, która uwidacznia trzy metody:

  • Metoda GetData używa obiektów danych ActiveX (ADO) do wyodrębniania informacji o zamówieniu w przykładowej bazie danych Northwind. Informacje o kolejności są przechowywane w m_Data zmiennej prywatnego elementu członkowskiego. Metodę GetData można wywołać, aby umożliwić wyodrębnianie danych po stronie klienta.
  • Metoda SendData używa kodu MICROSOFT XML (MSXML) do wypełnienia m_Data zmiennej prywatnego elementu członkowskiego informacjami o kolejności dostarczaną przez obiekt wywołujący. SendData oczekuje jednego parametru reprezentującego obiekt DOMDocument dla informacji o kolejności. Metodę SendData można wywołać w celu wysłania informacji o zamówieniu ze strony sieci Web do składnika. Dzięki temu podejściu można użyć protokołu ASP do wyodrębnienia po stronie serwera danych i zaprezentowania klientowi wyspy danych XML, która może być używana do generowania dokumentu.
  • Metoda MakeInvoice używa usługi Word Automation do utworzenia dokumentu zawierającego informacje o kolejności w m_Data zmiennej prywatnego elementu członkowskiego. Dokument przechowywany na serwerze sieci Web jest używany jako punkt początkowy faktury. Obiekt wywołujący może wybrać wyświetlanie ukończonego dokumentu programu Word poza przeglądarką lub zapisać ukończony dokument na dysku do późniejszego użycia.

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

Używanie składnika ActiveX ze strony sieci Web

Autoword1.htm pokazuje, jak można użyć metody GetData, aby umożliwić składnikowi ActiveX pobranie danych zamówienia po stronie klienta i skompilowanie dokumentu.

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>

Skrypt w Autoword1.htm używa składnika ActiveX do wyświetlania ukończonego dokumentu poza przeglądarką. Możesz również zapisać ukończony dokument i wyświetlić go w przeglądarce. Wymaga to jednak zapisania dokumentu programu Word na dysku. Składnik może zapisać dokument jako C:\Invoice.doc na dysku lokalnym klienta. Ponieważ składnik ActiveX jest oznaczony jako bezpieczny do obsługi skryptów, klient jest monitowany o potwierdzenie zapisania.

Jeśli chcesz wyświetlić ukończony dokument w przeglądarce, zmień wywołanie na MakeInvoice w Autoword1.htm na następujące:

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

Autoword2.htm pokazuje, jak za pomocą metody SendData wysyłać dane zamówienia jako obiekt DOMDocument do składnika ActiveX w celu wygenerowania ukończonego dokumentu. Obiekt DOMDocument jest tworzony na podstawie wyspy danych XML, która znajduje się na stronie sieci Web. Aby składnik ActiveX prawidłowo przetwarzał informacje o zamówieniu wysyłane przez obiekt wywołujący, kod XML musi być dobrze sformułowany i ustrukturyzowany, aby składnik mógł interpretować go jako informacje o kolejności.

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>

W Autoword1.htm i Autoword2.htm należy zauważyć, że składnik ActiveX jest tworzone za pomocą tagu, a nie funkcji CreateObject. Celem używania tagu jest włączenie automatycznego pobierania składnika ActiveX dla użytkowników, którzy nie mają jeszcze zainstalowanego składnika. Jeśli użytkownik odwiedzi jedną z tych stron, a składnik nie zostanie zainstalowany, składnik zostanie pobrany z pliku cabinet (CAB) pod adresem URL wskazanym w atrybucie CODEBASE. W zależności od ustawień zabezpieczeń użytkownika w programie Internet Explorer może on najpierw otrzymać monit o potwierdzenie pobrania.

UWAGA: Plik CAB dołączony do Autoword.exe został utworzony za pomocą Kreatora pakietów i wdrażania dla języka Visual Basic. Składnik ActiveX w pakiecie jest oznaczony jako bezpieczny do obsługi skryptów i inicjowania, ale nie jest podpisany cyfrowo.

Aby uzyskać więcej informacji na temat tworzenia składników internetowych do pobrania, podpisywania cyfrowego i oznaczania składników jako bezpiecznych dla skryptów i inicjowania, zobacz następujące witryny sieci Web microsoft developer network (MSDN):

Podpisywanie i sprawdzanie kodu za pomocą funkcji Authenticode https://msdn.microsoft.com/en-us/library/ms537364.aspx

Bezpieczna inicjowanie i wykonywanie skryptów dla kontrolek ActiveX https://msdn.microsoft.com/en-us/library/Aa751977.aspx

Informacje

Aby uzyskać dodatkowe informacje, kliknij następujące numery artykułów, aby wyświetlić artykuły w bazie wiedzy Microsoft Knowledge Base:

257757 INFO: Automatyzacja pakietu Office w przypadku wykonywania nienadzorowanego nie jest zalecana ani obsługiwana

(c) Microsoft Corporation 2001, Wszelkie prawa zastrzeżone. Wkład Lori B. Turner, Microsoft Corporation.