カテゴリー: ABAP

  • 【内部結合】Inner Joinを利用してデータを取得する方法

    【内部結合】Inner Joinを利用してデータを取得する方法

    内部結合とは

    ABAPにおける内部結合(Inner Join)は、複数のテーブルを共通キーに基づいて結合し、必要なデータをまとめて取得するための命令です。

    基本的には SELECT 文と組み合わせて使用し、指定した2つのテーブルの間で結合条件を満たすレコードを抽出します。

    内部結合のイメージを図示すると、結合部分だけを取り出しているように考えるとわかりやすいでしょう。

    基本構文(Inner Joinの基本)


    2つのテーブルを内部結合する場合、基本的な構文は以下のとおりです。

    SELECT COLUMNS
      FROM TABLEA
      INNER JOIN TABLEB ON
        TABLEA~COLUMNS = TABLEB~COLUMNS
      INTO TABLE @INNER_TABLE.

    ON 句の直後に結合先のテーブルを指定し、その次に結合条件を記述します。

    3つのテーブルを内部結合する方法

    続いて、3つのテーブルを内部結合する例を見てみましょう。

    たとえば、テーブルAとテーブルBは「COLUMNS1」で結合し、テーブルAとテーブルCは「COLUMNS2」で結合するケースを想定します。

    SELECT COLUMNS1,
           COLUMNS2
      FROM TABLEA
      INNER JOIN TABLEB ON
        TABLEA~COLUMNS1 = TABLEB~COLUMNS1
      INNER JOIN TABLEC ON
        TABLEA~COLUMNS2 = TABLEC~COLUMNS2
      INTO TABLE @INNER_TABLE.


    結合したいテーブルの数だけ INNER JOIN と結合条件を追加していけば、複数のテーブルを同時に結合できます。


    INTO TABLE で指定するテーブル変数の直前に @ をつける記法は ABAP 7.4 以降で導入されたもので、最新の構文に対応しています。

    まとめ

    • 内部結合を使う際は、まず2テーブルでの基本的な構文を押さえましょう。
    • 複数テーブルを結合する場合は、結合するテーブルとその条件をひとつずつ追加していくイメージです。
    • 実際の開発では、WHERE 句なども組み合わせて条件がより複雑になることがよくありますが、今回紹介したポイントを理解しておけば対応しやすくなります。


    以上がABAPでの内部結合(Inner Join)の基本的な使い方です。複数テーブルを結合して効率的にデータを取得したいときに、ぜひ活用してみてください。

  • クラスとメソッド

    はじめに

    ABAPプログラミングでは、大規模開発や保守のしやすさを考慮し、オブジェクト指向プログラミング(OOP)の考え方を取り入れることが重要です。その核となるのが、「クラス」と「メソッド」です。昔から使われている汎用モジュール(Function Module)に対して、クラスを使うことでカプセル化再利用性を高め、拡張しやすい設計を実現できます。

    クラスとは

    「クラス」は、属性(データ)とメソッド(処理)をまとめて定義したもので、いわば「設計図」のようなものです。
    クラスの性質をもつオブジェクト(実体)をプログラムで生成することをインスタンス化と呼びます。

    動的属性と静的属性

    動的属性(Instance Attributes)
    インスタンスに応じて異なる値を保持する属性のことです。たとえば ZCL_HUMAN クラスにおいて「名前」や「年齢」のようなプロパティは、各インスタンスごとに異なる値をもつため、動的属性となります。

    静的属性(Static Attributes)
    クラスそのものがもつ属性で、インスタンスに依存しません。全インスタンスで共有される情報や定数などを保持する場合に利用します。宣言には CLASS-DATA を使います。

    クラス化がもたらすメリット

    • カプセル化:データと処理をひとまとまりにして、外部から見えない情報を隠蔽できる。
    • 再利用性:同じ処理を複数箇所で使いまわしやすい。
    • 拡張性:クラス継承などで機能の追加や変更がしやすい

    メソッドとは

    「メソッド」は、クラス内部に定義される処理のまとまりです。
    関数やサブルーチンのように、ある特定の作業を行うロジックをまとめたブロックですが、クラスの一部として定義する点が大きな特徴です。

    • インスタンスメソッド:インスタンスに属するメソッドで、「インスタンス名->メソッド名」のように呼び出します。インスタンス固有の動作を実装します。
    • クラスメソッド(スタティックメソッド):クラス自体に属するメソッドで、インスタンス化せずに「クラス名=>メソッド名」で呼び出せます。

    クラスとメソッドの定義

    ABAPでは、クラス定義部(DEFINITION)クラス実装部(IMPLEMENTATION) を分けて記述します。

    トランザクションコード SE24 でもGUIベースで同様の概念があります。

    クラス定義部(DEFINITION)と実装部(IMPLEMENTATION)

    CLASS zcl_human DEFINITION PUBLIC.
      PUBLIC SECTION.
        DATA: mv_name  TYPE string,   "動的属性(インスタンス属性)
              mv_age   TYPE i.
    
        METHODS: constructor
          IMPORTING iv_name TYPE string
                    iv_age  TYPE i.
    
        METHODS: run.   "インスタンスメソッド
        CLASS-METHODS: show_count. "クラスメソッド(スタティックメソッド)
    ENDCLASS.
    
    
    CLASS zcl_human IMPLEMENTATION.
    
      METHOD constructor.
        me->mv_name = iv_name.
        me->mv_age  = iv_age.
      ENDMETHOD.
    
      METHOD run.
        "走る処理
        WRITE: / me->mv_name, 'は走っています。'.
      ENDMETHOD.
    
      METHOD show_count.
        " 静的メソッドのサンプル
        " 例:全体で何人のインスタンスがあるかを表示するとか
        WRITE: / 'クラスメソッド: インスタンス総数を表示します。'.
      ENDMETHOD.
    
    ENDCLASS.
    

    PUBLIC SECTION / PROTECTED SECTION / PRIVATE SECTION

    • PUBLIC SECTION は、他のプログラムやクラスからも参照・呼び出し可能な領域です。
    • PROTECTED SECTION は、サブクラス(継承)からはアクセスできるが、外部プログラムからはアクセス不可。
    • PRIVATE SECTION は、そのクラス内部からのみアクセス可能。

    アクセスレベル(PUBLIC/PROTECTED/PRIVATE)

    ABAPクラスは、外部への公開度をセクションによって管理します。これにより、必要な部分だけを公開し、内部の実装を隠蔽(カプセル化)できます。

    コンストラクタ(METHODS constructor)

    コンストラクタは、インスタンス生成時に自動的に呼び出される特別なメソッドです。初期化処理や必須の属性設定が必要な場合に使います。ABAPでは METHODS constructor として定義します。

    インスタンス化

    クラスを使うには、インスタンス(オブジェクト)を生成する必要があります。ABAPでは以下のように記述します。

    DATA: lo_human TYPE REF TO zcl_human.
    
    CREATE OBJECT lo_human
      EXPORTING
        iv_name = '太郎'
        iv_age  = 20.
    
    • TYPE REF TO <クラス名> は、クラスの参照型を意味します。
    • CREATE OBJECT でインスタンス(実体)を生成します。
    • コンストラクタが定義されていれば、EXPORTING で初期値を渡せます。

    メソッドの呼び出し

    インスタンスメソッドの呼び出し

    インスタンスメソッドは、生成したインスタンスを介して呼び出します。
    モダンな構文では、<インスタンス名>-><メソッド名> と記述します。

    lo_human->run( ).

    レガシーな構文では、以下のようにも記述できます。

    CALL METHOD lo_human->run.

    クラスメソッド(スタティックメソッド)の呼び出し

    クラスメソッド(スタティックメソッド)は、インスタンスを生成しなくても呼び出せます。
    クラス名=>メソッド名」が基本です。

    CALL METHOD zcl_human=>show_count.

    新しい書き方では、CALL METHOD を省略して以下のようにも記述可能です。

    zcl_human=>show_count( ).

    CALL METHOD の省略記法

    ABAP NetWeaver 7.40以降では、CALL METHOD を省略し、直接 クラス名=>メソッド名( ) または インスタンス名->メソッド名( ) のように記述できます。
    可読性の好みやプロジェクトルールによって使い分けましょう。

    汎用モジュールとの違い

    汎用モジュール(Function Module) は、どのプログラムからでも呼び出せる一方、クラスメソッドは特定のクラスに属します。
    ABAPでは、クラスメソッドを利用すれば、

    • カプセル化(関連するデータや処理をひとまとめに管理)
    • 継承
    • ポリモーフィズム(同名メソッドをクラスごとに実装)

    など、オブジェクト指向のメリットを活かした設計が可能です。

    ただし、スタティックメソッドはインスタンス化不要で呼び出せるので、汎用モジュールと呼び出しやすさの点では似ています。
    しかし、「あるクラスに紐付いた機能」という点が明確になるため、プログラムの構造や責務が分かりやすくなるのが大きな利点です。

    実際のクラス・メソッド使用例

    実際のSAP標準クラス(例: CL_ABAP_LIST_UTILITIES)を呼び出すコード例を見てみましょう。

    DATA: lv_field     TYPE string VALUE 'TMP_NAME3',
          lv_display   TYPE string.
    
    CALL METHOD CL_ABAP_LIST_UTILITIES=>REPLACE_INTO_DISPLAY_LAYOUT
      EXPORTING
        field          = lv_field
        display_offset = 40
        display_length = 0
      CHANGING
        display_data   = lv_display.
    
    " または、モダンな構文で記述
    CL_ABAP_LIST_UTILITIES=>REPLACE_INTO_DISPLAY_LAYOUT(
      EXPORTING
        field          = lv_field
        display_offset = 40
        display_length = 0
      CHANGING
        display_data   = lv_display
    ).
    
    • 上記の例はクラスメソッド呼び出しです(CL_ABAP_LIST_UTILITIES=>...)。
    • EXPORTINGCHANGING でパラメータを渡していることがわかります。

    まとめ

    本記事では、ABAPにおけるクラスとメソッドの基礎から具体的なサンプル実装、そして汎用モジュールとの違いを解説しました。主なポイントは以下のとおりです。

    1. クラス定義で属性(動的/静的)やメソッドをまとめて管理することで、データと処理のカプセル化が可能。
    2. インスタンスメソッドはオブジェクトに属する動作を実装し、クラスメソッド(スタティックメソッド) はインスタンス化不要で呼び出し可能。
    3. コンストラクタ(METHODS constructor) を使ってインスタンス化時の初期値や必須設定を確実に行う。
    4. CALL METHOD の古い構文と、新しい ->=> の呼び出し構文を両方理解し、プロジェクトルールや可読性に応じて使い分ける。
    5. 汎用モジュールとの大きな違いは、オブジェクト指向によるカプセル化や継承などの恩恵が得られるかどうか。

    ABAPでもオブジェクト指向を活用することで、保守性・拡張性の高いプログラムを実現できます。慣れないうちは少しとっつきにくいかもしれませんが、ぜひクラス設計を意識した開発にチャレンジしてみてください。

  • ABAP 7.4と7.5以降の新しい文法:内部テーブル操作の基本

    ABAP 7.4と7.5以降の新しい文法:内部テーブル操作の基本

    S/4 HANAで使用可能な文法「ABAP7.4以降」について、7.4と7.5より前の文法と比較しながら解説します。この記事では、特に内部テーブルから特定の行を抽出する方法に焦点を当てています。このテクニックは、データ分析やデータ管理において非常に重要なスキルとなります。

    ABAP 7.5以降の新しいSELECT文記述方法について

    ABAP 7.5以降では、SELECT文の記述方法が大幅に拡張され、より柔軟なデータ操作が可能になりました。この記事では、その新しい記述方法について詳しく解説します。

    リテラル値、固定値、変数値を取得項目に指定する

    ABAP 7.5xでは、リテラル値、固定値、変数値をSQLの取得項目として指定できます。これにより、より直感的なコード記述が可能になりました。以下に具体的なコードを示します。

    DATA: var1 TYPE char10 VALUE 'VARIABLES'.
    CONSTANTS: CONS1 TYPE char10 VALUE 'CONSTANTS'.
    
    SELECT FROM vbak AS t1
        FIELDS
          'LITERAL' AS lit,                  "リテラル値
          @var1 AS  var_field,               "変数
          @CONS1 AS cns_field,               "固定値
          @abap_on as check,                 "予約語
          @( VALUE vbak-erdat( ) ) AS erdat, "初期値
       INTO TABLE @DATA(results).
    

    演算値を取得項目に指定する

    ABAP 7.5以降では、テーブル項目値や変数、数値リテラルを使用した演算結果を項目値として格納することができます。以下に具体的なコードを示します。

    SELECT FROM vbap
        FIELDS
           netwr,  "項目IDがNETWRで定義される
           kwmeng, "項目IDがkwmengで定義される
           netwr * 100 AS jpy_netwr, "演算結果
           CASE kwmeng "条件分岐
            WHEN 0 THEN 0
            ELSE division( netwr , kwmeng, 3 )
           END AS calc2,
           CASE kwmeng 
             WHEN 0 THEN CAST( 0 AS FLTP )  "結果がFLTP型になるため
             ELSE CAST( netwr AS FLTP ) / CAST( kwmeng AS FLTP )
           END AS calc3
        INTO TABLE @DATA(results).
    

    文字列編集処理の結果を項目に設定する

    ABAP 7.5xでは、簡単な文字列の編集処理がSQLでできるようになりました。以下に具体的なコードを示します。

    SELECT FROM sflight
      FIELDS
        @abap_on AS check, "固定値
        carrid,
        connid,
        concat_with_space( carrid,connid,4 ) AS cws,
        left( planetype, 3 ) AS plane_series1,
        length( planetype ) as plane_series2,
        lpad( CAST( paymentsum AS
    

    ABAP7.5以降では、SELECT文の条件にFOR ALL ENTRIES を指定して内部テーブルの項目を抽出条件として使うことができます。

    データ宣言

    これまで事前に定義する必要があったデータオブジェクトをabap命令の一部として定義できます。

    データオブジェクト・・・変数、構造、内部テーブルのこと

    変数の宣言

    DATA(LT_XXX) = ‘HELLO’

    構造やフィールドシンボルも同じように宣言して使うことができます。

    内部テーブルの宣言

    DATA: BEGIN OF <内部テーブル> Occurs 0,

    具体例:

    DATA: BEGIN OF LT_TAB Occurs 0,
      MVKE-VKORG LIKE MVKE-VORG,
      ZZCONTS LIKE ZZCNTS,
    END OF LT_TAB.

    このように内部テーブルを記述できるのでコードが短くて済みます。

    「Ocuurs 0 」というのは、データが格納されるまでレコードが0という意味です。つまり、内部テーブルが宣言された段階ではヘッダだけを持つ内部テーブルということになります。

    TYPE STANDARD TABLE OFを使用していなくても、OCCURSを使用した宣言は内部テーブルを作成します。ただし、現在のABAPのバージョンでは、OCCURSを使用する代わりにTYPE STANDARD TABLE OFやTYPE SORTED TABLE OFなどのより明確な構文を使用することが推奨されています。

    ABAPの内部テーブル操作について

    ABAPでは、内部テーブルを使用してデータを一時的に格納し、操作することができます。この記事では、その操作方法について詳しく解説します。

    内部テーブルから特定の行を抽出する

    ABAP 7.4では、以下のようにREAD TABLE文を使用して行を抽出していました。

    READ TABLE lt_bkpf INTO ls_bkpf INDEX 1.

    しかし、ABAP 7.5では、新しい文法を使用して同じ操作を行うことができます。

    DATA(ls_bkpf) = lt_bkpf[ 1 ].

    この宣言方法では自動的に左側の構造は右側の内部テーブルと同じ項目を持つ型になるようにします。

    この文法は、より直感的で記述するコードを短くすることができます。ですが、以下のような欠点もあります。

    • BINARY SEARCHがない
    • SY-TABIXが更新されない

    BINARY SEARCHがないと、大きな内部テーブルを効率的に検索することができません。また、SY-TABIXが更新されないため、テーブルの現在のインデックスを追跡することができません。

    また、新文法を使って内部テーブルから特定の行を抽出する方法は以下の通りです。

    DATA(ls_bkpf) = lt_bkpf[ bukrs = ‘0001’ ].

    このコードは、内部テーブルlt_bkpfから、bukrsが’0001’の行を抽出します。このように、新文法を使用すると、特定の条件を満たす行を簡単に抽出することができます。

  • APPEND命令まとめ

    APPEND命令まとめ

    APPEND命令とは

    APPEND命令とは、内部テーブルにデータを格納できる命令です。この命令では、内部テーブルの一番下の行に格納されていきます。

    以下が基本的な記述方法になります。構造から内部テーブルへ格納するのが一般的です。

    APPEND (構造) TO (内部テーブル).

    この命令では構造から内部テーブルに1行分格納することができます。

    APPEND INITIAL (構造) TO (内部テーブル).

    内部テーブルの先頭行にレコードを格納したい場合は「INITIAL」を使います。

    フィールドシンボルを割り当てて内部テーブルに格納する

    構造から内部テーブルに格納するだけでなく、フィールドシンボルを割り当てて内部テーブルに格納することもできます。

    APPEND LINE TO (内部テーブルA) ASSIGNING (フィールドシンボル).

    (フィールドシンボル)-項目A = XXX.

    (フィールドシンボル)-項目B = XXX.

    直接値を指定して格納する

    APPEND VALUE #( 項目A = ‘XXX’ 項目B = ‘YYY’ ) TO 内部テーブル.

    この命令は「#」によって構造体が自動で作成され、内部テーブルに追加したいデータをカッコ内に記述します。

    APPEND命令ではデータを内部テーブルの最後の行に追加しています。

    LOOP文を使って複数行格納する

    内部テーブルから別の内部テーブルへデータを格納したい場合、LOOP文とAPPEND命令を組み合わせて使用することができます。

    LOOP AT (内部テーブルA) INTO (構造).

    APPEND (構造) TO (内部テーブルB).

    ENDLOOP.

    APPEND文のみで複数行格納する

    内部テーブルから別の内部テーブルに複数行格納する際にAPPEND命令だけを使うこともできます。

    APPEND LINES OF (内部テーブルA) TO (内部テーブルB).

    https://help.sap.com/doc/saphelp_nw70/7.0.12/ja-JP/fc/eb36c8358411d1829f0000e829fbfe/content.htm?no_cache=true

  • 構造宣言・データ宣言

    構造宣言・データ宣言

    構造宣言

    構造の作成

    パターン
    1から作成する(基本形)
    TYPES:
      BEGIN OF TY_S_DATA,
        A TYPE CHAR1,
        B TYPE CHAR1,
      END OF TY_S_DATA.
    
    パターン
    DBテーブルと同じ項目を参照して構造を作成する
    TYPES:
      BEGIN OF TY_S_DATA,
        A TYPE FLIGHT-A,
        B TYPE FLIGHT-B,
      END OF TY_S_DATA.

    テーブル型の作成

    TYPES:
      BEGIN OF TY_S_DATA,
        A TYPE CHAR1,
        B TYPE CHAR1,
      END OF TY_S_DATA,
    
      TY_T_DATA TYPE STANDARD TABLE OF TY_S_DATA.

    TY_T_DATAはテーブル型。

    データ宣言

    ワークエリアの作成

    パターン
    構造型を参照する
    TYPES:
      BEGIN OF TY_S_DATA,
        A TYPE CHAR1,
        B TYPE CHAR1,
      END OF TY_S_DATA.
    DATA: GW_WORKAREA TYPE TY_S_DATA.
    パターン
    DBテーブルを参照する
    DATA:GW_EORKAREA TYPE FLIGHT.

    FLIGHTはDBテーブル名かアドオンテーブル名となる

    内部テーブルの作成

    パターン
    テーブル型を参照
    TYPES:
      BEGIN OF TY_S_DATA,
        A TYPE CHAR1,
        B TYPE CHAR1,
      END OF TY_S_DATA,
    
      TY_T_DATA TYPE STANDARD TABLE OF TY_S_DATA.
    
    DATA: GT_TABLE TYPE TY_T_DATA.
    パターン
    テーブル型を参照しない
    TYPES:
      BEGIN OF TY_S_DATA,
        A TYPE CHAR1,
        B TYPE CHAR1,
      END OF TY_S_DATA.
    
    DATA: GT_TABLE TYPE STANDARD TABLE OF TY_S_DATA.
    パターン
    DBテーブルを参照
    DATA: GT_TABLE TYPE STANDARD TABLE OF FLIGHT.
  • ALVツールバーにボタンを追加する

    ALVツールバーにボタンを追加する

    ALVツールバーとは

    ALVの標準の機能であり、アプリケーションツールバーの略です。ALVツールバーには様々な機能ボタンが表示され、ユーザーはボタンを押すことで出力された画面のデータを並べ替えたりデータをエクセルに出力したりすることが可能です。

    ツールバーにボタンを追加する手順

    ALVツールバーには、ボタンを追加して任意の機能を作成することができます。

    手順は以下の通りです。

    STEP
    GUIステータスでボタンを作成

    STEP
    ボタンを呼び出すサブルーチンを作成

    STEP
    ALVで出力する。

    GUIステータスでボタンを作成

    トランザクションコード41でボタンを作成します。

    STEP
    ADDONプログラムのステータスを作成する

    STEP
    ボタンを作成する

    まず、REUSE_ALV_GRID_DISPLAYで使用されているGUIステータスですが、プログラムID:SAPLKKBL、ステータス:STANDARD_FULLSCREENとなっています。これを自分のテストプログラムにコピーし、実行ボタンをつけます。

    ボタンを呼び出すサブルーチンを作成

    ボタンを作成したら、プログラム内にサブルーチンを作成します。

    FORM PF_STATUS
     USING I_EXTAB TYPE SLIS_T_EXTAB.
      SET PF-STATUS 'LIST'.
    ENDFORM.

    サブルーチン内でこのように記述することでプログラム内にGUIステータスを作成することができます。

    「LIST」の部分はアドオンプログラムのステータス名です。名前は自由に決めて大丈夫です。

    SET PF-STATUSの記述によって機能ボタンを呼び出すことが可能になるが、不要な機能が含まれている場合がある。その場合、「EXCLUDING」を指定することで不要なコードを削除することができる。

    FORM PF_STATUS
      USING I_EXTAB TYPE SLIS_T_EXTAB.
      SET PF_STATUS 'LIST' EXCLUDING I_EXTAB.
    ENDFORM.

    USINGパラメーターの記述がないとエラーになるので、要注意!

    ALVで出力する

    ①「REUSE_ALV_GRID_DISPLAY」の汎用モジュールにあるi_callback_pf_status_setパラメータにGUIステータスを記述したサブルーチン名を渡します。

    ② i_callback_user_command パラメーターにボタンが押された際の処理を記述したサブルーチン名を渡します。

    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
     EXPORTING
       i_callback_program                = sy-repid
       i_callback_pf_status_set          = 'PF_STATUS'
       i_callback_user_command           = 'HANDLE_USER_COMMAND'
       is_layout                         = s_alv_layout_cat
       it_fieldcat                       = it_alv_field_cat
       i_default                         = 'X'
       i_save                            = 'A'
       it_events                         = it_alv_event_cat
      TABLES
        t_outtab                          = gt_zprice
    * EXCEPTIONS
    *   PROGRAM_ERROR                     = 1
    *   OTHERS                            = 2
              .
    
    *---------------------------------------------------------------------*
    *       FORM SET_PFSTATUS                                             *
    *---------------------------------------------------------------------*
    *       ........                                                      *
    *---------------------------------------------------------------------*
    *  -->  EXTAB                                                         *
    *---------------------------------------------------------------------*
    FORM PF_STATUS USING extab TYPE slis_t_extab.
      SET PF-STATUS 'LIST'.
    ENDFORM.

    ▼参考サイト①

    ▼参考サイト②

    Q&A

    上記の処理を実装してもボタンが表示されなかった

    アプリケーションツールバーの設定画面(T-code41)で機能コードの先頭に&をつける

    まとめ

    今回は、ALVで追加ボタンを作成してALVツールバーに表示する方法を紹介しました。

    ここまでだとALVの表示画面でボタンを押しても何も機能しません。(ボタンを押したときの処理作成していないからです)

    ということで、次はボタンを押したときの機能の実装方法について紹介していきます。

  • FOR ALL ENTRIES IN の使い方

    FOR ALL ENTRIES IN の使い方

    FOR ALL IN ENTRIES 命令は、主にSELECT文を使用する際に別の内部テーブルの項目を抽出条件として記述したいときに使われます。

    FOR ALL ENTRIES INの特徴

    抽出条件に他の内部テーブルの項目を指定できる。

    抽出条件とは、SELECT文ではWHERE句のことを指します。

    この命令を使うことで、他のテーブルの項目を抽出条件として指定できます。

    基本的な文法

    SELECT field1 field2
      FROM dbtable
      FOR ALL ENTRIES IN itab
      WHERE field1 = itab-field1 AND
            field2 = itab-field2
      INTO TABLE result.
    

    この例では、dbtableテーブルからfield1とfield2の項目をresultテーブルに格納します。

    <抽出条件>

    • dbtableテーブルのfield1の項目とitabテーブルのfield1の項目が等しい
    • dbtableテーブルのfield2の項目とitabテーブルのfield2の項目が等しい

    この命令を使う際には以下のことに注意する必要があります。

    • 内部テーブルを複製する必要がある
    • ソート、重複削除をする必要がある
    • ORDER BYと同時に指定することはできない。
  • SQL

    SQL

    OPENSQL

    ABAPプログラミングで用いられるSQLはOPENSQLといいます。

    SQLは、データベースから内部テーブルにデータを抽出する際に使う命令です。

    OPEN SQLは複雑なSQLを記述することなく、データベーステーブルからデータを抽出することができます。

    基本的なSELECT文

    READ、SELECT

    READとSELECTの特徴をまとめています。

    READ文は内部テーブルからデータを読み取るのに対し、SELECT文はデータベースからデータを読み取ります。

    READ

    • READステートメントは、内部テーブルからデータを読み取るために使用されます。
    • プログラムの実行中にデータを操作し、処理するために使用される一時的なデータ構造です。
    • READ TABLE itab INTO wa WHERE ... または READ TABLE itab WITH KEY ... といった形式で使用されます。
    • READは、指定された条件に一致する内部テーブルの最初のレコードを見つけるのに役立ちます。見つかった場合は、そのレコードをワークエリアやフィールドシンボルに割り当てます。
    • READステートメントは通常、線形検索またはバイナリ検索を使用して、内部テーブル内のデータを検索します。

    SELECT

    • SELECTステートメントは、データベーステーブルからデータを読み取るために使用されます。
    • データベーステーブルは、永続的なデータストレージであり、プログラムの実行間にデータが保持されます。
    • SELECT ... FROM dbtab WHERE ... INTO TABLE itab といった形式で使用されます。
    • SELECTは、指定された条件に一致するデータベーステーブルのレコードを抽出し、内部テーブルに格納するのに役立ちます。
    • SELECTステートメントは、データベースからデータを取得するためのクエリを実行します。

    複数のテーブルを内部結合してデータを取得する方法はこちらの記事で紹介しています。

    フィールドシンボル

    フィールドシンボルとは、変数のことで内部テーブルの1つ1つのレコードにフィールドシンボルを割り当てることができます。

    フィールドシンボルは、データオブジェクトへの動的な参照を提供し、メモリ内のデータを簡単にアクセスおよび操作できる

    フィールドシンボルを用いることで、ワークエリアを定義しなくてもよいためメモリを節約することができます。

    ・フィールドシンボルはワークエリアと同じようなものと考えてよい。

    LOOP処理

    LOOP AT (内部テーブル) ASSIGNING FIELD-SYMBOL(<xxx>).

  • ALV出力の基本

    ALV出力の基本

    ALVはデータの一覧表示方法の一つです。ALVを使うと、データの表示や表示機能を簡単に実装できます。

    AVL出力の流れ

    STEP
    データの取得

    ・構造、ワークエリア、内部テーブル、プログラムID、カタログを定義する。

    ・SQLでデータベースの値を内部テーブルに格納する。

    STEP
    フィールドカタログの設定

    A. 汎用モジュール”REUSE_ALV_FIELDCATALOG_MERGE

    B.  手入力で項目を指定

    STEP
    プログラムIDを渡す

    XXX = SY-REPID.

    STEP
    ALV出力

    ・汎用モジュール”REUSE_AVL_GRID_DISPLAY“(必須)

    フィールドカタログとは

    ALV出力に表示される各列の情報を定義する構造のことです。

    この記事では、フィールドカタログの設定が手入力になっていますが、汎用モジュールでフィールドカタログを設定することができます。

    用語解説

    プログラムID

    プログラムIDは、現在実行中のABAPプログラムの一意な識別子です。システムフィールドSY-REPIDを使用して取得できます。プログラムIDは、フィールドカタログの生成やALV出力の設定に関連する関数モジュールの呼び出し時に使用されます。プログラムIDを指定することで、関数モジュールは現在実行中のプログラムに関連する情報を取得し、正確なフィールドカタログやALV出力の設定を行うことができます。

    プログラムIDは現在実行中のプログラムを識別するためのもの

    カタログ

    カタログは、ALV出力に表示される各列の情報を定義するための構造体です。具体的には、SLISタイププールで定義されたSLIS_FIELDCAT_ALV型の内部テーブル(例:lt_fieldcat)で構成されています。カタログには、列のタイトル、データ型、列幅、表示・非表示、ソート順序などの情報が含まれています。

    ALV出力の例①

    以下にALV出力の例を挙げています。

    この例では、フィールドカタログを手入力で作成する必要があります。

    REPORT ZALV_SAMPLE.
    TYPE-POOLS: SLIS. " SLISタイププールを使用するための宣言
    
    TYPES: BEGIN OF ty_sflight,
             carrid TYPE sflight-carrid,
             connid TYPE sflight-connid,
             fldate TYPE sflight-fldate,
           END OF ty_sflight.
    
    DATA: lt_sflight TYPE STANDARD TABLE OF ty_sflight, " 内部テーブル
          wa_sflight TYPE ty_sflight, " ワークエリア
          lt_fieldcat TYPE SLIS_T_FIELDCAT_ALV, " フィールドカタログの内部テーブル
          wa_fieldcat TYPE SLIS_FIELDCAT_ALV, " フィールドカタログのワークエリア
          gd_repid TYPE sy-repid. " プログラムID
    
    * 1. データの取得
    SELECT * FROM sflight
      INTO TABLE lt_sflight
      UP TO 50 ROWS.
    
    * 2. フィールドカタログの作成
    CLEAR wa_fieldcat.
    wa_fieldcat-fieldname = 'CARRID'.
    wa_fieldcat-seltext_l = 'Airline Carrier'.
    APPEND wa_fieldcat TO lt_fieldcat.
    
    CLEAR wa_fieldcat.
    wa_fieldcat-fieldname = 'CONNID'.
    wa_fieldcat-seltext_l = 'Connection Number'.
    APPEND wa_fieldcat TO lt_fieldcat.
    
    CLEAR wa_fieldcat.
    wa_fieldcat-fieldname = 'FLDATE'.
    wa_fieldcat-seltext_l = 'Flight Date'.
    APPEND wa_fieldcat TO lt_fieldcat.
    
    * 3. プログラムIDの取得
    gd_repid = sy-repid.
    
    * 4. ALV出力
    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
        i_callback_program = gd_repid
        it_fieldcat        = lt_fieldcat
      TABLES
        t_outtab           = lt_sflight.
    

    解説①

    この例では、以下の手順でALV出力を実現しています。

    1. データの取得:sflightテーブルからデータを選択し、内部テーブルlt_sflightに格納しています。
    2. フィールドカタログの作成:各列について、フィールド名(fieldname)と列のタイトル(seltext_l)を設定し、フィールドカタログの内部テーブルlt_fieldcatに追加しています。
    3. プログラムIDの取得:sy-repidを使用して現在のプログラムIDを取得し、gd_repidに格納しています。
    4. ALV出力:REUSE_ALV_GRID_DISPLAY関数モジュールを呼び出し、必要なパラメータ(プログラムID、フィールドカタログ、データを含む内部テーブル)を渡してALV出力を表示しています。

    ALV出力の例②

    この例では、汎用モジュールを使ってフィールドカタログの設定を自動で行います。

    REPORT ZALV_SAMPLE_AUTO.
    TYPE-POOLS: SLIS. " SLISタイププールを使用するための宣言
    
    TYPES: BEGIN OF ty_sflight,
             carrid TYPE sflight-carrid,
             connid TYPE sflight-connid,
             fldate TYPE sflight-fldate,
           END OF ty_sflight.
    
    DATA: lt_sflight TYPE STANDARD TABLE OF ty_sflight, " 内部テーブル
          lt_fieldcat TYPE SLIS_T_FIELDCAT_ALV, " フィールドカタログの内部テーブル
          gd_repid TYPE sy-repid. " プログラムID
    
    * 1. データの取得
    SELECT * FROM sflight
      INTO TABLE lt_sflight
      UP TO 50 ROWS.
    
    * 2. プログラムIDの取得
    gd_repid = sy-repid.
    
    * 3. フィールドカタログの自動生成
    CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
      EXPORTING
        i_program_name     = gd_repid
        i_internal_tabname = 'TY_SFLIGHT'
      CHANGING
        ct_fieldcat        = lt_fieldcat.
    
    * 4. ALV出力
    CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
      EXPORTING
        i_callback_program = gd_repid
        it_fieldcat        = lt_fieldcat
      TABLES
        t_outtab           = lt_sflight.
    

    例②の解説

    1. データの取得:sflightテーブルからデータを選択し、内部テーブルlt_sflightに格納しています。
    2. プログラムIDの取得:sy-repidを使用して現在のプログラムIDを取得し、gd_repidに格納しています。
    3. フィールドカタログの自動生成:REUSE_ALV_FIELDCATALOG_MERGE関数モジュールを呼び出し、プログラムIDと内部テーブルのタイプ名(TY_SFLIGHT)を渡すことで、フィールドカタログを自動生成し、lt_fieldcatに格納しています。
    4. ALV出力:REUSE_ALV_GRID_DISPLAY関数モジュールを呼び出し、必要なパラメータ(プログラムID、フィールドカタログ、データを含む内部テーブル)を渡してALV出力を表示しています。

    ボタンを追加する

    ALVの基本的な表示に加えて、ボタンを追加することも可能です。

    詳しくはこちらの記事で紹介しています。