チュートリアル:Web アプリケーション プロジェクトの開発

概要

本チュートリアルでは、COBOL Web アプリケーション プロジェクトの作成方法、およびそのプロジェクトを既存の COBOL プログラムと連携させる方法を紹介します。プロジェクトには、.NET COBOL で生成されたページが含まれます。このページは、.NET データ型を COBOL データ型にマッピングするための中間プログラムを呼び出します。その後、中間プログラムは既存の COBOL プログラムを呼び出して、ビジネス ロジックを実行します。

この Web アプリケーション プロジェクトには、次の 3 つのプログラムがあります。

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

Web アプリケーション プロジェクトの作成

最初に、Web アプリケーション プロジェクトを作成します。次の手順を行います。

  1. Visual Studio を起動します。
  2. Visual Studio で、[ファイル > 新規作成 > プロジェクト] をクリックします。
  3. [新しいプロジェクト] ダイアログ ボックスで [インストール済み > COBOL] を展開します。
  4. [Web] カテゴリをクリックします。
  5. [ASP.NET Web アプリケーション] を選択します。
  6. 中央のペインの上のドロップダウン リストで .NET Framework 4.5 が選択されていることを確認します。
  7. BookDemoWebApplication などの名前を指定します。
  8. ファイル システム上のプロジェクトの保存場所 (c:\tutorials など) を指定します。
  9. [Create directory for solution] をオフにします。
  10. [OK] をクリックします。

BookDemoWebApplication プロジェクトが作成され、ソリューション エクスプローラーに表示されます。このプロジェクトには次のものが含まれます。

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

レガシー コードおよびラッパー コードの追加

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

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

提供されるファイルは、%PUBLIC%\Documents\Micro Focus\Visual COBOL\Samples および Forms サブフォルダーにあります。

Web アプリケーション プロジェクトに依存コードを含める場合は、次の手順で、そのコードへの参照をソリューションに追加する必要があります。

  1. ソリューション エクスプローラーでソリューションを右クリックします。
  2. [追加 > 既存のプロジェクト] をクリックします。
  3. Samples ディレクトリの Forms\BookWrapper サブフォルダーに移動します。
  4. .cblproj ファイルを選択し、[開く] をクリックします。
  5. 同様に、Samples の Forms\LegacyBook サブフォルダーから [LegacyBook] プロジェクトを追加します。
  6. 次の手順で、2 つのプロジェクトを参照として [BookDemoWebApplication] プロジェクトに追加します。
    • ソリューション エクスプローラーで [BookDemoWebApplication] を右クリックし、[参照の追加] をクリックします。
    • 左側のペインで [ソリューション] を展開し、[プロジェクト] をクリックします。
    • BookWrapper プロジェクトおよび LegacyBook プロジェクトにチェック マークを入れ、[OK] をクリックします。

      これで、プロジェクトがソリューションの [参照設定] フォルダーに追加されました。

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

次に、ラッパー コードを呼び出すために、フォームにコードを追加する必要があります。

  1. Default.aspx.cbl を開き、データ項目 my-book作業場所 節で次のように宣言します。
           01 my-book   type BookWrapper.Book.
  2. ソリューション全体をリビルドします。

    BookWrapper が宣言されたため、解析エラーがなくなります。エラーがある場合には、Samples の Forms\BookDemoWebApplication サブフォルダーにあるデモンストレーションと照合して、違いを確認します。

  3. ソリューション エクスプローラーで、[BookDemoWebApplication] プロジェクトの Web.config ファイルを右クリックし、[開く] をクリックしてエディターでファイルを開きます。
  4. 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>
        <sectionGroup name="MicroFocus.COBOL.Runtime">
          <section name="Tunables" type="System.Configuration.NameValueSectionHandler" />
          <section name="Switches" type="System.Configuration.NameValueSectionHandler" />
        </sectionGroup>
      </configSections>
  5. Samples\BookData ディレクトリに用意されている bookfile.* データ ファイルを指す環境変数を設定します。これを行うには、次の手順を使用します。

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

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

    MyPath は、Samples ディレクトリ内の BookData サブフォルダーにあるデータ ファイル bookfile.dat へのフル パスに置き換える必要があります。

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

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

  1. ソリューション エクスプローラーで、[Default.aspx] を右クリックし、[デザイナーの表示] をクリックして、空のフォームを表示します。
  2. 以下の表に示すとおり、いくつかのラベル、テキスト ボックス、およびボタンをペイントします。

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

  3. コントロールをダブルクリックしないように注意して、コントロールのプロパティを編集します。

    コントロールのプロパティを表示するには、デザイナーでコントロールをクリックして、[プロパティ] ペインにそのプロパティを表示します。該当するプロパティまでスクロールして編集します。

    コントロールをダブルクリックすると、コントロールのイベントが作成されますが、それは次の手順で行います。次の値で、プロパティを編集します。
    コントロール ID プロパティ テキスト プロパティ
    ラベル label1 カタログ検索
    ラベル catalogNumberLabel カタログ番号
    テキスト ボックス textBoxStockNo (大文字と小文字を区別します) (空白)
    ボタン searchButton 検索
    ラベル errorLabel ファイル状態

    また、[Visible] プロパティを [False] に設定します。

    テキスト ボックス errorField (空白)

    また、[Visible] プロパティを [False] に設定します。

    ラベル label2 結果
    ラベル titleLabel タイトル
    テキスト ボックス textBoxTitle (大文字と小文字を区別します) (空白)
    ラベル authorLabel 作成者
    テキスト ボックス textBoxAuthor (空白)
    ラベル typeLabel タイプ
    テキスト ボックス textBoxType (空白)
    ラベル priceLabel 価格
    テキスト ボックス textBoxPrice (大文字と小文字を区別します) (空白)
    ラベル soldLabel 販売済み
    テキスト ボックス textBoxSold (空白)
    ラベル onHandLabel 手持在庫
    テキスト ボックス textBoxOnhand (空白)
    ラベル stockValueLabel 在庫価値
    テキスト ボックス textBoxStockValue (空白)
  4. [検索] ボタンのクリック イベントを作成します。イベントを作成するには、ボタンをダブルクリックします。これにより、searchButton_Click というイベントが作成され、フォーム用に生成されたコードが表示されます。
  5. searchButton_Click メソッドのコードでは、まだ何も実行されません。手続き部は空です。さらにスクロールして、生成されたコードを確認できます。
  6. ソリューション エクスプローラーでソリューションを選択し、[ビルド > ソリューションのビルド] を選択して、ソリューションをビルドできます。これによるエラーは発生しません。

クリック イベントの処理

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

  1. コード ビューの Default.aspx.cbl ファイルで、 searchButton_Click メソッドを検索します。次のように、コードを更新します。
           method-id searchButton_Click protected.
           working-storage section.
           01 aBook type BookWrapper.Book.
           01 anException type System.Exception.
           
           local-storage section.
           
           procedure division using by value lnkSender as object by value lnkEvent as type EventArgs.
           try
               set aBook to type BookWrapper.Book::Read(textBoxStockNo::Text)
               invoke self::PopulateForm(aBook)
           catch anException 
               invoke self::DisplayException(anException)
           end-try
           
                          
           end method.
  2. 一部の語句の下に、赤い波線が引かれます。これらは、バックグラウンドで行われている自動解析で生じた構文エラーを示しています。下線の引かれた語句の上にカーソルを移動すると、エラーについての情報がポップアップで表示されます。ステータス バーには、バックグラウンドの解析エラーの数が表示されます。[エラー一覧] ウィンドウで実際のエラーを確認できます。
  3. 上記のコードで PopulateForm および DisplayException メソッドが起動されます。コードの searchButton_Click メソッドの後、 end class 文の前に、次のメソッドを追加します。
           method-id  PopulateForm final private.
           procedure division using aBook as type BookWrapper.Book.
    
               if aBook <> null
                   set errorLabel::Visible to false
                   set errorField::Visible to false
                   set textBoxStockNo::Text    to aBook::StockNumber
                   set textBoxTitle::Text      to aBook::Title
                   set textBoxAuthor::Text     to aBook::Author
                   set textBoxType::Text       to aBook::Type
                   set textBoxPrice::Text      to type System.Convert::ToString(aBook::RetailPrice)
                   set textBoxOnhand::Text     to type System.Convert::ToString(aBook::NumberOnHand)
                   set textBoxSold::Text       to type System.Convert::ToString(aBook::NumberSold)
                   set textBoxStockValue::Text to type System.Convert::ToString(aBook::StockValue)
               else
                   set textBoxStockNo::Text    to "****"
                   set textBoxTitle::Text      to "*************************************"
                   set textBoxAuthor::Text     to "*************************************"
                   set textBoxType::Text       to "****"
                   set textBoxPrice::Text      to "****"
                   set textBoxOnhand::Text     to "****"
                   set textBoxSold::Text       to "****"
               end-if
    
           end method.
           method-id DisplayException private.
           procedure division using by value lnkException as type System.Exception.
               set my-book to null
               set errorLabel::Visible to true
               set errorField::Visible to true
               set errorField::Text to lnkException::Message
               invoke self::PopulateForm(my-book)
           end method.
  4. 変更を保存します。ファイルにエラーがなくなったことを確認します。

アプリケーションの実行

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

  1. ソリューション エクスプローラーで [BookDemoWebApplication] を右クリックします。
  2. [リビルド] を選択します。
  3. [デバッグ > デバッグなしで開始] をクリックします。

    新しいブラウザー インスタンスで Web アプリケーションが起動します。

  4. 情報を入力し、[検索] ボタンを使用して動作を試します。

    カタログ番号 [1111] および [2222] のデータを検索できます。

サンプル コードの確認

このデモンストレーションの実行で問題が発生した場合は、Samples フォルダーにある同じサンプルとアプリケーションを比較できます。

Legacy Book プログラム

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

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

このプログラムの連絡節では、データが 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 メカニズムです。