1. 程式人生 > >ABAP表拋FTP通用程式

ABAP表拋FTP通用程式

ABAP表拋FTP通用程式

主要功能:

1支援R3所有表(標準、自建)下傳,下傳方式為FTP

2支援輸出欄位選擇及順序調整

3支援動態條件,不同的表會有不同的選擇條件,根據不同的條件選擇需要下傳的資料

4支援單表、多表、以及輸出資料再次加工(需自己寫輸出邏輯擴充套件程式,可參考YTEMPLET

5支援多表查詢,及多表查詢的動態選擇條件

6支援大資料量表分批取數、以及分批下傳(已通過BSEG大資料量表測試)

7支援單檔案下傳(只生產一個檔案,預設是分批下傳,會產生多個檔案)

8其它支援參看選擇螢幕

https://images2015.cnblogs.com/blog/717614/201701/717614-20170125105400987-414064615.png

 https://images2015.cnblogs.com/blog/717614/201701/717614-20170125105401503-1042877203.png

 

程式建立好後,請將螢幕程式碼下載下來,再通過

ABAP編輯器程式中的上傳功能,即可建立螢幕,而不需要手動畫:螢幕程式碼下載

 

Code listing for: YR3TABLE2FTP

Description: ABAP表拋FTP通用程式

REPORT YR3TABLE2FTP.

*&---------------------------------------------------------------------*
*& INCLUDE
*&---------------------------------------------------------------------*

include YR3TABLE2FTP_TOP.
include YR3TABLE2FTP_SELSCR.
include YR3TABLE2FTP_FORM.

*&---------------------------------------------------------------------*
*& 初始化處理
*&---------------------------------------------------------------------*

INITIALIZATION.
  but1 = '輸出欄位配置'.
  but2 = 'HIVE-TABLE-SQL'.
  but3 = '輸出邏輯擴充套件程式模板'.
  IF sy-sysid = 'DEV' OR sy-sysid = 'QAS' OR sy-sysid = 'PRE'.
    p_user = 'adssa'.
    p_pwd = 'fdsssdf'.
    p_host = '32.21.32.123'.
  ELSEIF sy-sysid = 'PRD'.
    p_user = 'fsfwewrew'.
    p_pwd  = 'fsfsfs'.
    p_host = '34.11.53.132'.
  ENDIF.

*&---------------------------------------------------------------------*
*& 選擇螢幕控制
*&---------------------------------------------------------------------*

AT SELECTION-SCREEN OUTPUT.
  IF p_prog IS NOT INITIAL.
    PERFORM frm_find_table USING 'X'.
    PERFORM frm_find_sel.
  ENDIF.

  CLEAR:p_snam1,p_snam2,p_snam3,p_snam4,p_snam5,
        s_asist1,s_asist2,s_asist3,s_asist4,s_asist5,
        s_asist1[],s_asist2[],s_asist3[],s_asist4[],s_asist5[].

  LOOP AT SCREEN.
    IF screen-name = 'P_PWD'.
      screen-invisible = '1'.
    ELSEIF screen-name = 'P_SNAM1' OR
           screen-name = 'P_SNAM2' OR
           screen-name = 'P_SNAM3' OR
           screen-name = 'P_SNAM4' OR
           screen-name = 'P_SNAM5' OR
           screen-name = 'S_ASIST1-LOW' OR screen-name = 'S_ASIST1-HIGH' OR
           screen-name = 'S_ASIST2-LOW' OR screen-name = 'S_ASIST2-HIGH' OR
           screen-name = 'S_ASIST3-LOW' OR screen-name = 'S_ASIST3-HIGH' OR
           screen-name = 'S_ASIST4-LOW' OR screen-name = 'S_ASIST4-HIGH' OR
           screen-name = 'S_ASIST5-LOW' OR screen-name = 'S_ASIST5-HIGH'.
      screen-input = 0.
      LOOP AT sel_flds.
        READ TABLE gt_vrm_values WITH KEY key = sel_flds-fld.
        CASE  sel_flds-p_snam.
          WHEN 's_asist1'.
            IF screen-name = 'S_ASIST1-LOW' OR screen-name = 'S_ASIST1-HIGH'.
              screen-input = 1.
              p_snam1 =  gt_vrm_values-text.
            ENDIF.
          WHEN 's_asist2'.
            IF screen-name = 'S_ASIST2-LOW' OR screen-name = 'S_ASIST2-HIGH'.
              screen-input = 1.
              p_snam2 =  gt_vrm_values-text.
            ENDIF.
          WHEN 's_asist3'.
            IF screen-name = 'S_ASIST3-LOW' OR screen-name = 'S_ASIST3-HIGH'.
              screen-input = 1.
              p_snam3 =  gt_vrm_values-text.
            ENDIF.
          WHEN 's_asist4'.
            IF screen-name = 'S_ASIST4-LOW' OR screen-name = 'S_ASIST4-HIGH'.
              screen-input = 1.
              p_snam4 =  gt_vrm_values-text.
            ENDIF.
          WHEN 's_asist5'.
            IF screen-name = 'S_ASIST5-LOW' OR screen-name = 'S_ASIST5-HIGH'.
              screen-input = 1.
              p_snam5 =  gt_vrm_values-text.
            ENDIF.
        ENDCASE.
      ENDLOOP.
    ENDIF.
    MODIFY SCREEN.
  ENDLOOP.
  CLEAR:gt_vrm_values,gt_vrm_values[].
  gt_vrm_values-key = 'GBK'.
  gt_vrm_values-text = gt_vrm_values-key.
  APPEND gt_vrm_values.
  gt_vrm_values-key = 'UTF-8'.
  gt_vrm_values-text = gt_vrm_values-key.
  APPEND gt_vrm_values.
  gt_vrm_values-key = 'GB2312'.
  gt_vrm_values-text = gt_vrm_values-key.
  APPEND gt_vrm_values.
  gt_vrm_values-key = 'UTF-16BE'.
  gt_vrm_values-text = gt_vrm_values-key.
  APPEND gt_vrm_values.
  gt_vrm_values-key = 'UTF-16LE'.
  gt_vrm_values-text = gt_vrm_values-key.
  APPEND gt_vrm_values.
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_encodi'
      values = gt_vrm_values[].


  CLEAR:gt_vrm_values,gt_vrm_values[].
  gt_vrm_values-key = '_NNNNNN'.
  gt_vrm_values-text = '_NNNNNN'.
  APPEND gt_vrm_values.
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_fileno'
      values = gt_vrm_values[].

  CLEAR:gt_vrm_values,gt_vrm_values[].
  gt_vrm_values-key = 'YYYYMMDD'.
  gt_vrm_values-text = 'YYYYMMDD'.
  APPEND gt_vrm_values.
  gt_vrm_values-key = 'YYYYMM'.
  gt_vrm_values-text = 'YYYYMM'.
  APPEND gt_vrm_values.
  gt_vrm_values-key = 'YYYYMMDDHHMMSS'.
  gt_vrm_values-text = 'YYYYMMDDHHMMSS'.
  APPEND gt_vrm_values.
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_ymd'
      values = gt_vrm_values[].


  CHECK p_table <> g_last_tbname.
  g_last_tbname = p_table.
  CLEAR:gt_vrm_values,gt_vrm_values[],gt_vrm_values_dt,gt_vrm_values_dt[],gt_dd03l,gt_dd03l[],rtables,rtables[].
  PERFORM frm_val TABLES gt_vrm_values rtables gt_vrm_values_dt gt_dd03l USING ''.


  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name1'
      values = gt_vrm_values_dt.
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name2'
      values = gt_vrm_values[].
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name3'
      values = gt_vrm_values[].
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name4'
      values = gt_vrm_values[].
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name5'
      values = gt_vrm_values[].
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name6'
      values = gt_vrm_values[].
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name7'
      values = gt_vrm_values[].
  CALL FUNCTION 'VRM_SET_VALUES'
    EXPORTING
      id     = 'p_name8'
      values = gt_vrm_values[].

  IF flg2 = 'X'.
    CONCATENATE p_table `_` INTO p_fil_px.
    CLEAR: p_name1,p_name2,p_name3,p_name4,p_name5,p_name6,p_name7,p_name8,
           s_val1,s_val2,s_val3,s_val4,s_val5,s_val6,s_val7,s_val8,
           s_val1[],s_val2[],s_val3[],s_val4[],s_val5[],s_val6[],s_val7[],s_val8[].
    LOOP AT gt_dd03l WHERE keyflag = 'X' .
      CASE sy-tabix.
        WHEN 1.
          p_name2 = gt_dd03l-fieldname.
        WHEN 2.
          p_name3 = gt_dd03l-fieldname.
        WHEN 3.
          p_name4 = gt_dd03l-fieldname.
        WHEN 4.
          p_name5 = gt_dd03l-fieldname.
        WHEN 5.
          p_name6 = gt_dd03l-fieldname.
        WHEN 6.
          p_name7 = gt_dd03l-fieldname.
        WHEN 7.
          p_name8 = gt_dd03l-fieldname.
      ENDCASE.
    ENDLOOP.
  ENDIF.
  CLEAR:flg2.

AT SELECTION-SCREEN ON p_table.
  flg2 = 'X'.
  SELECT SINGLE * FROM dd02l WHERE tabname = p_table AND ( tabclass = 'TRANSP' OR tabclass = 'CLUSTER' ) .
  IF sy-subrc <> 0.
    MESSAGE '表不存在' TYPE 'E'.
  ENDIF.

AT SELECTION-SCREEN ON p_fil_px.


AT SELECTION-SCREEN ON p_split.
  IF p_split = ''.
    MESSAGE '列分隔符不能為空' TYPE 'E'.
  ENDIF.

AT SELECTION-SCREEN ON p_counts.
  IF p_counts <= 0.
    MESSAGE '每檔案最大條目數需大於0' TYPE 'E'.
  ENDIF.

AT SELECTION-SCREEN ON p_prog.
  IF  p_prog <> ''.
    SELECT SINGLE * FROM progdir WHERE name = p_prog.
    IF sy-subrc <> 0.
      MESSAGE '輸出邏輯擴充套件程式不存在' TYPE 'E'.
    ENDIF.
  ENDIF.

*&---------------------------------------------------------------------*
*& 引數輸入檢查
*&---------------------------------------------------------------------*

AT SELECTION-SCREEN ON BLOCK b11.
  CLEAR: gt_name[].

  IF p_name1 IS NOT INITIAL AND s_val1[] IS NOT INITIAL.
    gt_name-name = p_name1.
    APPEND gt_name.
  ENDIF.

  IF p_name2 IS NOT INITIAL AND s_val2[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name2.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name2.
    APPEND gt_name.
  ENDIF.

  IF p_name3 IS NOT INITIAL AND s_val3[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name3.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name3.
    APPEND gt_name.
  ENDIF.

  IF p_name4 IS NOT INITIAL AND s_val4[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name4.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name4.
    APPEND gt_name.
  ENDIF.

  IF p_name5 IS NOT INITIAL AND s_val5[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name5.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name5.
    APPEND gt_name.
  ENDIF.

  IF p_name6 IS NOT INITIAL AND s_val6[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name6.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name6.
    APPEND gt_name.
  ENDIF.

  IF p_name7 IS NOT INITIAL AND s_val7[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name7.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name7.
    APPEND gt_name.
  ENDIF.

  IF p_name8 IS NOT INITIAL AND s_val8[] IS NOT INITIAL.
    READ TABLE gt_name WITH KEY name = p_name8.
    IF sy-subrc = 0.
      MESSAGE '條件欄位重複,請檢查輸入條件' TYPE 'E'.
    ENDIF.
    gt_name-name = p_name8.
    APPEND gt_name.
  ENDIF.

AT SELECTION-SCREEN.
  CASE sy-ucomm.
    WHEN 'CLI1'.
      CALL SCREEN 1001 STARTING AT 37 1
                      ENDING   AT 99 20.
    WHEN 'CLI2'.
      CALL SCREEN 1002 STARTING AT 37 1
                      ENDING   AT 97 20.
    WHEN 'CLI3'.
      CALL SCREEN 1003 STARTING AT 30 1
                      ENDING   AT 150 20.
  ENDCASE.

*&---------------------------------------------------------------------*
*& 程式開始處理
*&---------------------------------------------------------------------*

START-OF-SELECTION.
  CONDENSE p_fil_px.
  IF p_fil_px = ''.
    MESSAGE '檔名不能為空' TYPE 'S' DISPLAY LIKE 'E'.
    EXIT.
  ENDIF.

  PERFORM f_get_data. "取數邏輯

*&---------------------------------------------------------------------*
*& 程式結束處理
*&---------------------------------------------------------------------*

END-OF-SELECTION.

*  PERFORM xxxxxxx.

*GUI Texts
*----------------------------------------------------------
* 1001 --> 輸出欄位配置
* 1002 --> HIVE-TABLE-SQL檢視
* 1003 --> 輸出邏輯擴充套件程式樣例

*Text elements
*----------------------------------------------------------
* 001 源表配置
* 002 目標FTP
* 003 條件1
* 004 條件2
* 005 條件3
* 006 條件4
* 007 條件5
* 008 主表名
* 009 輸完表名請回車
* 010 條件6
* 011 條件7
* 012 條件8
* 013 欄位分隔符
* 014 若為Tab請輸入\t;換行符固定為\r\n不可指定(首次轉到FTP為\r\n,但HIVE接過去時為\n)
* 016 1、條件1為日期型別,可用於按日期增量,支援變式裡的動態日期
* 017 檔名
* 018 最終檔案存放路徑:路徑+資料夾日期,資料夾日期可以不輸入
* 021 主表選擇條件
* 022 輸出欄位
* 023 輸出欄位選擇
* 028  NNNNNN為檔案編號,留空時將只產生一個檔案
* 030 關聯表選擇條件
* 031 2、除條件1外如果是日期型別,請按YYYMMDD格式輸入,不帶日期格式
* 032 dddd
* 033 .
* 071 資料夾日期
* 112 輸出邏輯擴充套件程式
* 114 
* 118 當上面檔名中有YYYYMMDD(或YYYYMM),且檔案日期留空時,取當前日期
* 121 是否生成標記檔案
* 122 是否生成時間戳欄位(ZTIMESTAMPL)
* 123 是否帶表頭
* 124 檔名是否帶編號
* 125 如去掉,則主表會一次查出所有資料後下傳,檔名不會帶 _NNNNNN 編號
* 126 預設不帶。表頭每列資訊由欄位名+欄位描述+長度(欄位名:欄位描述(長度))組成
* 127 SQL效能日誌
* 128 生成的表頭裡是否帶 表字段名+欄位長度 資訊
* 129 抽取時間戳(YYYYMMDDhhmmss.mmmuuun)
* 132 檔案字元編碼
* 133 標記副檔名
* 140 
* 213 表頭是否帶技術資訊
* 231 _YYYYMMDD
* 771 檔案日期
* 900 輸完程式名請回車


*Selection texts
*----------------------------------------------------------
* FTP_PATH         路徑
* PFLGFILE         標記檔案
* P_COUNTS         主表分批查詢記錄數
* P_DIR_DT         資料夾日期
* P_ENCODI         檔案字元編碼
* P_EXTENS         資料副檔名
* P_FIL_PX         資料檔名
* P_FLG_FL         標記檔名
* P_HEADER         是否帶表頭
* P_HOST         主機IP
* P_NAME1         條件1欄位名
* P_NAME2         條件2欄位名
* P_NAME3         條件3欄位名
* P_NAME4         條件4欄位名
* P_NAME5         條件5欄位名
* P_NAME6         條件6欄位名
* P_NAME7         條件7欄位名
* P_NAME8         條件8欄位名
* P_PROG         輸出擴充套件邏輯程式名
* P_PWD         密碼
* P_SNAM1         關聯表選擇條件名1
* P_SNAM2         關聯表選擇條件名2
* P_SNAM3         關聯表選擇條件名3
* P_SNAM4         關聯表選擇條件名4
* P_SNAM5         關聯表選擇條件名5
* P_SPLIT         列分隔符
* P_TABLE         主表名
* P_USER         使用者名稱
* P_VARUSR         變式建立者
* S_ASIST1         關聯表選擇條件值1
* S_ASIST2         關聯表選擇條件值2
* S_ASIST3         關聯表選擇條件值3
* S_ASIST4         關聯表選擇條件值4
* S_ASIST5         關聯表選擇條件值5
* S_VAL1         條件1值
* S_VAL2         條件2值
* S_VAL3         條件3值
* S_VAL4         條件4值
* S_VAL5         條件5值
* S_VAL6         條件6值
* S_VAL7         條件7值
* S_VAL8         條件8值


*Messages
*----------------------------------------------------------
*
* Message class: Hard coded
*   請輸入內容

Extracted by Mass Download version 1.5.5 - E.G.Mellodew. 1998-2017. Sap Release 640

Code listing for: YR3TABLE2FTP_FORM

Description: Include YR3TABLE2FTP_FORM

*&---------------------------------------------------------------------*
*&  包括              YR3TABLE2FTP_FORM
*&---------------------------------------------------------------------*


*&---------------------------------------------------------------------*
*&      Form  f_get_data
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*

FORM f_get_data .
  FIELD-SYMBOLS: <dyn_table> TYPE STANDARD TABLE,
                 <dyn_table_new> TYPE STANDARD TABLE,
                 <dyn_wa>.
  DATA: dy_table TYPE REF TO data,
        dy_line TYPE REF TO data.
  DATA: str TYPE string.
  DATA: lv_selflds TYPE string.

  IF p_ymd = 'YYYYMMDD'.
    IF p_ymd2 IS NOT INITIAL.
      CONCATENATE p_fil_px p_ymd2 INTO p_fil_px2.
    ELSE.
      CONCATENATE p_fil_px sy-datum INTO p_fil_px2.
    ENDIF.
  ELSEIF p_ymd = 'YYYYMM'.
    IF p_ymd2 IS NOT INITIAL.
      CONCATENATE p_fil_px p_ymd2+0(6) INTO p_fil_px2.
    ELSE.
      CONCATENATE p_fil_px sy-datum+0(6) INTO p_fil_px2.
    ENDIF.
  ELSEIF p_ymd = 'YYYYMMDDHHMMSS'.
    IF p_ymd2 IS NOT INITIAL.
      CONCATENATE p_fil_px p_ymd2 sy-uzeit INTO p_fil_px2.
    ELSE.
      CONCATENATE p_fil_px sy-datum sy-uzeit INTO p_fil_px2.
    ENDIF.
  ELSE.
    p_fil_px2 = p_fil_px.
  ENDIF.

  CLEAR: gt_YTEST300,gt_YTEST300[].
  SELECT * FROM YTEST300 INTO TABLE gt_YTEST300 WHERE username = p_varusr AND tabname = p_table ORDER BY sequence ASCENDING.
  struct_type ?= cl_abap_typedescr=>describe_by_name( p_table ).
  comp_tab[] = struct_type->get_components( ).
  PERFORM frm_comp_tab TABLES comp_tab.

  IF gt_YTEST300[] IS NOT INITIAL.
    CLEAR:comp_tab2[].
    LOOP AT gt_YTEST300.
      READ TABLE comp_tab WITH KEY name = gt_YTEST300-fldname.
      MOVE-CORRESPONDING comp_tab TO comp_tab2.
      APPEND comp_tab2.
      CONCATENATE lv_selflds ` ` gt_YTEST300-fldname INTO lv_selflds.
    ENDLOOP.
    comp_tab[] = comp_tab2[].


    IF timestmp = 'X'.
      comp_tab-name = 'ZTIMESTAMPL'.
      comp_tab-type = cl_abap_elemdescr=>get_c( 22 ).
      APPEND comp_tab.
    ENDIF.

    struct_type = cl_abap_structdescr=>create( comp_tab[] ).
  ELSE.
    LOOP AT comp_tab.
      CONCATENATE lv_selflds ` ` comp_tab-name INTO lv_selflds.
    ENDLOOP.

    IF timestmp = 'X'.
      comp_tab-name = 'ZTIMESTAMPL'.
      comp_tab-type = cl_abap_elemdescr=>get_c( 22 ).
      APPEND comp_tab.
      struct_type = cl_abap_structdescr=>create( comp_tab[] ).
    ENDIF.

  ENDIF.

  table_type = cl_abap_tabledescr=>create( struct_type ).

  CREATE DATA dy_table TYPE HANDLE table_type.
  ASSIGN dy_table->* TO <dyn_table>.
  CREATE DATA dy_line LIKE LINE OF <dyn_table>.
  ASSIGN dy_line->* TO <dyn_wa>.

  DATA: cond TYPE string,orderby TYPE string.

  CLEAR:cond .
  IF p_name1 IS NOT INITIAL AND s_val1[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name1 ` in s_val1 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name1 ` in s_val1` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name2 IS NOT INITIAL AND s_val2[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name2 ` in s_val2 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name2 ` in s_val2` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name3 IS NOT INITIAL AND s_val3[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name3 ` in s_val3 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name3 ` in s_val3` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name4 IS NOT INITIAL AND s_val4[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name4 ` in s_val4 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name4 ` in s_val4` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name5 IS NOT INITIAL AND s_val5[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name5 ` in s_val5 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name5 ` in s_val5` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name6 IS NOT INITIAL AND s_val6[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name6 ` in s_val6 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name6 ` in s_val6` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name7 IS NOT INITIAL AND s_val7[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name7 ` in s_val7 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name7 ` in s_val7` INTO cond.
    ENDIF.
  ENDIF.

  IF p_name8 IS NOT INITIAL AND s_val8[] IS NOT INITIAL.
    IF cond = ''.
      CONCATENATE  p_name8 ` in s_val8 ` INTO cond.
    ELSE.
      CONCATENATE cond ` and ` p_name8 ` in s_val8` INTO cond.
    ENDIF.
  ENDIF.

  DATA: str_len TYPE i.
  str_len = STRLEN( ftp_path ).
  str_len = str_len - 1.
  REPLACE ALL OCCURRENCES OF `\` IN ftp_path  WITH `/`.
  CONDENSE ftp_path.
  IF ftp_path+str_len = '/' AND p_dir_dt IS NOT INITIAL.
    CONCATENATE ftp_path p_dir_dt INTO ftp_path.
  ELSEIF p_dir_dt IS NOT INITIAL.
    CONCATENATE ftp_path '/' p_dir_dt INTO ftp_path.
  ENDIF.

  IF ftp_path+str_len = '/' AND str_len <> 0.
    ftp_path = ftp_path+0(str_len).
  ENDIF.
  FIELD-SYMBOLS: <fldvalue>,<key_constr>.
  DATA: key_constr TYPE TABLE OF string WITH HEADER LINE,l_total TYPE string,lins TYPE i,lins2 TYPE i,strtmp TYPE string.
  DATA:lt_dd03l TYPE TABLE OF dd03l WITH HEADER LINE,wa_dd03l LIKE lt_dd03l.
  SELECT tabname fieldname keyflag rollname position inttype leng decimals FROM dd03l INTO CORRESPONDING FIELDS OF TABLE lt_dd03l
          WHERE tabname = p_table AND keyflag = 'X' .
  SORT lt_dd03l BY position.

  LOOP AT lt_dd03l.
    CONCATENATE ` ` orderby ` ` lt_dd03l-fieldname INTO orderby.
  ENDLOOP.
  CONDENSE orderby.

  DELETE lt_dd03l WHERE fieldname = 'MANDT'.
  READ TABLE lt_dd03l INTO wa_dd03l INDEX 1."第一主鍵欄位

  DATA: counts TYPE i,diff_counts TYPE i.
  DO.
    g_count = sy-index.
    CONCATENATE `_` g_count INTO g_count_c.

    CLEAR:key_constr,key_constr[].
    IF sy-index = 1."首次查
      IF cond IS INITIAL.
        IF wa_dd03l-inttype = 'C'.
          CONCATENATE wa_dd03l-fieldname ` >= ''` INTO key_constr.
        ELSE.
          CONCATENATE `( ` wa_dd03l-fieldname ` >= -128 )`INTO key_constr.
        ENDIF.
      ELSE.
        IF wa_dd03l-inttype = 'C'.
          CONCATENATE `( ` wa_dd03l-fieldname ` >= '' ) AND ( ` cond ` )` INTO key_constr.
        ELSE.
          CONCATENATE `( ` wa_dd03l-fieldname ` >= -128 ) AND ( ` cond ` )` INTO key_constr.
        ENDIF.
      ENDIF.

      APPEND key_constr.
      CLEAR key_constr.
    ELSE.
      IF <dyn_table> IS NOT INITIAL ."最近一次查到資料後
        DESCRIBE TABLE lt_dd03l LINES lins.
        IF lins > 1."如果主鍵欄位個數大於1
          PERFORM frm_key_constr TABLES <dyn_table> lt_dd03l key_constr.
          LOOP AT key_constr ASSIGNING <key_constr>.
            IF cond IS NOT INITIAL.
              CONCATENATE `( ` <key_constr> ` ) AND ( ` cond ` )` INTO <key_constr>.
            ENDIF.
          ENDLOOP.
        ENDIF.

        CLEAR <dyn_wa>.
        DESCRIBE TABLE <dyn_table> LINES lins.
        READ TABLE <dyn_table> INTO <dyn_wa> INDEX lins.
        ASSIGN COMPONENT wa_dd03l-fieldname OF STRUCTURE <dyn_wa> TO <fldvalue>.

        "非首次查詢時,無論怎樣第一主鍵欄位大於條件需要
        IF cond IS INITIAL.
          CONCATENATE wa_dd03l-fieldname ` > '` <fldvalue> `'` INTO key_constr.
        ELSE.
          CONCATENATE wa_dd03l-fieldname ` > '` <fldvalue> `' AND ( ` cond ` )` INTO key_constr.
        ENDIF.
        APPEND key_constr.
      ENDIF.
    ENDIF.

    CONCATENATE  `正在讀取第 ` g_count ` 批資料...` INTO str.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = 20
        text       = str.

    FREE <dyn_table>.
    LOOP AT key_constr.
      DESCRIBE TABLE <dyn_table> LINES lins.
      diff_counts = p_counts - lins.
      IF diff_counts <= 0 .
        EXIT.
      ENDIF.
      strtmp = key_constr.
      GET RUN TIME FIELD tm1.
      SELECT (lv_selflds) APPENDING CORRESPONDING FIELDS OF TABLE <dyn_table> FROM (p_table) UP TO diff_counts ROWS WHERE (strtmp) ORDER BY (orderby).
      DESCRIBE TABLE <dyn_table> LINES lins2.
      diff_counts = lins2 - lins.
      IF psqllog = 'X'.
        PERFORM frm_write_file2 USING strtmp diff_counts sy-tabix.
      ENDIF.
    ENDLOOP.
    IF psqllog = 'X'.
      PERFORM frm_write_file3 .
    ENDIF.

    "首次查詢為空時,需要下傳空檔案
    IF sy-index > 1 AND <dyn_table> IS INITIAL.
      EXIT.
    ENDIF.

    DATA:dy_table_new TYPE REF TO data.
    IF p_prog IS NOT INITIAL.

************************************

      CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
        EXPORTING
          percentage = 20
          text       = `輸出欄位邏輯擴充套件處理...`.

      PERFORM frm_dyn IN PROGRAM (p_prog) TABLES <dyn_table> comp_tab[]
                                s_asist1 s_asist2 s_asist3 s_asist4 s_asist5
                                USING dy_table_new .
      ASSIGN dy_table_new->* TO <dyn_table_new>.
      IF p_fileno IS NOT INITIAL."分檔案拋FTP
        PERFORM to_ftptab TABLES <dyn_table_new>.
      ELSE."不分檔案
        IF g_count = 1.
          PERFORM to_ftptab TABLES <dyn_table_new>.
        ELSE.
          PERFORM frm_write_file TABLES <dyn_table_new>.
        ENDIF.
      ENDIF.
      DESCRIBE TABLE <dyn_table_new> LINES lins.

************************************

    ELSE.
      IF p_fileno IS NOT INITIAL.
        PERFORM to_ftptab TABLES <dyn_table>.
      ELSE.
        IF g_count = 1.
          PERFORM to_ftptab TABLES <dyn_table>.
        ELSE.
          PERFORM frm_write_file TABLES <dyn_table>.
        ENDIF.
      ENDIF.
      DESCRIBE TABLE <dyn_table> LINES lins.
    ENDIF.
    l_total = l_total + lins.
    IF flg_ftp IS NOT INITIAL.
      EXIT.
    ENDIF.
  ENDDO.

  IF p_fileno IS INITIAL.
    CONCATENATE  `正在將SAP服務上檔案Append到FTP:` gv_filename INTO str.
    CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
      EXPORTING
        percentage = 20
        text       = str.
    PERFORM frm_ftp_append.
    CONCATENATE  `/usr/sap/tmp/` p_fil_px2 `.` p_extens INTO gv_filename SEPARATED BY ``.
    DELETE DATASET gv_filename.
  ENDIF.

  CHECK flg_ftp IS INITIAL AND pflgfile = 'X'.

  DATA: codepage TYPE cpcodepage,
     encoding TYPE abap_encoding,
    convout TYPE REF TO cl_abap_conv_out_ce,
    buffer TYPE xstring.
  DATA: BEGIN OF dest_xtab OCCURS 0,
        x(6144) TYPE x,
      END OF dest_xtab.

  CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
    EXPORTING
      external_name = p_encodi
    IMPORTING
      sap_codepage  = codepage.
  encoding = codepage.

  CALL METHOD cl_abap_conv_out_ce=>create
    EXPORTING
      encoding = encoding
    RECEIVING
      conv     = convout.

*  CONCATENATE `資料總條數:` l_total INTO l_total.

  CONDENSE l_total.
  CALL METHOD convout->write
    EXPORTING
      data = l_total.

  CALL METHOD convout->get_buffer
    RECEIVING
      buffer = buffer.

  DATA: lv_binary_len TYPE i.
  CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
    EXPORTING
      buffer        = buffer
    IMPORTING
      output_length = lv_binary_len
    TABLES
      binary_tab    = dest_xtab.

  PERFORM f_ftp_connect.
  PERFORM frm_cd_dir.

  CONCATENATE p_fil_px2 `.` p_flgex INTO gv_filename.

  CONDENSE gv_filename.
  CALL FUNCTION 'FTP_R3_TO_SERVER'
    EXPORTING
      handle        = thandle
      fname         = gv_filename
      blob_length   = lv_binary_len
    TABLES
      blob          = dest_xtab
    EXCEPTIONS
      tcpip_error   = 1
      command_error = 2
      data_error    = 3
      OTHERS        = 4.
  IF sy-subrc EQ 0.
    WRITE:/ gv_filename,'傳輸成功!'.
  ELSE.
    WRITE:/ gv_filename,'資料檔案傳輸失敗!'.
  ENDIF.
  PERFORM f_ftp_disconnect.
ENDFORM. " f_get_data

*&---------------------------------------------------------------------*
*&      Form  to_ftptab
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_SRC_TAB    text
*      -->P_DEST_XTAB  text
*      -->OF           text
*      -->X            text
*----------------------------------------------------------------------*

FORM to_ftptab TABLES p_src_tab.
  DATA: BEGIN OF dest_xtab OCCURS 0,
        x(6144) TYPE x,
      END OF dest_xtab.
  DATA: lv_binary_len TYPE i.

  DATA:str TYPE string.
  IF p_fileno IS NOT INITIAL.
    CONCATENATE  p_fil_px2 g_count_c `.` p_extens INTO gv_filename SEPARATED BY ``.
  ELSE.
    CONCATENATE  p_fil_px2 `.` p_extens INTO gv_filename SEPARATED BY ``.
  ENDIF.
  CONCATENATE  `正在準備檔案:` gv_filename INTO str.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      percentage = 20
      text       = str.

  PERFORM frm_data_to_binary TABLES p_src_tab dest_xtab USING lv_binary_len 'X'.

  CONCATENATE  `正在上傳檔案:` gv_filename INTO str.
  CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
    EXPORTING
      percentage = 20
      text       = str.
  PERFORM f_ftp_connect.
  PERFORM frm_mkdir.
  PERFORM frm_cd_dir.

  PERFORM f_ftp TABLES dest_xtab USING lv_binary_len.
  PERFORM f_ftp_disconnect.
  CLEAR:dest_xtab.
  REFRESH:dest_xtab[].
ENDFORM. "to_ftptab

*&---------------------------------------------------------------------*
*&      Form  to_ftptab2
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_SRC_TAB  text
*----------------------------------------------------------------------*

FORM frm_data_to_binary TABLES p_src_tab dest_xtab USING lv_binary_len TYPE i first.
  DATA:strct_type_ref TYPE REF TO cl_abap_structdescr,
       tab_type_ref TYPE REF TO cl_abap_tabledescr,
       t_component TYPE cl_abap_structdescr=>component_table,
       wa_component LIKE LINE OF t_component.
  FIELD-SYMBOLS: <fldvalue>.
  DATA:time_stamp TYPE timestampl,timestamp_c(22).

  DATA: l_str TYPE string,fldstr TYPE string,fldtype,firsttime VALUE 'X'.
  DATA: str TYPE string.
  DATA: len TYPE string.
  DATA: codepage TYPE cpcodepage,
     encoding TYPE abap_encoding,
    convout TYPE REF TO cl_abap_conv_out_ce,
    buffer TYPE xstring.

  CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
    EXPORTING
      external_name = p_encodi
    IMPORTING
      sap_codepage  = codepage.
  encoding = codepage.

  CALL METHOD cl_abap_conv_out_ce=>create
    EXPORTING
      encoding = encodi