（初）第三弾　ABAPー訓練「REPORT」

:writing_hand_tone1:[第二弾](https://qiita.com/luyu1567/items/3bc5c0db61e5543b4b38)
:writing_hand_tone1:[SAP 訓練目次](https://qiita.com/items/dd1fdf83a42f90a78c6e)
#学習の目的
この単元を完了すると、次のことができるようになります。

- ＣＳＶファイルのアップロード機能
- ＣＳＶファイルのダウンロード機能
- 論理パスの定義
- ディレクトリパス
- オンライン方式／バックグラウンド方式
- ジョブログ監視

#概要説明

##学生成績インポート（学生成績エクスポート）
###詳細説明
- DB保存：サーバーファイルからCSVファイルを読み込んで学生一覧と学生成績に保存する。
- 実行モード：二つを分けてオンラインとバックグラウンドです。
- 出力：出力画面とジョブログです。

###技術一覧
- Report[SE38]
- Upload[CG3Z]
- 論理パス定義[FILE]
- ディレクトリパスとファイル内容[AL11]
- 選択画面
- オンライン／バックグラウンド
- ジョブログ[SM37]
- CSVファイルの取り込み


#データベース説明

#実装順序
##設定
- Tr-Cd:SE11→テーブル→データエレメント→ドメイン

##学生一覧テーブル
- 以下の図に示す。
![ZSTUDENT01.PNG](https://qiita-image-store.s3.amazonaws.com/0/185058/f8f9a7dd-dbd7-0aa4-406b-d6a1e75f01b2.png)


##学生成績テーブル
- 以下の図に示す。
![ZSTU_GRADE01.PNG](https://qiita-image-store.s3.amazonaws.com/0/185058/fa71da82-4949-e09d-6eae-7511ab0a4efa.png)

##サーバフォルダ
- Tr-Cd:FILE
ZCSV_PATH:C:\temp\input\

##出力サンプル「出力画面／ジョブログ」
- 処理開始します
- 入力ファイル:¥XXX¥XXX¥XXX.txt
- 入力データ:NN件
- 成功データ:NN件
- 失敗データ:NN件
- 処理終了します

##汎用モジュールリスト
- FILE_GET_NAME_USING_PATH:フルパス取得
- MESSAGE SNNN(ZA)

##ファイルのI/O

```ruby:ABAP
DATA:
  result TYPE string,
  output TYPE TABLE OF string WITH EMPTY KEY,
  ld_header     TYPE STRING."ヘッダ

*- フィールドシンボル
FIELD-SYMBOLS:
  <lfs_outdata> TYPE STRING.

*- カンマでタイトルを結合する。
CONCATENATE:
  TEXT-item001
  TEXT-item002
  TEXT-item003
  TEXT-item004
  TEXT-item005
  TEXT-item006
  INTO ld_header
  SEPARATED BY ','.

TRY.

*-↓↓↓↓↓↓テーブルからTXTファイルを出力する↓↓↓↓↓↓  
  OPEN:
    DATASET パス
    FOR OUTPUT
    IN TEXT MODE
    ENCODING UTF-8.
  
  TRANSFER:
    ld_header TO パス.

  LOOP AT テーブル
    ASSIGNING <構造>.

    TRANSFER:
      <構造> TO パス.
  ENDLOOP.
*-↑↑↑↑↑↑テーブルからTXTファイルを出力する↑↑↑↑↑↑
*-↓↓↓↓↓↓TXTファイルをテーブルに読み込む↓↓↓↓↓↓  
  OPEN:
    DATASET パス
    FOR INPUT
    IN TEXT MODE
    ENCODING UTF-8.

  WHILE sy-subrc = 0. 
    READ DATASET パス INTO result. 
    APPEND result TO output. 
  ENDWHILE. 
 *-↑↑↑↑↑↑TXTファイルをテーブルに読み込む↑↑↑↑↑↑
  CLOSE:
    DATASET パス.
CATCH:
  CX_SY_FILE_OPEN.

CATCH:
  CX_SY_FILE_AUTHORITY.

CATCH:
  CX_SY_FILE_IO.

CATCH:
  CX_SY_FILE_CLOSE.

ENDTRY.
```

##DB挿入

```ABAP
DATA: IT_ZSTUDENT TYPE HASHED TABLE OF ZSTUDENT
                WITH UNIQUE KEY ZNO,
      WA LIKE LINE OF IT_ZSTUDENT.

*- データを設定する
*WA-ZNO = 1001.
*...
*- 挿入
INSERT WA INTO TABLE IT_ZSTUDENT.

IF SY-SUBRC = 0
OR SY-SUBRC = 4.

*- コミット
  COMMIT WORK.

*- ログ処理
  MOVE:
    SY-DBCNT TO ログ内部テーブル-件数.

ELSE.

*- エラー件数
  MOVE:
    SY-DBCNT TO ログ内部テーブル-エラー件数.

*- ロールバック
  ROLLBACK WORK.


ENDIF.


```

#実装サンプル
```ruby:ABAP

REPORT  ZSTUDENTS01.
constants:
  gcf_file_name type string value 'ZSTUDENTS01.TXT',
  gcf_tab       TYPE c VALUE CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB,
  gcf_on_flg    type flag value ' '.

DATA:
  gw_result TYPE string,
  gw_output TYPE STANDARD TABLE OF ZSTUDENT01,
  gw_line   TYPE ZSTUDENT01,
  gw_path       TYPE string.

*SELECT-OPTIONS:
*  s_matnr      for gd_matnr_for_scr
*  matchcode    object mat1.

PARAMETERS:
  p_path       type pathintern
  obligatory
  matchcode object h_filepath.

************************************************************************
INITIALIZATION.
************************************************************************

************************************************************************
AT SELECTION-SCREEN.
************************************************************************

************************************************************************
START-OF-SELECTION.
************************************************************************

DATA:
  LCNT_READ TYPE I.

MESSAGE S001(ZB).
  CALL FUNCTION 'FILE_GET_NAME_USING_PATH'
    EXPORTING
      logical_path                = p_path
      file_name                   = gcf_file_name
    IMPORTING
      file_name_with_path         = gw_path
    EXCEPTIONS
      path_not_found              = 1
      missing_parameter           = 2
      operating_system_not_found  = 3
      file_system_not_found       = 4
    OTHERS                      = 5.

MESSAGE S002(ZB) WITH gw_path.

  IF sy-subrc <> 0.

  ENDIF.

TRY.
  CLEAR LCNT_READ.

  OPEN:
    DATASET gw_path
    FOR INPUT
    IN TEXT MODE
    ENCODING UTF-8.

  DO.
    READ DATASET gw_path INTO gw_result.

    IF gw_result IS INITIAL.
      EXIT.
    ENDIF.

    SPLIT gw_result AT gcf_tab into :gw_line-ZNO01 gw_line-ZNM01 gw_line-ZBIRTHDAY_DT01 gw_line-ZADDRESS01 gw_line-ZCONTACT01 gw_line-ZCLASS01 gw_line-ZCREATE_DT01 gw_line-ZCREATER01 gw_line-ZUPDATE_DT01 gw_line-ZUPDATER01.

    APPEND gw_line TO gw_output.
  ENDDO.

  DESCRIBE TABLE gw_output LINES LCNT_READ.
  MESSAGE S003(ZB) WITH LCNT_READ.

  CLOSE:DATASET gw_path.
CATCH:
  CX_SY_FILE_OPEN.

CATCH:
  CX_SY_FILE_AUTHORITY.

CATCH:
  CX_SY_FILE_IO.

CATCH:
  CX_SY_FILE_CLOSE.

ENDTRY.

  INSERT ZSTUDENT01 FROM TABLE gw_output ACCEPTING DUPLICATE KEYS.

  IF SY-SUBRC = 0
  OR SY-SUBRC = 4.

    MESSAGE S004(ZB) WITH SY-DBCNT.
    COMMIT WORK.

  ELSE.
    MESSAGE S005(ZB) WITH SY-DBCNT.
    ROLLBACK WORK.

  ENDIF.
************************************************************************
END-OF-SELECTION.
************************************************************************

MESSAGE S006(ZB).

```
#CSVファイル

```ruby:TXT
101001	新宿	新宿三丁目	20080101	新宿区三丁目１-１号棟	taro@hotmail.com	101	2018/11/19	TR00001	2018/11/19	TR00001
101002	渋谷	渋谷一丁目	20080318	渋谷区	shibuya@hotmail.com	101	2018/11/19	TR00001	2018/11/19	TR00001
```
#実行サンプルの整理

```ruby:ABAP
*&---------------------------------------------------------------------*
*& Report ZSTUDENTS01
*&---------------------------------------------------------------------*
*& プログラム名：XXX名前はプログラム属性と一致させるXXXXXXXXX
*& 処理概要　　：XXXX72文字を超えないようになってくださいXXXXXXXXXXXX
*&            　XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*&---------------------------------------------------------------------*
*& 変更履歴
*& No.  変更日　　　変更者　　　　　　　変更内容
*& 000  yyyy/mm/dd 芦(会社名略名)　　　新規作成
*& 001  yyyy/mm/dd AA(CC)　　　　　　　不具合修正
*&---------------------------------------------------------------------*

REPORT  ZSTUDENTS01.

*-Include定義

*-Type定義

*-Constant定義
constants:
  gcf_file_name type string value 'ZSTUDENTS01.TXT',
  gcf_tab       TYPE c VALUE CL_ABAP_CHAR_UTILITIES=>HORIZONTAL_TAB,
  gcf_on_flg    type flag value ' '.

*-Data定義
DATA:
  gw_result TYPE string,
  gw_output TYPE STANDARD TABLE OF ZSTUDENT01,
  gw_line   TYPE ZSTUDENT01,
  gw_path       TYPE string.

*-Field symbol定義

*-Selection screen定義
*SELECT-OPTIONS:
*  s_matnr      for gd_matnr_for_scr
*  matchcode    object mat1.    "品目コード

PARAMETERS:
  p_path       type pathintern
  obligatory
  matchcode object h_filepath. "論理パス

************************************************************************
INITIALIZATION.
************************************************************************

************************************************************************
AT SELECTION-SCREEN.
************************************************************************

************************************************************************
START-OF-SELECTION.
************************************************************************


  MESSAGE S001(ZB).

  PERFORM FRM_PATH_SET.

  PERFORM FRM_READ_DATA.

  PERFORM FRM_INSERT_DATA.


*-↑↑↑↑↑↑内部テーブルデータからテーブルに挿入する↑↑↑↑↑↑
************************************************************************
END-OF-SELECTION.
************************************************************************

  MESSAGE S006(ZB).
*&---------------------------------------------------------------------*
*&      Form  FRM_PATH_SET
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_PATH_SET .

*- 物理パスを取得する
  CALL FUNCTION 'FILE_GET_NAME_USING_PATH'
    EXPORTING
      logical_path               = p_path
      file_name                  = gcf_file_name
    IMPORTING
      file_name_with_path        = gw_path
    EXCEPTIONS
      path_not_found             = 1
      missing_parameter          = 2
      operating_system_not_found = 3
      file_system_not_found      = 4
      OTHERS                     = 5.

  MESSAGE S002(ZB) WITH gw_path.

ENDFORM.                    " FRM_PATH_SET
*&---------------------------------------------------------------------*
*&      Form  FRM_READ_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_READ_DATA .

  DATA:
    LCNT_READ TYPE I.

*- CSVファイルからデータを取り込む
*-↓↓↓↓↓↓TXTファイルをテーブルに読み込む↓↓↓↓↓↓
  TRY.
      CLEAR LCNT_READ.

      OPEN:
        DATASET gw_path
        FOR INPUT
        IN TEXT MODE
        ENCODING UTF-8.

      DO.
        READ DATASET gw_path INTO gw_result.

        IF gw_result IS INITIAL.
          EXIT.
        ENDIF.

*- あの行データを分割する
        SPLIT gw_result AT gcf_tab into :gw_line-ZNO01 gw_line-ZNM01 gw_line-ZBIRTHDAY_DT01 gw_line-ZADDRESS01 gw_line-ZCONTACT01 gw_line-ZCLASS01 gw_line-ZCREATE_DT01 gw_line-ZCREATER01 gw_line-ZUPDATE_DT01 gw_line-ZUPDATER01.

        APPEND gw_line TO gw_output.
      ENDDO.

      DESCRIBE TABLE gw_output LINES LCNT_READ.
      MESSAGE S003(ZB) WITH LCNT_READ.
*-↑↑↑↑↑↑TXTファイルをテーブルに読み込む↑↑↑↑↑↑
      CLOSE:DATASET gw_path.
    CATCH:
      CX_SY_FILE_OPEN.

    CATCH:
      CX_SY_FILE_AUTHORITY.

    CATCH:
      CX_SY_FILE_IO.

    CATCH:
      CX_SY_FILE_CLOSE.

  ENDTRY.

ENDFORM.                    " FRM_READ_DATA
*&---------------------------------------------------------------------*
*&      Form  FRM_INSERT_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_INSERT_DATA .

*-↓↓↓↓↓↓内部テーブルデータからテーブルに挿入する↓↓↓↓↓↓
  INSERT ZSTUDENT01 FROM TABLE gw_output ACCEPTING DUPLICATE KEYS.

  IF SY-SUBRC = 0
  OR SY-SUBRC = 4.

    MESSAGE S004(ZB) WITH SY-DBCNT.
    COMMIT WORK.

  ELSE.
    MESSAGE S005(ZB) WITH SY-DBCNT.
    ROLLBACK WORK.

  ENDIF.
ENDFORM.                    " FRM_INSERT_DATA
```
#GUI_UPLOAD実行サンプルの整理
```ruby:ABAP

REPORT  Z_STUD2_UPD001.

DATA:W_FILE TYPE STRING.
DATA:GDT_TBL  TYPE TABLE OF ZSTUDENT001.

SELECTION-SCREEN BEGIN OF BLOCK B01 WITH FRAME TITLE TEXT-T01.
PARAMETERS:
  P_PATH TYPE LOCALFILE OBLIGATORY.

SELECTION-SCREEN END OF BLOCK B01.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_PATH.
  CALL FUNCTION 'KD_GET_FILENAME_ON_F4'
    EXPORTING
      PROGRAM_NAME  = SYST-REPID
      DYNPRO_NUMBER = SYST-DYNNR
      FIELD_NAME    = P_PATH
    CHANGING
      FILE_NAME     = P_PATH
    EXCEPTIONS
      MASK_TOO_LONG = 1
      OTHERS        = 2.

  IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

************************************************************************
INITIALIZATION.
************************************************************************

************************************************************************
START-OF-SELECTION.
************************************************************************
  W_FILE = P_PATH.

  CALL FUNCTION 'GUI_UPLOAD'
    EXPORTING
       FILENAME = W_FILE
       FILETYPE = 'ASC'
       HAS_FIELD_SEPARATOR = 'X'
    TABLES
      DATA_TAB = GDT_TBL.

   IF SY-SUBRC <> 0.
      MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
   ENDIF.

   DELETE GDT_TBL FROM 1 TO 1.


   INSERT ZSTUDENT001 FROM TABLE GDT_TBL.

************************************************************************
END-OF-SELECTION.
************************************************************************
```

:writing_hand_tone1:[第四弾](https://qiita.com/luyu1567/items/99c366529daae823ea29)
:writing_hand_tone1:[SAP 訓練目次](https://qiita.com/items/dd1fdf83a42f90a78c6e)