ESP8266-01S烧录AT固件避坑全记录:从固件大小匹配到串口无响应排查
2026/5/27 3:22:01
输入接口增加两个字段:
PAGE_NUM 类型 INT4 (调取第几页,如果不传默认第一页)
PAGE_SIZE 类型 INT4 (每页多少数据,如果不传默认一页500条数据)
输出增加两个字段:
TOTAL_COUNT 类型 INT4 一共多少数据
TOTAL_PAGES 类型 INT4 一共多少页
以下是两个案例:
FUNCTION zmes_me03_mm083. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *"VALUE(INPUT)TYPE ZMES083_S_INPUT *" EXPORTING *"VALUE(OUTPUT)TYPE ZMES083_S_OUTPUT *"---------------------------------------------------------------------- " 1. 初始化 CLEAR output. " 2. 基础输入校验 IF input-zsysid IS INITIAL. output-type ='E'. output-message ='错误:外围系统调用必须传入系统编号(ZSYSID)。'. RETURN. ENDIF. " 3. 分页参数初始化(防御性容错处理)" 如果外部没传或者传了负数/0,给予默认值以保护 SAP 内存DATA(lv_size)= CONDi(WHEN input-page_size <= 0 THEN 500 ELSE input-page_size).DATA(lv_page)= CONDi(WHEN input-page_num <= 0 THEN 1 ELSE input-page_num). " 计算底层 SQL 需要的偏移量(例如第 2 页,每页 500,则偏移量为 500)DATA(lv_offset)=(lv_page - 1)* lv_size. " 4. 第一步:获取满足条件的总数据条数(极其轻量级的 COUNT 查询)SELECTCOUNT(*)FROM resb AS a INNER JOIN rkpf AS h ON a~rsnum = h~rsnum WHERE a~bdart ='MR'AND a~xloek = @space AND a~kzear = @space AND(a~werks = @input-werks OR @input-werks IS INITIAL).DATA(lv_total_count)= sy-dbcnt. IF lv_total_count = 0. output-type ='S'. output-message ='未找到符合条件的预留单数据。'. output-total_count = 0. output-total_pages = 0. RETURN. ENDIF. " 计算总页数(利用 ABAP 整型运算特性自动进位处理)output-total_count = lv_total_count. " 使用 DIV 进行向下取整的整数除法,完美实现向上进位 output-total_pages =(lv_total_count + lv_size - 1)DIV lv_size. " 5. 第二步:分页执行精准取数(OFFSET + UP TO ROWS)" 注意:使用 OFFSET 时,必须配合 ORDER BY 保证每次分页取数的一致性 SELECT a~rsnum,a~rspos,h~usnam,a~werks,a~bdart,a~xloek,a~kzear,a~matnr,t~maktx,a~meins,a~sobkz,a~lgort,l1~lgobe,a~charg,a~bdmng,a~enmng,a~bdter,a~shkzg,a~aufnr,a~kdauf,a~kdpos,a~bwart,a~umwrk,a~umlgo,l2~lgobe AS lgobe1 FROM resb AS a INNER JOIN rkpf AS h ON a~rsnum = h~rsnum LEFT OUTER JOIN makt AS t ON a~matnr = t~matnr AND t~spras ='1'LEFT OUTER JOIN t001l AS l1 ON a~werks = l1~werks AND a~lgort = l1~lgort LEFT OUTER JOIN t001l AS l2 ON a~umwrk = l2~werks AND a~umlgo = l2~lgort WHERE a~bdart ='MR'AND a~xloek = @space AND a~kzear = @space AND(a~werks = @input-werks OR @input-werks IS INITIAL)ORDER BY a~rsnum,a~rspos " <--- 必须排序,否则分页数据会混乱 INTO TABLE @DATA(lt_result)UP TO @lv_size ROWS " <--- 限制返回条数(Limit)OFFSET @lv_offset. " <--- 设定起始位置(Offset)" 6. 数据处理与格式转换 output-item = CORRESPONDING #(lt_result). LOOP AT output-item ASSIGNINGFIELD-SYMBOL(<fs_item>). " 计算剩余未发货数量 <fs_item>-zwfsl = <fs_item>-bdmng - <fs_item>-enmng." 去除前导零 <fs_item>-rsnum = |{<fs_item>-rsnum ALPHA = OUT}|. <fs_item>-matnr = |{<fs_item>-matnr ALPHA = OUT}|. <fs_item>-aufnr = |{<fs_item>-aufnr ALPHA = OUT}|. <fs_item>-kdauf = |{<fs_item>-kdauf ALPHA = OUT}|. " 单位内外码转换 CALL FUNCTION'CONVERSION_EXIT_CUNIT_OUTPUT'EXPORTING input = <fs_item>-meins IMPORTING output = <fs_item>-meins EXCEPTIONS unit_not_found = 1 OTHERS = 2. ENDLOOP." 7. 成功返回 output-type = 'S'. output-message = |查询成功。当前第{lv_page}页,本页读取{lines(output-item)}条。共计{output-total_count}条数据。|. ENDFUNCTION.FUNCTION zmes_me02_mm052a. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *"REFERENCE(INPUT)TYPE ZMMS052A_INPUT *" EXPORTING *"REFERENCE(OUTPUT)TYPE ZMMS052A_OUTPUT *"----------------------------------------------------------------------CLEAR:output.REFRESH:output-body.DATA:lr_werks TYPE RANGE OF eban-werks,ls_werks LIKE LINE OF lr_werks.DATA:lv_tdid TYPE thead-tdid VALUE'B01',lv_name TYPE thead-tdname,lv_objt TYPE thead-tdobject VALUE'EBAN',lt_line TYPE TABLE OF tline.DATA:lv_ekorg TYPE ekorg,lrs_lifnr TYPE RANGE OF lifnr,lv_index TYPE sy-tabix,lv_fldname TYPE fieldname. " 临时变量,用于 SQL 逃逸DATA:lv_tmp_matnr TYPE matnr,lv_tmp_lifnr TYPE lifnr,lv_tmp_infnr TYPE infnr,lv_tmp_werks TYPE werks_d,lv_tmp_ekorg TYPE ekorg,lv_tmp_esokz TYPE esokz,lv_tmp_kschl TYPE kschl.TYPES:BEGIN OF ty_vendor_price,matnr TYPE matnr,werks TYPE werks_d,ekorg TYPE ekorg,lifnr TYPE lifnr,infnr TYPE infnr,zname TYPE name1,mwskz TYPE mwskz,esokz TYPE esokz,knumh TYPE knumh,kbetr TYPE kbetr,kpein TYPE kpein,konwa TYPE konwa,delete TYPE char1,END OF ty_vendor_price.DATA:lt_price TYPE TABLE OF ty_vendor_price.FIELD-SYMBOLS:<fs_val> TYPE any. " 声明一个临时内表,用于存放全量基础数据DATA:lt_base LIKE output-body. "====================================================================== " 1. 入参校验与分页参数初始化 "====================================================================== IF input-zsysid IS INITIAL. output-type ='E'. output-message ='系统编号 ZSYSID 为必填项'. RETURN. ENDIF. " 分页参数防御性处理DATA(lv_size)= CONDi(WHEN input-page_size <= 0 THEN 500 ELSE input-page_size).DATA(lv_page)= CONDi(WHEN input-page_num <= 0 THEN 1 ELSE input-page_num). IF input-werks IS NOT INITIAL. ls_werks-sign ='I'. ls_werks-option ='EQ'. ls_werks-low = input-werks. APPEND ls_werks TO lr_werks. ELSE. lr_werks = VALUE #((sign ='I'option ='EQ'low ='1000')(sign ='I'option ='EQ'low ='1100')(sign ='I'option ='EQ'low ='2000')(sign ='I'option ='EQ'low ='3000')). ENDIF. "====================================================================== " 2. 主数据查询(取入临时表 lt_base,并加入 ORDER BY)"====================================================================== SELECT eban~ekgrp,eban~zgroup,eban~werks,eban~bsart,eban~frgkz,eban~banfn,eban~bnfpo,eban~pstyp,eban~knttp,eban~infnr,ebkn~vbeln,ebkn~vbelp,ebkn~aufnr,ebkn~anln1,eban~matnr,eban~txz01,eban~badat,eban~lfdat,eban~menge,eban~bsmng,(eban~menge - eban~bsmng)AS zwqsl,eban~meins,eban~lgort,eban~lifnr AS lifnr1,a~zcpjd INTO CORRESPONDING FIELDS OF TABLE @lt_base FROM eban LEFT JOIN ebkn ON ebkn~banfn = eban~banfn AND ebkn~bnfpo = eban~bnfpo AND ebkn~loekz =''INNER JOIN mara AS a ON a~matnr = eban~matnr WHERE eban~werks IN @lr_werks AND eban~bsart NE'NB'AND eban~loekz =''AND eban~ebakz =''ORDER BY eban~banfn,eban~bnfpo. " <--- 必须通过主键绝对排序 IF sy-subrc <> 0. output-type ='S'. output-message ='未找到符合条件的数据'. output-total_count = 0. output-total_pages = 0. RETURN. ENDIF. " 直接在临时表中进行条件过滤 DELETE lt_base WHERE zwqsl = 0. "====================================================================== " 3. 内表精准切片分页(在耗时的 LOOP 之前进行切片,大幅提升性能!)"====================================================================== output-total_count =lines(lt_base). IF output-total_count = 0. output-type ='S'. output-message ='查询成功,但所有记录均不满足交货未清条件。'. output-total_pages = 0. RETURN. ENDIF. " 使用 CEIL 避免四舍五入 Bug output-total_pages =ceil(output-total_count / lv_size).DATA(lv_from)=(lv_page - 1)* lv_size + 1.DATA(lv_to)= lv_page * lv_size. IF lv_from > output-total_count. CLEAR output-body. ELSE. IF lv_to > output-total_count. lv_to = output-total_count. ENDIF. " 将切片数据写入真正的输出表 INSERT LINES OF lt_base FROM lv_from TO lv_to INTO TABLE output-body. ENDIF. "====================================================================== " 4. 数据加工(仅仅 LOOP 当前页的数据,省去海量无用计算)"====================================================================== LOOP AT output-body ASSIGNINGFIELD-SYMBOL(<fs_alv>)." 获取文本 lv_name = |{<fs_alv>-banfn}{<fs_alv>-bnfpo}|. CALL FUNCTION 'READ_TEXT' EXPORTING id = lv_tdid language = '1' name = lv_name object = lv_objt TABLES lines = lt_line EXCEPTIONS not_found = 1 OTHERS = 2. IF sy-subrc = 0. LOOP AT lt_line INTO DATA(ls_line). <fs_alv>-zbz = |{<fs_alv>-zbz},{ls_line-tdline}|. ENDLOOP. IF <fs_alv>-zbz IS NOT INITIAL. <fs_alv>-zbz = <fs_alv>-zbz+1. ENDIF. ENDIF. " --- 供应商价格处理 --- IF <fs_alv>-knttp ='F'. CHECK <fs_alv>-lifnr1 IS NOT INITIAL. SELECT SINGLE name1 INTO @<fs_alv>-zname1 FROM lfa1 WHERE lifnr = @<fs_alv>-lifnr1. lv_tmp_werks = <fs_alv>-werks. lv_ekorg = COND #(WHEN lv_tmp_werks ='1000'THEN'1000'WHEN lv_tmp_werks ='1100'THEN'1000'WHEN lv_tmp_werks ='2000'THEN'2000'WHEN lv_tmp_werks ='3000'THEN'3000'ELSE''). SELECT SINGLE mwskz INTO @<fs_alv>-mwskz1 FROM eine WHERE infnr = @<fs_alv>-infnr AND ekorg = @lv_ekorg AND esokz = @<fs_alv>-pstyp AND werks = @<fs_alv>-werks AND loekz =''. " 注意:这里需取 b 表中的 kbetr,kpein,konwa SELECT b~kbetr,b~kpein,b~konwa INTO TABLE@DATA(lt_p2)FROM a025 AS a INNER JOIN konp AS b ON b~knumh = a~knumh WHERE a~lifnr = @<fs_alv>-lifnr1 AND a~ekorg = @lv_ekorg AND a~infnr = @<fs_alv>-infnr AND a~werks = @<fs_alv>-werks AND a~kschl ='PB00'AND a~datbi GE @sy-datum AND a~datab LE @sy-datum. IF sy-subrc = 0. READ TABLE lt_p2 INTODATA(ls_p2)INDEX 1. <fs_alv>-kbetr1 = ls_p2-kbetr. <fs_alv>-kpein1 = ls_p2-kpein. <fs_alv>-konwa1 = ls_p2-konwa. ENDIF. ELSE. CLEAR <fs_alv>-infnr. IF <fs_alv>-bsart <>'Z06'AND <fs_alv>-bsart <>'Z12'. CLEAR <fs_alv>-lifnr1. ENDIF. CLEAR lrs_lifnr[]. IF <fs_alv>-lifnr1 IS NOT INITIAL. lrs_lifnr = VALUE #((sign ='I'option ='EQ'low = <fs_alv>-lifnr1)). SELECT SINGLE name1 INTO @<fs_alv>-zname1 FROM lfa1 WHERE lifnr = @<fs_alv>-lifnr1. ENDIF. lv_ekorg = COND #(WHEN <fs_alv>-werks ='1000'THEN'1000'WHEN <fs_alv>-werks ='1100'THEN'1000'WHEN <fs_alv>-werks ='2000'THEN'2000'WHEN <fs_alv>-werks ='3000'THEN'3000'ELSE''). CLEAR lt_price. SELECT DISTINCT a~matnr,b~werks,b~ekorg,a~lifnr,a~infnr,c~name1 AS zname,b~mwskz INTO CORRESPONDING FIELDS OF TABLE @lt_price FROM eina AS a INNER JOIN eine AS b ON b~infnr = a~infnr AND b~werks = @<fs_alv>-werks AND b~ekorg = @lv_ekorg INNER JOIN lfa1 AS c ON c~lifnr = a~lifnr WHERE a~lifnr IN @lrs_lifnr AND a~matnr = @<fs_alv>-matnr AND a~loekz =''AND b~loekz =''. LOOP AT lt_price ASSIGNINGFIELD-SYMBOL(<fs_price>). lv_tmp_matnr = <fs_price>-matnr. lv_tmp_lifnr = <fs_price>-lifnr. lv_tmp_esokz = <fs_alv>-pstyp. lv_tmp_ekorg = <fs_price>-ekorg. lv_tmp_kschl ='PB00'. SELECT SINGLE b~kbetr,b~kpein,b~konwa INTO(@<fs_price>-kbetr,@<fs_price>-kpein,@<fs_price>-konwa)FROM a017 AS a INNER JOIN konp AS b ON b~knumh = a~knumh WHERE a~matnr = @lv_tmp_matnr AND a~lifnr = @lv_tmp_lifnr AND a~kschl = @lv_tmp_kschl AND a~esokz = @lv_tmp_esokz AND a~ekorg = @lv_tmp_ekorg AND a~datbi GE @sy-datum AND a~datab LE @sy-datum. IF sy-subrc <> 0. <fs_price>-delete ='X'. ENDIF. ENDLOOP. DELETE lt_price WHERE delete ='X'. SORT lt_price BY lifnr. lv_index = 0. LOOP AT lt_price ASSIGNINGFIELD-SYMBOL(<fs_final>)FROM 1 TO 4. lv_index += 1. ASSIGN COMPONENT |LIFNR{lv_index}| OF STRUCTURE <fs_alv> TO <fs_val>. <fs_val> = <fs_final>-lifnr. ASSIGN COMPONENT |ZNAME{lv_index}| OF STRUCTURE <fs_alv> TO <fs_val>. <fs_val> = <fs_final>-zname. ASSIGN COMPONENT |KBETR{lv_index}| OF STRUCTURE <fs_alv> TO <fs_val>. <fs_val> = <fs_final>-kbetr. ASSIGN COMPONENT |KPEIN{lv_index}| OF STRUCTURE <fs_alv> TO <fs_val>. <fs_val> = <fs_final>-kpein. ASSIGN COMPONENT |KONWA{lv_index}| OF STRUCTURE <fs_alv> TO <fs_val>. <fs_val> = <fs_final>-konwa. ASSIGN COMPONENT |MWSKZ{lv_index}| OF STRUCTURE <fs_alv> TO <fs_val>. <fs_val> = <fs_final>-mwskz. ENDLOOP. ENDIF. ENDLOOP. output-type = 'S'. output-message = |查询成功。当前第{lv_page}页,本页读取{lines(output-body)}条。共计{output-total_count}条数据。|. ENDFUNCTION.