Een VB ActiveX-onderdeel gebruiken voor Word-automatisering vanuit Internet Explorer

Samenvatting

In dit artikel wordt gedemonstreerd hoe u een ActiveX-onderdeel kunt gebruiken voor automatisering aan de clientzijde van Word vanaf een webpagina die wordt weergegeven in Internet Explorer. Er zijn verschillende voordelen aan het gebruik van een ActiveX-onderdeel van een webpagina in plaats van script dat is ingesloten in de webpagina zelf:

  • Als u al Visual Basic-code hebt waarmee Microsoft Word wordt geautomatiseerd, kunt u uw code opnieuw gebruiken in de browser door uw Visual Basic-project te converteren naar een ActiveX EXE of een ActiveX DLL.
  • Word is niet gemarkeerd als veilig voor het uitvoeren van scripts. Afhankelijk van de beveiligingsinstellingen in Internet Explorer wordt Word Automation-code in het script mogelijk niet uitgevoerd of wordt de gebruiker mogelijk gevraagd om een beveiligingswaarschuwing. Ervan uitgaande dat uw ActiveX-onderdeel voldoet aan bepaalde richtlijnen, is het mogelijk gemarkeerd als veilig voor het uitvoeren van scripts om deze beveiligingsproblemen te voorkomen.
  • Visual Basic heeft verschillende functies die u niet kunt gebruiken met scripts op een webpagina. Een functie die bijvoorbeeld beschikbaar is voor Visual Basic, maar niet voor webpaginascripts, is de mogelijkheid om de Windows-API (Application Programming Interface) aan te roepen.

Een veelvoorkomend scenario voor ontwikkelaars is om gebruikers te presenteren met een webpagina-interface voor het maken van een Word-document met behulp van gegevens uit een externe bron of logica. Hoewel u Word Automation aan de serverzijde kunt gebruiken om het document te genereren en terug te streamen naar de client, zijn er veel nadelen aan het gebruik van een benadering aan de serverzijde die Word Automation omvat. Het belangrijkste nadeel is schaalbaarheid; Word is een zeer resource-intensieve Automation-server en wordt niet aanbevolen voor het genereren van documenten op de webserver.

Door een ActiveX-onderdeel te gebruiken om het genereren van documenten op de client uit te voeren, kunt u de resource-intensieve Word Automation van de webserver verwijderen. Dit is de oplossing die wordt gepresenteerd door het ActiveX-voorbeeldonderdeel dat in dit artikel wordt besproken. Hoewel het voorbeeld specifiek is voor Word Automation, kunnen dezelfde principes worden toegepast voor het automatiseren van andere Microsoft Office-toepassingen, zoals Microsoft Excel.

Meer informatie

Visual Basic ActiveX-onderdeel

Het Visual Basic ActiveX-onderdeel in dit voorbeeld communiceert met een webpaginascript om op verzoek van de gebruiker een orderfactuurdocument te genereren. De webtoepassing kan het ActiveX-onderdeel toestaan om de ordergegevens voor een bepaalde order-id op te halen, of de webtoepassing kan ervoor kiezen om de ordergegevens als XML te verpakken en naar het ActiveX-onderdeel te verzenden voor verwerking. In beide gevallen, nadat het onderdeel de ordergegevens heeft verkregen, kan het Word automatiseren om het factuurdocument voor de order te maken en weer te geven.

Het ActiveX-onderdeel (AutomateWord) bevat één klasse, de klasse Invoice, waarmee drie methoden worden weergegeven:

  • De Methode GetData maakt gebruik van ActiveX-gegevensobjecten (ADO) om informatie te extraheren over een order in de Northwind-voorbeelddatabase. De ordergegevens worden opgeslagen in de m_Data persoonlijke lidvariabele. De Methode GetData kan worden aangeroepen om de gegevensextractie aan de clientzijde te laten plaatsvinden.
  • De SendData-methode maakt gebruik van Microsoft XML (MSXML) om de m_Data persoonlijke lidvariabele te vullen met de ordergegevens die door de aanroeper worden verstrekt. SendData verwacht één parameter die een DOMDocument-object vertegenwoordigt voor de orderinformatie. De SendData-methode kan worden aangeroepen om de ordergegevens van de webpagina naar het onderdeel te verzenden. Met deze methode kunt u ASP gebruiken om de gegevensserver te extraheren en de client te presenteren met een XML-gegevenseiland dat kan worden gebruikt voor het genereren van het document.
  • De methode MakeInvoice maakt gebruik van Word Automation om een document te maken dat de ordergegevens bevat in de m_Data persoonlijke lidvariabele. Een document dat is opgeslagen op de webserver, wordt gebruikt als uitgangspunt voor de factuur. De beller kan ervoor kiezen om het voltooide Word-document buiten de browser weer te geven of het voltooide document op te slaan op een schijf voor later gebruik.

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

Het ActiveX-onderdeel gebruiken vanaf een webpagina

Autoword1.htm laat zien hoe u de methode GetData kunt gebruiken om het ActiveX-onderdeel de clientzijde van de ordergegevens op te halen en het document te bouwen.

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>

Het script in Autoword1.htm gebruikt het ActiveX-onderdeel om het voltooide document buiten de browser weer te geven. U kunt er ook voor kiezen om het voltooide document op te slaan en weer te geven in de browser; Als u dit doet, moet het Word-document echter worden opgeslagen op een schijf. Het onderdeel kan het document opslaan als C:\Invoice.doc op het lokale station van de client. Omdat het ActiveX-onderdeel is gemarkeerd als veilig voor het uitvoeren van scripts, wordt de client gevraagd om het opslaan te bevestigen.

Als u het voltooide document in de browser wilt weergeven, wijzigt u de aanroep naar MakeInvoice in Autoword1.htm in het volgende:

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

Autoword2.htm laat zien hoe u de SendData-methode kunt gebruiken om de ordergegevens als DOMDocument-object te verzenden naar het ActiveX-onderdeel voor het genereren van het voltooide document. Het DOMDocument wordt gemaakt op basis van een XML-gegevenseiland dat zich op de webpagina bevindt. Om ervoor te zorgen dat het ActiveX-onderdeel de orderinformatie die door de aanroeper wordt verzonden correct verwerkt, moet de XML goed zijn opgemaakt en gestructureerd, zodat het onderdeel deze kan interpreteren als orderinformatie.

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>

In zowel Autoword1.htm als Autoword2.htm moet u er rekening mee houden dat het ActiveX-onderdeel wordt geïn instantieerd via een tag in plaats van de functie CreateObject. Het doel van het gebruik van de tag is het automatisch downloaden van het ActiveX-onderdeel in te schakelen voor gebruikers die het onderdeel nog niet hebben geïnstalleerd. Als een gebruiker een van deze pagina's bezoekt en het onderdeel niet is geïnstalleerd, wordt het onderdeel gedownload uit het CAB-bestand (cabinet) op de URL die wordt aangegeven in het CODEBASE-kenmerk. Afhankelijk van de beveiligingsinstellingen van de gebruiker in Internet Explorer, ontvangen ze mogelijk eerst een prompt om het downloaden te bevestigen.

OPMERKING: het CAB-bestand dat is opgenomen in Autoword.exe is gemaakt met de wizard Pakket en implementatie voor Visual Basic. Het ActiveX-onderdeel in het pakket is gemarkeerd als veilig voor scripts en initialisatie, maar is niet digitaal ondertekend.

Zie de volgende MSDN-websites (Microsoft Developer Network) voor meer informatie over het maken van downloads van internetonderdelen, digitale ondertekening en het markeren van onderdelen als veilig voor scripts en initialisatie:

Ondertekening en controle van code met Authenticode https://msdn.microsoft.com/en-us/library/ms537364.aspx

Veilige initialisatie en scripting voor ActiveX-besturingselementen https://msdn.microsoft.com/en-us/library/Aa751977.aspx

Verwijzingen

Klik voor meer informatie op de volgende artikelnummers om de artikelen in de Microsoft Knowledge Base weer te geven:

257757 INFO: Automatisering van Office voor uitvoering zonder toezicht wordt niet aanbevolen of ondersteund

(c) Microsoft Corporation 2001, Alle rechten voorbehouden. Bijdragen van Lync B. Turner, Microsoft Corporation.