ネットワークとハイパーカード

オフィスでのコンピュータ活用はネットワーク抜きでは考えられない。手軽にネットワークを構築できるマッキントッシュの利点を生かして、ハイパーオフィスを実現しよう。

ネットワークはパワーだ

アメリカの雑誌に、CIAがインターネットを導入するようになったという記事がでていた。元来スパイというのは自分の持っている情報を仲間と共有したがらなかったのだけれど、こういうシステムが出てくると、取り残されないために、先を争ってオンライン情報を利用しているのだそうだ。

コンピュータの本当の力は、高速な計算や高機能な文書作成能力などではない。ネットワークで他のマシンと接続され、情報を共有できるコミュニケーションツールとなって初めてその真価が発揮される。三人寄れば文殊の知恵というわけで、メンバーの知識を相互に交換できるような環境の構築がオフィスシステムの目指すべき所だ。

しかし、パソコンのネットワーク化率はアメリカで52%に達するのに対し、日本ではわずか8.6%に過ぎない。コンピュータの利用は、文書作成や集計などの単独利用が中心であるように思う。日本のオフィスのインテリジェント化はまだこれからだ。

マッキントッシュは他の機種に比べネットワークを構築しやすい。オフィスでは、高価なソフトを導入するよりもまずマシンの台数を増やしてネットでつなぐのが先決である。その結果として残りの予算が少なくなってしまうのならば、ハイパーカードで処理システムを作ればよい。今回は、ハイパーカードをネットワーク環境で活用する手段について検討してみる。

ファイルの共有とローンチャ

ネットワーク活用の第一歩はファイル共有である。住所録、スケジュール表など、全員がよく使うファイルをサーバーに置き、どこからでも利用できるようにするだけで、オフィスの効率は断然違ってくる。

しかし、ただファイルを公開しただけでは、まだ使いやすい環境とは言えない。必要なファイルに簡単にアクセスできる仕組みが用意されないと、宝の持ち腐れになる恐れがある。第1回で取り上げたローンチャ(HyperLauncher)にファイルを登録し、各コンピュータに用意しておけば、この点も改善されるはずだ(*注1)。

これでユーザーは便利になるが、管理する側には少し問題が残る。ローンチャはファイル/フォルダの名称や位置を登録するものだが、これらはシステムの進化にあわせて変更されることが多いのだ(*注2)。こうなると、せっかく登録したローンチャが役に立たなくなる。かといって、変更に合わせて毎回ネットワーク上の全ローンチャを書き換えるというのは大変な作業だ。

これを解決するために、共有ファイルやフォルダの名前をグローバル変数に登録し、ボタンではこの変数を使ってファイルを起動することにしよう。つまり

  on mouseUp
    global gFileName, gAppName
    open gFileName with gAppName
  end mouseUp

のようにするわけだ。これならば、ファイルを別のフォルダに移動しても、アプリケーションがバージョンアップして名称が変わっても、個々のボタンに手を加えることなく、gFileNameやgAppNameの定義を変更するだけでよい。そして、この変数を外部ファイルによって定義するようにしておけば、定義ファイルを書き換えるだけで、全てのローンチャがこれらの変更に一発で対応できるようになるはずである(図1)。

do命令とファイル/フォルダの抽象化

ここで威力を発揮するのがハイパートークのdo命令だ。doというのは特殊な命令で、命令を定義した<文>を引数として実行する「メタ命令」である。例えば

put "go next cd" into str
do str

とすると、strに納められた“次のカードに移動する”という命令がdoによって実行されるのだ。命令文が変数になるのがミソである。変数なら外部から中身を与えることができる。つまり実行内容を前もって決めておかなくてもよいというわけだ。しかも変数には複数行の<文>を納められるから、do命令ひとつで大がかりな作業をすることも可能なのである。

これを応用すると、柔軟な初期設定の仕組みができあがる。まずローンチャで使うグローバル変数の定義命令をサーバー上のファイルに保存しておく(リスト1)。そしてスタックの起動時にその内容を変数strに読み込んでdo strで実行する。こうしてファイル/フォルダを抽象化してしまうのである。ファイルの移動などがあったら、定義ファイルを書き換えるだけでよい。

ユーザーの定義と登録

多くのコンピュータがネットワークで共同作業するようになると、それぞれのコンピュータを何らかの方法で識別する必要が生じる。ネットワーク上のコンピュータの名称は、漢字Talk 6ならば「セレクタ」で、漢字Talk 7ならコントロールパネルの「共有設定」で設定するのだが、ハイパーカードからはこれを直接参照することはできない。その代わりに、ハイパーカードではHomeスタックで定義するグローバル変数UserNameがあるので、これを活用することにしよう(画面)。

UserNameには利用者の本名、ニックネームなどを自由に設定できるが、この一部としてユーザーのIDとなる番号を加えておくと便利である。例えばUserNameを画面のように「03 Kan」とすると、word 1 of UserNameでID番号の03、word 2 of UserNameでニックネームのKanが取得できる(*注3)。

応用例として、このID番号を使ってユーザーの環境をカスタマイズしてみよう。前項ではシステム全体の環境に関する定義ファイルを使ったが、同じ手法で、ユーザーごとのグローバル変数を保存したファイルを用意する。ここには、個人用フォルダのパス名や、所属グループの名前などを書き込んで置くと良い。このファイル名をID番号と同じにしておけば、

do ReadFile(word 1 of UserName)*注4

という命令1行で、メンバーそれぞれに独自の環境が整うことになるのだ(図2)。この方法には、機械を変更しても簡単に環境を再構築できるというメリットもある。

利用者の確認

もう一つUserNameの利用例を示す。HyperLauncherには、ファイルの利用統計を取る命令が用意してあった。オリジナルでは利用回数をスタックのフィールドに書き込むようにしていたが、ネットワークを考えると、利用者情報も合わせて、サーバー上のファイル(ログファイル)に蓄積する必要がある(リスト2)。

ここでは、利用ファイル名+".log"をログファイル名とし、サーバー上のフォルダpLogに保存することにしている。利用ファイルが「名簿」ならば、ログファイルは「名簿.log」となるわけだ。ログは毎回の利用者名と利用日時を新しい順に並べたもので、1行目、すなわち最新の利用情報にはitem 3に累計利用回数を記録するようにした。ファイルの中身は

03 kan,95.05.26 11:30 AM,1345
11 太田,95.05.26 9:12 AM
...

のようになっている(*注5)。

ログファイルは統計を取るだけではなく、スタックやファイルの最新利用情報を調べることも重要な役割だ。例えば、ネットワーク上のスタックは基本的に同時使用できないから、誰かがスタックを先に開いていると他のユーザーはその機能を利用できないことになる。こうしたとき、ユーザーに単に「スタックが開けません」と伝えるよりも「今スタックは△△さんが使用中です」とするほうが親切である。そこで、スタックを開くところに次のようなエラー処理を加えることにしよう。

    go stack stackName
    if the resultis NOT "" then
      get line 1 of ReadFile(pLog & stackName & ".log")
      answer word 2 of item 1 of it & "さんが使用中です"
    end if

ログファイルの1行目には最後の利用者が書き込まれているから、これをチェックすれば誰が使っているかを知らせることができるわけだ。些細なことのようだが、システムの使いやすさは案外こういうところで左右されるものである。UserNameのような情報をうまく利用して、メンバーの必要にできるだけ応えることが大切だ。

会議室予約スタック

画面 さて、ここでネットワークを念頭に置いたスタックの具体例を検討してみる。会議室を予約するシステムだ。画面のようなものだが、詳細を解説する余裕はないので、大まかなポイントだけ押さえておく。

まず、予約の流れは次のようになる:

  1. 利用者がフィールドの行(開始時刻)をクリックする。
  2. 予約済みの時間なら、予約状況を示し、取り消しなどの処理をする。
  3. 空いていれば、終了時刻(行)をクリックして選び、予約者の名前をインプットし、登録する。

この基本形に、スタックならではのきめ細かい機能をつけ加えていく。ここでは2つの例を考えてみよう。

●社員番号による入力と予約の保護:

(3)のステップで名前の代わりにIDを入力できるようにするもの。外部ファイルに社員番号と氏名を対応させたテーブルを用意しておき、リスト3のようにしてIDから名前を取得する。インプットが簡単になるばかりでなく、あらかじめ許可された人以外は部屋を使えないようにブロックすることもできる。また、(2)では社員番号が分からなければ取り消しできないように予約を保護することができる(リスト4)。

●スタックの強制解放:

共有環境では自分の作業が終わったら速やかにファイル(スタック)を閉じて他の人に明け渡すのがマナーなのだが、実際は使いっ放しにしてしまうことが多い。そこで、一定時間入力がなかったら自動的にスタックを閉じる機能を用意する。スタックを開いた時点でタイムリミットをグローバル変数に保存し、on idleハンドラで常に現在時刻がタイムリミットを越えていないかを監視するのだ(*注6)。もしタイムリミットを越えたら、その時点でスタックを閉じる命令を発してやればよい(リスト5)。

ハイパーカードだからできること

これらの機能は、会議室予約システムに限らず、あらゆるネットワーク型のスタックで応用可能だ。

社員番号テーブルは、ファイルのグローバル変数と同じ抽象化の手法である。社員番号は様々なところで参照されるだろうが、異動でメンバーが変更になってもファイル一つ修正すれば事足りるわけだ。

また、多くのユーザーが共同作業をする環境では、資源の有効な利用が大切である。同時利用できないものについては、このスタックのようなタイムリミットの仕組みが効果的だ。

ネットワーク上のスタックの連動と外部ファイルによる抽象化は、オフィスシステム構築の強力な武器となるだろう。この方向を進めると、グループウェアとしてのハイパーカードの可能性が視野に入ってくる。これについては、稿を改めて本格的に検討してみたい。

*注1

共有フォルダを、フォルダごとボタンに登録してしまうのも効果的だが、これにはstdFileなどの外部命令を使う必要がある。

*注2

共有するファイルが増えると、ジャンルごとにフォルダを分けたり、分類を見直したりする必要が生じる。逆に、こういう見直しをしないと、システムは次第に混沌としたものになってしまう。

*注3

ここで使うIDは、ユーザーの登録順に01、02...としておくと分かり易い。

*注4

ReadFile()はハイパーカードの組み込み命令ではなく、前号で紹介したように(1995/7号:注4)、open,read,closeのファイル読み込み命令をまとめてスタックスクリプトにおいたもの。

*注5

システム全体の利用状況をチェックするには、フォルダpLogにある全てのファイルの1行目をまとめて読み出せばよい。

*注6

idleメッセージは豊かな可能性を秘めており、これをうまく使うと遠隔操作や定時作業の自動化なども実現できる。この活用については別の機会に詳しく検討する(1995/10号:idleメッセージ)。

リスト

リスト1

-- 外部の定義ファイルに保存する初期化命令
-- 最初に定義するグローバル変数を宣言する
-- do命令の引数とする場合は、on XXXのようなハンドラの形にはしない
global pCommon, pLog, gFolderName
global gAppName

-- フォルダを定義する
-- 個々のフォルダを別々に定義するより、サーバー名など
-- 上位のフォルダをまず変数に定義し、その変数を使って
-- 下位フォルダを定義していくとよい
put "TheServer:" into pRoot
put pRoot & "共有フォルダ:" into pCommon
put pRoot & "LOG:" into pLog
put pRoot & "MacUser:" into gFolderName

-- アプリケーション名もグローバル変数にすると便利
-- これらのアプリケーションは、Homeスタックの
-- 「Applications」カードに記述したフォルダに置いておく
put "TheWordProcessor" into gAppName
...

リスト2

-- 統計を取るハンドラを改良し、ファイルに利用者名とともに
-- 過去50回分ログを記録していく
-- リスト1のようにしてログを記録するフォルダpLogを決めておく
on getStat FileName
  global UserName, pLog
  put pLog & FileName & ".log" into LogFile
  put ReadFile(logFile) into lastLog -- ReadFile()は*注4参照
  
  -- 1行目のitem 3には前回までの累計利用回数が記録されている
  put (item 3 of line 1 of lastLog) + 1 into LogCount
  delete item 3 of line 1 of lastLog
  put UserName & "," & the date && the time & "," & LogCount & RETURN & line 1 to 49 of lastLog into NewLog
  open file LogFile
  write NewLog to file LogFile
  close file LogFile
end getStat

リスト3

-- 社員コ−ドを確認、名前を定義ファイルから取得する
-- 定義ファイルは、item 1をコード、item 2を名前としておく
-- 定義されていないコードなどエラーの場合はemptyを返す
function testUser
  put "" into user
  put readFile(<member File>) into userInfo
  ask "会議室を予約します。社員コ−ドを入力して下さい。"
  if it is "" then return ""
  put it into userID
  repeat with i = 1 to number of lines of userInfo
    if item 1 of line i of userInfo is userID then
      put item 2 of line i of userInfo into user
      exit repeat
    end if
  end repeat
  if user is "" then
    answer "登録されていない社員コ−ドです。"
    return ""
  end if
  return user & "," & userID
end testUser

リスト4

-- 社員コードで保護されている予約について確認
-- 予約情報のtem 1に名前、item 3に社員コードが保存されている
-- 取り消しを許可するときはTRUE、許可しないときはFALSEを返す

function clearRes ResFld
  get line (word 2 of the clickLine) of fld ResFld
  put item 1 of it into user
  put item 3 of it into hisID
  ask "予約を取り消します。確認のため" & user & "さんの社員コードを入力してください。"
  put it into userID
  if userID is hisID then return TRUE
  else
    answer "社員コ−ドが正しくありません。" & user & "さんに確認して、もう一度やり直してください。"
    return FALSE
  end if
end clearRes

リスト5

-- スタックを開いたまま放置しないようチェックする
-- 最初にタイムリミットを設定する
on openStack
  global TimeOut
  ...
  put the seconds + 300 into TimeOut -- 5分間をタイムリミットとする場合
  ...
end openStack

-- idleメッセージを監視する。バックグラウンドに置く。
on idle
  global TimeOut
  if the seconds > TimeOut then
    go stack "HyperLauncher" -- pop cdなどでもよい。スタックを強制的に閉じる。
  else
    pass idle
  end if
end idle

用語

グローバル変数

ハイパートークで使う変数には、ハンドラが終了すると変数の値も消去されるものと、ハイパーカードが終了するまで値が保存されるものがある。後者をグローバル変数と呼び、

global var-name

という宣言を行った上で使用する。複数のハンドラで同じ値を共有するときなど便利。

Homeスタックで定義する

通常ハイパーカードは起動時に、Homeのカードに記載された大切な情報を読み出して、ユーザーの環境を設定する。これにはUserNameのほかにグローバル変数としてStacks,Applications,Documentsがある。また、変数ではないがこのときにユーザーレベルなどの情報(プロパティ)も設定される。詳しくはHomeのスタックスクリプトにあるハンドラgetHomeInfoを参照。

引数(parameter)

ハンドラや関数を呼び出すときに、呼び出し側が与える情報で、ハンドラの名前の後に続けて記述する。

on myHandler param1, param2 ...

という形で定義しておき、呼び出すときにはmyHandler value1, value2とする。ハンドラの内部では、変数と同様に扱うことができる。

the result

ハイパートークの命令のうち、go, open, readなどは実行の結果を関数the resultで調べることができる。例えばスタックを開こうとして(go stack ..)うまく行かなかったときはthe resultは"Can't open stack"というエラーを返す。成功したときはthe resultの返り値はemptyになる。

idle

ハイパーカードが何もしていない状態の時に、常にカードに対して送り続けられるメッセージ。これを使うと、ハイパーカードの空き時間に作業をさせることができる。

(MacUser Japan, August 1995)