実践 クライアント/サーバーデータベースソリューション 第16回 第18回

第17回
Access 2000はType x DB Serverのクライアント開発ツールになりえるか?

Access,VB6,Jetデータベースエンジンを利用した
C/Sシステム構築に関する考察,実験および実践



秋月巌ソリューション事務所
秋月 巌 AKIZUKI,Iwao


Access 2000はType x DB Serverのクライアント開発ツールになりえるか?


答え---
なりえる。また、Microsoft SQL Serverのクラアント開発ツールにもなりえる。

Microsoft Access 2000

 Microsoft Office 2000最終評価版が、編集部から送られてきた。付属のドキュメントにはベータ版ソフトウェアを使用していると書いてあるが、多分、ベータ版よりは精度の高いレビジョンだと思う。昔はベータ版というと仕様がフィックスしていたが、最近ではベータ版を配布しながら仕様を変更する。仕様が最終的に確定するのはリリース候補版においてである。
 受け取ったMicrosoft Office 2000最終評価版はリリース候補版直前のもののような気がする。別にはっきりとした根拠はないが、リリース時期との兼ね合いやプロダクトのもつ匂いがそう感じさせるのだ。

ベータ版の悲劇は起こるのか?

 Internet Explorerのような、ベータ版が一般公開される製品をまめにインストールしてきた方は気づいているかもしれないが、Microsoftの製品は、最後のベータ版がリリースされた後の数ヶ月間で飛躍的に品質が向上する。あんなにひどいベータ版を配布しなければ、もっと品質に対するイメージが変わるかもしれないだけに残念である。
 私はInternet Explorer 3.0以降、ベータ版をマシンにインストールしない方針を貫いていた。ベータ版の品質の低いことだけが問題なのではなく、ベータ版のインストールによって、マシンの環境が破壊されるのがいやだったのである。もっとも、Internet Explorer 3.0とVisual Studio 97の以降、Microsoftから革新的なテクノロジーが発表されないというのも理由のひとつである。あえて言えば、DHTMLとVisual InterDev 6.0のDTCだということになるが、どちらもインパクトとその必要性に欠ける。

今回はテスト専用環境で…

 今回、Microsoft Office 2000最終評価版をインストールしたのは、新製品の発売直後で手元にテスト環境が残っていたからである。
 とりあえず、最終評価版に付属していた『これでわかった! Office 2000新機能ガイド』を丹念に読んでみる。この本はよく見ればMicrosoft Pressの発行ではないか。おまけに表紙に堂々と「Microsoft公式解説書」と記載されている。私はMicrosoft Pressの本はすべてMicrosoftの公式解説書だと理解していたのだが、わざわざ書いてあるところをみると、そうでないものもあるのかもしれない。
 この本には、新しいMicrosoft Officeのバージョンアップポイントが的確に解説されている。さすが、公式解説書である。これを読めば、既存のMicrosoft Officeユーザーがバージョンアップすべきかどうかということが、すぐに判断できる。そう「既存のMicrosoft OfficeユーザーはOffice 2000にバージョンアップする必要はない」ということがすぐに理解できる、優れた本なのだ。

最大のトピックはWeb対応

 Microsoft Office 2000の最大の目玉は、Digital Nervouse Systemを睨んだWeb対応ということになるだろう。しかしこれを誰が使うのか、私にはよくわからない。世間が騒ぐほどにイントラネットは普及していないし、Microsoftのイントラネット技術を、荒野とも言えるインターネットで使用する勇気のある人はそういない。
 もっとも、イントラネットはいずれ普及するので、その時点でMicrosoft Office 2000の新機能は意味をもつことになるのかもしれない。だから「バージョンアップする必要はない」というのは、「今は、バージョンアップする必要はない」と言い換えるベきだろう。何も、こんな不景気のときにお金を遣わずに、景気がよくなってから、ゆっくりと考えればいいのである。もちろん、細部はよくなっているようなので、新規にMicrosoft Officeを購入するユーザーならば、わざわざ旧バージョンを探し出して買う必要はない。

しかし、Access 2000のC/S開発対応はすばらしい

 さて、さんざ不必要性を説いてから言うのもはばかられるが、もし、Microsoft Accessを使ってクライアント/サーバーシステムを作りたいと考えているならば、すぐにでもアップグレートすべきだ。
 Microsoft Access 2000はクライアント/サーバー開発システムとして、旧バージョンと比較にならないくらいに素晴らしい。とくにMicrosoft SQL Serverへの対応は秀でている。多くの設定が自動化された最新のMicrosoft SQL Server 7.0と組み合わせれば、クライアント/サーバーシステムの構築の簡易さは革命的に進歩したということができる。
 今までもMicrosoft Accessはアップサイジングツールを提供していた。このツールは最初は単体で販売され、次にはMicrosoft Access Developer Edition(当時は別の名称だったと思う)にバンドルされ、最後には無償でダウンロードが可能になった。アップサイジングツールは、Microsoft Accessのテーブルをエクスポート機能より、高精度にMicrosoft SQL Serverに移植できる。使いにくいツールだったが、その機能にとくに不満はなかった。しかし、アップサイズしたテーブルを、Microsoft Accessで今まで使用していたように扱うためには、テーブルをリンクする必要があった。しかし設定したリンクは壊れやすかったし、データを取得するために実行するクエリーの内容は絶望的だった。

旧バージョンは何が問題だったのか?

 本誌4月号が手元にある人は、83ページの拙稿を参照していただきたい。Microsoft AccessにリンクされたMicrosoft SQL Serverに次のような要求を行なうために、リスト1に示される5つのSELECT文を実行する。

SELECT titles.title, publishers.pub_name
 FROM publishers INNER JOIN titles 
 ON publishers.pub_id = titles.pub_id

 リスト1のような方法は、あまり好ましいとは言えない。Microsoft Accessはこのような方法をとることで、ネイティブのデータベースエンジンであるJetデータベースエンジンと、外部データベースエンジンとの扱いの差を最小限定に抑えているのである。つまり、Microsoft Accessのリモートデータベースとローカルデータベースの操作性の互換性に重点が置かれていた。
 これはMicrosoft Accessのリンクメカニズムが、テーブル単位で実装されているためである。テーブル単位でキーセットを取得し、クライアントで合成する。あまり賢いとは言えない方法だが、サーバーとの整合性は確保される。今までMicrosoft Accessがこの方法にこだわってきたのは、テーブル単位での対応を重視してきたからだろう。それにより、Microsoft Accessが備えているデータアクセスのメカニズムを、すべてそのまま利用することができる。

リスト1:ひとつのクエリーを実行するために、JetデータベースエンジンからODBC経由でMicrosoft SQL Serverが受け取ったSQL文
SELECT "dbo"."publishers"."pub_id","dbo"."titles"."title_id" 
    FROM "dbo"."titles","dbo"."publishers" 
    WHERE ("dbo"."publishers"."pub_id" = "dbo"."titles"."pub_id" ) 
go

SELECT "pub_id","pub_name"  
    FROM "dbo"."publishers"  
    WHERE "pub_id" = '1389' OR "pub_id" = '1389'
       OR "pub_id" = '0736' OR "pub_id" = '1389'
       OR "pub_id" = '0877' OR "pub_id" = '0877'
       OR "pub_id" = '0877' OR "pub_id" = '1389'
       OR "pub_id" = '1389' OR "pub_id" = '1389'
go

SELECT "title_id","title","pub_id"  
    FROM "dbo"."titles"  
    WHERE "title_id" = 'BU1032' OR "title_id" = 'BU1111'
       OR "title_id" = 'BU2075' OR "title_id" = 'BU7832'
       OR "title_id" = 'MC2222' OR "title_id" = 'MC3021'
       OR "title_id" = 'MC3026' OR "title_id" = 'PC1035'
       OR "title_id" = 'PC8888' OR "title_id" = 'PC9999'
go

SELECT "pub_id","pub_name"  
    FROM "dbo"."publishers"  
    WHERE "pub_id" = '0877' OR "pub_id" = '0736'
       OR "pub_id" = '0736' OR "pub_id" = '0736'
       OR "pub_id" = '0736' OR "pub_id" = '0877'
       OR "pub_id" = '0877' OR "pub_id" = '0877'
       OR "pub_id" = '0877' OR "pub_id" = '0877'
go

SELECT "title_id","title","pub_id"  
    FROM "dbo"."titles"  
    WHERE "title_id" = 'PS1372' OR "title_id" = 'PS2091'
       OR "title_id" = 'PS2106' OR "title_id" = 'PS3333'
       OR "title_id" = 'PS7777' OR "title_id" = 'TC3218'
       OR "title_id" = 'TC4203' OR "title_id" = 'TC7777'
       OR "title_id" = 'TC7777' OR "title_id" = 'TC7777'

ODBC Directやパススルークエリーの限界

 もちろん、DAOにODBC Directがあることは知っている。ODBC DirectはJetデータベースエンジンをロードすることなく、リモートデータベースへのアクセスを実現する。先の記事でも紹介しているように、ODBC Directはリスト2のようなシンプルなクエリーを送信する。ODBC DirectはRDOをDAOのインターフェイスでラップしたものである。そのパフォーマンスは申し分ない。
 また、パススルークエリーも性能的には、最高速の部類の属する。Microsoft SQL Serverが受け取るクエリーも、リスト3のように実行したクエリーそのままである。
 しかし、ODBC Directにもパススルークエリーにも、Microsoft Accessから使用する上で、致命的な欠点がある。それはMicrosoft Accessのフォームとの連結が困難だという点である。確かにパススルークエリーやODBC Directを使用することで高速にSQLを実行することができる。しかし、Microsoft AccessはフォームとRecordsetオブジェクトが一体化した構造をしている。フォームに配置したオブジェクトにレコードセットの内容を表示するには、フォームのレコードソースプロパティによって得られるレコードセットに値を格納しなければならない。しかし、レコードソースプロパティに選択できるのは、フォームが格納されているMDBファイルに格納されているテーブルとクエリーだけである。

リスト2:ODBC Directの使用時に、ODBC経由でMicrosoft SQL Serverが受け取るSQL文
sp_cursoropen 0, _
 "SELECT titles.title, publishers.pub_name" & _
 "FROM publishers INNER JOIN titles ON publishers.pub_id = titles.pub_id" , 4, 1, 1
go
sp_cursorfetch 19225392, 2, 1, 100
go
sp_cursorfetch 19225392, 2, 1, 100
go
sp_cursorclose 19225392

リスト3:パススルークエリーの使用時に、ODBC経由でMicrosoft SQL Serverが受け取るSQL文
SELECT titles.title, publishers.pub_name 
 FROM publishers INNER JOIN titles ON publishers.pub_id = titles.pub_id

(旧バージョンは)フォームとの連結は困難だった

 パススルークエリーやODBC Directをアクセスのフォームに表示するには、Microsoft Accessが用意した表示コントロールを使わずにActiveXコントロールを使用するか、そうでなければテンポラリのテーブルをMDBファイルに作成することになる。
 ActiveXコントロールを使用する方法は、根本的な解決策だとは言えるが、それならばVisual Basicを使ってプログラミングした方がいい。テンポラリファイルをローカルテーブルとして作成する方法は、データ表示のためのプログラミングが複雑になること以上に、データ更新のメカニズムを自力で実装しなければならないことである。コントロールにユーザーが入力した内容は、テンポラリテーブルに書き込まれるだけなので、それをプログラムによってサーバーに反映させる必要があるのである。
 だから、これらのリモートデータアクセスを高速化するための手法は、結局Microsoft Accessのメリットを失ってはじめて実現できるものだったのである。つまり、プログラミングの便宜をはかってデータアクセス方法に問題のあるリンクテーブルを使用するか、あるいはデータアクセスのパフォーマンスを追及するかの選択が迫られたのである。

OLE DBを使用したリモートデータベースアクセスが飛躍的に進歩

 今までのMicrosoft Accessは、リモートデータベースへのアクセスにODBCに使用していた。だからリンクテーブルもODBC DirectもODBCデータベースにアクセスするための仕掛けである。ODBCという意味で、Microsoft Access 2000のリモートデータベースへのアクセス機能は強化されていない。ODBCデータベースに接続するためには、相変わらずテーブルリンクやODBC Directを使用する必要がある。
 しかし、OLE DBを経由するリモートデータベースにおいて、Microsoft Access 2000は圧倒的に強化された。ここで断わっておきたいのは、OLE DBがODBCよりも高速だとは限らないということである。「OLE DBはODBCを経由しないから高速だ」という言う方をされることがあるが、それを言うなら、「ODBCはOLE DBを経由しないから高速だ」ということになってしまう。これは、正確に表現するならば、OLE DBを使用してデータアクセスする場合、ODBC for OLE DBを使用せずにネイティブのOLE DBプロパイダを使用すれば高速だということである。言い換えれば、ADOを使用した場合は、ODBCを使用しない方が高速であるということになる。だから、公平に扱うためには、ネイティブなOLE DBプロパイダを使用したADOと、RDOのデータアクセス速度を比較すべきである。もちろん、これでもRDOとADOの個体差が出てしまうが、それぞれがODBCとOLE DBに対応したデファクトスタンダードのインターフェイスなのだから、その方がより現実的な比較だと言える。今月号から本誌で開始する連載「SQL Server 解体新書」でも、いずれこのようなテストを扱うつもりなので、期待していただきたい。
 ちなみに、OLE DBはユニバーサルなデータベースインターフェイスとして策定されたもので、クライアント開発者の便宜のために用意されたものではない。それでも実装が新しいだけに、高速化されている可能性は高い。

Microsoft SQL Serverにアクセスするには、MDBでない別のプロジェクトファイルを作成する

 Microsoft SQL Serverにアクセスするためには、今までのようなMDBファイルではなく、ADPファイルを作成する(図1)。ADPファイルはフォームやモジュールのほかに、Microsoft SQL Serverへのリンク情報が格納されているという意味では、テーブルリンクされたMDBファイルと変わらない。しかし、テーブルリンクMDBファイルが、ネイティブテーブルをエミュレートするのに対して、ADPファイルはリモートデータベースアクセスに最適化されている。実は、最初、ADPファイルの作成機能を見たときには、実は単に自動的にリンクを貼るだけなのではないかと疑ったのだ。しかし、MDBファイルを使ったときには、フォームに連結されるRecordsetオブジェクトはDAOのそれだが、ADPファイルを使用したときにはADOのRecordsetオブジェクトである。
 MDBファイルを扱うMicrosoft Access 2000とADPを扱うMicrosoft Access 2000は、その操作性こそ共通だが、ほとんど別もののように私には見える。同じSQL文を操作するにしても、JetデータベースエンジンとMicrosoft SQL Serverが別もののように…

図1:作成するファイルタイプを選択
図1:作成するファイルタイプを選択

ADPプロジェクトはMicrosoft SQL Server専用ではない

 Microsoft AccessのOLE DBを使用したデータアクセスは、一見、Microsoft SQL Server(後述するMSDEを含む)専用に見える。実際、リモートデータベースアクセス用のプロジェクトを新規作成すると、アクセスするMicrosoft SQL Serverのサーバー名を聞いてくる。しかし、ここでダミーの内容を入力しておいて、新しく実装されたFormオブジェクトのRecordsetプロパティを使うことで、プログラムコードで作成したADOのRecordstオブジェクトをフォームに連結することができる。この場合、アクセスした結果はMicrosoft Accessの表示コントロールで表示することができ、また、そのコントロールで編集した内容がサーバーデータベースに反映される。つまり、テーブルリンクを使用した場合と同様に扱うことができる。
 たとえば、リスト4のようなプロシージャをフォームのLoadイベントで実行することで、任意のレコードセットの内容をフォームに表示することができる。
 次の2行のコードは、作成したADOのRecordsetオブジェクトを、Employeesフォームのレコードソースに指定している。

rs.Open "Select * From Employees", _
 con, adOpenKeyset, adLockOptimistic
Set Forms("Employees").Recordset = rs

 フォームに配置されているテキストボックスにRecordsetオブジェクトのフィールドを連結しているのは、次の2行である。

EmployeeID.ControlSource = "EmployeeID"
LastName.ControlSource = "LastName"

 この2行を記述せずに、テキストボックスの「ControlSource」プロパティに事前にセットしておく方法もあるが、この場合、一瞬だがフォームのロード時に“#Name?”という文字列がテキストボックスに表示されてしまう。これは、Recordsetオブジェクトがフォームに指定されるまでの間、該当するフィールド名が見つからないことから発生する現象である。

リスト4:任意のレコードセットの内容をフォームに表示する
Private Sub Form_Open(Cancel As Integer)
    Set con = New ADODB.Connection
    con.Open "Provider=SQLOLEDB.1;Persist Security Info=False;User ID=sa;Initial Catalog=Northwind;Data Source=SANTIAGO"
    Set rs = New ADODB.Recordset
    rs.CursorLocation = adUseClient
    rs.Open "Select * From Employees", con, adOpenKeyset, adLockOptimistic
    Set Forms("Employees").Recordset = rs
    EmployeeID.ControlSource = "EmployeeID"
    LastName.ControlSource = "LastName"
End Sub

Microsoft Access 2000は巨大な入出力コントロール

 このような処理は、Microsoft Accessを巨大なユーザーインターフェイスビルダーと見立てているのと同じである。レポートビルダーまで付いている、強力な入出力コントロールである。データベースアクセスを行なっているのは、あくまでもADOであって、Microsoft Accessではない。
 Microsoft Access 2000の登場で、私はデータベースプログラミングにおいて、開発環境としてのVisual Basicは不要になるかもしれないと考えている。Office 2000 Developerには、再配布ライセンスも付属しているので、コンパイルして配布すれば、Microsoft Access 2000をユーザー分だけ購入する必要もない。
 Visual Basicには、ネイティブコンパイラや、各種COMコンポーネントの作成機能があるのは魅力だが、データベースシステム開発者がこれらの機能を使用しなければならない機会はそれほど多くない。
 また、言語としてのVBAはVisual Basicよりも格が下だという印象をもつ人もいるかもしれない。しかしVisual Basic 3.0の時代にはVBAの方が先行していた。当時のVBAは、Visual Basic 4.0の言語エンジンだったのだから、当然である。Visual Basicが5.0にバージョンアップしたとき、VBAのアップデートは見送られ、今度のMicrosoft Access 2000では、バージョン6.0である。
 現在のVBAとVisual Basicの言語エンジンの関係がどうなっているのか私はわからないが、少なくとも言語仕様の差という理由で現実的な優劣があるとは考えていない。それでなくても、Visual Basicはすでに十分に大きすぎる言語仕様なのだ。
 もっとも、データベースベンダーが提供するミドルウェアを利用し、ADOを使用しないケースでは、Microsoft Accessのメリットはまったくない。それだったら、当然Visual Basicを選択すべきである。

Microsoft SQL Serverと統合された環境

 Microsoft Access 2000をMicrosoft SQL Serverクライアント開発ツールとして特徴づけているのは、単なるOLE DBクライアントではなく、SQL-DMOクライアントでもあることである。SQL-DMOはMicrosoft SQL Serverが自分自身をCOMオブジェクト公開する仕様であり、これを使ったプログラミングは本誌でも紹介されたことがある。Microsoft SQL Serverの管理ツールであるSQL Enterprise Managerが、代表的なSQL-DMOクライアントアプリケーションであることからも、その強力な仕様が理解できるだろう。
 SQL-DMOクライアントであることで、Microsoft Access 2000の操作環境から、Microsoft SQL Serverのテーブル、ストアドプロシージャ、ビュー、データベースダイアグラムの作成と変更ができる。これらの要素はフォームやモジュールといったローカルの要素と同様に扱うことができ、開発環境内で完全に統合されている。
 今までにMicrosoft AccessでMicrosoft SQL Serverのテーブルを作成するには、データベースファイルに一般的なテーブルを作成しておいて、それをエクスポートするか、あるいはアップサイジングツールを使う必要があった。しかし、Microsoft Access 2000ではMicrosoft SQL Serverのテーブルをローカルテーブルと同じような操作で直接作成できる。SQL Enterprise Managerほどの十分な管理機能はないが、プログラマが必要とする操作の多くはMicrosoft Accessの環境から操作することができる。

これまで、Microsoft AccessはC/Sシステム開発ツールではなかった

 Microsoft Accessは、ユーザーが簡単にクライアント/サーバーシステムを開発できるツールであるという言い方をする人がいたが、今まで、これはほとんど嘘だった。確かにテーブルリンクすれば一応動くことは動いたが、それだったらJetデータベースエンジンを使ってファイル共有した方がよっぽど上等な代物だったのである。
 これは今までのMicrosoft Accessがクライアント/サーバーシステム開発ツールとしての制限を意味するのと同時に、高性能なクライアント/サーバーシステムを開発するには、制限を越えるための高度なスキルが必要だったことを意味する。クライアント/サーバーシステムの開発ツールでないものを、その用途に使おうとするのだから、不自然で難しいのは当然である。
 Microsoftの責任はMicrosoft Accessというプロダクトに問題があったのではなく(もちろん、プロダクトにも問題はあったのだが)、難しいことをいかにも簡単にできるかのように喧伝したことに問題があったのである。もっとも、クライアント/サーバーシステム用の開発ツールでないものを、その目的のために使うから難しいという事情はVisual Basicも変わらない。

ならば、C/Sシステム開発ツールなら話は簡単なのか?

 では、クライアント/サーバーシステム開発に特化したツールであるPowersoft Power Builderを使うと簡単に開発できるかというと、話はそれほど簡単ではない。Power BuilderやPowersoft Power++に搭載されているデータウィンドウは、私が知る範囲でもっとも優れたデータアクセスコンポーネントだが、そのアーキテクチャは決してシンプルではなく、また、私が使用した以前のバージョンでは多くのバグに悩まされた。しかし、最終的な柔軟性と可能性という意味では強力だった。
 Microsoft Access 2000のMicrosoft SQL Server対応は、データウィンドウほどのパワーには欠けるが、それでもデータベースアクセス専用ツールである強みは十分に発揮される。とくに優れているのは、十分な性能ではなく、低いスキルと少ない手間で、まあまあのものをいい加減に作成するポテンシャルの高さである。つまり、今まで嘘として語られてきたことが、70%程度の確率で真実になったのである。
 とくに今までは、Microsoft Access以上にMicrosoft SQL Serverで問題が発生することが多かった。Microsoft SQL Serverのようなデータベースサーバーは、自動車で言えばレーシングマシンのようなものである。その性能を引き出すためには、入念なセッティングが必要になる。しかし、最新のMicrosoft SQL Serverでは、かなりの部分がセルフチューニングされるようになった。70%という数字は、Microsoft SQL Serverの進歩も含んでいる。
 ちなみに今までのMicrosoft AccessでMicrosoft SQL Server 6.5のテーブルリンクしたとしたら、成功の可能性は10%にも満たないはずである。もっとも、70%とは現在クライアント/サーバーシステムを導入しているユーザーの70%という意味ではない。クライアント/サーバーシステムを導入する可能性のあるユーザーの70%という意味である。現在、すでに導入しているような比較的大規模のユーザーのケースでは、その成功率は40%くらいまで下落するだろう。それはMicrosoft Access 2000やMicrosoft SQL Serverの標準設定に問題があるのであり、それを克服したいのならば、それなりのスキルが必要になる。

AccessはType x DB Serverクライアントになり得るか?

 今回、Microsoft Access 2000の評価をしたのは、Microsoft SQL Serverとの相性を探ることよりも、本連載で開発しているType x DB Serverのクライアントとしての適正を探るためであった。私は今度のMicrosoft Accessが、Visual Basicのデータ連結機能をサポートすることを期待していたのだが、それは果たされなかった。しかし、Recordsetオブジェクトのフォームへの連結機能がサポートされているので、それを利用してクライアントアプリケーションを開発することができる。クライアントライブラリに実装したコードの何割かは無駄になるが、作り直せばいいことだ。Recordsetオブジェクトを直接表示コントロールに連結する機能は、Visual Basicでもサポートしていないので、このような展開になるとは想像もしていなかった。それでも、私はType x DB ServerのクライアントをVisual Basicではなく、Microsoft Accessで作成できることを喜んでいる。連載開始以来、登場の機会もないのにAccessの名前が本連載のサブタイトルに入っていたのが、嘘にならなかったことにほっとしている。
 Microsoft Access 2000は、この1年間に発売されたMicrosoftの開発製品の中で出色のものだと思う。Microsoft Accessはバージョン2の完成度が高かったが、それ以来の進歩だと言うことができる。ただ、伝統的に障害の多いプロダクトなので、それで嫌気がさす可能もある。
 まだ十分な評価は終了していないが、Microsoft SQL Server 7.0とそれに付属するOLAP Serviceも期待できる製品のように思えるので、コンビネーションに期待したい。ただ、これらを使ったプログラミングをしてみたいという衝動にかられないのは、どういうわけだろう? その完成度の反面、Delphiの最初のバージョンやVisual Basic 5.0に漲っていた情熱が感じられないからだろうか。それでも、Microsoftが使えるソリューションを提供したことは評価しよう。Microsoftだって、きっといつまでも子供のままではいられないのだ。


VB Magazine ライブラリ| Visual Basic WorkGroup
int21 ホームページ| PCDN ホームページ

PCDN
Copyright (c) 1998 int21 CorporationAll Rights Reserved.
For questions or comments, please send mail to: pcdn@int21.co.jp