チュートリアル:COBOL での Web フォームの作成

概要

このチュートリアルでは、Web ページの作成方法と、この Web ページを既存の COBOL プログラムと相互に動作させる方法を示します。Web ページはマネージ COBOL で生成されます。Web ページは、.NET データ型を COBOL データ形式にマッピングするための中間プログラムを呼び出します。中間プログラムは、ビジネス ロジックを実行するための既存の COBOL プログラムを呼び出します。

この Web サイトには、次の 3 つのプログラムがあります。

  • Web ページ。Microsoft のフォーム デザイナーでは、C# や COBOL などの任意の .NET 言語で Web ページ (Web フォームとも呼ぶ) を作成できます。このチュートリアルでは、.NET COBOL でフォームを生成する方法を説明します。
  • 既存の COBOL プログラムである Book プログラム。このプログラムは、既存の COBOL プログラムをシミュレートします。このプログラムにはビジネス ロジックが含まれています。また、このプログラムが変更されることはありません。Book プログラムは製品に付属しており、このチュートリアルではこのプログラムを Web サイトに追加します。このプログラムのソースを変更しないで、マネージ コードとして再コンパイルし、.NET マネージ コードから呼び出し可能なクラスとして公開します。
  • 中間 COBOL クラスである BookWrapper プログラム。このプログラムは、既存の COBOL プログラムとクライアント フォームとの間のインターフェイスとして機能します。この中間クラスは、.NET クライアント フォームとのインターフェイスにオブジェクトを使用し、既存の COBOL とのインターフェイスに標準の COBOL PIC X データ形式を使用します。BookWrapper 中間クラスは製品に付属しており、このチュートリアルではこの中間クラスを Web サイトに追加します。

前提条件

このチュートリアルの前提条件として、次のように WinBook サンプルの一部である BookWrapper プロジェクトと LegacyBook プロジェクトをビルドしておく必要があります。

  1. [スタート > すべてのプログラム > Micro Focus Enterprise Developer > サンプル > Visual COBOL サンプル] をクリックしてサンプル ブラウザーを起動します。
    注:Windows 8、Windows 10、または Windows Server 2012 でサンプル ブラウザーを開始するには、[スタート] 画面に移動し、[サンプル] タイルをクリックします。
  2. 左側のウィンドウで [Windows Forms] をクリックし、[Win Book] をクリックします。
  3. [Open sample in Visual Studio] をクリックします。
  4. ソリューション エクスプローラーで ソリューション 「WinBook」 を右クリックして、[ソリューションのビルド] を選択します。

ビルドにより、WinBook ソリューションの bin サブフォルダーに BookWrapper.dll および LegacyBook.dll という 2 つのバイナリが作成されます。

Web サイトの作成

最初に、Web サイトを作成します。次の手順を行います。

  1. Visual Studio を起動します。
  2. [ファイル > 新規作成 > Web サイト] をクリックして、新規の Web サイトを作成します。
  3. [インストール済み > テンプレート] と選択して [COBOL] をクリックします。
  4. インストールされているテンプレート ペインの上のドロップダウン リストで .NET Framework 4.5 が選択されていることを確認します。
  5. [ASP.NET Web サイト] を選択します。
  6. [Web location] フィールドで、[File System] を選択し、このチュートリアルを置くディレクトリを参照して、ディレクトリ WebBook を指定します。
  7. [OK] をクリックします。

WebBook Web サイトが作成され、ソリューション エクスプローラーに表示されます。この Web サイトの構成は次のとおりです。

  • App_Data。アプリケーションデータを保持するための空のフォルダーです。
  • Default.aspx。メインフォームを表示するトリガー プログラムです。
  • Default.aspx.cbl。フォームのコードが記述されています。
  • Web.config。アプリケーション構成ファイルです。

ソリューション エクスプローラーには、Web サイトがプロジェクトと同様に表示されますが、Web サイトはプロジェクトではありません。Web サイトを簡単にパブリッシュできるようにするためのディレクトリです。詳細は、Visual Studio のヘルプ トピック「.NET開発\Webアプリケーション (ASP.NET)」などを参照してください。このチュートリアルでは、その他の相違点を示します。次の違いがあります。

  • Web サイトには、豊富なプロジェクト プロパティはありませんが、Web.config ファイルに Web 構成設定があります。Web.config ファイルを使用して、指令ファイルまたは COBCPY 環境変数に追加されるコピーブックの場所 (copypath) を指定します。
  • Web サイトに依存コードを含める場合は、通常の方法でそのコードへの参照を追加しますが、コードはソリューションの参照としてではなく Web サイトの Bin フォルダーに格納されます。
  • Web サイトには、任意の言語の Web ページを追加できます。プロジェクトではないので言語に依存しないためです。

フォームのペイントの開始

ここでは、フォームをペイントします。生成されたコードを確認することもできます。フォームのペイントの基本情報については、「チュートリアル:.NET マネージCOBOLの開発」を参照してください。

  1. ソリューション エクスプローラーで、[Default.aspx] を右クリックし、[デザイナの表示] をクリックして、空のフォームを表示します。
  2. フォーム上にラベルを 4 つ、テキスト ボックスを 3 つ、ボタンを 1 つ作成します。

    Web フォームのレイアウトは、テキスト エディターや HTML の場合と同様で、空白文字や改行を使用して行います。

  3. コントロールをダブルクリックしないように注意して、コントロールのプロパティを編集します。ダブルクリックすると、コントロールのイベントが作成されますが、それは次の手順で行います。次の値で、プロパティを編集します。
    コントロール ID プロパティ テキスト プロパティ
    ラベル label1 在庫番号
    テキスト ボックス textBoxStockNo (大文字と小文字を区別します) (空白)
    ラベル label2 タイトル
    テキスト ボックス textBoxTitle (大文字と小文字を区別します) (空白)
    ラベル label3 価格
    ラベル label4 (大文字と小文字を区別します) (空白)
    テキスト ボックス textBoxPrice (大文字と小文字を区別します) (空白)
    ボタン button1 (大文字と小文字を区別します) 検索

    プロパティを表示するには、ラベルをクリックしてから [プロパティ] ペインを表示します。該当するプロパティまでスクロールして編集します。

  4. [検索] ボタンのクリック イベントを作成します。イベントを作成するには、ボタンをダブルクリックします。これにより、button1_Click というイベントが作成され、フォーム用に生成されたコードが表示されます。
  5. button1_Click メソッドのコードでは、まだ何も実行されません。手続き部は空です。さらにスクロールして、生成されたコードを確認できます。
  6. ソリューション エクスプローラーで Default.aspxをクリックし、[Build > Build Page] を選択して、フォームをビルドできます。これによるエラーは発生しません。

クリック イベントの処理

次に、ボタン クリックに対応するコードを追加する必要があります。このコードでは、レガシー COBOL プログラムを呼び出して、返された情報をフォームに入力する必要があります。

  1. コードビューで、button1_Click メソッドを検索します。次のように、コードを更新します。
           method-id  button1_Click protected.
           local-storage section.
           01 input-string string.
           01 my-exception type System.Exception.
           procedure division using by value lnkSender as object lnkEvent as type System.EventArgs.
               set input-string to textBoxStockNo::Text
               try
                   set my-book to type BookWrapper.Book::Read(input-string)
                   invoke self::PopulateForm(my-book)
               catch my-exception
                   invoke self::DisplayException(my-exception)
               end-try
           end method.
  2. 一部の語句の下に、赤い波線が引かれます。これらは、バックグラウンドで行われている自動解析で生じた構文エラーを示しています。下線の引かれた語句の上にカーソルを移動すると、エラーについての情報がポップアップで表示されます。ステータス バーには、バックグラウンドの解析エラーの数が表示されます。
  3. 上記のコードでPopulateForm およびDisplayException メソッドが起動されます。コードのbutton1_Click メソッドの後、end object 文の前に、次のメソッドを追加します。
           method-id  PopulateForm final private.
           procedure division using my-book as type BookWrapper.Book.
               if my-book <> null
                   set textBoxStockNo::Text      to my-book::StockNumber
                   set textBoxTitle::Text        to my-book::Title
                   set textBoxPrice::Text        to type System.Convert::ToString(my-book::RetailPrice)
               else
                   set textBoxStockNo::Text      to "****"
                   set textBoxTitle::Text        to "*************************************"
                   set textBoxPrice::Text        to "****"
               end-if
           end method.
           method-id DisplayException private.
           procedure division using by value lnkException as type System.Exception.
               set label4::Text to lnkException::Message
               set my-book to null
               invoke self::PopulateForm(my-book)
           end method.

レガシーコードとラッパー コードの追加

次に、ビジネス ロジックが含まれている既存の COBOL コードを追加して、フォームで使用できるようにする必要があります。このコードは、book.cbl を含む LegacyBook プロジェクトにあります。

さらに、データを .NET 型から COBOL 形式に変換するためのラッパー コードが必要です。Web ページでは .NET データ型が使用されます。このチュートリアルでは、System.String オブジェクトがこれにあたります。Book プログラムは、PIC X や PIC 99V99 などの COBOL 形式を使用します。付属のプログラム BookWrapper.cbl でこの変換が行われるので、このプログラムをソリューションに追加する必要があります。

  1. WebBook Web サイトの bin ディレクトリを作成します。これを行うには、ソリューション エクスプローラーで Web サイトを右クリックして、[Add >Add ASP.NET Folder > Bin] をクリックします。
  2. 付属の LegacyBookBookWrapper プログラムのプレビルド ファイルを追加します。これを行うには、ソリューション エクスプローラーで [Bin] を右クリックし、[Add >Add Existing Item] をクリックして、samples フォルダー内の Forms\WinBook\WinFormBook\bin\Debug フォルダーにある bin\Debug サブフォルダーを参照します。.dll ファイルを選択します。アプリケーションをデバッグする場合には、.pdb も選択して、[Add] をクリックします。これで、プログラムが Web サイトに追加されます。

レガシー コードへのアクセスの設定

次に、ラッパー コードを呼び出し、my-book に関連する最後の赤い波線を消去するために、フォームにコードを追加する必要があります。

  1. オブジェクトの作業場所節でデータ項目 my-book を次のように宣言します。
           01 my-book   type BookWrapper.Book.

    BookWrapper が宣言されたので、解析エラーがなくなります。

  2. Web.config ファイルで、<configuration>で始まる開始タグ行の後に、次の構成節を追加します。
    <!--The following code declares a section group for application configuration -->
      <configSections>
      <sectionGroup name="MicroFocus.COBOL.Application">
        <section name="Switches" type="System.Configuration.NameValueSectionHandler" />
        <section name="Environment" type="System.Configuration.NameValueSectionHandler" />
      </sectionGroup>
      <!--The following code declares a section group for run-time configuration -->
      <sectionGroup name="MicroFocus.COBOL.Runtime">
        <section name="Tunables" type="System.Configuration.NameValueSectionHandler" />
        <section name="Switches" type="System.Configuration.NameValueSectionHandler" />
      </sectionGroup>
    </configSections>
    
  3. WinBook に用意されている bookfile.* データ ファイルを指す環境変数を設定します。これを行うには、次の手順を行います。

    Web.config ファイルで、</configSections> 行の直後に次のテキストを追加します。

    <appSettings />
    <MicroFocus.COBOL.Application>
          <Switches/>
          <Environment>
             <add key="dd_bookfile" value="MyPath\bookfile.dat"/>
          </Environment>
       </MicroFocus.COBOL.Application>

    MyPath は、サンプル内の \Forms\WinBook\WinFormBook\bin\Debug サブフォルダーにあるデータ ファイル bookfile.dat へのフル パスです。

アプリケーションの実行

これで、アプリケーションが実行可能な状態になります。

  1. Web サイトをビルドします。
  2. [デバッグ] > [デバッグなしで開始] をクリックします。
  3. 情報を入力し、[検索] ボタンを使用して動作を試します。

    在庫番号1111および2222のデータを検索できます。

サンプル コードの確認

次のセクションでは、サンプル コードの機能について詳しく説明します。

Legacy Book プログラム

この book.cbl プログラムは、Micro Focus 製品に長らく同梱されているデモ プログラムです。このデモ プログラムは、手続き型 COBOL で作成されています。このプログラムによって、ブック レコードを含む索引付きファイルを読み書きします。

このソリューションでは、Book デモ プログラムを変更しないで、マネージ コードとして再コンパイルします。プログラムを再コンパイルすることにより、クラスとして公開し、そのメイン エントリ ポイントを静的メソッドとして公開します。

このプログラムの連絡節では、データが PIC X などの標準 COBOL 形式で定義されています。そのため、COBOL 以外のクライアント プログラムでは、これらのデータ形式を認識できません。クライアント プログラムと通信するためには、これらの形式を .NET と互換性がある型にマッピングする必要があります。このマッピングは、中間プログラム BookWrapper.cbl によって行われます。

クライアント Web フォーム

クライアント Web フォーム Default.aspx.cbl は、COBOL として生成されます。ユーザーはこのフォームにデータを入力し、そこで戻りデータを受け取ります。クライアント フォームでは、次の処理が実行されます。

  1. フォームのテキスト ボックスから、入力データを System.Strings として抽出します。
  2. BookWrapper を呼び出して、その文字列オブジェクトを渡します。
  3. System.Strings でフォームのテキスト ボックスにデータを出力します。

Book Wrapper プログラム

BookWrapper.cbl プログラムは、既存の COBOL プログラム book.cbl と Web フォームとの間の中間プログラムとして機能します。この中間プログラムにより、既存の COBOL を変更する必要がなくなります。

ここで重要な点は、複数の言語を使用する場合、互換性がある型を使用することです。Web フォームではデータを .NET 型として格納しますが、Book プログラムではデータを COBOL 形式と見なします。

BookWrapper プログラムの目的は、COBOL の PICTURE を .NET System.Strings にマッピングすることです。このプログラムは、Web フォームからデータを System.Strings として受け取り、標準の COBOL データ形式にマッピングしてから既存の Book プログラムに渡します。

作業場所節では、コピーブックを使用してブック レコードのデータ項目を次のように宣言しています。

working-storage section.
        copy "book-rec-dotnet.cpy" replacing == (prefix) == by == book ==.
    ...

コピーブック book-rec-dotnet.cpy では、book-details レコードを宣言しています。ここで、book-title と book-stockno を COBOL の Picture 形式で宣言し、プロパティとしても宣言します。したがって、Getter/Setter メソッドを使用してこれらにアクセスできます。コピーブックには、以下が含まれます。

    01 (prefix)-details.
        03 (prefix)-text-details.
            05 (prefix)-title  pic x(50) property as "Title".
        ...
        03 (prefix)-stockno pic x(4) property as "StockNumber".

次の property メソッドでは、book-details レコードへのポインターを受け取ります。

       property-id BookDetails pointer.
       getter. 
           set property-value to address of book-details
       end property.

Read メソッドは、次のように実装されています。

       method-id Read static. 
       local-storage section.
       01 file-status pic xx.
       procedure division using by value stockno-in as string
                          returning      myBook     as type BookWrapper.Book. 

           set myBook to new BookWrapper.Book()
           set myBook::StockNumber to stockno-in

           call "BookLegacy" using by value readRecord
                                   by value myBook::BookDetails
                                   by reference file-status       
            
           invoke self:RaiseExceptionIfError(file-status)
           goback.
       end method.

詳細は次のとおりです。

  • procedure division using ...

    クライアント フォームから渡される、.NET の System.String である stockno-in が記述されています。返される Book クラスのインスタンスも記述されています。BookWrapper.cbl では、新規の .NET 型である Book が定義されています。Book は、任意の .NET 言語で書かれたプログラムで使用できます。

  • set myBook to new BookWrapper.Book() 

    BookWrapper クラスの新規インスタンスを作成します。

  • set mybook::StockNumber

    .NET の System.String (stockno-in) からデータを受け取り、myBook の StockNumber プロパティとして格納します。このプロパティは、コピーブックで Picture 文字列として宣言されており、データは標準の COBOL データ形式として book-stockno に格納されます。COBOL コンパイラは、データを .NET 文字列から COBOL の USAGE DISPLAY 項目 (pic x) に暗黙的に変換します。

  • call BookLegacy using ...

    レガシー プログラム book.cbl を呼び出します。book.cbl プログラムに、myBook の「BookDetails」プロパティを渡します。BookWrapper.cbl のコードを見ると、BookDetails は book-rec-net.cpy で定義された BookRecord 構造体へのポインターを渡すことがわかります。この構造体は古い book-rec.cpy の構造体と一致します。したがって、従来の Book プログラムが見るのは、参照によって渡されるブック レコードです。これは想定通りの動作です。Book は、このレコードから在庫番号を読み取って、索引付きファイルから対象のレコードを読み取り、このレコードの他のフィールドにそのデータを書き込みます。

  • invoke self:RaiseExceptionIfError(file-status)

    ファイルの読み取りで返されたファイルのステータスを確認します。エラーがあった場合には、.NET 例外が発生します。例外は、エラー状態を通知するための標準の .NET メカニズムです。