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/ するページを参照してください。