次の方法で共有


XML Web Service-Enabled Office ドキュメント

 

Chris Lovett
Microsoft Corporation

2001 年 3 月 19 日

Xml03192001.exeをダウンロード します

Microsoft Office XP と .NET Web Services の結婚の準備はできましたか? B2B eコマースのネットワーク化された世界では、ビジネス プロセス ワークフローをデスクトップからすべてのユーザーに統合することで、Web サービスの機能をエンド ユーザーに提供してみませんか? 私は何について話していますか? 図 1 のような Excel スプレッドシートです。

図 1. Web サービス対応 Excel スプレッドシート

これは通常のスプレッドシートだけではありません。 UDDI を使用して会社の住所を検索し、カタログ Web サービスを使用して製品情報を検索します。 また、[ 送信 ] ボタンをクリックすると、XML スプレッドシート形式で XML 変換が実行され、RosettaNet PIP 3 A4 発注書要求形式が生成されます。

購入元の会社の名前を入力し、[ 検索 ] ボタンをクリックすると、スプレッドシートの背後にある一部の VBA コードで UDDI 呼び出しが行われ、アドレス セクションの残りの部分が入力されます。 たとえば、「 Microsoft」と入力し、[ 検索] をクリックすると、[ 購入元 ] フィールドに次の情報が表示されます。

図 2. [購入元] フィールド

たとえば 、23 の数量を入力し、説明フィールドに Pear という用語を入力してから Tab キーを押すと、一部の VBA コードは SOAP Catalog Web サービスにクエリを実行して、一致する製品が見つかるかどうかを確認し、詳細を入力します。 この場合、Catalog Web Service を Northwind データベースに接続したので、次が返されます。

図 3: スプレッドシートの順序部分を詳しく見る

この場合は、説明も入力し、その製品に関するすべての情報を示す HTML ページに移動するリンクに変えました。

複数の製品が見つかり、入力した製品と正確に一致するものがない場合は、選択肢のドロップダウン リストが提供されます。 たとえば、「 tofu」と入力すると、次の選択肢が表示されます。

図 4: 完全一致が見つからない場合に提供される複数の選択肢の例

これらの選択肢のいずれかを選択すると、特定の詳細が表示されます。

完了したら、[ 送信 ] ボタンをクリックすると、RosettaNet PIP 3 A4 XML 発注書形式が生成され、注文が送信されます。

この機能はすべてどのように機能しますか?

スプレッドシートの背後にある VBA コードを参照するには、[ ツール ] メニューの [ マクロ]、[ Visual Basic Editor] の順に選択します。 ThisWorkbook の背後には、スプレッドシートの変更に対応するコードがいくつかあります。特に、Workbook_SheetChange イベントでは説明を削除すると行項目がクリアされ、Workbook_SheetSelectionChange イベントは [説明] フィールドから SKU フィールドにタブアウトしたときに FindProduct() を呼び出します。 FindProduct がXMLNode を返す場合、関連するフィールドがそのノードから取り出され、残りの行項目の詳細が設定されます。

UDDI find_business 呼び出しのしくみについては、前の記事 「UDDI: XML Web サービス」を参照してください。 ビジネスが見つかった場合、UDDI 応答の /businessInfo/contacts/contact/address/ 部分にある addressLines を使用して、 Purchase From アドレス ブロックが設定されます。

カタログ Web サービス

Catalogs モジュールの FindProduct 関数は、検索する検索語句を含む URL パラメーターを使用して Catalog Service URL を呼び出します。 SOAP 応答が返されると想定され、最初に /Envelope/Body/Fault と一致するかどうかを確認します。Fault でない場合は、CatalogQueryResult> チェックを開<き、返されたアイテムの ProductName 属性が指定された用語と一致するかどうかを確認します。 また、表示領域の外側のページの下に選択肢のドロップダウン リストも作成されます。 ドロップダウン リストの動作を確認するには、[ データ ] メニューに移動し、[ 検証] を選択します。

カタログ Web サービスは非常にシンプルです。 .aspx エントリ ポイントは、search.cs で定義されている CatalogSearch オブジェクトを作成し、 Execute を呼び出し、HttpResponse 出力ストリームを次のように渡します。

<%@Language="C#" src="search.cs"  Debug="true" %>
<%
   Response.ContentType = "text/xml";
   string term = Request.QueryString["term"];
   if (term != null) {
      CatalogSearch s = new CatalogSearch(term);
      s.Execute(output);
   } else {
      Response.Write("<Empty/>");
   }
%>

Execute メソッドは、楽しみが始まる場所です。 これは、SQL SELECT ステートメントから特定のフィールドを返す XmlTextWriter にラップされた非常に単純な SQL マネージド プロバイダー コードです。 したがって、基本的には、次のように XmlTextWriter に書き込み、 DataReader をループ処理します。

public void Execute(TextWriter stm)
{      
   XmlTextWriter xw = new XmlTextWriter(stm);
   xw.WriteStartElement("Envelope", "http://schemas..../envelope/");
   xw.WriteStartElement("Body", "http://schemas..../envelope/");
   try {
      String const = "server=localhost;uid=sa;pwd=;database=northwind";
      SQLConnection con = new SQLConnection(constr);
      con.Open();
      IDataReader reader;
      String query = "SELECT ProductName,UnitPrice,QuantityPerUnit," +
           "SupplierID,ProductID FROM Products WHERE " +
           "ProductName LIKE '%" + term + "%'";
      SQLCommand cmd = new SQLCommand(query, con);
      cmd.Execute(out reader);
      string funNamespace = "urn:schemas-b2b-fun:catalogs";
      xw.WriteStartElement("CatalogQueryResult", funNamespace);
      while (reader.Read())
      {
         xw.WriteStartElement("item");
         xw.WriteAttribute("ProductName", reader.GetString(0));
         xw.WriteAttrDecimal("UnitPrice", reader.GetDecimal(1));
         xw.WriteAttribute("UnitOfMeasure", reader.GetString(2));
         xw.WriteAttribute("SKU", "S"+reader.GetInt32(3)+
"-P"+reader.GetInt32(4));
         xw.WriteEndElement();
      }
      xw.WriteEndElement(); 
      con.Close();
   } catch (Exception e) {
      xw.WriteStartElement("Fault");
         xw.WriteElementString("faultcode","500");
         xw.WriteElementString("faultstring",e.ToString());
      xw.WriteEndElement();
   }
   xw.WriteEndElement();
   xw.WriteEndElement();
   xw.Close();
}

URL https://localhost/catalog/search.aspx?term=tofu は次の結果を返します。

<Envelope xmlns="https://schemas.xmlsoap.org/soap/envelope/">
<Body>
  <CatalogQueryResult xmlns="urn:schemas-b2b-fun:catalogs">
    <item ProductName="Tofu" UnitPrice="23.25" 
 UnitOfMeasure="40 - 100 g pkgs." SKU="S6-P14"/>
    <item ProductName="Longlife Tofu" UnitPrice="10" 
 UnitOfMeasure="5 kg pkg." SKU="S4-P74"/>
  </CatalogQueryResult>
</Body>
</Envelope>

これは、.NET フレームワークを使用して xml をSQL Serverから取得する最も効率的な方法についてです。 非常に大まかな測定で、私はDell PowerEdge 2400で毎秒約80から90を得ました。

[送信] ボタン

SendOrder() 関数は、スプレッドシート内の選択したセル範囲の XML 表現から XML ドキュメントを読み込みます。 これは、次の VBA コードのマジック ラインで行われます。

With ActiveSheet 
  Set sourcexml = New MSXML2.DOMDocument
  sourcexml.loadXML .Range("B1:N34").value(xlRangeValueXMLSpreadsheet)
End With

これにより、スプレッドシート内のセル範囲に関するすべてを完全に記述する XML の巨大なチャンクが返されます。 XML のチャンクからのスニペットを次に示します。

<Workbook>
    <Worksheet>
        <Table>
            <Row>
                <Cell ss:StyleID="s23"><Data ss:Type="Number">23</Data>
<NamedCell ss:Name="Item"/></Cell>
 <Cell ss:MergeAcross="4" ss:StyleID="m31209522" 
ss:HRef="http://eshop.msn.com/category.asp?catId=170">
<Data ss:Type="String">Uncle Bob's Organic Dried 
Pears</Data></Cell>
<Cell ss:StyleID="s52">
<Data ss:Type="String">S3-P7</Data></Cell>
                <Cell ss:StyleID="s26">
<Data ss:Type="Number">30</Data>
<NamedCell ss:Name="UnitPrice"/></Cell>
                <Cell ss:StyleID="s27">
<Data ss:Type="String">12 - 1 lb pkgs.</Data></Cell>
<Cell ss:StyleID="s37">
<Data ss:Type="Number">690</Data></Cell>
                <Cell ss:StyleID="s49"/>
            </Row>
        </Table>

    </Worksheet>
</Workbook>

次に、XSL を使用してこれを次の形式に変換します。

<PurchaseOrder xmlns="http://www.rosettanet.org">
   <deliverTo>
      <PhysicalAddress>
         <cityName>Seattle, WA, USA 98111</cityName>
         <addressLine1>Airport Chocolates</addressLine1>
         <addressLine2>2711 Alaskan Way</addressLine2>
         <regionName>USA</regionName>
      </PhysicalAddress>
   </deliverTo>
   <ProductLineItem>
      <ProductQuantity>23</ProductQuantity>
      <productUnit>
         <ProductPackageDescription>
            <ProductIdentification>
               <GlobalProductIdentifier>S3-P7</GlobalProductIdentifier>
            </ProductIdentification>
         </ProductPackageDescription>
      </productUnit>
      <Description>Uncle Bob's Organic Dried Pears</Description>
      <requestedPrice>
         <FinancialAmount>
            <GlobalCurrencyCode>USD</GlobalCurrencyCode>
            <MonetaryAmount>30</MonetaryAmount>
         </FinancialAmount>
      </requestedPrice>
   </ProductLineItem>
   <thisDocumentGenerationDateTime>
      <DateTimeStamp>2001-03-15T00:00:00.000</DateTimeStamp>
   </thisDocumentGenerationDateTime>
</PurchaseOrder>

メモ これはおそらく 、RosettaNet PIP 3 A4 発注書要求仕様に従った技術的に完全な要求ではありませんが、アイデアを得ることができます。

この変換をやや堅牢にするトリックは、データをプルする重要なセルに名前を付けます。 これは、XSLT 変換で次のスタイルの XPath 式を使用して行われます。

 select="/Workbook/Worksheet/Table/Row/Cell[NamedCell[@ss:Name='City']]

この特定の式は、 という名前の Cell である Named を検索します City。 スタイルシートの残りの部分はかなり簡単です。 詳細については、「XLToPO.xsl」を参照してください。

試してみる

これを実行するには、MSXML 3.0 をインストールして Northwind データベースを保持するだけです。 デモ コードは、次のようにSQL Serverにワイヤードされます。

   SQLConnection("server=localhost;uid=sa;pwd=;database=northwind");

Northwind データベースが他の場所にある場合は、このコードのビットを変更する必要がある場合があります。

PO.xsl スプレッドシートは、カタログ サービスが次の場所に配置されることを想定しています。

https://localhost/catalog/search.aspx

ローカル コンピューター上の catalog という仮想ディレクトリに Web サービス search.aspx、search.cs、XLToPO.xsl をインストールするか、スプレッドシートを別の場所を指すように変更する必要があります。

スプレッドシートを編集するには、保護をオフにする必要があります。保護は、[ ツール/保護 ] サブメニューを使用して行うことができます。

次の手順

サプライヤーのカタログ サービス バインドを UDDI に格納するのが理想的です。 これを行う VBA コードがコメントアウトされています。 認識された Catalog Service serviceInfo (serviceKey) を検索し、それが見つかると、serviceDetails に含まれる accessPoint を使用します。 このデモで使用している擬似カタログ API は、UDDI で既知のサービスの種類として登録されていません。

Office スマート タグを使用して同様のことを行うのが楽しい演習です。 その他の情報については、スマート タグ SDK に関 https://msdn.microsoft.com/office/ するページを参照してください。