長谷川 裕行 (はせがわ ひろゆき)
有限会社 手國堂 代表取締役
http://www.hirop.com/
テクニカルライターとして活躍。プログラミングに関する著書多数、DB Magazineなどにも多くの記事を提供している。 |
コンピュータ・ネットワークを利用している組織は多いでしょう。ネットワーク環境で業務アプリケーションを利用すれば、多数のユーザーが共通のデータを扱って処理を進められます。今回は、ネットワーク環境でデータベースを利用するアプリケーションについて考えてみましょう。
まず、ネットワークの基本事項について簡単に触れておきます。
- ネットワークによるデータの共有 -
すべての処理が1台のコンピュータの中で完結する状態をスタンドアロン(stand alone)といいます。ネットワークに接続されていない状態、あるいは接続されていても、ネットワークの機能を使っていない状態です。
これまでの解説は、すべてスタンドアロンの状態を前提としてきました。
ネットワーク環境では、複数のコンピュータが1つのデータを共同利用することが可能になります。業務処理に用いるデータは、基本的に様々な立場のユーザーから利用されることが多いため、ネットワークは非常に有用です。
例えば、商品や顧客、得意先などの基礎データは、実際に販売を行う部署だけではなく、経理部門や管理部門でも必要になります。販売や仕入れの状況は、日々のデータ入力は担当部門が行いますが、別の部門が集計や分析を行うためにも利用されます。
- 集中型と分散型 -
コンピュータ・ネットワークには、大きく分けると集中型と分散型の2つの形態が存在します。
・ |
集中型ネットワーク
ホストと呼ばれる大型のコンピュータに、複数の端末装置がつながった形態がよく知られています。この形態では、ホスト・コンピュータがすべての処理を担当します。ディスクもメモリもCPUもすべてホストが集中管理しており、ユーザーは端末装置を通じてホストの能力を分かち合いながら作業します。
汎用機やオフコンでCOBOLを使って業務用アプリケーションを組んでいた方は、このスタイルのネットワークをよくご存じでしょう。
|
・ |
分散型ネットワーク
一般にクライアント・サーバー型と呼ばれる形態です。コンピュータはハードディスクなどの資源をネットワーク上に公開するサーバー(server)と、それを利用するクライアント(client)に役割が分かれます。
サーバーの役割はホスト・コンピュータに似ていますが、サーバーはネットワークの中心として1台だけ存在するわけではありません。クライアント・サーバー型ネットワークの特徴は、サーバーが複数存在し、互いに資源を利用しあえるという点にあります。
独自の処理能力を持ったコンピュータ同士が、互いに資源を共同利用しあって、処理を進めていきます。
|
- WindowsによるパソコンLAN -
本書のテーマはVBで業務用アプリケーションを作ることなので、パソコン+Windowsという環境を前提とします。その場合、クライアント・サーバー型のネットワークを利用することになります。
Windowsを中心としたネットワークは、特に社内など狭い範囲を接続するLAN(Local Area Network)で威力を発揮します。大容量で高速なハードディスクを搭載したファイルサーバー、複数のプリンタを管理するプリントサーバーなど、各々のコンピュータの強みを活かした役割を与え、それを多数のクライアントマシンが共同利用する形です。
コンピュータの台数が多く、取り扱うデータの量も使用頻度も高い場合には、全体を汎用機やミニコンピュータで管理し、さらに各部署単位などでワークステーションやパソコンをサーバーとして配置するというスタイルが一般的です。
コンピュータも取り扱うデータもそこまで多くない場合は、すべてをパソコンでまかなうことも可能です。実際、Windows 2000 ServerをサーバーOSに使って、100台規模のネットワークを管理することも可能です(もちろん、サーバーとするコンピュータに大きな処理能力が必要です)。
Windowsネットワークには、大きく分けて2つの形態があります。Windows 2000 ServerまたはAdvanced Serverを利用したドメイン方式と、Windows MeやWindows 98、Windows 2000 Professionalを利用したワークグループ方式です。
- ドメイン方式 -
Windows 2000 ServerとAdvanced Serverには、“ドメイン”と呼ばれる単位でコンピュータを管理する機能が備わっています。ここでいうドメインはTCP/IPネットワーク(インターネットやイントラネット)で用いるドメインとは異なります(コラム参照)。
1つのドメインには、最低1台のドメイン・コントローラと呼ばれるコンピュータが必要です。ドメイン・コントローラは、ドメイン内のコンピュータやユーザーの操作権限などを集中管理します。
“信頼関係”という概念によって、他のドメインと連携させることも可能です。これによって、例えば経理部のユーザーが営業部のデータにアクセスすることはできても、その逆のアクセスはできない――といった形が作れます。
ドメインの中に、後述するワークグループを複数設定することも可能で、部の中の課、課の中の係など小さなネットワークをドメインでまとめてしまえます。
このようにドメインを使うと、非常に大規模で複雑なネットワークを構成できます。しかし、設定と管理も難しくなってきます。
図1:ドメイン方式
- ワークグループ方式 -
ネットワーク全体を管理する機構を持たない、ピア・ツー・ピア方式によるネットワークです。
ドメイン方式ではドメイン・コントローラがコンピュータとユーザーを一括管理しますが、ワークグループでは個々のコンピュータ単位でユーザーを管理し、コンピュータは同じグループ内で公開されている資源(ディスクとプリンタ)を相互に利用できます。
厳密なユーザー管理ができないため大規模な業務では不安ですが、小規模な構成なら設定も容易なため気軽に運用できます。Windows 2000 Serverなどの管理用OSは不要で、Windows Me、Windows 98、Windows 2000 Professionalで利用できます。
図2:ワークグループ方式
Windowsのドメインとインターネットのドメイン
TCP/IPネットワークでいうドメインは、ネットワークを構成する機器の集合であり、IPアドレスによって識別されます。一方Windows 2000のドメインはコンピュータとユーザーの集合を管理する単位で、ドメイン名によって識別されます。
Windows 2000のドメインとTCP/IPネットワークのドメインは、基本的に互換性がありません。が、Windows 2000にActiveDirectryという機能をインストールすると、Windows 2000のドメインをTCP/IPのドメインとしても扱えるようになります。
|
ネットワークでデータベースを扱う場合、その管理方法を考えておかなければなりません。
- データベース管理 -
ネットワークでデータベースを扱う場合、一番問題となるのがデータベース管理機構です。大規模な業務処理では、SQL ServerなどのRDBMS(Relational Database Management System:リレーショナル・データベース管理システム)を用い、大量のデータを一括管理させる必要があります。
が、少量のデータでわずかなクライアントからアクセスするだけの場合、本格的なRDBMSではかえって効率が悪くなります。小規模な業務処理では、データベースにAccessのmdbファイルを使い、ADOを介してアプリケーションからアクセスする形でも十分でしょう。
データベースを接続してしまえば、アプリケーション内の処理はネットワークであれスタンドアロンであれ、またRDBMSが何であれ変わりません。このあたりは、アプリケーションの規模やネットワーク環境、ユーザー数などを元に決めればよいでしょう。
- 規模に応じてデータを分散する -
ここでは、Windows MeやWindows 98で構成した小規模なワークグループ方式のLANを想定します。
サーバーには、大きく分けてファイルサーバーとプリントサーバーの2種類が存在します。ファイルサーバーはハードディスクのフォルダを公開し、そこに共有したいファイルを保存します。プリントサーバーはプリンタを公開します。
ファイルサーバーもプリントサーバーも、ネットワーク内に複数配置できます。特にファイルサーバーは、データファイルだけを保存するコンピュータ、アプリケーションを保存するコンピュータ、データベースを保存するコンピュータ…と役割ごとに分けると、負荷が分散されて効率的です。
但し、小規模なネットワークでそれを行うと管理が面倒になり、混乱する場合もあります。
ネットワークについて基本的な事柄を紹介しました。あまり詳しく書くときりがないので、この辺にしておきます。ネットワーク構築の詳細については、別途書籍などを参考にしてください。
ネットワークであれスタンドアロンであれ、アプリケーションの内部処理は変わりません。問題となるのは「サーバーに保存されたデータベースを、複数のクライアントから参照する」ための仕掛けです。
- ネットワーク環境の前提 -
以降の説明では、以下のような構成を前提にします。
・ |
ファイルサーバー
コンピュータ名:Main
ハードディスクの“C:\Data\Public”を共有名“Public”として公開。
mdbファイルを含むデータとアプリケーションを保存。
|
・ |
業務
販売管理
ファイルサーバー“Main”に“Hanbai.mdb”というデータベース・ファイルを保存。
クライアントのアプリケーションから“Hanbai.mdb”をオープンし、販売データの入力や在庫の更新、集計などの処理を行う。
|
- パスの指定方法 -
データベースを操作するアプリケーションは、クライアントに保存されているものとします。その場合、アプリケーションからデータベースのパス(存在する場所)を示す作業が重要になります。
スタンドアロンの場合なら、自分自身の存在するパスにデータベース・ファイルを保存し、“App.Path”(AppオブジェクトのPathプロパティ)でそれを取得できます。が、ネットワーク環境では、ファイルサーバー上のパスを取得しなければなりません。
ネットワーク上のパスは、通常UNC表記で書き表します。UNC“Universal Naming Convention”の略で、
という形式で表記します。
コンピュータ“Main”の“C:\Data\Public”(共有名“Public”)に保存されている“Hanbai.mdb”なら
と指定できます。 |
|
ネットワークでは、クライアントの環境がすべて同じであるとは限りません。異なるコンピュータから、1つのデータベースの場所を示す手段が必要です。
- 柔軟なパス指定を考える -
データベース・ファイルを保存しているパスは固定されているので、UNC表記を使って直接パスを指定するのが最も簡単です。しかし、この方法には欠点があります。プログラム中に絶対パスを埋め込むと、万一データベースの保存先が変更された場合、アプリケーション自体を作り替えなければなりません。
データベースの場所はそう変更されるものではありませんが、絶対変更されないという保証もありません。特に開発~テスト環境と実行環境が異なる場合、実行時に問題が発生して作り直し…などということもあり得ます。環境の変更に対して、できるだけ柔軟に対処できるようにしておきましょう。
- 本来ならレジストリを使う -
データベースのパスなど、アプリケーションの基本的な設定項目は、本来ならレジストリに記録するのが正当な方法です。しかし業務用アプリケーションの場合、仕様変更などでリリース後に何度も改版される場合があるため、レジストリを頻繁に書き換えることになり、ヘタをするとWindowsが不安定になることもあり得ます。
また、レジストリの内容を確認するには、レジストリエディタ(regedit.exeまたはregedt32.exe)でエントリを検索するなど、開発途中の確認にも手間がかかります。商用パッケージのようにあらゆる環境で使用される場合はともかく、組織内の限定された範囲だけで使用されるアプリケーションは、もっと簡単な仕掛けで構いません。
- 設定用ファイルを使う -
ここでは、テキストファイルにデータベース・ファイルのパスを記録しておき、アプリケーションは起動時にそれを読み込んで処理をする――という形にしてみます。
テキストファイルのパスだけが明らかになっていれば、データベース・ファイルはどこにでも配置できます。プログラムの中には、設定を記述したテキストファイルのパスを記録しておくことになります。
「プログラム内にテキストファイルのパスを埋め込むのなら、結局同じことじゃないか」と思われるかもしれません。しかし、プログラム内に埋め込む情報がデータベースのパスである場合と、データベースのパスを示すテキストファイルである場合とでは、事情は大きく異なります。
- 簡単で柔軟 -
テキストファイルは、アプリケーションと一緒に配布できます。インストール時にアプリケーションと同じフォルダに保存させたり、あるいは“My Documents”などWindowsに必ず備わっているフォルダに保存させたりできるため、プログラム内でパスを固定的に記録しても大きな問題とはなりません。
データベース・ファイルの場所やファイル名が変更されても、テキストファイルの記述を変更するだけで済みます。つまり、間接的にデータベース・ファイルの場所を指し示すことで、万一の変更に対処しやすくなるのです。
図3:設定用ファイルがデータベースの場所を示すようにする
上述のような環境を前提に、クライアントのアプリケーションが設定ファイルを用いてデータベースを参照するための処理を紹介しておきましょう。非常に単純です。
設定用のテキストファイルが“Hanbai.cfg”という名前で“C:\My Documents”に保存されているとします。
- 記号定数とグローバル変数 -
設定用テキストファイルのパスを示す記号定数と、そこから読み込んだデータベース・ファイルのパス名を保存する変数“strDbName”を宣言します。
この2行は宣言セクションに記述し、変数strDbNameはPublicキーワードを付けて、すべてのモジュールから参照できるようにしておきます。
リスト1:設定ファイルを示す記号定数の定義とグローバル変数の宣言
Const CFGPATH = _
"C:\My Documents\Hanbai.cfg"
Public strDbName As String |
- 設定ファイルの読み込み -
設定用テキストファイルの内容を読み込み、データベース・ファイルのパスを変数strDbNameに保存します。設定用のテキストファイルには、単に
のように、データベース・ファイルのパスをUNC表記で1行記述しているだけです。
リスト2:設定ファイルからデータベース名を取得するプロシージャ
Public Sub SetDbName()
Open CFGPATH For Input As #1
↑設定ファイルをオープン
Do Until EOF(1)
Input #1, strDbName
↑設定ファイルから変数strDbNameに
パス名を読み込む
Loop
Close #1 ←必ずクローズする
End Sub |
- 初期化処理で呼び出す -
アプリケーションの初期化処理で、上記のプロシージャSetDbName(リスト2)を呼び出し、データベース・ファイルのパスを取得して、グローバル変数strDbNameに保存します。
以降、strDbNameを参照すれば、データベース・ファイルのパスを利用できます。
アプリケーションが多数のフォームで構成される場合、リスト1とリスト2は標準モジュールに記述し、どのコードモジュールからも参照できるようにしておきます。リスト3のForm_Loadプロシージャは、アプリケーションのメインフォーム(起動時に表示されるフォーム)に設定します。
リスト3:初期化処理
Private Sub Form_Load()
SetDbName
End Sub
|
- 設定ファイルをアプリケーションと -
- 同じフォルダに保存する場合 -
設定用のテキストファイルをアプリケーションと同じフォルダに保存するなら、リスト1とリスト2を、それぞれリスト4とリスト5のように変更すればよいでしょう。この処理では、“アプリケーションがディスクのルート(¥)に保存されない”という前提となっています。
リスト4:設定ファイルを示す記号定数の定義とグローバル変数の宣言
Const CFGNAME = "Hanbai.cfg"
Public strDbName As String |
リスト5:設定ファイルからデータベース名を取得するプロシージャ
Public Sub SetDbName()
Dim ConfigPath As String
ConfigPath = App.Path & "\" & CFGNAME
Open ConfigPath For Input As #1
↑設定ファイルをオープン
Do Until EOF(1)
Input #1, strDbName
↑設定ファイルから変数strDbNameに
パス名を読み込む
Loop
Close #1
End Sub
|
レジストリを使用する場合は、SaveSettingとGetSettingステートメントを使います。参考までに、これらのステートメントの使用方法を紹介しておきましょう。
- レジストリの基本 -
レジストリは、
アプリケーション セクション キー 値
という形で設定します。アプリケーションは、その設定を使用するアプリケーション名またはプロジェクト名です。最終的に“キー=値”という形で記録され、キーはその種類ごとにセクションでまとめます。
- レジストリの記録~ -
- SaveSetting ステートメント -
書式
SaveSetting appname, section, key, setting
appname:アプリケーション
section:セクション
key:キー
setting:値
上述のような環境で、アプリケーション名が“Zaiko”である場合、以下のようにしてレジストリにデータベース・ファイルのパスを記録できます。
SaveSetting appname := "Zaiko", _
section := "Startup", _
key := "DbName", _
setting := "\\Main\Public\Hanbai.mdb"
上の例では、
アプリケーション:Zaiko
セクション:Startup
キー:DbName
値:"\\Main\Public\Hanbai.mdb"
という形で記録されます。
- レジストリの取得~GetSetting 関数 -
書式
GetSetting(appname, section, key)
変数strDbPathにレジストリ
アプリケーション:Zaiko
セクション:Startup
キー:DbName
の値を取得するなら、以下のようにします。
strDbPath = GetSetting(appname := _
"Zaiko", section := "Startup", _
key := "DbName")
ネットワーク環境でクライアント・アプリケーションからデータベースを共有する方法について、紹介してきました。どのようなクライアント環境からでも同じように共有フォルダのパスを参照できれば、あとの処理はスタンドアロンの場合と変わりません。
ただ、複数のユーザーが1つのデータを共有するネットワーク環境では、スタンドアロンでは気にかける必要のなかったことに、注意を払う必要も生じます。次回、ネットワーク・アプリケーション開発の注意点などを取り上げます。
|