プラットフォームを超越せよ

      コボル開発者のためのVisual Basic入門講座 〜導入編〜

    福岡 寿和 FUKUOKA, Toshikazu 富士通SSL  


    私は長いあいだ,富士通のMシリーズというホストシステム上で,アセンブラやCOBOLを使って業務システムを開発してきました.そのことを近ごろ知り合った方にお話すると,「どうやって,WindowsのことやVisual Basicのことを覚えたのか」と質問されることがあります.なぜ,そのような質問をされたのか聞いてみると,その方の周りでは,ホストシステムの開発に長年携わってきた人が,Windows系システムの開発のリーダーとして,あるいは管理職として仕様の決定を行ない,失敗する事例をときどき見かけるからだそうです.そして,失敗したときの言い訳として「ホストならできるのに」とか「COBOLなら簡単なのに」ということを言われるそうです.しかし,私自身が初めてWindows上でのプログラムを体験したときのことを思い出してみると,「ホストでできないことができる」とか「COBOLで難しいことが簡単にできる」という印象を受けました.そして,その感想は今も変わっていません.
    どうしてこのような差が生じるのかを考えることにより,COBOLERと呼ばれているホストシステム開発者の方がVisual Basicのことを理解するための一助になればと考えています.そして,大規模な業務システム構築にVisual Basicを使う機会が増えてくるのであれば,ホストシステムでの開発経験がきっと役に立つと考えています.同時に「ホストしか知らないから」とか「コボルしか知らないから」ということが,Windows系のシステム開発での失敗の根本原因ではないことも明らかにしていきます.

    言語の違いを考える

     COBOL(Computer Business Oriented Language)は,1960年に事務処理などを効率的に処理するために開発された言語で,金額などの丸め誤差が許されない計算やファイル管理,文字列の操作に重点を置いています.また,BASIC(Beginner's All purpose Symbolic Instruction Code)は,1964年に初心者向きの会話型言語として開発されました.そして,現在に至るまで,この2つの言語は,それぞれ別々に世の中のトレンドを吸収して大きく進歩してきました.
     この生い立ちの違いが,2つの言語の現在の違いを生み出しています.たとえば,COBOLは,生い立ちからもわかるように,事務処理などの計算処理,しかもバッチ処理という一括処理での効率化を目指してきました.このような目的のアプリケーションを作成するには,事前に処理順やアルゴリズムなどの綿密な設計が必要です.かたやBASICはユーザーインターフェイスから徐々に成長させてゆくようなプロトタイプ型の開発によくマッチします.
     現在のWindowsアプリケーションの開発では,短期間に手早く開発することが求められています.また,複雑なアルゴリズムを実装するときでもホストのダウンサイジングなどのパターンで似たような処理が,すでにコンピュータ化されているときがあります.このようなことがBASICにとっての追い風になっています.Windowsアプリケーション用のCOBOL処理系も発売されていますが,Visual Basicの対抗馬になり得ていないのは,このように母体となる言語系の違いが大きいと考えられます.ある意味では,BASIC言語のいいかげんさが,イベントドリブンというBASICの言語系が開発されたあとに出てきた新しい概念を,スムーズに受け入れさせる土壌を培ったのかもしれません.
     Microsoft Visual COBOLというような製品を想定してください.この製品の仕様はどのような感じになるでしょう.たとえば,ボタンをクリックしたときのイベントを記述するときに,そのイベントで起動されるプロシージャの中で変数宣言なども含めてプログラムを完結すると,リスト1のようになるかもしれません.このように,いろいろなSECTIONをイベントごとに記述するのは結構大変かもしれません.何かCOBOLに新しい考え方を導入する必要があるでしょう.たとえば,オブジェクト指向COBOL(COBOL97規格?)などがそれにあたります.このことからもわかるように,ホスト上で動いているCOBOLソースがほとんど無修正で動いたり,ホストでの経験だけで,Windows上で動作するCOBOL処理系を使って,インタラクティブなアプリケーションを作成したりすることはできないのです(Windowsの仕組みに頼らずにUI部分もホストの処理系を移植すれば別ですが).つまり,Windows版のCOBOLで開発すればCOBOLしか知らない要員でも開発できるとか,教育の手間が省けるというのは嘘なのです.そんなうまい話など世の中にあるはずがありません.

      リスト1:Visual COBOLのプログラム例
      Private cmdOK_Click()       SECTION.
        INPUT-OUTPUT              SECTION.
        FILE-CONTROL.
        SELECT MBR-O-FILE ASSIGN TO PUT.
        DATA                      DIVISION.
       *
        FILE                      SECTION.
        FD  MBR-O-FILE .
        01  IN-REC             PIC X(2000).
       *
        WORKING-STORAGE SECTION.
        01  SWITCHING-AREA.
          03  SW-END  PIC X(001)  VALUE '0'.
        01  COUNTER-AREA.
          03      COUNT-NO1       PIC 9(5).
          03      COUNT-NO2       PIC 9(5).
        01  W-DATE.
          03      W-YYMM          PIC X(4).
          03      W-DD            PIC X(2).
       *
        PROCEDURE                 DIVISION.
            MOVE  ZERO    TO      COUNT-NO1.
            MOVE  ZERO    TO      COUNT-NO2.
                            :
        EXIT.
      cmdOK_Click. EXIT.
      

    COBOLは死なず
    〜本当にVisual Basicが有効か〜

     では,COBOLしか知らない状態では開発ができなかったり,教育の手間も省けないのであれば,Windows版のCOBOLで開発する意味などないのでしょうか.
     そんなことはありません.COBOLにはCOBOLの良さがあります.その良さを無視して,Visual Basicと同じ土俵で評価したり,プラットフォームの違いを言語系で吸収しようと考えるのが,そもそもの間違いなのです.
     では,COBOLの良さはどこにあるのでしょうか.Visual Basicではなく,COBOLでWindowsアプリケーションを作成する局面は存在するのでしょうか.もちろん存在します.たとえば,Visual Basicの通貨型は15桁の整数部分と4桁の小数部分をもつ固定小数点数を表現できます.ですから,900兆円程度までは演算誤差がなく計算できますが(99兆円は大丈夫ですが,999兆円は扱えないので,実際の有効桁数は14桁ですね),それ以上の金額についてはお手上げになってしまいます.COBOLでは18桁までの整数演算がサポートされていますから,国家予算も扱うことができます.そして,COBOLではこの桁数が通貨型ではなく整数型として定義されているので,通貨以外を扱う変数で大きな整数値を扱うときでもわかりやすいコーディングが可能です.もちろん,Visual Basicでも金額以外の変数に通貨型を使うことはできますが,プログラムの可読性は低くなります.このように固定有効桁数の確保が絶対に必要な処理では,COBOLが威力を発揮します.
     このCOBOLの良さを発揮させるためにはどのようにすればよいのでしょうか.よく取り上げられる例としては,DLLをCOBOLで作成して,いわゆるビジネスロジック部分をVisual Basicと切り離してしまうことです.しかし現実的なことを考えると,画面で入力された多数の値をDLLのパラメータとして受け渡すのは,かなり手間がかかります.それよりも,すべてをCOBOLで作成してしまうほうが,よほど仕組みが簡単になります.結局,Visual Basicの限界を超えたアプリケーションを作成するときのひとつの解として,Windows上のCOBOL処理系があるととらえるのが無難でしょう.そのときは,いろいろなことが日本語化されてしまった「コボル」ではなく「COBOL」として言語をとらえる必要があります.

    プラットフォームの違いを考える

     結局のところBASICとCOBOLの違いはあまり大した違いではないのです.それよりも,プラットフォームの違いがシステム開発の勘所の違いになることを,無視または軽視してしまうことが問題なのです.ホストシステムとWindowsシステムの違いを理解することが,Windows系のシステム開発での失敗を防ぐ第一歩なのです.
     ホストシステムは,乱暴な言い方ですが,ハードウェアもOSの各サブシステムも開発言語も,自分以外の他の部分を信用していません.ハードウェアはハードウェアでディスク装置などのエラー監視をしていますし,OSの各サブシステムも相手のサブシステムやハードウェアの状況などを監視し,相手が間違った行動をすればすぐに検出できるようになっていたり,また相手のエラーが自分に影響しないように防御したりしています.そのため,ほかからエラーと認識されないように仕様を明確にして,その仕様をきちんと守ることが前提になっています.そのため開発言語を知っていれば,OSの仕組みの深いところであるデータ管理サブシステム,ジョブ管理サブシステムなどの動作知識などは,プログラムに必要なかったのです.それに比べてWindowsでは,お互いを信頼して,それぞれの役割分担を明確に分けていないところがあります.そのため,開発を行なうには,開発言語だけではなく,最終的にはOSの仕組みの深い部分の動作知識が必要になってくるのです.そして,Windowsは作り直しのようなバージョンアップが激しく,日本語化が100%完全ではない点も忘れないでください.だから,コボルではなくCOBOLなのです.
     それでは,以上のようなことを踏まえたうえで,何点かホストとWindowsの違いに基づく設計の違いを見てゆきたいと思います.なお,ここで記載していることは言語の違いに左右されないものです.

    Windows系でのバッチ処理について
     もしかしたらRDBMSを使ったクライアント/サーバーシステムでバッチ処理をCOBOLでコーディングするのが知識的インパクトが一番が少ないかもしれません.しかし,まずは徹底的にバッチ処理を排除すべきでしょう.RDBMSを使ったシステムの基本は「欲しいときに欲しい情報を取得する」ということですから,バッチ処理でサマリーを作ったり,帳表に出力する必要は本来ないはずです.サマリー情報が欲しいのならば,欲しいときに計算すればよいのですし,そうすることによってつねに最新の情報が提供できる利点がある訳です.帳表にしてもそうです.大量の帳表を出力して結果的にどうするのでしょうか.その帳表を使って過去のデータを閲覧するのはナンセンスなシステム仕様です.過去のデータを閲覧したいときは過去のデータを検索すればよい訳ですし,そうすることによってデータを探すという本来の仕事とは別の部分に人手を使う必要がなくなる訳です.
     そして,このように「本当にバッチ処理する必要があるのか」という疑問を投げかけても,バッチ処理が適切な処理方法の場合があります.たとえば,締め処理もそのひとつです.

    バッチクライアントの設置
     これから開発するシステムで,どうしてもバッチ処理が必要なことが判明したら,ぜひ,バッチ処理専用のクライアントマシンを用意してください.RDBMSもWindows NTなどのプラットフォームで動作していたとしても,このバッチクライアントは必要です.

    動作ログの出力
     Windowsアプリケーションでログを出力する責任は,すべて動作しているプログラムに任されています.バッチ処理で動作させるプログラムでは,必ずログファイルの出力をサポートするのがよいでしょう.ログファイルの出力は,プログラム起動時にオープンして終了時にクローズするのではなく,リスト2のように毎回オープン〜クローズを行ないます.なぜ,このような方法をとるかといえば,Write文により直接ファイルに出力される訳ではなく,ある程度,出力バッファにレコードが蓄積されてからファイルに出力されるからです.つまり,起動時にオープンの方法だと,プログラムが異常終了したときに,直前のログがファイルに書き込まれていなかったために調査が難航したり,ログファイル自体が壊れてしまうことがあるからです.

      リスト2:ログ出力のプログラム例
      Dim intFno      As Integer
      Dim strFileName As String
      
             :
      intFno = FreeFile
      Open strFileName _
        For Append Access Write Shared _
        As #intFLog
      Write #intFLog, _
        Format$(Now, "mm/dd hh:nn:ss") & _
        vbTab & App.EXEName & vbTab & _
        app.Title & " 開始"
      Close #intFno
             :
      

    スケジューリング
     バッチ処理の起動タイミングが定時起動であるならば,起動タイミングのスケジューリングを考慮しなければなりません.このこともバッチクライアントを別途用意する理由のひとつです.バッチクライアントをWindows NTにすれば,ATコマンドによりスケジューリングが可能です.これがバッチクライアント設置の第一の理由です.ほかのクライアントがWindows 95だとしても,1台だけNTにして最速のCPUを実装しメモリも大量に実装してバッチ処理の効率を向上させるのは現実的な解答です.また,ATコマンドは管理者権限でログインする必要があるので,バッチ処理を行なうマシンは,ほかと隔離しておく必要があるでしょう.これがバッチクライアント設置の第2の理由です.

    Visual Basicでのバッチ処理
     Visual Basicは,イベントドリブンな言語です.ですから,ボタンをクリックするとかタイマーがタイムアウトするなどのイベントがないと動作しないように思われます.しかし,EXEを起動すると何もイベントがなくても動作させる方法が,ひとつだけあります.それが,スタートアップを[Sub Main]にする方法です(リスト3).このリスト3を組み込んだサンプルプログラムは,フォームモジュールがないので画面上には何も表示されません.唯一の頼りが動作ログになります.しかし,これでは長時間にわたる処理を行なうようなプログラムではいろいろ不便を感じます.処理を途中できれいに中断する方法もありません.
     そこで最低限のGUIを提供するように改良したのがリスト4になります(図1).これはログを画面に出す処理と途中でキャンセルできるようにしただけですが,かなり利用者の心理的不安は解消できると思います.また,サンプルの状態では,フォームが自動的に閉じませんが,コメントアウトされているUnload Meを生かせば,自動的にフォームが閉じられます.各自確認してみてください.Form_Loadイベントではフォームを閉じる処理をコーディングできないので,タイマーイベントを発生させて,その中にロジックをコーディングしています.

      リスト3:バッチ処理のプログラム例(Batch.bas)
      Attribute VB_Name = "basBatch"
      Option Explicit
      
      Public Sub main()
        Dim intFno      As Integer
          
        On Error GoTo errMain:
          
        intFno = FreeFile
        Open CurDir$ & "\batch.txt" _
          For Output Shared As #intFno
        Write #intFno, "起動しました。"
        Write #intFno, "計算しています。"
        Write #intFno, "計算しています。"
        Write #intFno, "計算しています。"
        Write #intFno, "計算しています。"
        Write #intFno, "計算しています。"
        Write #intFno, "計算しています。"
          
      exitMain:
        On Error Resume Next
        Write #intFno, "終了します。"
        Close #intFno
        Exit Sub
          
      errMain:
        Write #intFno, Error$
        Resume exitMain:
      End Sub
      
      リスト4:バッチ処理のプログラム例(fdlgBatchGUI抜粋)
      Option Explicit
      '終了フラグ
      Private mblnEnd     As Boolean  
      'キャンセルフラグ
      Private mblnCancel  As Boolean
      
      Private Sub cmdCancel_Click()
        Unload Me
      End Sub
      
      Private Sub Form_Load()
        mblnEnd = False
        mblnCancel = False
        tmrLoad.Enabled = True
      End Sub
      
      Private Sub Form_QueryUnload _
        (Cancel As Integer, UnloadMode As Integer)
        '終了判定
        If Not mblnEnd Then
          'バッチ処理が終了していないときは、
          'キャンセル予約のみ
          mblnCancel = True
          Cancel = True
        End If
      End Sub
      
      Private Sub tmrLoad_Timer()
        Dim intFno      As Integer
        Dim ilngLoop    As Long
        Dim iintLoop    As Integer
      
        tmrLoad.Enabled = False
          
        On Error GoTo errTimer:
          
        'バッチ処理
        intFno = FreeFile
        Open CurDir$ & "\batch.txt" _
          For Output Shared As #intFno
        lstlog.Clear
          
        lstlog.AddItem "起動しました。"_
          : Write #intFno, "起動しました。"
          
        For iintLoop = 1 To 10
          If Not mblnCancel Then
            lstlog.AddItem "計算しています。"_
              : Write #intFno, "計算しています。"
            For ilngLoop = 0 To 10000
              If mblnCancel Then
                Exit For
              End If
              DoEvents
            Next
          Else
            Exit For
          End If
        Next
          
      exitTimer:
        On Error Resume Next
        lstlog.AddItem "終了します。"_
          : Write #intFno, "終了します。"
        Close #intFno
        mblnEnd = True
        ' Unload Me 本来ならば生かしておく行です。
        Exit Sub
      
      errTimer:
        lstlog.AddItem Error$
        Write #intFno, Error$
        Resume exitTimer:
      End Sub
      

      図1:

    キー入力について
     ホストシステムにしても,WindowsにしてもマルチタスクOSです.しかし,ホストシステムではひとつの端末はひとつのタスクの支配下にあります.そのため,その端末でのキー入力は画面を表示中にプログラムに確実に受け渡されます.しかし,Windowsでは,ウィンドウひとつひとつが,ひとつのタスクであり,キー入力は現在アクティブなウィンドウに送信され,希望するプログラムに受け渡される保証はありません.さらにPFキーはWindowsが予約済みですので,それを回避して独自の処理をPFキーに割り当てるのは,Windows標準のGUIから離れるばかりか,WindowsやVisual Basicに眠っていた障害を呼び覚ましたり,「操作の統一による教育工数の削減」というWindowsアプリケーションの利点すら享受できないシステムを作成することになります.Enterキーによる項目移動やPFキーによる処理分岐は考えないほうがよいでしょう.Tabキーやアクセスキーなどの代替機能もありますし,市販アプリケーションのGUIを参考にして使い勝手のよいインターフェイスを設計しましょう.

    サーバー側からの通知について
     ホストシステムでは,端末に表示する内容をすべてホスト側から送信していました.そのため,比較的簡単にホストから端末へ強制的にメッセージを送ることが可能でした.しかし,クライアント/サーバー型のシステムで,サーバー側からクライアント側に強制的にメッセージを送るのは,かなり難しいことなのです.これは,クライアント/サーバーが「クライアントの依頼によりサーバーが該当したサービスを提供する」という前提があるからです.ですから,どうしても強制メッセージが必要なときは図2のように強制メッセージ用の別プログラムを常駐させる必要があるのです.

      図2:

    最後に

     コボル開発者ではなくCOBOL開発者ならば,入社のころを思い出して,ほこりをかぶった当時の解説書を取り出し,そこに書かれている問題をVisual Basicで解いてみてください.それがVisual Basic理解の第一歩になるでしょう.そして,それが理解できたら,これから設計しようとしているWindows系のアプリケーションのプロトタイプを自らの手で作成して,プラットフォームの違いを肌で感じて,誤った設計を行なわないノウハウを蓄積していってください.

     実は本稿を執筆するにあたり,COBOL文法書を久しぶりにひも解いてみました.また,当時読んでいたCOBOLの解説書も開いてみました.これらの書籍と現在流通しているVisual Basicの解説書を比較してみると,COBOLの解説書のほうが圧倒的に基本的アルゴリズムについて記載されている点が目を引きました.まあ,COBOLの解説をするときに導入部分については,基本的アルゴリズムのコーディングくらいしか取り上げるものがなかったともいえますが,Visual Basicの解説書でも,バブルソートとかクイックソートだとか,有効桁数の話や桁落ちの話などが載っていてもよいのではと思えてきました.
     生まれて初めて触れたコンピュータ言語がVisual Basicであれば,きちんとしたアルゴリズム設計を経験することなしに,大規模な業務アプリケーションを構築しなければならないことがこれから増加してゆくような気がします.そうしたとき,いま「コボルしか知らない人だから」と同じようなニュアンスで「ビジュアルベーシックしか知らない人だから」と言われないように,基本的なアルゴリズムをVisual Basic開発者も勉強する必要があると思います.BASICがF-BASICとかN88-BASICが主流のときには,BASICを使った基本的アルゴリズムの解説書があったのですから,Visual Basicで基本的なアルゴリズムの勉強ができないことはないのです.Visual Basicで基本的なアルゴリズムをコーディングする前に,まずGUIを決めなくてはいけないような脅迫観念があるかもしれません.しかしInputBoxとMsgBoxでも十分なのです.COBOL開発の経験のある方から勉強した解説書を譲り受けて,そこに出てくるアルゴリズムや演習問題をVisual Basicで解いてみてください.きっと新しい力が身につくと思います.


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


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