LOOP AT SCREEN

本文介绍ABAP中如何通过修改SCREEN構造来动态调整画面元素属性,包括显示、隐藏、输入等控制方式。文章还详细解释了ACTIVE、INPUT、OUTPUT、INVISIBLE等组件的功能及其相互作用。

用法

主に、画面の属性を変更させるために使用する。

照会モードでは入力不可とするが入力可能モードでは入力可能とする、ラジオボタンAが選択された場合はラジオボタンBに関連する項目は非表示とするなど。

 

サンプル

LOOP AT SCREEN INTO WA_SCREEN.
  IF ( WA_SCREEN-NAME = 'RAD_A' ) AND ( RAD_A = 'X' ).
    WA_SCREEN-INPUT = '1'.
    MODIFY SCREEN.
  ENDIF.
ENDLOOP.

属性を変更する場合は、値を代入の上MODIFY SCREENで変更すること。

SCREENの構造と項目

過去のバージョンではデータ型グループで定義されていたようだが、現在は構造SCREENで定義されている。

コンポーネント長さプロパティ内容説明
NAME132CName名称
GROUP13CGroup1修正グループ
GROUP23CGroup2修正グループ
GROUP33CGroup3修正グループ
GROUP43CGroup4修正グループ
REQUIRED1CRequired-entry field必須項目
INPUT1CInput入力可能項目
OUTPUT1COutput表示項目
INTENSIFIED1CIntensified強調項目
INVISIBLE1CInvisible非表示エレメント
LENGTH1XvisLength項目長
ACTIVE1CInput/Output/Invisible有効項目
DISPLAY_3D1CTwo-dimensionalボックス
VALUE_HELP1CInput help入力ヘルプキー
REQUEST1C-入力あり
VALUES_IN_COMBO1CDropdown listbox値ヘルプあり

これらの属性を取り扱うことはできるが、あまり込み入ったことをするとヤヤコシイことになるので、入力可否の制御くらいにしておいた方が無難かと思う。

----------------------------------------------------------------------------------------------------------------

 

属性の動的設定 

画面の各項目には属性のセットがあり、スクリーンペインタでDynpro を定義する際に固定されます。ABAP プログラムの実行時に、特定の命令を使用して、各画面項目の属性の一部を事前定義された構造 screen に読み込むことができます。その後、これらの属性で画面項目を変更することができます。

構造 'screen'

プログラムでこの構造を宣言する必要はありません。ダイアログモジュールでの画面処理中に、screen にアクセスすることができます。

コンポーネント

長さ

データ型

意味

属性

surname

132

C

画面項目の名称

名称

group1

3

C

モディフィケーショングループ 1

グループ 1

group2

3

C

モディフィケーショングループ 2

グループ 2

group3

3

C

モディフィケーショングループ 3

グループ 3

group4

3

C

モディフィケーショングループ 4

グループ 4

required

1

C

項目は入力必須

必須項目

input

1

C

項目は入力可能

エントリ

output

1

C

項目は表示専用

出力

intensified

1

C

項目は強調表示

強調表示

invisible

1

C

項目は非表示

非可視

length

1

X

項目長

表示長

active

1

C

項目は有効

入力/出力/非表示

display_3d

1

C

3 次元ボックス

2 次元

value_help

1

C

入力ヘルプボタン表示

入力ヘルプ

request

1

C

入力あり

-

最後の列には、スクリーンペインタの画面項目の該当する属性が含まれています。

Dynpro のPBO イベント時に ABAP プログラムで構造 screen を変更し、ABAP プログラムの画面エレメントを変更することができます。変更されたエレメントにより、1 回の画面呼出について画面項目の静的属性が上書きされます。screen とともに使用することができるのは、以下の命令のみです。

  LOOP AT SCREEN.
...
      MODIFY SCREEN.
...
ENDLOOP.

LOOP AT SCREEN は独立した命令です。内部テーブルでのループと混同しないでください。

コンポーネント NAME には、画面項目の名称が指定されます。コンポーネント GROUP1 から GROUP4 には、3 文字のコードを指定することができます。これらのコードを使用すると、画面項目を最大で 4 つのモディフィケーショングループに含めることができます。1 つの画面項目は、複数の異なるモディフィケーショングループに属することができます。モディフィケーショングループは構造 screen の追加キー項目のようなもので、これを使用して、グループ内のすべてのエレメントの属性を同時に変更することができます。スクリーンペインタでエレメントをモディフィケーショングループに静的に割り当てますが、これはプログラムで動的に上書きすることができます。

残りのコンポーネントは、画面項目の表示属性を変更したり、有効化/無効化したりするために使用されます。LENGTH 以外のすべてのコンポーネントでは、1 は有効を表し、0 は無効を表します。

ACTIVE、INPUT、OUTPUT、および INVISIBLE

コンポーネント ACTIVE、INPUT、OUTPUT、およびINVISIBLE の間には、特定の階層化されたルールがあります。また、それぞれの静的設定に応じて異なる影響をもたらします。

ACTIVE コンポーネントには、対応するエレメント属性はありません。代わりに、このコンポーネントによって、コンポーネント INPUT、OUTPUT、および INVISIBLE が変更されます。

PBO の開始時には、属性の静的設定に関係なく、ACTIVE は常に 1 に設定されます。ACTIVE を 0 に設定すると、自動的に INPUT = 0、OUTPUT = 0、および INVISIBLE = 1 に設定されます。現在の Dynpro エレメントの INPUT、OUTPUT、および INVISIBLE の設定への変更は無視されます。逆に、INPUT = 0、OUTPUT = 0、および INVISIBLE = 1 と設定すると自動的に ACTIVE が 0 に設定され、現在の画面エレメントの ACTIVE へのその他の割当はすべて無視されます。設定 ACTIVE = 1 には、属性へのその他の影響はありません。ACTIVE コンポーネントの唯一の目的は、1 回の割当によって画面項目を無効化することです。Dynpro 制御ロジックで FIELD 命令にリンクされているモジュール呼出は、該当する項目が SCREEN-ACTIVE = 0 の場合でも、必ず実行されることに特に注意してください。無効な項目に対してモジュールが処理されないようにするには、FIELD 命令と MODULE 命令を別個に指定する必要があります。

ACTIVE、INPUT、OUTPUT、およびINVISIBLE には 8 とおりの組合せがあります。各組合せは、それぞれ以下のような影響を画面項目に及ぼします。

ACTIVE

入力

OUTPUT

INVISIBLE

動作

1

1

1

0

非表示が静的に設定されていても、画面項目が表示されます。

項目内容が表示されます。

入力が静的に設定されていなくても、入力可能です。ただし、出力専用が静的に設定されている場合は、入力不可です。

1

1

0

0

出力専用が静的に設定されている場合を除き、非表示が静的に設定されていても画面項目が表示されます。

項目内容は表示されません。

入力が静的に設定されていなくても、入力可能です。

1

0

1

0

非表示が静的に設定されていても、画面項目が表示されます。

項目内容が表示されます。

入力が静的に設定されていても、入力不可です。

1

0

0

0

出力専用が静的に設定されている場合を除き、非表示が静的に設定されていても画面項目が表示されます。

項目内容は表示されません。

入力が静的に設定されていても、入力不可です。

1

1

1

1

出力専用が静的に設定されている場合を除き、非表示が静的に設定されていても画面項目が表示されます。

項目内容は表示されません。

入力が静的に設定されていなくても、入力可能です。ユーザ入力は、アスタリスク (*) でマスキングされます。

1

1

0

1

出力専用が静的に設定されている場合を除き、非表示が静的に設定されていても画面項目が表示されます。

出力は、アスタリスク (*) でマスキングされます。

入力が静的に設定されていなくても、入力可能です。ユーザ入力は、アスタリスク (*) でマスキングされます。

1

0

1

1

画面項目は無効です。

静的属性に関係なく、画面項目は表示されません。

0

0

0

1

画面項目は無効です。

静的属性に関係なく、画面項目は表示されません。

項目が出力専用として静的に定義されている場合、設定INPUT = 1 による影響はありません。これらの項目については、常に INPUT は 0 です。アスタリスク (*) によるユーザ入力のマスキングは、ユーザパスワードを入力するために使用することができます。

項目を非表示にすると行全体が非表示になる場合、自動的に画面が小さくなります。ただし、静的 Dynpro 属性の実行時圧縮オフを選択することで、この属性を切り替えることができます。

REQUIRED

REQUIRED = 1 と設定すると、入力可能項目が必須項目になります。すべての必須項目に値を入力しないと、画面を終了できません。タイプ E の機能コード、および AT EXIT-COMMAND オプションを含むモジュールは例外です。

DISPLAY_3D

DISPLAY_3D = 0 と設定すると、入出力項目の 3 次元フレームが削除されます。DISPLAY_3D = 1 を使用して、出力専用属性が設定されているテキスト項目や画面項目に 3 次元効果を生成することはできません。

VALUE_HELP

VALUE_HELP を 0 または 1 に設定すると、入力ヘルプボタンがそれぞれオフまたはオンに切り替わります。

INTENSIFIED

INTENSIFIED = 1 と設定すると、入力項目の項目内容が黒から赤に変わります。出力項目の内容は、黒から青に変わります。

LENGTH

LENGTH コンポーネントは、入出力項目と出力専用項目に静的に定義された出力長 (表示長) よりも短い値に設定することができます。このコンポーネントを使用すると、これらの項目の出力長を短くすることができます。他の画面エレメントは、短くすることも長くすることもできません。

REQUEST

入力可能項目に REQUEST = 1 と設定した場合、PAI イベントにおける影響はユーザが項目内容を変更した場合と同じになります。すなわち、ユーザが実際に項目を変更したかどうかに関係なく、ON REQUEST または ON CHAIN-REQUEST を使用した条件モジュール呼出が実行されます。REQUEST は、自動的に 0 にリセットされます。

この例では、基本的な画面モディフィケーションについて説明します。プログラムDEMO_DYNPRO_MODIFY_SCREEN を使用して、可能なモディフィケーションをすべて示します。

動的な画面モディフィケーション

REPORT demo_dynpro_modify_simple.

DATA: ok_code TYPE sy-ucomm,
      save_ok TYPE sy-ucomm.

DATA flag(1) TYPE c.

CALL SCREEN 100.

MODULE status_0100 OUTPUT.
  SET PF-STATUS 'SCREEN_100'.
  LOOP AT SCREEN.
    IF screen-group1 = 'MOD'.
      IF flag = ' '.
        screen-input = '0'.
      ELSEIF flag = 'X'.
        screen-input = '1'.
ENDIF.
      MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDMODULE.

MODULE cancel.
    LEAVE PROGRAM.
ENDMODULE.

MODULE user_command_0100 INPUT.
  save_ok = ok_code.
  CLEAR ok_code.
  CASE save_ok.
    WHEN 'TOGGLE'.
      IF flag = ' '.
      flag = 'X'.
      ELSEIF flag = 'X'.
      flag = ' '.
ENDIF.
ENDCASE.
ENDMODULE.

  

Dynpro 100 の静的定義による次Dynpro は 100 です。この Dynpro は以下のようなレイアウトになります。

 LOOP_AT_SCREEN

入出力項目は、ABAP ディクショナリの構造DEMO_CONN からコピーされています。下部の 4 つの入出力項目は、モディフィケーショングループ MOD に割り当てられています。

Dynpro 制御ロジックは以下のようになります。

PROCESS BEFORE OUTPUT.
  MODULE status_0100.

PROCESS AFTER INPUT.
  MODULE cancel AT EXIT-COMMAND.
  MODULE user_command_0100.

GUI ステータスSCREEN_100 で、機能コード TOGGLE が押ボタンとリンクされます。

プログラムが呼び出された際に、下部の 4 つの入出力項目は入力可能として表示されません。これは、最初に変数 flag に空白が含まれているためです。TOGGLE を使用して、入力可能ステータスのオン/オフを切り替えることができます。

转载于:https://www.cnblogs.com/yjyongil/p/10605226.html

REPORT ZBISMT_UPDATE. * 定义数据类型 TYPES: BEGIN OF ty_excel_data, matnr TYPE matnr, " 物料号 maktx TYPE maktx, " 物料描述(仅用于读取Excel,不处理) bismt TYPE bismt, " 库格 werks TYPE werks_d, " 工厂 lgort TYPE lgort_d, " 库位 END OF ty_excel_data. * 定义内表和工作区 DATA: gt_excel_data TYPE TABLE OF ty_excel_data, gs_excel_data TYPE ty_excel_data, gt_zmm_bismt TYPE TABLE OF zmm_bismt, gs_zmm_bismt TYPE zmm_bismt, gt_updated TYPE TABLE OF zmm_bismt, " 存储更新的数据 gt_skipped TYPE TABLE OF zmm_bismt. " 存储跳过的数据(库格相同) * 保存结果到全局变量用于显示 DATA: gv_updated TYPE i, gv_skipped TYPE i, gv_inserted TYPE i. * 单物料维护相关变量 DATA: gv_edit_mode TYPE c, " 编辑模式:E=编辑,C=新建 gs_curr_data TYPE zmm_bismt. " 当前编辑的数据 * 选择屏幕定义 SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-t01. PARAMETERS: p_file TYPE rlgrap-filename. " Excel文件路径 PARAMETERS: p_werks TYPE werks_d DEFAULT '1011' OBLIGATORY. " 工厂输入 PARAMETERS: p_lgort TYPE lgort_d DEFAULT 'MT01' OBLIGATORY. " 库位输入 SELECTION-SCREEN SKIP. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN COMMENT 1(20) TEXT-fil. " 文件选择标签 SELECTION-SCREEN PUSHBUTTON 21(15) but_file USER-COMMAND file_sel. " 文件选择按钮 SELECTION-SCREEN END OF LINE. PARAMETERS: p_test AS CHECKBOX DEFAULT 'X' USER-COMMAND test. " 测试模式开关 SELECTION-SCREEN END OF BLOCK b1. SELECTION-SCREEN SKIP. SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-t02. PARAMETERS: p_matnr TYPE matnr. " 物料号输入 SELECTION-SCREEN SKIP. SELECTION-SCREEN BEGIN OF LINE. SELECTION-SCREEN PUSHBUTTON 1(10) but1 USER-COMMAND query. " 查询按钮 SELECTION-SCREEN PUSHBUTTON 12(10) but2 USER-COMMAND create. " 新建按钮 SELECTION-SCREEN PUSHBUTTON 23(10) but3 USER-COMMAND save. " 保存按钮 SELECTION-SCREEN END OF LINE. SELECTION-SCREEN SKIP. PARAMETERS: p_w_s TYPE werks_d MODIF ID dis, " 工厂(显示用) p_lg_s TYPE lgort_d MODIF ID dis, " 库位(显示用) p_bismt TYPE bismt MODIF ID edt. " 库格(可编辑) SELECTION-SCREEN END OF BLOCK b2. * 文本符号定义 INITIALIZATION. " 设置按钮文本 but1 = '查询'. but2 = '新建'. but3 = '保存'. but_file = '浏览...'. " 文件选择按钮文本 * 主程序 START-OF-SELECTION. " 只有在提供了文件路径时才执行批量更新 IF p_file IS NOT INITIAL. PERFORM read_excel_data. PERFORM process_data. PERFORM show_result. ELSE. " 显示提示信息,只有单物料维护被执行 WRITE: / '未提供Excel文件,跳过批量更新'. WRITE: / '仅执行了单物料维护功能'. ENDIF. *&---------------------------------------------------------------------* *& Form READ_EXCEL_DATA *&---------------------------------------------------------------------* FORM read_excel_data. DATA: lt_raw_data TYPE truxs_t_text_data. DATA: lt_temp_excel TYPE TABLE OF ty_excel_data. " 临时内表 " 检查文件是否存在 PERFORM check_file_existence USING p_file. " 调用函数上传Excel文件 CALL FUNCTION 'TEXT_CONVERT_XLS_TO_SAP' EXPORTING i_tab_raw_data = lt_raw_data i_filename = p_file TABLES i_tab_converted_data = lt_temp_excel " 先读到临时内表 EXCEPTIONS conversion_failed = 1 OTHERS = 2. IF sy-subrc <> 0. MESSAGE 'Excel文件读取失败' TYPE 'E'. ENDIF. " 从第二行开始读取数据(跳过标题行) LOOP AT lt_temp_excel INTO gs_excel_data FROM 2. " 使用用户输入的工厂和库位值 gs_excel_data-werks = p_werks. gs_excel_data-lgort = p_lgort. APPEND gs_excel_data TO gt_excel_data. ENDLOOP. " 删除可能存在的空行(仅检查物料号) DELETE gt_excel_data WHERE matnr IS INITIAL. ENDFORM. " READ_EXCEL_DATA *&---------------------------------------------------------------------* *& Form PROCESS_DATA *&---------------------------------------------------------------------* FORM process_data. " 从目标表读取现有数据 SELECT matnr werks lgort bismt FROM zmm_bismt INTO TABLE gt_zmm_bismt. " 处理Excel数据 LOOP AT gt_excel_data INTO gs_excel_data. " 检查目标表中是否已存在相同物料号、工厂和库位的记录 READ TABLE gt_zmm_bismt INTO gs_zmm_bismt WITH KEY matnr = gs_excel_data-matnr werks = gs_excel_data-werks lgort = gs_excel_data-lgort. IF sy-subrc = 0. " 记录已存在,检查库格是否相同 IF gs_zmm_bismt-bismt = gs_excel_data-bismt. " 库格相同,跳过不处理 gv_skipped = gv_skipped + 1. APPEND gs_zmm_bismt TO gt_skipped. ELSE. " 库格不同,准备更新记录 gs_zmm_bismt-bismt = gs_excel_data-bismt. " 仅在非测试模式下执行更新 IF p_test <> 'X'. UPDATE zmm_bismt SET bismt = gs_excel_data-bismt WHERE matnr = gs_excel_data-matnr AND werks = gs_excel_data-werks AND lgort = gs_excel_data-lgort. ENDIF. IF sy-subrc = 0 OR p_test = 'X'. gv_updated = gv_updated + 1. APPEND gs_zmm_bismt TO gt_updated. ENDIF. ENDIF. ELSE. " 新记录,准备插入 gs_zmm_bismt-matnr = gs_excel_data-matnr. gs_zmm_bismt-werks = gs_excel_data-werks. gs_zmm_bismt-lgort = gs_excel_data-lgort. gs_zmm_bismt-bismt = gs_excel_data-bismt. " 仅在非测试模式下执行插入 IF p_test <> 'X'. INSERT zmm_bismt FROM gs_zmm_bismt. ENDIF. IF sy-subrc = 0 OR p_test = 'X'. gv_inserted = gv_inserted + 1. ENDIF. ENDIF. ENDLOOP. " 仅在非测试模式下提交更改 IF p_test <> 'X'. COMMIT WORK. ENDIF. ENDFORM. " PROCESS_DATA *&---------------------------------------------------------------------* *& Form SHOW_RESULT *&---------------------------------------------------------------------* FORM show_result. DATA: lv_total TYPE i. DATA: ls_updated TYPE zmm_bismt. " 工作区用于显示 " 计算总记录数 DESCRIBE TABLE gt_excel_data LINES lv_total. " 显示测试模式提示 IF p_test = 'X'. WRITE: / '当前处于测试模式,不会实际修改数据库'. SKIP 1. ENDIF. WRITE: / '批量更新处理完成'. WRITE: / '总记录数:', lv_total. WRITE: / '更新记录数:', gv_updated. WRITE: / '跳过记录数(库格相同):', gv_skipped. WRITE: / '插入记录数:', gv_inserted. " 仅显示数量,不显示明细 " 显示所有更新记录 IF gv_updated > 0. WRITE: / '所有更新记录:'. WRITE: / '物料号', 20 '工厂', 27 '库位', 35 '原库格', 50 '新库格'. LOOP AT gt_updated INTO ls_updated. " 获取原库格值用于显示 READ TABLE gt_zmm_bismt INTO gs_zmm_bismt WITH KEY matnr = ls_updated-matnr werks = ls_updated-werks lgort = ls_updated-lgort. IF sy-subrc = 0. WRITE: / ls_updated-matnr, 20 ls_updated-werks, 27 ls_updated-lgort, 35 gs_zmm_bismt-bismt, " 原库格 50 ls_updated-bismt. " 新库格 ENDIF. ENDLOOP. ENDIF. " 显示所有跳过记录 IF gv_skipped > 0. WRITE: / '所有跳过记录(库格相同):'. WRITE: / '物料号', 20 '工厂', 27 '库位', 35 '库格'. LOOP AT gt_skipped INTO gs_zmm_bismt. WRITE: / gs_zmm_bismt-matnr, 20 gs_zmm_bismt-werks, 27 gs_zmm_bismt-lgort, 35 gs_zmm_bismt-bismt. ENDLOOP. ENDIF. ENDFORM. " SHOW_RESULT *&---------------------------------------------------------------------* *& Form CHECK_FILE_EXISTENCE *&---------------------------------------------------------------------* FORM check_file_existence USING p_filename. DATA: lv_file TYPE string. DATA: lv_exists TYPE abap_bool. lv_file = p_filename. " 使用GUI前端服务检查文件是否存在 CALL METHOD cl_gui_frontend_services=>file_exist EXPORTING file = lv_file RECEIVING result = lv_exists EXCEPTIONS cntl_error = 1 error_no_gui = 2 OTHERS = 3. IF sy-subrc <> 0 OR lv_exists <> abap_true. MESSAGE '文件不存在或无法访问' TYPE 'E'. ENDIF. ENDFORM. " CHECK_FILE_EXISTENCE *&---------------------------------------------------------------------* *& AT SELECTION-SCREEN OUTPUT *&---------------------------------------------------------------------* AT SELECTION-SCREEN OUTPUT. " 控制单物料维护区域字段状态 PERFORM control_single_mat_fields. *&---------------------------------------------------------------------* *& AT SELECTION-SCREEN *&---------------------------------------------------------------------* AT SELECTION-SCREEN. " 处理按钮事件 CASE sy-ucomm. WHEN 'QUERY'. PERFORM handle_query. WHEN 'CREATE'. PERFORM handle_create. WHEN 'SAVE'. PERFORM handle_save. WHEN 'FILE_SEL'. " 文件选择按钮事件 PERFORM handle_file_selection. ENDCASE. *&---------------------------------------------------------------------* *& Form CONTROL_SINGLE_MAT_FIELDS *&---------------------------------------------------------------------* FORM control_single_mat_fields. " 设置显示字段属性 LOOP AT SCREEN. IF screen-group1 = 'DIS'. " 显示字段设为只读 screen-input = 0. MODIFY SCREEN. ELSEIF screen-group1 = 'EDT'. " 库格字段:编辑模式下可编辑 IF gv_edit_mode IS NOT INITIAL. screen-input = 1. ELSE. screen-input = 0. ENDIF. MODIFY SCREEN. ENDIF. ENDLOOP. ENDFORM. " CONTROL_SINGLE_MAT_FIELDS *&---------------------------------------------------------------------* *& Form HANDLE_QUERY *&---------------------------------------------------------------------* FORM handle_query. " 检查物料号是否输入 IF p_matnr IS INITIAL. MESSAGE '请输入物料号' TYPE 'S' DISPLAY LIKE 'E'. RETURN. ENDIF. " 检查物料号是否存在 PERFORM check_matnr_exists USING p_matnr. " 检查物料在指定工厂和库位是否存在 SELECT SINGLE * FROM zmm_bismt INTO gs_curr_data WHERE matnr = p_matnr AND werks = p_werks AND lgort = p_lgort. IF sy-subrc = 0. " 存在,进入编辑模式 gv_edit_mode = 'E'. p_w_s = gs_curr_data-werks. p_lg_s = gs_curr_data-lgort. p_bismt = gs_curr_data-bismt. MESSAGE s000(zmsg) WITH '物料已存在,进入编辑模式'. ELSE. " 不存在 CLEAR: p_w_s, p_lg_s, p_bismt. gv_edit_mode = ''. MESSAGE '该工厂和库位不存在该物料' TYPE 'S' DISPLAY LIKE 'E'. ENDIF. ENDFORM. " HANDLE_QUERY *&---------------------------------------------------------------------* *& Form HANDLE_CREATE *&---------------------------------------------------------------------* FORM handle_create. " 检查物料号是否输入 IF p_matnr IS INITIAL. MESSAGE '请输入物料号' TYPE 'S' DISPLAY LIKE 'E'. RETURN. ENDIF. " 检查物料号是否存在 PERFORM check_matnr_exists USING p_matnr. " 检查是否已存在 SELECT SINGLE * FROM zmm_bismt INTO gs_curr_data WHERE matnr = p_matnr AND werks = p_werks AND lgort = p_lgort. IF sy-subrc = 0. " 已存在,进入编辑模式 gv_edit_mode = 'E'. p_w_s = gs_curr_data-werks. p_lg_s = gs_curr_data-lgort. p_bismt = gs_curr_data-bismt. MESSAGE s000(zmsg) WITH '物料已存在,自动进入编辑模式'. ELSE. " 不存在,进入新建模式 gv_edit_mode = 'C'. p_w_s = p_werks. p_lg_s = p_lgort. CLEAR p_bismt. MESSAGE s000(zmsg) WITH '进入新建模式,请填写库格'. ENDIF. ENDFORM. " HANDLE_CREATE *&---------------------------------------------------------------------* *& Form HANDLE_SAVE *&---------------------------------------------------------------------* FORM handle_save. " 检查是否在编辑模式 IF gv_edit_mode IS INITIAL. MESSAGE '请先查询或新建物料' TYPE 'S' DISPLAY LIKE 'E'. RETURN. ENDIF. " 检查库格是否填写 IF p_bismt IS INITIAL. MESSAGE '库格不能为空' TYPE 'S' DISPLAY LIKE 'E'. RETURN. ENDIF. " 设置数据 gs_curr_data = VALUE #( matnr = p_matnr werks = p_w_s lgort = p_lg_s bismt = p_bismt ). " 根据模式保存 CASE gv_edit_mode. WHEN 'E'. " 编辑模式 UPDATE zmm_bismt SET bismt = p_bismt WHERE matnr = p_matnr AND werks = p_w_s AND lgort = p_lg_s. IF sy-subrc = 0. MESSAGE '物料更新成功' TYPE 'S'. ELSE. MESSAGE '物料更新失败' TYPE 'S' DISPLAY LIKE 'E'. ENDIF. WHEN 'C'. " 新建模式 INSERT zmm_bismt FROM gs_curr_data. IF sy-subrc = 0. MESSAGE '物料创建成功' TYPE 'S'. ELSE. MESSAGE '物料创建失败' TYPE 'S' DISPLAY LIKE 'E'. ENDIF. ENDCASE. " 重置编辑模式 gv_edit_mode = ''. ENDFORM. " HANDLE_SAVE *&---------------------------------------------------------------------* *& Form CHECK_MATNR_EXISTS *&---------------------------------------------------------------------* FORM check_matnr_exists USING p_matnr. " 检查物料主数据是否存在 SELECT SINGLE matnr FROM mara INTO @DATA(lv_matnr) WHERE matnr = @p_matnr. IF sy-subrc <> 0. MESSAGE '物料号不存在' TYPE 'S' DISPLAY LIKE 'E'. gv_edit_mode = ''. CLEAR: p_w_s, p_lg_s, p_bismt. STOP. ENDIF. " 检查库存视图是否存在 SELECT SINGLE matnr FROM mard INTO @lv_matnr WHERE matnr = @p_matnr AND werks = @p_werks AND lgort = @p_lgort. IF sy-subrc <> 0. MESSAGE '物料在指定工厂和库位的库存视图不存在' TYPE 'S' DISPLAY LIKE 'W'. ENDIF. ENDFORM. " CHECK_MATNR_EXISTS *&---------------------------------------------------------------------* *& Form HANDLE_FILE_SELECTION *&---------------------------------------------------------------------* FORM handle_file_selection. DATA: lt_file_table TYPE filetable, lv_rc TYPE i, lv_action TYPE i. " 调用文件选择对话框 CALL METHOD cl_gui_frontend_services=>file_open_dialog EXPORTING window_title = '选择Excel文件' default_extension = 'XLS' file_filter = 'Excel文件 (*.XLS;*.XLSX)|*.XLS;*.XLSX|所有文件 (*.*)|*.*|' CHANGING file_table = lt_file_table rc = lv_rc user_action = lv_action EXCEPTIONS file_open_dialog_failed = 1 cntl_error = 2 error_no_gui = 3 not_supported_by_gui = 4 OTHERS = 5. IF sy-subrc = 0 AND lv_action = cl_gui_frontend_services=>action_ok. " 获取用户选择的第一个文件 READ TABLE lt_file_table INDEX 1 INTO p_file. IF sy-subrc = 0. " 更新屏幕字段值 p_file = p_file. ENDIF. ENDIF. ENDFORM. " HANDLE_FILE_SELECTION 读取文件数据时从第一行读取,去掉代码的测试功能,改成输出错误内容并且不执行数据库写入。错误分为如下几种:第一类错误.导入的文件中出现相同的物料号时,记录物料号及其所在行并输出,例如物料A在第18行,第50行和第99行出现,则报错输出为问题物料号为A,出现的所在行为18,50,99。第二类错误.导入的文件中第62行物料号B及其库格(bismt)与要修改的数据库中的物料号B及其库格完全相同,输出为出现同样的物料号B,出现的所在行为62行。第三类错误,输入的物料号A一定要在mara表中存在,输出内容为:有不存在的物料号A,所在行为。。。.首先将要读取的数据进行第一类错误检验,出错了就终止程序输出错误内容,第一类错误未发现进行第三类错误检验,最后才进行第二类错误检验,都通过了执行数据库写入。出现某一种错误时统计并输出所有此类错误的物料后才会结束程序,例如出现了第一类错误,输出所有重复的物料号及其所在行才会终止程序,不会再检查下面的错误
最新发布
08-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值