mm 采购单 附件 内文 文字转换 发邮件 邮件附件

本文介绍了一个基于 SAP ALV 的报表程序,该程序能够从 SAP 数据库中提取采购订单相关信息,并通过电子邮件将报表发送给指定的采购组。文章详细描述了 ABAP 代码的结构,包括数据获取、ALV 显示配置、邮件内容准备及发送流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

*&---------------------------------------------------------------------*
*& Report  YAMM02R2201
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

report  yamm02r2201 message-id zamm01.

type-pools: slis.

tables:ekpo,ekko.

include zamm_alv_data_type.


data: begin of i_tab occurs 0 ,
      werks     like  ekpo-werks,
      lifnr     like  ekko-lifnr,
      name1     like  lfa1-name1,
      ekorg     like  ekko-ekorg,
      ekgrp     like  ekko-ekgrp,
      ebeln     like  ekko-ebeln,
      ebelp     like   ekpo-ebelp,
      matnr     like  ekpo-matnr,
      txz01     like  ekpo-txz01,
      aedat     like  ekpo-aedat,
      objky     like  drad-objky,
      drad      type  i,
      tdline    like  tline-tdline,
      flag(1)   type c,
  end of i_tab.

data:   lines   like tline occurs 0 with header line.
data:   doc_id  like thead-tdname.

***********************************************************************
* Email相關objects -- 20111017 added by Robert
***********************************************************************
data: it_objpack like sopcklsti1 occurs 0 with header line, "attribute
      it_reclist like somlreci1  occurs 0 with header line, "receiver
      it_objtxt  like solisti1   occurs 0 with header line, "content
      it_objbin  like solisti1   occurs 0 with header line, "attach
      it_record  like solisti1   occurs 0 with header line. "data record

data: wa_objhead  type soli_tab,     "SO:Objcont 與 Objhead 作為表格類型
      wa_doc_chng type sodocchgi1.   "SO:可更改的物件資料

data: g_rowcount_txt type i,
      g_lines_bin type i.

data: v_lines_bin type i.
data: v_lines_bin_all type i.

data: enter(2) type c value cl_abap_char_utilities=>cr_lf,
      tab      type c value cl_abap_char_utilities=>horizontal_tab.



data: g_admin_mail like t024-smtp_addr value''.



selection-screen: begin of block b1 with frame title text-001.
parameter:  p_werks like ekpo-werks obligatory.
select-options : s_lifnr for ekko-lifnr,
                 s_ekorg for ekko-ekorg,
                 s_ekgrp for ekko-ekgrp,
                 s_ebeln for ekko-ebeln,
                 s_aedat for ekpo-aedat.

selection-screen:end of block b1.


selection-screen: begin of block b2 with frame title text-002.
parameters: p_send type c as checkbox default ''.

selection-screen:end of block b2.


* ALV 儲存配置選取 ----------------------------------------------
selection-screen begin of block b3 with frame title text-003.
selection-screen: begin of line.
selection-screen comment 1(12) text-110.
parameters: p_vari type slis_vari.
selection-screen:end of line.
selection-screen end of  block b3.


initialization .

  "由 T-CODE -> SU01 取得使用者帳號,頁簽 -參數,針對參數設定值        *
  get parameter id 'WRK' field p_werks.

  "取得 ALV 儲存配置預設值
  g_save = 'A'.
  perform get_default_variant.


  "在 show 畫面之前,針對欄位特殊控制,例如:隱藏,只show不可編輯 .....

at selection-screen output.




at selection-screen on value-request for p_vari."ALV 儲存配置 按 F4 查詢
  perform f4_alv_variant.

  "在 畫面輸入後針對欄位後續處理


at selection-screen.
  "檢查權限,因畫面工廠只能輸入單一值,故在此檢查,若可輸入多工廠,
  "請在資料處理迴路中進行檢查
  perform check_authority.





start-of-selection.

  perform get_data.

  perform define_fieldcat using 'I_TAB'.  "定義ALV欄位設定 *

  perform send_mail_process.

  perform alv_display tables i_tab.

*&---------------------------------------------------------------------*
*&      Form  get_data
*&---------------------------------------------------------------------*
*       獲取數據
*----------------------------------------------------------------------*
form get_data.

  "獲取 主資料
  select *
    into corresponding fields of table i_tab
    from ekko
    inner join ekpo on ekko~ebeln = ekpo~ebeln
*    inner join lfa1 on ekko~lifnr = lfa1~lifnr
    where ekpo~werks = p_werks and
          ekko~lifnr in s_lifnr and
          ekko~ekorg in s_ekorg and
          ekko~ekgrp in s_ekgrp and
          ekko~ebeln in s_ebeln and
          ekpo~aedat in s_aedat.

  loop at i_tab.
    "取 供應商 名稱
    select single name1 into i_tab-name1 from lfa1 where lifnr =
    i_tab-lifnr.
    "  添加前置零
    call function 'CONVERSION_EXIT_ALPHA_INPUT'
      exporting
        input  = i_tab-ebeln
      importing
        output = i_tab-ebeln.
    "  添加前置零
    call function 'CONVERSION_EXIT_ALPHA_INPUT'
      exporting
        input  = i_tab-ebelp
      importing
        output = i_tab-ebelp.

    " 組合 組件 代碼
    concatenate i_tab-ebeln i_tab-ebelp into i_tab-objky.

    " 取 附件筆數
    select count(*) into i_tab-drad from drad where objky = i_tab-objky.

    doc_id = i_tab-objky.

    clear: lines[].
    " 取 內文
    call function 'READ_TEXT'
      exporting
*   CLIENT                        = SY-MANDT
        id                            = 'F08'
        language                      = 'M'
        name                          = doc_id
        object                        = 'EKPO'
      tables
        lines                         = lines
       exceptions
         id                            = 1
         language                      = 2
         name                          = 3
         not_found                     = 4
         object                        = 5
         reference_check               = 6
         wrong_access_to_archive       = 7
         others                        = 8.

    if sy-subrc = 0.

      read table lines index 1.

      i_tab-tdline = lines-tdline.

      if i_tab-drad > 0 .
        i_tab-flag = ''.
      else.
        i_tab-flag = 'X'.
      endif.
    else.

      if i_tab-drad > 0 .
        i_tab-flag = 'X'.
      else.
        i_tab-flag = ''.
      endif.
    endif.

    modify i_tab.

  endloop.

endform.                    "get_data

*&---------------------------------------------------------------------*
*&      Form  define_fieldcat
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->U_STRUCTURE_NAME  text
*----------------------------------------------------------------------*
form define_fieldcat using  u_structure_name type slis_tabname.
  data:wa_fieldcat type slis_t_fieldcat_alv with header line.
  clear:it_fieldcat,it_fieldcat[],wa_fieldcat,wa_fieldcat[].

  "從SAP DDIC 抓出 ALV 欄位標準設定  ---------------------------------------
  call function 'REUSE_ALV_FIELDCATALOG_MERGE'
    exporting
      i_program_name         = sy-repid
      i_internal_tabname     = u_structure_name   " IT_ALV 一定要大寫
*      i_structure_name       = u_structure_name   " IT_ALV 一定要大寫
      i_inclname             = sy-repid
    changing
      ct_fieldcat            = it_fieldcat
    exceptions "
      inconsistent_interface = 1
      program_error          = 2
      others                 = 3.


  loop at it_fieldcat into wa_fieldcat.
    case wa_fieldcat-fieldname.
      when 'DRAD'.
        wa_fieldcat-icon = 'X'.
        wa_fieldcat-seltext_l = wa_fieldcat-seltext_m =
        wa_fieldcat-seltext_s = wa_fieldcat-reptext_ddic = text-601.
        wa_fieldcat-outputlen =  8.
      when 'TDLINE'.
        wa_fieldcat-icon = 'X'.
        wa_fieldcat-seltext_l = wa_fieldcat-seltext_m =
        wa_fieldcat-seltext_s = wa_fieldcat-reptext_ddic = text-602.
        wa_fieldcat-outputlen =  8.
      when 'FLAG'.
        wa_fieldcat-icon = 'X'.
        wa_fieldcat-seltext_l = wa_fieldcat-seltext_m =
        wa_fieldcat-seltext_s = wa_fieldcat-reptext_ddic = text-603.
        wa_fieldcat-outputlen =  8.
    endcase.
    modify it_fieldcat  from wa_fieldcat index sy-tabix.
    clear wa_fieldcat.
  endloop.

endform.                    "define_fieldcat


*&---------------------------------------------------------------------*
*&      Form  alv_display
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form alv_display tables   t_internal_table.
  data:l_title type lvc_title.


  call function 'REUSE_ALV_GRID_DISPLAY'
    exporting
      i_callback_program      = sy-repid
      i_callback_user_command = 'USER_COMMAND'
      i_grid_title            = l_title    "SHOW ALV Title + 總筆數
      i_save                  = g_save
      is_variant              = is_variant "傳入 使用者 在show ALV 配置設定
      it_fieldcat             = it_fieldcat "傳入ALV Field Catalog *
      i_default               = 'X'
    tables
      t_outtab                = t_internal_table
    exceptions
      program_error           = 1.

endform.                    "alv_display

*&---------------------------------------------------------------------*
*&      Form  get_layout_variant
*&---------------------------------------------------------------------*
*  取得 使用者 在show ALV 預設配置設定 *
*----------------------------------------------------------------------*
form get_default_variant.
  clear is_variant.

  is_variant-report = sy-repid.
  call function 'REUSE_ALV_VARIANT_DEFAULT_GET'
    exporting
      i_save        = g_save
      " A,U --> 先取使用者設定預設,若無再取 Global 設定預設
      " X   --> 僅取 Global 設定預設
    changing
      cs_variant    = is_variant
    exceptions
      wrong_input   = 1
      not_found     = 2
      program_error = 3.

  if sy-subrc = 0.
    p_vari = is_variant-variant.  "將選取值傳回畫面欄位
  endif.

endform.                    "initialize_variant

*&---------------------------------------------------------------------*
*&      Form  f4_alv_variant
*&---------------------------------------------------------------------*
*       ALV 儲存配置 按 F4 查詢
*----------------------------------------------------------------------*
form f4_alv_variant.
  data: is_variantx  like disvariant.         "ALV 儲存配置

  call function 'REUSE_ALV_VARIANT_F4'
    exporting
      is_variant    = is_variant
      i_save        = g_save
    importing
      e_exit        = g_exit
      es_variant    = is_variantx
    exceptions
      not_found     = 1
      program_error = 2.

  if sy-subrc = 2.
    message id sy-msgid type 's'      number sy-msgno
            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  else.
    if g_exit = space.
      p_vari = is_variantx-variant.  "將選取值傳回畫面欄位
    endif.
  endif.

endform.                    "f4_alv_variant


*&---------------------------------------------------------------------*
*&      Form  check_authority
*&---------------------------------------------------------------------*
*       檢查權限
*----------------------------------------------------------------------*
form check_authority.


  "必須有查詢 工單權限
  authority-check object 'C_AFKO_AWA'
           id 'ACTVT'  field '03'
           id 'AUFART' field '*'
           id 'AUTYP'  field '10'
           id 'WERKS'  field   p_werks.
  if sy-subrc <> 0.
*    MESSAGE s009(zapp01) WITH p_dwerk .

    stop.
  endif.
endform.                    "check_authority



*&---------------------------------------------------------------------*
*&      Form  send_mail_process
*&---------------------------------------------------------------------*
*       text  寄送通知信件主程式
*----------------------------------------------------------------------*
form send_mail_process.
  if p_send eq 'X'.
    "僅IT共用帳號1000BC6能執行發送作業(安全性考量)
    if sy-uname eq 'SONGLAI.ZHU' or sy-uname eq 'ROBERT.HAN'.

*      perform send_mail_by_purgoup.
      "by採購群組發送MAIL+附檔
      read table i_tab index 1.

      perform send_mail using i_tab-ekgrp.
    else.
      message e000 with '您的帳號' sy-uname '無發信權限'.
    endif.
  endif.
endform.                    "send_mail_process

*&---------------------------------------------------------------------
*&      Form  Send_Mail
*&---------------------------------------------------------------------
*       text  寄送通知信件
*----------------------------------------------------------------------
form send_mail using p_ekgrp like ekko-ekgrp.

  if i_tab[] is initial.
    exit.
  endif.

  clear:  wa_objhead[],   wa_objhead,   wa_doc_chng,
          it_objpack[],   it_objpack,
          it_reclist[],   it_reclist,
          it_objtxt[],    it_objtxt,
          it_objbin[],    it_objbin,
          it_record[],    it_record.

  perform set_mail_address using p_ekgrp.        "設定收件人

  data: mailattachname type string.
  concatenate sy-datum '-ZAMM2201-夾檔差異清單-' into mailattachname.
  data: mailcontent type string
        value '注意:本信件由 SAP 系統自動發送,請勿直接回信。'.

  clear it_objtxt.
  it_objtxt = mailcontent.                          "mail content
  append it_objtxt.
  describe table it_objtxt lines g_rowcount_txt.    "取得txt筆數
  read table it_objtxt index g_rowcount_txt.        "使用txt的最新一筆

  "設定 Mail Mail Attribute
  wa_doc_chng-obj_descr   = mailattachname.         "mail subject
  wa_doc_chng-doc_size    = g_rowcount_txt * 255.   "給資料每行255字元
  wa_doc_chng-obj_langu   = sy-langu.               "文件語言屬性
  wa_doc_chng-obj_name    = 'Email'.                "文件性質
  wa_doc_chng-expiry_dat  = sy-datum + 10.          "文件到期日
  wa_doc_chng-sensitivty  = 'F'.                    "F:功能 / G:商業
  wa_doc_chng-priority    = '1'.                    "優先處理等級

  data: tmpstr type string.
  perform itab_to_str using tmpstr.                 "附件檔內容轉字串
  perform str_to_record using tmpstr.               "將字串轉夾檔source
  clear tmpstr.

  append lines of it_record to it_objbin.           "附加 attach file
  describe table it_record lines v_lines_bin.       "取得 attach 長度
  describe table it_objbin lines v_lines_bin_all.   "取binary object長度

  it_objpack-head_start = 1.
  it_objpack-head_num   = 0.
  it_objpack-body_start = 1.
  it_objpack-body_num   = g_rowcount_txt.
  it_objpack-doc_type   = 'RAW'.
  append it_objpack.

  "Attachment (excel-Attachment)
  clear it_objpack-transf_bin.
  it_objpack-transf_bin = 'X'.
  it_objpack-head_start = v_lines_bin_all - v_lines_bin + 1 .
  it_objpack-head_num   = v_lines_bin.

  "Attachment File Name
  describe table it_objbin lines g_lines_bin.
  read table it_objbin index g_lines_bin.
  it_objpack-obj_descr  = mailattachname.
  it_objpack-obj_name   = 'Email 附件'.
  it_objpack-transf_bin = 'X'.
  it_objpack-doc_size   = v_lines_bin * 255.
  it_objpack-body_num   = g_lines_bin.
  it_objpack-doc_type   = 'xls'.
  append it_objpack.

  "*** Do Send Mail ***
  perform do_send_mail using p_ekgrp.

endform.                    " Send_Mail


*&---------------------------------------------------------------------
*&      Form  Set_Mail_Address
*&---------------------------------------------------------------------
*       text  設定 mail 收件人信箱
*----------------------------------------------------------------------
form set_mail_address using p_ekgrp like ekko-ekgrp.

  data: l_email like t024-smtp_addr.

  data: spr1 type c value ',',
        spr2 type c value '@'.

  data: begin of it_email occurs 0,
    mail_addr like adr6-smtp_addr,
  end of it_email.

  data: begin of it_mailpart occurs 0,
    mail_part type c,
  end of it_mailpart.

  clear: it_email[], it_reclist[].

  "取出採購群組的mail欄位值
  select single smtp_addr
    into l_email
    from t024
   where ekgrp = p_ekgrp.

  if l_email is initial.
*    message w000 with '採購群組 ' p_ekgrp ' 的 e-mail 未設定'.
    l_email = g_admin_mail.
  endif.

  condense l_email no-gaps.
  split l_email at spr1 into table it_email.

  "檢查每筆e-mail格式是否正確
  loop at it_email.
    split it_email-mail_addr at spr2 into table it_mailpart.
    data row_cnt type i value 0.
    describe table it_mailpart lines row_cnt.
    if row_cnt ne 2.
*      message w000 with '採購群組 ' p_ekgrp ' 的 e-mail 設定不正確'.
      it_email-mail_addr = g_admin_mail.
      modify it_email.
    endif.
    row_cnt = 0.
  endloop.

  loop at it_email.
    clear it_reclist.
    translate it_email-mail_addr to lower case.

    if sy-mandt = '030'. " or sy-mandt = '510' or sy-mandt = '520'.
      it_reclist-receiver = g_admin_mail.
    else.
      it_reclist-receiver = it_email-mail_addr.
    endif.

    it_reclist-rec_type = 'U'.      "接收方類型的規範--網址
    it_reclist-rec_date = sy-datum. "Date document was received
    it_reclist-express  = 'X'.      "傳送快遞
    it_reclist-com_type = 'INT'.
    append it_reclist.
  endloop.

endform.                    " Set_Mail_Address


*&---------------------------------------------------------------------
*&      Form  Do_Send_Mail
*&---------------------------------------------------------------------
*       text  發送 Email
*----------------------------------------------------------------------
form do_send_mail using p_ekgrp like ekko-ekgrp.

  data:l_msg(50) type c.

  call function 'SO_NEW_DOCUMENT_ATT_SEND_API1'
    exporting
      document_data              = wa_doc_chng
      put_in_outbox              = 'X'
      commit_work                = 'X'
    tables
      packing_list               = it_objpack   "mail的屬性
      object_header              = wa_objhead   "mail表頭
      contents_bin               = it_objbin    "mail附件
      contents_txt               = it_objtxt    "mail內文
      receivers                  = it_reclist   "mail收件者
    exceptions
      too_many_receivers         = 1
      document_not_sent          = 2
      document_type_not_exist    = 3
      operation_no_authorization = 4
      parameter_error            = 5
      x_error                    = 6
      enqueue_error              = 7
      others                     = 8.

  if sy-subrc = 0.
    message s000 with '發送採購群組 ' p_ekgrp ' 已訂未交採購單信件成功'.
  endif.
*  message s000 with '發送採購群組 ' p_ekgrp ' 已訂未交採購單信件成功'.

endform.                    " Do_Send_Mail


*&---------------------------------------------------------------------
*&      Form  itab_to_Str
*&---------------------------------------------------------------------
*       text  internal table 轉 string 組成連續字串
*----------------------------------------------------------------------
form itab_to_str using outstr type string.

  data: n type i.

  data: begin of headtab occurs 0,
    length    type i,
    decimals  type i,
    type_kind type c,
    name(30)  type c,
  end of headtab.

  data: descr_ref type ref to cl_abap_structdescr.

  field-symbols:  <comp_wa> type abap_compdescr,
                  <f_field>,
                  <f_attach> type any.

  data: fieldvalue type string,
        linestr    type string,
        nonusestr  type c,
        sprminus   type c value '-'.

  "取得 Attach 結構
  descr_ref ?= cl_abap_typedescr=>describe_by_data( i_tab ).

  "將 Attach 結構放入 headtab[]
  clear: headtab, headtab[].
  loop at descr_ref->components assigning <comp_wa>.
    move-corresponding <comp_wa> to headtab.
    append headtab.
  endloop.


  "欄位標題字串
  concatenate '工廠' tab '供應商' tab '供應商名稱' tab '採購組織' tab
              '採購群組' tab '單號' tab '項目號' tab '物料' tab
              '短文' tab '建立日期' tab '物件ID' tab '文件數量' tab
              '文本內容' tab '差異'  enter into outstr.

  describe table headtab lines n. "取得head table筆數

  "逐筆將PO資料轉string組成字串
  loop at i_tab assigning <f_attach>.

    "逐欄(n)處理資料
    clear linestr.
    do n times.

      "指定資料至component結構中
      assign component sy-index
            of structure <f_attach> to <f_field>.
      fieldvalue = <f_field>.  "取得欄位值
      read table headtab index sy-index.

      "將數值欄位後置的負號放在前面(I/P/F皆是數值type關鍵字)
      if headtab-type_kind = 'I' or headtab-type_kind = 'P'
         or headtab-type_kind = 'F'.
        search fieldvalue for sprminus.
        if sy-subrc = 0 and sy-fdpos <> 0.
          split fieldvalue at sprminus into fieldvalue nonusestr.
          condense fieldvalue.
          condense sprminus.
          concatenate nonusestr fieldvalue into fieldvalue.
        else.
          condense fieldvalue.
        endif.
      endif.

      "日期轉為yyyy/mm/dd格式
      "if sy-index = 1 or sy-index = 14.
      if headtab-type_kind = 'D'.
        if fieldvalue = '00000000'.
          fieldvalue = space.
        else.
          concatenate fieldvalue+0(4) '/' fieldvalue+4(2) '/'
                      fieldvalue+6(2) into fieldvalue.
        endif.
      endif.

      "多位數的數值字串處理,避免Excel將過大的數字轉為浮點表示法
      if sy-index = 7.
        concatenate '=asc(' fieldvalue ')' into fieldvalue.
      endif.

      "逐欄組字串成一列
      concatenate linestr tab fieldvalue into linestr.
    enddo.

    shift linestr. "去除第一個#符號
    concatenate outstr linestr enter into outstr. "組完一列,enter換行

  endloop.

endform.                    "itab_to_Str

*&---------------------------------------------------------------------
*&      Form  Str_to_Record
*&---------------------------------------------------------------------
*       text  string 轉 xstring 再轉 binary 成為附檔的 data source
*----------------------------------------------------------------------
form str_to_record using tmpstr.

  data: tmpbuffer type xstring,
        tmplen type i.

  data:l_mimetype type char64 value 'APPLICATION/MSEXCEL;charset=gbk'.

  "string轉xstring
  call function 'SCMS_STRING_TO_XSTRING'
    exporting
      text     = tmpstr
      mimetype =  l_mimetype
*      encoding = '4102'
    importing
      buffer   = tmpbuffer
    exceptions
      failed   = 1
      others   = 2.

  "xstring轉binary
  call function 'SCMS_XSTRING_TO_BINARY'
    exporting
      buffer          = tmpbuffer
*      append_to_table = ''
*    importing
*      output_length   = tmplen
    tables
      binary_tab      = it_record.    "***最後輸出至此物件

endform.                    "Str_to_Record
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值