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をご参照ください。
半自動生成
項目カタログの半自動生成は、
- ABAPディクショナリーの構造体から項目カタログを自動生成する
- 自動生成された項目カタログに対してマニュアル修正を加える
というプロセスになります。
ABAPディクショナリーの構造体から項目カタログを自動生成するには、汎用モジュールLVC_FIELDCATALOG_MERGEを使用します。
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
TABLESt_outtab = gtbl_account_doc
EXCEPTIONS
program_error = 0
OTHERS = 0このトピックでは、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.カタログの作成
ALV出力
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表示
ALVを再表示します。
CALL METHOD VG_GRID->REFRESH_TABLE_DISPLAY
EXPORTING IS_STABLE = WL_STABLE.
このトピックでは、ALVの項目カタログを取り上げて説明します。
概要
項目カタログは、ALVで出力される各列(項目)のデータ型情報等が定義されます。 項目カタログに格納される定義情報は、以下のように分類することができます。
- 項目名
内部出力テーブルの項目名を指定します。列定義構造体のキー項目になります。 - データ型情報
ABAPデータ型や出力長などの情報が定義されます。
ABAPディクショナリーの項目を参照して定義するとマニュアルで定義するとの2パターンがあります。 - 単位や通貨情報
数量や金額などの項目は、それぞれ関連する単位や通貨の情報を定義する必要があります。 - 列の書式情報
- 列の出力オプション
項目カタログの項目
項目カタログの項目一覧は下記のリンクをご参考ください。 項目カタログの項目-SAP Help Portal
項目カタログの生成
基本的に、ALVを使用して表示する一覧ごとに項目カタログが必要です。項目カタログを生成する方法として、以下の方法があります。
- データディクショナリ構造を使用して自動的に生成
- ABAPプログラムでマニュアル生成
- 上記の2 つの方法を組み合わせて半自動的に生成
外部リンク
このトピックでは、ツールバー関連のプログラミングを取り上げて説明します。
機能固有のボタンを追加
関連技術
自動的に設定される選択画面の 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. 概要
バリアントとは
バリアントとは、同じ選択条件で実行することが多いプログラムに対して、入力値のセットを保存させておくものです。 レポートプログラムバリアント、画面バリアント、トランザクションバリアントなどがあります。
バリアント変数とは
バリアント変数とは、バリアントに格納される値を変数化したものです。 バリアント変数は二つのタイプがあります。
- TYPE P
単一値を定義することができます。 - TYPE S
選択テーブルとして条件を定義することができます。
格納テーブル
メンテナンス
トランザクション利用
バリアント変数のメンテナンスは、トランザクション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命令を使用して、変数のデータタイプを取得することができます。
構文
DESCRIBE FIELD obj TYPE 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.RTTS関連クラスを使用
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 における内部テーブルの構造と機能属性を示します。このトピックでは、テーブルデータ型を取り上げて、その構成や種類などを説明します。
構成
行データ型
通常、内部テーブルのデータ型は構造であり、その構造の各コンポーネントは、それぞれ内部テーブル内の1つの列になります。 ただし、内部テーブルのデータ型の仕様としては、構造以外の任意のデータ型を使用することも可能です。
キー
テーブル行データはキーによって識別されます。キーは、システムからデフォルトで生成されるは標準キーのほかに、ユーザから定義することもできます。ユーザ定義キーはUNIQUE または NON-UNIQUE として指定することができます。
アクセス方法
内部テーブルのアクセス方法は以下三つの種類から指定できます。
- 標準テーブル
標準テーブルは内部的な線型索引を持ちます。
索引を使用して個別のテーブルエントリをアドレス指定する予定がある場合には、これが最適なデータ型です。 - ソートテーブル
ソートテーブルは常にキー別にソートされ、保存されます。ソートテーブルも内部索引を持ちます。
バイナリ検索が求められる場合には、これが最適なデータ型です。 - ハッシュテーブル
ハッシュテーブルは線型索引を持ちません。キーを使用した場合にのみハッシュテーブルにアクセスすることができます。
ハッシュ検索が求められる場合には、これが最適なデータ型です。
分類
完全指定のテーブルデータ型
内部テーブルのアクセス方法が明示されたテーブルデータ型です。
- STANDARD TABLE または TABLE
標準テーブルを登録します。 - SORTED TABLE
ソートテーブルを登録します。 - HASHED TABLE
ハッシュテーブルを登録します。
ジェネリックテーブルデータ型
内部テーブルのアクセス方法が明示されたテーブルデータ型です。
- INDEX TABLE
索引アクセスを使用するジェネリックテーブルデータ型を登録します。 - ANY TABLE
完全なジェネリックテーブルデータ型を登録します。
ジェネリックテーブルデータ型は動的なプログラミングでよく使用されます。
定義
テーブルデータ型は、ローカルまたはグローバルに定義することができます。
ローカル定義
プログラムの中でTYPE命令を使用してテーブルデータ型をローカルに定義することができます。 構文:
TYPES type TYPE|LIKE tabkind OF linetype [WITH key] [INITIAL SIZE n].
グローバル定義
このトピックでは、EXCELファイル出力の方法を取り上げて説明します。
仕組
ABAPプログラムは、ABAP言語のOLE オートメーション技術を利用して、Excelファイルの読み取り、書き込みを行うことができます。 以下の図でその仕組みを示します。
- OLEサーバとなるデスクトップアプリケーション(ExcelやWordなど)は、フロントエンドマシンに稼働します。
- ABAPプログラムはAS ABAPに稼働します。
- OLEサーバを直接アクセスするのは同じフロントエンドマシンに稼働するSAP GUIです。
- ABAPプログラムのOLE関連命令はAS ABAPによりRFCを通して、フロントエンドマシンに稼働するSAP GUIと連携されます。
ABAPで制御されるアプリケーションはすべて、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.


































