峯文さんの投稿
拡張開発に投稿されました 続きを読む

標準機能の拡張を検討する際に、標準機能でどんなカスタマExitを用意されているかを調査しなければならない場面がしばしば出てきます。 このトピックでは、カスタマExitの検索方法を取り上げて説明します。

STEP1

STEP2

STEP3

STEP4

STEP5

STEP6

STEP1

STEP2

STEP3

STEP1

STEP2

STEP3

STEP4

STEP5

STEP6

拡張開発に投稿されました 続きを読む

このトピックでは、既存のBadi実装を作成する方法や手順を取り上げて説明します。

1.BAdi定義名を指定

SE18でBAdiビルダ画面を開き、BAdi定義名を入力して照会ボタンを押下

2.BAdi定義照会画面表示

指定されたBAdi定義の照会画面が表示されます。

3.実装照会機能を選択

「実装」→「照会」をクリック

4.BAdi実装一覧画面表示

BAdi定義の実装一覧がポップアップで表示されます。

5.BAdi実装照会画面表示

BAdi定義の実装一覧ポップアップで、対象実装を選択して、確定すると、対象実装の照会画面が表示されます。

変更モードにしておけば、実装を有効化したり無効化したりすることができます。

拡張開発に投稿されました 続きを読む

このトピックでは、指定Badi定義の実装を検索する方法や手順を取り上げて説明します。

SE18でBAdiビルダ画面を開き、BAdi定義名を入力して照会ボタンを押下

指定されたBAdi定義の照会画面が表示されます。

「実装」→「照会」をクリック

BAdi定義の実装一覧がポップアップで表示されます。

BAdi定義の実装一覧ポップアップで、対象実装を選択して、確定すると、対象実装の照会画面が表示されます。

変更モードにしておけば、実装を有効化したり無効化したりすることができます。

ALV開発に投稿されました 続きを読む

ALV出力時の項目カテゴリ制御は主に以下三つの方法があります。

  • 自動生成
  • マニュアル生成
  • 半自動生成

このトピックでは、各方法をそれぞれ取り上げて説明します。

出力テーブルの構造がデータディクショナリに定義されている場合、汎用モジュールを呼び出す際に入力パラメータI_STRUCTURE_NAMEで構造体の名前を指定することにより、項目カテゴリは内部に自動的に生成されることになります。 ここで注意すべきのは、出力テーブルは必ず該当構造体を使って定義しなけれなりません。そうではない場合、なかみが同じでも、実行時ランタイムエラーが発生します。

16をこのやり方で見直す場合、ABAPディクショナリに該当構造体を定義しておけば、以下のようにソースプログラムがすごくシンプルになります。

REPORT  YLWF_ALV_FC_AUTO.
*ALV用のタイププール
TYPE-POOLS: slis.
TYPES ttbl_account_doc TYPE STANDARD TABLE OF YLWF_FC_AUTO_STRUC.
DATA g_account_doc TYPE YLWF_FC_AUTO_STRUC.
DATA gtbl_account_doc TYPE ttbl_account_doc.
DATA: g_bukrs TYPE bukrs.
SELECTION-SCREEN BEGIN OF BLOCK LAYOUT WITH FRAME .
SELECT-OPTIONS: S_BUKRS FOR  g_bukrs.
SELECTION-SCREEN END OF BLOCK LAYOUT.
START-OF-SELECTION.
  SELECT
    bukrs
    belnr
    gjahr
    buzei
    pswbt
    pswsl
  FROM bseg
  INTO CORRESPONDING FIELDS OF TABLE gtbl_account_doc
  UP TO 10 ROWS
  WHERE
    bukrs in  s_bukrs.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
     i_structure_name = 'YLWF_FC_AUTO_STRUC'
     i_grid_title       = '伝票照会'
   TABLES
      t_outtab           = gtbl_account_doc
    EXCEPTIONS
     OTHERS             = 0
      .

データディクショナリでは、テーブルデータ型LVC_T_FCAT によって項目カタログが定義されています。項目カタログテーブルの各行には、出力テーブルの項目が記述されています。 項目カタログのマニュアル生成は、上記のテーブルを作成して、汎用モジュールを呼び出す際に入力パラメータIT_FIELDCATとして受け渡します。

実装の詳細は、16をご参照ください。

項目カタログの半自動生成は、

  1. ABAPディクショナリーの構造体から項目カタログを自動生成する
  2. 自動生成された項目カタログに対してマニュアル修正を加える

というプロセスになります。

ABAPディクショナリーの構造体から項目カタログを自動生成するには、汎用モジュールLVC_FIELDCATALOG_MERGEを使用します。

ALV開発に投稿されました 続きを読む

ALVを出力する前に、選択画面でユーザにALVの出力レイアウトを指定してもらう場面があります。 このトピックでは、16を元に出力レイアウト選択機能を追加する例を取り上げて説明します。

変数の定義を追加

DATA: g_variant TYPE disvariant.
DATA:  VG_SAVE       TYPE CHAR1,
           VG_EXIT       TYPE CHAR1,
           VG_VARIANT    TYPE DISVARIANT,
           VG_VARIANT_EX TYPE DISVARIANT.

選択パラメータを追加

PARAMETERS:     P_LAYOUT TYPE DISVARIANT-VARIANT.

初期化処理を追加

初期化処理で、デフォルトのバリアント値を取得して自動提案します。

INITIALIZATION.
  VG_SAVE = 'A'.   "ユーザ定義レイアウトとグローバルレイアウトの両方を保存できます。
  VG_VARIANT-REPORT = SY-REPID.
  VG_VARIANT_EX = VG_VARIANT.
  • バリアントの初期化
    CALL FUNCTION 'REUSE_ALV_VARIANT_DEFAULT_GET'
    EXPORTING
    I_SAVE = VG_SAVE
    CHANGING
    CS_VARIANT = VG_VARIANT_EX
    EXCEPTIONS
    WRONG_INPUT = 1
    NOT_FOUND = 2
    PROGRAM_ERROR = 3
    OTHERS = 4.
    IF SY-SUBRC = 0.
    P_LAYOUT = VG_VARIANT_EX-VARIANT.
    ENDIF.

検索ヘルプ実装

* AT SELECTION-SCREEN  選択画面:レイアウトのヘルプ設定
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_LAYOUT .
  • レイアウトのヘルプ設定
    CALL FUNCTION 'REUSE_ALV_VARIANT_F4'
    EXPORTING
    IS_VARIANT = VG_VARIANT
    I_SAVE = VG_SAVE
    IMPORTING
    E_EXIT = VG_EXIT
    ES_VARIANT = VG_VARIANT_EX
    EXCEPTIONS
    NOT_FOUND = 1
    PROGRAM_ERROR = 2.
    IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
    WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ELSE.
    IF VG_EXIT = SPACE.
    P_LAYOUT = VG_VARIANT_EX-VARIANT.
    ELSE.
    ENDIF.
    ENDIF.
  • 入力チェックを追加

    入力チェック処理で、入力されたレイアウトバリアント値が存在するかどうかをチェックします。

    AT SELECTION-SCREEN.
    
  • バリアント存在チェック
    IF P_LAYOUT IS NOT INITIAL.
    VG_VARIANT-VARIANT = P_LAYOUT.
    CALL FUNCTION 'REUSE_ALV_VARIANT_EXISTENCE'
    EXPORTING
    I_SAVE = VG_SAVE
    CHANGING
    CS_VARIANT = VG_VARIANT
    EXCEPTIONS
    WRONG_INPUT = 1
    NOT_FOUND = 2
    PROGRAM_ERROR = 3.
    IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
    WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
    ENDIF.
    ENDIF.
  • レイアウト選択値を反映

    汎用モジュールを呼び出してALV一覧出力を行う時、汎用モジュールの入力パラメータとしてレイアウトの選択値を受け渡します。

      CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
  •   i_callback_pf_status_set = 'PF_STATUS_SIMP'
    
    it_fieldcat = gtbl_fieldcat
  •  i_structure_name = 'YLWF_AL'
    
  • is_layout          = g_layout
    IS_VARIANT    = VG_VARIANT
    i_save             = VG_SAVE
    
    TABLES
    t_outtab = gtbl_account_doc
    EXCEPTIONS
  •  program_error      = 0
    
    OTHERS = 0
  • ALV開発に投稿されました 続きを読む

    このトピックでは、ALVコントロールを利用したALV出力実装の基本方法を取り上げて説明します。

    イベントキャッチ

    *---------------------------------------------------------------------*
    *       クラス イベントキャッチ(定義)
    *       CLASS lcl_event_receiver DEFINITION
    *---------------------------------------------------------------------*
    CLASS LCL_EVENT_RECEIVER DEFINITION .
      PUBLIC SECTION.
    *   選択行のダブルクリックイベント
    *   CATCH THELINE BOUBLECLICK EVENT
        METHODS CATCH_DOUBLECLICK
          FOR EVENT DOUBLE_CLICK OF CL_GUI_ALV_GRID
          IMPORTING E_ROW
                    E_COLUMN.
    *   グリッドのツールバー(PDFボタン=オン)
    *   CATCH THE TOOLBAR'S PDF BUTTON
        METHODS HANDLE_TOOLBAR_PDF
          FOR EVENT TOOLBAR  OF CL_GUI_ALV_GRID
          IMPORTING E_OBJECT.
    *   グリッドのコマンド
    *   CATCH THE GRID COMMAND EVENT
        METHODS HANDLE_UCOMM
          FOR EVENT USER_COMMAND  OF CL_GUI_ALV_GRID
          IMPORTING E_UCOMM  .
    ENDCLASS.                    "lcl_event_receiver DEFINITION
    

    ALV出力用コンテナ対象

    DATA  VG_GRID      TYPE REF TO CL_GUI_ALV_GRID.

    ALVイベントキャッチ

    DATA: EVENT_RECEIVER TYPE REF TO LCL_EVENT_RECEIVER.

    ALV出力用コンテナ対象をインスタンス化する。

        CREATE OBJECT VG_GRID
          EXPORTING
            I_PARENT = CL_GUI_CONTAINER=>SCREEN0.
      CALL METHOD VG_GRID->SET_TABLE_FOR_FIRST_DISPLAY
        EXPORTING
          IS_LAYOUT                     = WL_SLA
        CHANGING
          IT_OUTTAB                     = TG_ALV[]
          IT_FIELDCATALOG               = TG_FIELDCAT[]
        EXCEPTIONS
          INVALID_PARAMETER_COMBINATION = 1
          PROGRAM_ERROR                 = 2
          TOO_MANY_LINES                = 3
          OTHERS                        = 4.
      CALL METHOD VG_GRID->SET_READY_FOR_INPUT "
        EXPORTING
          I_READY_FOR_INPUT = 1.

    ALV出力用イベント対象をインスタンス化します。

    CREATE OBJECT EVENT_RECEIVER.

    ALV出力用イベント「ダブルクリック」を実装します。

    SET HANDLER EVENT_RECEIVER->CATCH_DOUBLECLICK FOR VG_GRID.

    「ツールバー」イベントを実装します。

    SET HANDLER EVENT_RECEIVER->HANDLE_TOOLBAR_FAX FOR VG_GRID 

    ALVを再表示します。

      CALL METHOD VG_GRID->REFRESH_TABLE_DISPLAY
        EXPORTING 

    IS_STABLE = WL_STABLE.

    ALV開発に投稿されました 続きを読む

    このトピックでは、ALVの項目カタログを取り上げて説明します。

    項目カタログは、ALVで出力される各列(項目)のデータ型情報等が定義されます。 項目カタログに格納される定義情報は、以下のように分類することができます。

    • 項目名
      内部出力テーブルの項目名を指定します。列定義構造体のキー項目になります。
    • データ型情報
      ABAPデータ型や出力長などの情報が定義されます。
      ABAPディクショナリーの項目を参照して定義するとマニュアルで定義するとの2パターンがあります。
    • 単位や通貨情報
      数量や金額などの項目は、それぞれ関連する単位や通貨の情報を定義する必要があります。
    • 列の書式情報
    • 列の出力オプション

    項目カタログの項目一覧は下記のリンクをご参考ください。 項目カタログの項目-SAP Help Portal

    基本的に、ALVを使用して表示する一覧ごとに項目カタログが必要です。項目カタログを生成する方法として、以下の方法があります。

    • データディクショナリ構造を使用して自動的に生成
    • ABAPプログラムでマニュアル生成
    • 上記の2 つの方法を組み合わせて半自動的に生成

    項目カタログ-SAP Help Portal

    レポート開発に投稿されました 続きを読む

    このトピックでは、ツールバー関連のプログラミングを取り上げて説明します。

    関連技術

    自動的に設定される選択画面の GUI ステータスでは、 アプリケーションツールバーに無効な 押ボタンが 5 つあり、これらに機能コード FC01 から FC05 までが割り当てられ ています。この命令を使用すると、機能コード FC0n の押ボタンが有効化されます。 n には 1 と 5 の間にある値を入力しなければなりません。 押ボタンを使用できるようにするには、 TABLES 命令を使用して、ABAP ディクショナリに由来する構造 SSCRFIELDS の インタ フェース作業領域を宣言しなければなりません。 選択画面を呼び出す前にインタフェース領域 sscrfields のコンポーネント functxt_0n にテキスト が割り当てられていると、 このテキストが該当の押ボ タン上に表示されます。割 り当てられていないと、押 ボタンにテキストは表示されません。

    サンプル

    SAP標準のMIR5請求書一覧照会トランザクションのエキスパートモード機能の実装を例として解説します。 * 画面イメージ * 機能概要 「エキスパートモード」ボタンを押下により、エキスパートモードの表示/非表示を切り替える * 実装詳細 ①選択画面の定義に対象機能コードのボタンを有効にする

    SELECTION-SCREEN FUNCTION KEY 1.

    ②INITIALIZATIONイベントブロックでボタンの初期表示テキストを設定

    sscrfields-functxt_01 = text-001. "エキスパートモード

    ③AT SELECTION /AT USER-COMMANDイベントブロックでボタン押下イベントを処理

    CASE sscrfields-ucomm.	
     WHEN 'FC01'.	
      IF status_expert = c_hide."元々エキスパートモードが閉じれれた場合	
       status_expert = c_show. "エキスパートモードフラグをONにする	
       sscrfields-functxt_01 = text-007."ボタンテキストを「エキスパートモード非表示」に	
      ELSE.              "元々エキスパートモードがオープンれれた場合	
       status_expert = c_hide."エキスパートモードフラグをOFFにする	
       sscrfields-functxt_01 = text-001. "ボタンテキストを「エキスパートモード」に	
      ENDIF.	
    ENDCASE.

    ④AT SELECTION-SCREEN OUTPUTイベントブロックでエキスパートモード項目の表示/非表示を切り替え

    LOOP AT SCREEN.	
      CASE screen-group1.	
        WHEN 'F'.	
          IF  status_expert  = c_show.	
            screen-active = 1.	
            SET CURSOR FIELD 'PA_FIDOC'.	
          ELSE.	
            screen-active = 0.	
          ENDIF.	
          MODIFY SCREEN.	
      ENDCASE.	
    ENDLOOP.	

    ABAP開発に投稿されました 続きを読む

    このトピックでは、プログラムの実行方法を取り上げて説明します。

    トランザクションコード指定

    レポートプログラムにトランザクションコードを割り当てておけば、トランザクションコード指定により、レポートを実行することができます。 レポートプログラムに割り当てられたトランザクションは、レポートトランザクションと呼ばれます。

    • トランザクションの確認
      • SE93を実行
      • MIR5を入力、照会ボタンを押下
    • トランザクションの実行
      • MIR5を入力
      • Enterキーを押下

    プログラム名指定

    SE38でプログラム名を指定してプログラムを実行することができます。

    プログラミングからは、submit命令を利用すれば、別のレポートプログラムを起動することができます。

    プログラミング基礎に投稿されました 続きを読む

    このトピックでは、SAP標準で用意された採番システムの使用方法を取り上げて説明します。

    採番処理のために共通的な仕組みを提供します。 

    • NRIV
      番号範囲間隔
    • SNRO
      番号範囲オブジェクト


    • SM56
      番号範囲バッファの管理

    下記の汎用モジュールを使用できます。

    • NUMBER_GET_NEXT 採番
    • NUMBER_GET_INFO 情報取得
    • NUMBER_CHECK チェック

    プログラミング基礎に投稿されました 続きを読む

    概要

    バリアントとは

    バリアントとは、同じ選択条件で実行することが多いプログラムに対して、入力値のセットを保存させておくものです。 レポートプログラムバリアント、画面バリアント、トランザクションバリアントなどがあります。

    バリアント変数とは

    バリアント変数とは、バリアントに格納される値を変数化したものです。 バリアント変数は二つのタイプがあります。

    • TYPE P
      単一値を定義することができます。
    • TYPE S
      選択テーブルとして条件を定義することができます。

    バリアント変数の値定義はテーブルTVARVCに格納されます。

    トランザクション利用

    バリアント変数のメンテナンスは、トランザクションSTVARVとSTVARVCを使用します。

    • STVARV
      クライアント000用
    • STVARVC
      現在のクライアント用

    プログラム利用

    以下はバリアント変数をABAPプログラムで動的に変更して使用する方法です。

    * バリアント変数テーブルを更新
    UPDATE TVARVC
    SET LOW = WK_FROM
      HIGH = WK_TO
    WHERE NAME = 'VAL_NAME' 

    AND TYPE = 'S'. "タイプ S:SELECT OPTIONS、P:パラメータ

    プログラミング基礎に投稿されました 続きを読む

    実行時データ型識別、略語は RTTI です。プログラム実行時にデータ型を識別して処理を行う仕組みです。。

    DESCRIBE FIELD命令を使用して、変数のデータタイプを取得することができます。

    構文

    DESCRIBE FIELD obj TYPE typ.

    • obj
      データ型を取得したいデータオブジェクト。通常の変数やフィールドシンポルなどを使用することができます。
    • typ
      取得したデータ型が格納されるデータオブジェクト。

    データ型

    データ型は1 桁のIDで識別され、IDでは大文字と小文字が区別されます。

    IDデータ型
    b基本タイプB:1バイト整数(内部用)
    C基本タイプC:固定長テキスト項目
    D基本タイプD:日付項目
    F基本タイプF:浮動小数点数
    g基本タイプSTRING:可変長文字順序
    h内部テーブル
    i基本タイプI:整数
    lデータ参照
    N基本タイプN:数値テキスト項目
    P基本タイプP:パック数値
    rオブジェクト参照
    s基本タイプS:2バイト整数(内部用)
    T基本タイプT:時刻項目
    uフラット構造
    vディープ構造
    X基本タイプX:16進数
    y基本タイプXSTRING:可変長バイト順序

    サンプルソース

    FORM PARSE_STRING_TO_STRUC   USING    U_STR TYPE STRING
                            CHANGING C_STRUC.
      CONSTANTS:
        CONST_DT_DATE TYPE C VALUE 'D',
        CONST_TAB            TYPE STRING VALUE CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB.
      DATA:
       VL_STRINGS  TYPE STRING_TABLE, 
       VL_STR  TYPE STRING,
       VL_DATE TYPE D,
       VL_TYPE TYPE C.
      FIELD-SYMBOLS:
        <FS_WA>   TYPE ANY,
        <FS_COMP> TYPE ANY.
       SPLIT U_STR AT CONST_TAB INTO TABLE VL_STRINGS.
       ASSIGN C_STRUC TO <FS_WA>.
       TRY.
              LOOP AT TG_STRING INTO VG_STRING.
                ASSIGN COMPONENT SY-TABIX OF STRUCTURE <FS_WA> TO <FS_COMP>.
                DESCRIBE FIELD <FS_COMP> TYPE vl_type.
                IF vl_type = CONST_DT_DATE.    "日付型
                   CALL FUNCTION 'CONVERT_DATE_TO_INTERNAL'
                     EXPORTING
                       date_external            = VL_STR
                       accept_initial_date      = 'X'
                     IMPORTING
                       date_internal            = vl_date
                     EXCEPTIONS
                       date_external_is_invalid = 1
                     OTHERS                   = 2.
                   IF sy-subrc = 0.
                     VL_STR = vl_date.
                   ENDIF.
                    ENDIF.
                 ENDIF.
                MOVE VL_STR TO <FS_COMP>.
              ENDLOOP.
            CATCH CX_SY_CONVERSION_ERROR.
              CLEAR: EX_AFDATA.
          ENDTRY.
    ENDFORM.

    CL_ABAP_TYPEDESCR

    |
    |--CL_ABAP_DATADESCR
    |     |
    |     |--CL_ABAP_ELEMDESCR
    |     |--CL_ABAP_REFDESCR
    |     |--CL_ABAP_COMPLEXDESCR
    |         |
    |         |--CL_ABAP_STRUCTDESCR
    |         |--CL_ABAP_TABLEDESCR
    |
    |--CL_ABAP_OBJECTDESCR
          |
          |--CL_ABAP_CLASSDESCR
           |--CL_ABAP_INTFDESCR

    データ型を判定

    型毎のメタ情報

    属性名意味基本型参照型構造型テーブル型クラス型インタフェース型
    absolute_name型名称
    type_kind内部ABAPデータ型
    length内部長
    decimals小数桁数P×××××
    OUTPUT_LENGTH出力長×××××
    STRUCT_KIND構造タイプ×××××
    COMPONENTSコンポーネント(name/type_kind/length/decimals)テーブル×××××
    KEYテーブルキー×××××
    INITIAL_SIZEテーブルの初期サイズ×××××
    KEY_DEFKINDテーブルデータ型定義×××××
    HAS_UNIQUE_KEY一意キー定義×××××
    TABLE_KINDテーブルカテゴリ×××××
    CLASS_KINDクラスタイプ×××××
    CREATE_VISIBILITY可視性登録×××××
    INTF_KINDインタフェースタイプ×××××

    プログラミング基礎に投稿されました 続きを読む

    背景

    編集中

    型の作成

    編集中

    基本型

    数値や文字列などのABAP基本型を動的に作成するには、クラスCL_ABAP_ELEMDESCRのメソッドを利用します。 クラスCL_ABAP_ELEMDESCRからいかのようなStaticメソッドが用意されております。

    メソッド名機能
    GET_Cパラメータで指定された長さのC(テキスト)項目型を取得
    GET_Nパラメータで指定された長さのN(数値テキスト)項目型を取得
    GET_Xパラメータで指定された長さのX(16進数)項目型を取得
    GET_Pパラメータで指定された長さのP(パック数値項目)型を取得

    STRING(文字順序)、XSTRING(バイト順序)、I(整数)、F(浮動小数点数)、D(日付)、T(時間)などの型もメソッドが用意されておりますが、こちらの型は長さの指定がないので、型名を静的に指定すればよく、あえてメソッドを利用する必要がありません。

    下記のサンプルソースでは、長さ10の固定長テキスト項目型を動的生成する方法を示しています。

    DATA c10  TYPE REF TO cl_abap_datadescr. 

    c10 = cl_abap_elemdescr=>get_c( 10 )."動的な型を取得

    プログラミング基礎に投稿されました 続きを読む

    このトピックは動的なデータオブジェクトを取り上げて、その特徴と使用方法を説明します。

    動的なデータオブジェクトを説明する前にまず静的なデータオブジェクトを説明しておきます。

    プログラムの宣言部分において DATAなどの命令を使用して定義するデータオブジェクトはすべて静的に登録され、プログラムの起動時にはすでに存在する「静的なデータオブジェクト」となります。

    一方、動的なデータオブジェクトとは、プログラム実行時に、CREATE DATA命令を使用して作成されるデータオブジェクトです。

    動的なデータオブジェクトは以下の特徴があります。

    • 現在の ABAPプログラムの内部セッションの中にデータオブジェクトが登録されます。
    • 動的なデータ型を利用することができます。
    • 登録されるデータオブジェクトは独自の名称を持ちません。データ参照変数を使用した場合にのみアドレス指定することができます。
    • 内容をアクセスするにはフィールドシンボルを利用しなければなりません。

    静的なデータ型使用の場合

    静的なデータ型を利用して動的なデータオブジェクトを作成するには、TYPEオプションを使用します。 TYPEオプションの使い方は基本DATA命令と同じですが、タイプ名を指定する際に動的な名称も使用可能です。 以下のような型を使用することができます。

    • ABAP基本タイプ
      CREATE DATA dref TYPE c LENGTH 3.
    • TYPESによって定義された任意のデータ型
      TYPES TYP_BKPF TYPE STANDARD TABLE OF BKDF
      CREATE DATA dref TYPE TYP_BKPF.
    • ABAP ディクショナリによる任意のデータ型
      CREATE DATA dref TYPE BKDF.
      CREATE DATA dref TYPE STANDARD TABLE OF BKDF

    サンプルソース:

    DATA typ  TYPE c.
    DATA len  TYPE i.
    DATA dref TYPE REF TO data.
    FIELD-SYMBOLS <fs> TYPE ANY.
    typ = 'c'.
    len = 30.
    CREATE DATA dref TYPE (typ) LENGTH len.
    ASSIGN dref->* TO <fs>.
    <fs> =  'ABCDEF'.
    write <fs>.

    動的なデータ型使用の場合

    実行時データ型サービス (RTTS) データ型オブジェクトによって記述される動的なデータ型のデータオ ブジェクトを生成するには、TYPE HANDLEオプションを使います。

    サンプルソース:

    DATA:
          r_stru TYPE REF TO cl_abap_structdescr,
          it_comp TYPE cl_abap_structdescr=>component_table,
          r_comp TYPE abap_componentdescr,
          r_elem TYPE REF TO cl_abap_elemdescr,
          r_data TYPE REF TO DATA.
    DATA: length_of_field
              TYPE I VALUE 10.
    FIELD-SYMBOLS: <fs> TYPE ANY.
    START-OF-SELECTION.
    r_elem = cl_abap_elemdescr=>get_c( length_of_field ).
    r_comp-name = 'FIELD1'.
    r_comp-type  = r_elem.
    APPEND r_comp TO it_comp.
    r_stru = cl_abap_structdescr=>create( it_comp ).
     CREATE DATA r_data TYPE HANDLE r_stru.
     ASSIGN r_data->('FIELD1') TO <fs>.
    <fs> = 'ABC'.
    WRITE: / <fs>.

    プログラミング基礎に投稿されました 続きを読む

    このトピックでは、動的な名称の使用方法を取り上げて説明します。

    ABAPプログラムでは、以下のように様々な名称が使用されます。

    • データ型を指定するための名称
    • データオブジェクトを参照するための名称
    • SQL文に記述されるテーブル名称

    通常はプログラムを作成する際に明示的に記述しますが、より機能性が高いプログラムを作成する場合、その名前を可変にしなければならないケースがあります。この可変の名前は動的な名前と呼ばれます。

    基本構文は以下のようになります (名称が格納された変数)

    REPORT Y_TEST.
    DATA:
          A TYPE C,
          V1 TYPE C.
    FIELD-SYMBOLS <FS> TYPE ANY.
    A  = 'T'.
    V1 = 'A'.
    ASSIGN (V1) TO <FS>.
    WRITE:  <FS> . 

    ツール型のプログラム作成

    テーブル内容をエクスポートするツールを例とします、テーブル名はユーザから任意に指定可能です。

    以下はその実装の抜粋です。

    PARAMETERS: pn TYPE dd02l-tabname obligatory.
    START-OF-SELECTION.
    DATA:
       t_itab TYPE REF TO DATA.
    FIELD-SYMBOLS:
       <itab>   TYPE STANDARD TABLE.
    CREATE DATA t_itab TYPE STANDARD TABLE OF (pn).
    ASSIGN t_itab->* TO <itab>.
    SELECT *
    FROM (pn)
    INTO TABLE <itab>.
    *後続は省略

    コードの簡潔化

    名前が番号違いだけである複数の変数に対してそれぞれ何かの処理を行う時に、動的に変数を割り当てループ処理化することにより、コーディング記述量を劇的に減らすことができます。

    REPORT  Y_VARNAME_TEST.
    DATA:V1(2) TYPE C,     
         V2(2) TYPE C,
         V3(2) TYPE C,
         V4(2) TYPE C,
         V5(2) TYPE C,
         V6(2) TYPE C,
         V7(2) TYPE C,
         V8(2) TYPE C,
         V9(2) TYPE C.
    

    DATA: VNAME(5) TYPE c ,
    VINDEX TYPE c.

    FIELD-SYMBOLS <FS> TYPE ANY.
    START-OF-SELECTION.
    DO 9 TIMES.
    VINDEX = SY-INDEX.
    CONCATENATE 'V' VINDEX INTO VNAME.
    ASSIGN (VNAME) TO <FS>.
    CONCATENATE 'X' VINDEX INTO <FS>.
    ENDDO.
    DO 9 TIMES.
    VINDEX = SY-INDEX.
    CONCATENATE 'V' VINDEX INTO VNAME.
    ASSIGN (VNAME) TO <FS>.

    WRITE:/ VNAME,
    : '=' ,
    : <FS>.
    ENDDO.

    上記のサンプルの実行結果は以下の図で示します。

    変数参照制限の回避

    ABAPでは異なるプログラム(レポート、汎用グループetc)のグローバル変数を直接参照することができません。 但し、Exit実装のアドオンプログラムから、直接拡張された標準プログラムのグローバル変数を直接参照したいというニーズはたまたま発生します。 そこで裏技になりますが、動的な変数名を利用すれば、プログラムを跨ってグローバル変数を参照できないというABAP言語の制限を回避することができます。

    以下はそのサンプルです。

    *
    DATA: I_OKCODE(17) TYPE C VALUE '(SAPLMR1M)OK-CODE'.
    FIELD-SYMBOLS: <FS_OKCODE> TYPE ANY.
    ASSIGN (I_OKCODE) TO <FS_OKCODE>.

    プログラミング基礎に投稿されました 続きを読む

    フィールドシンボルとは、物理的なメモリを占有せずに、任意の変数(単一変数、構造、内部テーブルなど)に 割り当てる(Assign)ことで、任意の変数を指し示すことができます。C言語でいうポインタのようなものです。

    フィールドシンボルを宣言するには、以下のような構文を使用します。

    FIELD-SYMBOLS <FS> [< データ型 >|STRUCTURE <s> DEFAULT <wa>]. <FS>にある角かっこも構文の一部です、タイプ指定しない場合は、TYPE ANYで宣言することができます。

    FIELD-SYMBOLS <FS1> TYPE ANY. FIELD-SYMBOLS <FS2> TYPE ANY TABLE.

    Assign命令を使います。

    フィールドシンボルにやまかっこをつけて、フィールドシンボルがアドレスするデータを参照または書き込みすることができます。

    FORM f_get_range_table  USING u_setclass u_subclass u_setname
                            CHANGING r_range TYPE TABLE.
    DATA:
      lt_set LIKE setleaf OCCURS 0 WITH HEADER LINE,	 
      wl_range      TYPE REF TO DATA  
    .
    FIELD-SYMBOLS : <fs_rec>,<fs_itm>
    .
    

    SELECT * FROM setleaf
      INTO TABLE lt_set
      WHERE setclass = u_setclass
      AND subclass = u_subclass
      AND setname = u_setname.

    LOOP AT lt_set.
    CREATE DATA wl_range LIKE LINE OF r_range.
    ASSIGN wl_range->* TO <fs_rec>.
    ASSIGN COMPONENT 'SIGN' OF STRUCTURE <fs_rec> TO <fs_itm>.
    <fs_itm> = lt_set-valsign.
    ASSIGN COMPONENT 'OPTION' OF STRUCTURE <fs_rec> TO <fs_itm>.
    <fs_itm> = lt_set-valoption.
    ASSIGN COMPONENT 'LOW' OF STRUCTURE <fs_rec> TO <fs_itm>.
    <fs_itm> = lt_set-valfrom.
    ASSIGN COMPONENT 'HIGH' OF STRUCTURE <fs_rec> TO <fs_itm>.
    <fs_itm> = lt_set-valto.
    APPEND wl_range to r_range.
      ENDLOOP.
    ENDFORM.

    プログラミング基礎に投稿されました 続きを読む

    このトピックはテーブルのデータ行に対して、読み込みや変更などの操作方法を取り上げて説明します。

    内部テーブルから単一行を読み込みするには、以下の命令を使用します。

    • READ TABLE itab search-key search-result.

    検索キーを指定

    読み込む対象となるデータ行の検索キーを指定する方法を説明します。

    (1)テーブルキー指定

    検索キーとして itab のテーブルキーを使用するには、以下のように key を入力します。

    • READ TABLE itab FROM wa result.

    または

    • READ TABLE itab WITH TABLE KEY k1 = f1 … kn = fn result.

    全タイプの内部テーブルに対して、この方法を利用することができます。

    (2)任意キー指定

    テーブルキー以外の項目も検索キーとして指定することができます。

    • READ TABLE itab WITH KEY k1 = f1 … kn = fn result.

    標準テーブルの場合、「BINARY SEARCH」をつけて検索の高速化を図ることができます。これは、標準テーブルが検索キー項目によってソートされていることを前提にしています、そうではない場合、エラーにならないが、意図しないデータ行が読み出されることになってしまいます。

    (3)index指定

    標準テーブルおよびソートテーブルに限りますが、読み込む行のテーブル索引を明示的にidxによって指定することができます。

    • READ TABLE 読出元の内部テーブル INTO 読み出し先構造 INDEX idx

    idx は、i 型のデータオブジェクトである必要があります。

    取得できたかをチェック

    対象データが取得できた場合と取得できなかった場合、それぞれ以下のようにシステム項目に値が設定されます。

    • 取得できた場合
      • sy-subrc: 0
      • sy-tabix: 取得された行のインデックス
    • 取得できなかった場合
      • sy-subrc: エラーコード(0でない数字)

    対象行のデータを照会

    検索対象行のデータを照会するには、作業領域かフィールドシンボルかを使用することができます。

    • 作業領域を使用
      READ TABLE itab key INTO wa
    • フィールドシンボルを使用
      READ TABLE itab key ASSIGNING <fs>.

    対象データ行の内容を関心せず、対象データが存在しているかどうかのみをチェックする場合があります。その際、「READ TABLE」命令に「NO FIELDS」オプションをつけることができます。

    単一行挿入

    単一行を内部テーブルの特定の箇所に挿入する場合は、「INSERT」を使用します。

    • INSERT wa INTO TABLE itab INDEX idx.

    複数行挿入

    複数行を内部テーブルの特定の箇所に挿入する場合は「INSERT LINES OF」を使用します。

    • INSERT LINES OF itab1 FROM idx1_1 TO idx1_2 INTO TABLE itab2 INDEX idx2.

    単一行変更

    単一行を変更するには、以下の命令を使用します。

    • MODIFY TABLE itab FROM wa [TRANSPORTING f1 f2 …].

    複数行変更

    条件を使用して 1 行または複数行を変更するには、以下の命令を使用します。 MODIFY itab FROM wa TRANSPORTING f1 f2 …WHERE cond.

    単一行削除

    内部テーブルの単一行を削除する場合は、DELETE 命令を使用します。

    • DELETE TABLE itab FROM wa.

    または

    • DELETE TABLE itab WITH TABLE KEY k1 = f1 … kn = fn.

    または

    • DELETE TABLE itab Index idx

    複数行削除

    内部テーブルの行を複数まとめて削除する場合には、「DELETE .. WHERE」文を使用します。

    • DELETE TABLE itable WHERE key = value.

    内部テーブルを走査するには、命令LOOP~ENDLOOPを使用します。 FROM を指定できるのは、 標準テーブルおよび ソートテ ーブルの場合に限られます。 すべてのテーブルデータ型について WHERE を指定することができます。

      DATA : T_WITH_ITEM TYPE TABLE OF WITH_ITEM,
             W_WITH_ITEM TYPE WITH_ITEM.
    * 処理         
      LOOP AT T_WITH_ITEM INTO W_WITH_ITEM WHERE
         BELNR = W_BELNR AND
         BUZEI = W_BUZEI.        
    * 処理   

    ENDLOOP.

    プログラミング基礎に投稿されました 続きを読む

    このトピックでは内部テーブル全体に対する操作を取り上げて説明します。

    内部テーブルの割り当ては、MOVE命令を使用します。 MOVE itab1 TO itab2. なお、代入演算子も同様の働きを持ちます。 itab2 = itab1.

    上記の命令が実行された結果、内部テーブルitab1の内容が内部テーブルitab2にコピーされることになります。

    内部テーブルを初期化するには、clear、fresh、freeなどの命令を使用します。

    • clear
      • 構文1:clear itab[]
        内部テーブルの本体を初期化します。
        内部テーブルは初期メモリ所要量が予約され、その以外のメモリ領域がすべて解放されます。
      • 構文2:clear itab
        ヘッダ行を含まない内部テーブルの場合は、この命令はclear itab[]と同様に動作します。
        ヘッダ行を含る内部テーブルの場合は、ヘッダ行(作業領域)の名前が内部テーブルと同じであるため、このテーブルは単なるヘッダ行のクリアのみとなります。
    • fresh
      • 構文:fresh itab
        常に内部テーブルの本体を初期化します。この命令はclear itab[]と同様に動作します。
    • free
      • 構文:fresh itab
        常に内部テーブルの本体を初期化します。この命令はclear、fresh命令と異なり、内部テーブルに対して、初期メモリ所要量を含めた記憶域全体をすべて解放します。

    ABAPでは、内部テーブルも論理式内のオペランドとして比較することができます。

    内部テーブルのソートはSORT命令を使用します。

    SORT itab [ASCENDING|DESCENDING] [AS text] [STABLE].

    DESCRIBE TABLE命令を使用して、件数などの内部テーブルの各属性を取得することができます。

    • DESCRIBE TABLE
      構文:DESCRIBE TABLE itab [LINES lin] [OCCURS n] [KIND knd].
      • パラメータ:LINES
        内部テーブルのレコード件数を取得します。
      • パラメータ:OCCURS
        内部テーブルの初期サイズを取得します。
      • パラメータ:KIND
        内部テーブルの種類を取得します。

    プログラミング基礎に投稿されました 続きを読む

    テーブルデータ型は、ABAP における内部テーブルの構造と機能属性を示します。このトピックでは、テーブルデータ型を取り上げて、その構成や種類などを説明します。

    テーブルデータ型は、行データ型、キー、およびアクセス方法によって完全指定されます。

    (source:SAP Help Portal)

    行データ型

    通常、内部テーブルのデータ型は構造であり、その構造の各コンポーネントは、それぞれ内部テーブル内の1つの列になります。 ただし、内部テーブルのデータ型の仕様としては、構造以外の任意のデータ型を使用することも可能です。

    キー

    テーブル行データはキーによって識別されます。キーは、システムからデフォルトで生成されるは標準キーのほかに、ユーザから定義することもできます。ユーザ定義キーはUNIQUE または NON-UNIQUE として指定することができます。

    アクセス方法

    内部テーブルのアクセス方法は以下三つの種類から指定できます。

    • 標準テーブル
      標準テーブルは内部的な線型索引を持ちます。
      索引を使用して個別のテーブルエントリをアドレス指定する予定がある場合には、これが最適なデータ型です。
    • ソートテーブル
      ソートテーブルは常にキー別にソートされ、保存されます。ソートテーブルも内部索引を持ちます。
      バイナリ検索が求められる場合には、これが最適なデータ型です。
    • ハッシュテーブル
      ハッシュテーブルは線型索引を持ちません。キーを使用した場合にのみハッシュテーブルにアクセスすることができます。
      ハッシュ検索が求められる場合には、これが最適なデータ型です。

    テーブルデータ型は以下の階層図で示されたように、内部テーブルのアクセス方法により分類することができます。

    (source:SAP Help Portal)

    完全指定のテーブルデータ型

    内部テーブルのアクセス方法が明示されたテーブルデータ型です。

    • STANDARD TABLE または TABLE
      標準テーブルを登録します。
    • SORTED TABLE
      ソートテーブルを登録します。
    • HASHED TABLE
      ハッシュテーブルを登録します。

    ジェネリックテーブルデータ型

    内部テーブルのアクセス方法が明示されたテーブルデータ型です。

    • INDEX TABLE
      索引アクセスを使用するジェネリックテーブルデータ型を登録します。
    • ANY TABLE
      完全なジェネリックテーブルデータ型を登録します。

    ジェネリックテーブルデータ型は動的なプログラミングでよく使用されます。

    テーブルデータ型は、ローカルまたはグローバルに定義することができます。

    ローカル定義

    プログラムの中でTYPE命令を使用してテーブルデータ型をローカルに定義することができます。 構文:

    TYPES type TYPE|LIKE tabkind OF linetype [WITH key]
     [INITIAL SIZE n].

    グローバル定義

    ABAP ディクショナリのデータ型としてテーブルデータ型をグローバルに定義することもできます。 例として、標準のMMPUR_REQUISITION_ITEMSを取り上げてそのイメージを示します。

    プログラミング基礎に投稿されました 続きを読む

    このトピックでは、EXCELファイル出力の方法を取り上げて説明します。

    ABAPプログラムは、ABAP言語のOLE オートメーション技術を利用して、Excelファイルの読み取り、書き込みを行うことができます。 以下の図でその仕組みを示します。 

    1. OLEサーバとなるデスクトップアプリケーション(ExcelやWordなど)は、フロントエンドマシンに稼働します。
    2. ABAPプログラムはAS ABAPに稼働します。
    3. OLEサーバを直接アクセスするのは同じフロントエンドマシンに稼働するSAP GUIです。
    4. ABAPプログラムのOLE関連命令はAS ABAPによりRFCを通して、フロントエンドマシンに稼働するSAP GUIと連携されます。

    ABAPで制御されるアプリケーションはすべて、ABAPシステムに登録しなければなりません。

    以下のABAP命令でOLEサーバアプリケーションを制御します。

    • CREATE OBJECT
      OLEサーバアプリケーションのアプリケーションオブジェクトを作成します。
      アプリケーション名が指定されます、例えばExcelアプリケーションの場合は、'Excel.Application'になります。
    • SET PROPERTY
      アプリケーションオブジェクトのプロパティの値を設定します。
    • GET PROPERTY
      アプリケーションオブジェクトのプロパティの値を取得します。
    • CALL METHOD
      アプリケーションオブジェクトのメソッドを呼び出します。

    任意テーブルのデータをExcelファイルへエクスポートするツールをサンプルとして取り上げてそのソースを以下に示します。 動的プログラミングのサンプルソースとしても参考できるものです。

    REPORT  Y_XXXXX01.
    INCLUDE ole2incl.
    TYPES: BEGIN OF s_tabstr,
      fieldname TYPE fieldname,
      as4local TYPE as4local,
      POSITION TYPE tabfdpos,
      keyflag TYPE keyflag,
      rollname TYPE rollname,
      datatype TYPE datatype_d,
      leng TYPE ddleng,
      scrtext_s TYPE scrtext_s,
    END OF s_tabstr.
     PARAMETERS: p_table TYPE dd02l-tabname obligatory.
     PARAMETERS: p_file TYPE localfile DEFAULT 'c:\temp\test1.xls'.
    TABLES: v_username.
    DATA: BEGIN OF i_data OCCURS 0.
      INCLUDE STRUCTURE v_username.
    DATA: END OF i_data.
    START-OF-SELECTION.
      DATA:
            g_tablename TYPE tabname,
            g_filename TYPE localfile,
            g_itab_header TYPE REF TO DATA,
            g_itab_data TYPE REF TO DATA.
    g_tablename = p_table.
    g_filename = p_file.
    * get table header
    PERFORM f_get_tablestruc
                  USING g_tablename
                  CHANGING  g_itab_header.
    * get table data
    PERFORM f_extract_tabledata
                  USING g_tablename
                  CHANGING  g_itab_data.
    * create and export data to excel file
    PERFORM f_export_to_excel
                  USING g_itab_header
                            g_itab_data
                            g_filename.
    FORM f_get_tablestruc   USING VALUE(u_tabnam) TYPE tabname
                                           CHANGING c_itab TYPE REF TO DATA.
      DATA:
           v_delm TYPE C,
           str_ty TYPE REF TO cl_abap_structdescr,
            t_cm TYPE cl_abap_structdescr=>component_table,
            s_cm LIKE LINE OF t_cm,
            ref_cm TYPE REF TO DATA,
            f_seq TYPE n length 4,
            tabstr TYPE STANDARD TABLE OF s_tabstr.
      FIELD-SYMBOLS:
      <str> TYPE ANY,
      <cmp> TYPE ANY,
      <tabstr> LIKE LINE OF tabstr,
      <lab> TYPE STANDARD TABLE.
      CLEAR: f_seq, t_cm[].
      MOVE cl_abap_char_utilities=>horizontal_tab TO v_delm.
      SELECT fieldname as4local POSITION keyflag rollname datatype leng scrtext_s
      FROM dd03vt
      INTO TABLE tabstr
      WHERE tabname EQ u_tabnam AND ddlanguage EQ sy-langu.
      IF sy-subrc NE 0.
        MESSAGE e004(zasd1) WITH TEXT-e01 u_tabnam space space.
        STOP.
      ENDIF.
      SORT tabstr BY POSITION ASCENDING.
      LOOP AT tabstr ASSIGNING <cmp>.
        CLEAR s_cm.
        f_seq = f_seq + 1.
        CONCATENATE 'col' f_seq INTO s_cm-name.
        s_cm-type = cl_abap_elemdescr=>get_c( 30 ).
        APPEND s_cm TO t_cm.
      ENDLOOP.
      str_ty = cl_abap_structdescr=>create( t_cm ).
      CREATE DATA ref_cm TYPE handle str_ty.
      ASSIGN ref_cm->* TO <str>.
      CREATE DATA c_itab  LIKE STANDARD TABLE OF <str>.
      ASSIGN c_itab->* TO <lab>.
      CLEAR f_seq.
      DATA w_cl TYPE string.
      LOOP AT tabstr ASSIGNING <tabstr>.
        f_seq = f_seq + 1.
        CLEAR w_cl.
        CONCATENATE 'COL' f_seq INTO w_cl.
        ASSIGN COMPONENT w_cl OF STRUCTURE <str> TO <cmp>.
        <cmp> = <tabstr>-scrtext_s.
      ENDLOOP.
      APPEND <str> TO <lab>.
      CLEAR f_seq.
      LOOP AT tabstr ASSIGNING <tabstr>.
        f_seq = f_seq + 1.
        CLEAR w_cl.
        CONCATENATE 'COL' f_seq INTO w_cl.
        ASSIGN COMPONENT w_cl OF STRUCTURE <str> TO <cmp>.
        <cmp> = <tabstr>-fieldname.
      ENDLOOP.
      APPEND <str> TO <lab>.
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.
    ENDFORM.
    *
    *
    FORM f_extract_tabledata   USING VALUE(u_tabnam) TYPE tabname
                                           CHANGING c_itab TYPE REF TO DATA.
      DATA:
            w_file TYPE string,
            tabstr TYPE STANDARD TABLE OF s_tabstr.
      FIELD-symbols:
      <itab>   TYPE STANDARD TABLE.
      CREATE DATA c_itab TYPE STANDARD TABLE OF (u_tabnam).
      ASSIGN c_itab->* TO <itab>.
      SELECT *
      FROM (u_tabnam)
      INTO TABLE <itab>.
      IF sy-subrc <> 0.
        MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
        WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
      ENDIF.
    ENDFORM.                    "f_down_proc
    FORM f_export_to_excel USING u_itab_header TYPE REF TO DATA
                                                 u_itab_data TYPE REF TO DATA
                                                 u_filename TYPE localfile.
    DATA: w_excel TYPE ole2_object,
          w_workbooks TYPE ole2_object,
          w_workbook TYPE ole2_object,
          w_cell TYPE ole2_object.
    DATA: w_row TYPE I,
              w_col  TYPE I,
              type   TYPE C,
              count TYPE I.
      FIELD-SYMBOLS:
      <str> TYPE ANY,
      <cmp> TYPE ANY,
      <fs_itab_header> TYPE STANDARD TABLE,
      <fs_itab_data> TYPE STANDARD TABLE,
      <fs_itab_headrow> TYPE ANY,
      <fs_itab_datarow> TYPE ANY.
    * Create OLE automation object of type Excel.Application.
    CREATE OBJECT w_excel 'Excel.Application'.
    * Add a new Excel Workbook.
    CALL METHOD OF w_excel 'Workbooks' = w_workbooks.
    CALL METHOD OF w_workbooks 'Add' = w_workbook.
    * Display MS-Excel when executing the program.
    SET PROPERTY OF w_excel 'Visible' = 1.
    * Export title to the Excel sheet.
     ASSIGN u_itab_header->* TO <fs_itab_header>.
     FIELD-SYMBOLS:
      <fs_headrow> TYPE ANY.
    w_row = 1.
    LOOP AT <fs_itab_header> ASSIGNING <fs_itab_headrow>.
      w_col = 1.
      DESCRIBE FIELD <fs_itab_headrow> TYPE type COMPONENTS count.
      WHILE w_col <= count.
        ASSIGN COMPONENT w_col OF STRUCTURE <fs_itab_headrow> TO <cmp>.
        CALL METHOD OF w_excel 'Cells' = w_cell
           EXPORTING #1 = w_row  #2 = w_col.
        SET PROPERTY OF w_cell 'Value' = <cmp>.
        w_col = w_col + 1.
      ENDWHILE.
      w_row = w_row + 1.
    ENDLOOP.
    * Export data to the Excel sheet.
     ASSIGN u_itab_data->* TO <fs_itab_data>.
    LOOP AT <fs_itab_data> ASSIGNING <fs_itab_datarow>.
      w_col = 1.
      DESCRIBE FIELD <fs_itab_headrow> TYPE type COMPONENTS count.
      WHILE w_col <= count.
        ASSIGN COMPONENT w_col OF STRUCTURE <fs_itab_datarow> TO <cmp>.
        CALL METHOD OF w_excel 'Cells' = w_cell
           EXPORTING #1 = w_row  #2 = w_col.
        SET PROPERTY OF w_cell 'Value' = <cmp>.
        w_col = w_col + 1.
      ENDWHILE.
      w_row = w_row + 1.
    ENDLOOP.
    * Save file.
    CALL METHOD OF w_workbook 'SaveAs'
    EXPORTING #1 = u_filename
      #6 = 1.
    * Quit Excel.
    CALL METHOD OF w_excel 'Quit'.
    FREE OBJECT: w_excel,
    w_workbooks,
    w_workbook,
    w_cell.
    ENDFORM.